hutongqing
2024-12-10 8d341db9d2d5699d527c88c935f0c4ce255a57a4
代码提交
已添加243个文件
已修改100个文件
已删除18个文件
59163 ■■■■■ 文件已修改
代码管理/WMS/WIDESEA_WMSClient/.eslintrc.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/.gitignore 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/README.md 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/babel.config.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/config/buttons.js 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/package-lock.json 13937 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/package.json 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/public/index.html 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/public/static/login_bg.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/public/wcslogo.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/public/wms_d.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/App.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/api/http.js 324 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/api/permission.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/api/useTest.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/css/common.less 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/element-icon/fonts/element-icons.ttf 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/element-icon/fonts/element-icons.woff 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/element-icon/icon.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/imgs/error-img.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/imgs/error.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/imgs/wms_d.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/imgs/wms_x.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/script/common.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/script/extend.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/assets/script/testFormExtend.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/AsyncLoading.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/Audit.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/Empty.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ErrorMsg.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/Icons.vue 345 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/QuickSearch.vue 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/RouterLoading.vue 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/UploadExcel.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/AuditHis.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/ViewGrid.less 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/ViewGrid.vue 806 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/ViewGridAudit.vue 427 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/ViewGridCustomColumn.js 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/ViewGridCustomColumn.vue 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/detailMethods.js 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/index.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/methods.js 1684 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/props.js 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/serviceFilter.js 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolBox.vue 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolElementMenu.vue 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolElementMenuChild.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolForm.vue 1487 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolForm/VolFormRender.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/DownloadForm.js 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/VolFormDraggable.vue 1159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/VolFormPreview.vue 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/formTemplate.js 664 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/index.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/options.js 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/templateCode.js 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolHeader.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolTable.vue 1874 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolTable/VolTableRender.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/basic/VolUpload.vue 880 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/redirect/401.vue 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/redirect/404.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/redirect/Message.vue 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/redirect/RedirectError.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/components/redirect/coding.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/basic/CachePoint.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/basic/areaInfo.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/basic/areaRouter.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/basic/extend/GetLocationStatus.vue 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/basic/locationInfo.js 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/basic/materielInfo.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/basic/roadwayInfo.js 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/basic/warehouse.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/inbound/inboundOrderDetail.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/inbound/receiveOrder.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/SelectedStock.vue 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/StockSelect.vue 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue 371 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/outbound/outboundOrderDetail.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/record/locationStatusChangeRecord.js 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/record/stockQuantityChangeRecord.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/stock/stockInfo.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/stock/stockInfoDetail.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/stock/stockView.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Dictionary.js 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/system/Sys_DictionaryList.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Log.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Role.js 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Role1.js 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/system/Sys_User.js 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/system/Sys_User/Sys_UserGridHeader.vue 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/system/system/Sys_Department.js 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/taskinfo/task.js 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/taskinfo/task_hty.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/main.js 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/router/charts.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/router/index.js 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/router/redirect.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/router/viewGird.js 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/store/index.js 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/uitils/common.js 344 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/Home.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/Index.vue 834 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/Login.vue 408 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/basic/areaInfo.vue 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/basic/areaRouter.vue 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/basic/cachePoint.vue 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/basic/locationInfo.vue 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/basic/materielInfo.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/basic/roadwayInfo.vue 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/basic/warehouse.vue 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/bigdata.vue 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/bigdata/IviewCircle.vue 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/bigdata/chart-options.js 551 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/bigdata/head_bg.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/bigdata/layout.less 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/chart.vue 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/chartOptions.js 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/flex.vue 386 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/formChart.vue 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/formOptions.js 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/home/home-chart-options.js 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue 319 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/inbound/inboundOrderDetail.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/inbound/receiveOrder.vue 376 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/index/Message.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/index/MessageConfig.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/index/index.less 644 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/outbound/outboundOrder.vue 328 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/outbound/outboundOrderDetail.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/record/locationStatusChangeRecord.vue 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/stock/stockInfoDetail.vue 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue 327 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/Permission.vue 359 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/Permission/RoleTree.vue 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/PermissionPDA.vue 369 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_Dictionary.vue 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_DictionaryList.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_Log.vue 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_Menu.vue 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_Role.vue 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_Role1.vue 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_User.vue 369 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/UserInfo.vue 317 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/system/Sys_Department.vue 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/system/test.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/taskinfo/task.vue 231 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_hty.vue 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/tests/unit/example.spec.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/vue.config.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/yarn.lock 10203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/5719e6ae-bc65-4344-93bf-c0d23dd5d595.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/6c6ca66c-f03a-48f7-9fb7-7620f4736346.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/789398d4-ad10-4b21-9f9c-c017ed2e4aa0.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/7dfb58b4-b4db-4726-99ab-289029af1540.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/914d9c3f-57db-4637-bc40-52081424fde2.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/e2441919-0f15-4240-aa6e-d0b378dfd0ba.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/eef0aa91-791e-44dd-b321-3146cf9e9a18.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/f3502ed8-fc43-47df-b9a2-74d7c2feb215.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/f91e73eb-1823-4174-b99b-0eb163ec64f8.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/fed10872-4afc-4516-bd7e-bb67d0b38147.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalRepository/ApprovalFlowRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalRepository/ApprovalNodeRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalRepository/ApprovalTaskRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalRepository/NodeTransitionRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalRepository/WIDESEA_ApprovalRepository.csproj 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalService/ApprovalFlowService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalService/ApprovalNodeService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalService/ApprovalTaskService.cs 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalService/WIDESEA_ApprovalService.csproj 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_BasicRepository/LocationInfoRepository.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_BasicRepository/WarehouseRepository.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/Base/LocationInfoService.cs 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/Base/WarehouseService.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/Service/LocationInfoService.cs 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckRepository/CheckOrderRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckRepository/CheckOrderResultRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckRepository/WIDESEA_CheckRepository.csproj 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckService/CheckOrderResultService.cs 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckService/CheckOrderService.cs 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckService/WIDESEA_CheckService.csproj 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/CommonEnum/AuditStatusEnum.cs 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/CommonEnum/UploadStatusEnum.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/LocationEnum/LocationChangeType.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/CheckOrderEnum.cs 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InOrderStatusEnum.cs 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InOrderTypeEnum.cs 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InboundOrderMenu.cs 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutOrderStatusEnum.cs 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutOrderTypeEnum.cs 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutboundOrderEnum.cs 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/PurchaseOrderEnum.cs 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/ReceiveOrderEnum.cs 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/SynchronizationFlagEmun.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockChangeTypeEnum.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/AOP/SqlSugarAop.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/App.cs 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Attributes/SequenceAttirbute.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/BaseController/ApiBaseController.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/BaseModels/PageDataOptions.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/BaseRepository/IRepository.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/BaseRepository/RepositoryBase.cs 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/BaseServices/ServiceBase.cs 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/CodeConfigEnum/AnalysisCodeEnum.cs 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/CodeConfigEnum/AnalysisFormatTypeEnum.cs 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/CodeConfigEnum/RuleCodeEnum.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/DB/MainDb.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/DB/Models/BaseWarehouseEntity.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Enums/AuthorityScopeEnum.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Enums/OperateTypeEnum.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Extensions/AutofacModuleRegister.cs 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Extensions/SqlsugarSetup.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Extensions/WebSocketSetup.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Helper/CodeAnalysisHelper.cs 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Helper/ObjectExtension.cs 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/HostedService/PermissionDataHostService.cs 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/HostedService/SeedDataHostedService.cs 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/HttpContextUser/AspNetUser.cs 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/LogHelper/Logger.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Utilities/EntityProperties.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Utilities/ModelValidate.cs 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Utilities/ParamsValidator.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/WIDESEA_Core.csproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Basic/MatSerNumAnalysisModel.cs 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/ERP/PurchaseOrderModel.cs 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/ERP/ReceiveOrderModel.cs 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Inbound/InboundOrderAddDTO.cs 54 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Inbound/InboundOrderDetailAddDTO.cs 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MatSerialNumberDTO.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Stock/StockViewDTO.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/System/VueDictionaryDTO.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_External/ERPService/ERPInvokeService.cs 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_External/IERPService/IERPInvokeService.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_External/Model/PurchaseOrderModel.cs 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_External/WIDESEA_External.csproj 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalRepository/IApprovalFlowRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalRepository/IApprovalNodeRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalRepository/IApprovalTaskRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalRepository/INodeTransitionRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalRepository/WIDESEA_IApprovalRepository.csproj 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalService/IApprovalFlowService.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalService/IApprovalTaskService.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalService/WIDESEA_IApprovalService.csproj 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IBasicRepository/ILocationInfoRepository.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/ILocationInfoService.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckRepository/ICheckOrderRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckRepository/ICheckOrderResultRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckRepository/WIDESEA_ICheckRepository.csproj 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckService/ICheckOrderResultService.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckService/ICheckOrderService.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckService/WIDESEA_ICheckService.csproj 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundRepository/IInboundRepository.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundRepository/IPurchaseOrderDetailRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundRepository/IPurchaseOrderRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundRepository/IReceiveOrderDetailRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundRepository/IReceiveOrderRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IInboundOrderDetailService.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IInboundOrderService.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IInboundService.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IPurchaseOrderService.cs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IReceiveOrderDetailService.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IReceiveOrderService.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutStockLockInfoService.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundOrderService.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IRecordService/ILocationStatusChangeRecordSetvice.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IRecordService/IStockQuantityChangeRecordService.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ISystemRepository/ISys_RoleDataPermissionRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ISystemService/ISys_RoleService.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITask_HtyService.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundRepository/InboundRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundRepository/PurchaseOrderDetailRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundRepository/PurchaseOrderRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundRepository/ReceiveOrderDetailRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundRepository/ReceiveOrderRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Base/InboundOrderDetailService.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Base/InboundOrderDetail_HtyService.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Base/InboundOrderService.cs 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Base/InboundOrder_HtyService.cs 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderDetailService.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderDetail_HtyService.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs 285 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrder_HtyService.cs 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/InboundService.cs 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/PurchaseOrderService.cs 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/ReceiveOrderDetailService.cs 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/ReceiveOrderService.cs 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Service/InboundOrderDetailService.cs 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Service/InboundOrderService.cs 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/WIDESEA_InboundService.csproj 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/ApprovalFlow/Dt_ApprovalFlow.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/ApprovalFlow/Dt_ApprovalNode.cs 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/ApprovalFlow/Dt_ApprovalTask.cs 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/ApprovalFlow/Dt_NodeTransition.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Basic/Dt_LocationInfo.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Basic/Dt_MaterielInfo.cs 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Basic/Dt_SupplierInfo.cs 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Basic/Dt_Warehouse.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Check/Dt_CheckOrder.cs 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Check/Dt_CheckOrderResult.cs 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_InboundOrder.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_InboundOrderDetail.cs 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_PurchaseOrder.cs 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_PurchaseOrderDetail.cs 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_ReceiveOrder.cs 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_ReceiveOrderDetail.cs 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Record/Dt_StockQuantityChangeRecord.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Stock/Dt_StockInfo.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Stock/Dt_StockInfoDetail.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_Log.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_Role.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_RoleDataPermission.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_User.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/TaskInfo/Dt_Task.cs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/TaskInfo/Dt_Task_Hty.cs 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/Base/OutStockLockInfoService.cs 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/Base/OutboundOrderDetailService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/Base/OutboundOrderDetail_HtyService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/Base/OutboundOrderService.cs 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/Base/OutboundOrder_HtyService.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_RecordService/Service/LocationStatusChangeRecordSetvice.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_RecordService/Service/StockQuantityChangeRecordService.cs 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockRepository/StockInfoRepository.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/Base/StockInfoService.cs 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/Base/StockInfo_HtyService.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/Base/StockViewService.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/Service/StockInfoService.cs 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemRepository/Sys_DictionaryRepository.cs 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemRepository/Sys_RoleDataPermissionRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemRepository/Sys_UserRepository.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_DictionaryService.cs 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_RoleService.cs 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_UserService.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemService/WIDESEA_SystemService.csproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/Task_HtyService.cs 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer.sln 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Approval/ApprovalFlowController.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Approval/ApprovalTaskController.cs 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Basic/LocationInfoController.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Check/CheckOrderController.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Check/CheckOrderResultController.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/ERP/ErpController.cs 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/ReceiveOrderController.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/ReceiveOrderDetailController.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutStockLockInfoController.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundOrderController.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Filter/CustomProfile.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/wwwroot/WIDESEA_DB.DBSeed.Json/Sys_Dictionary.tsv 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/wwwroot/WIDESEA_DB.DBSeed.Json/Sys_User.tsv 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/.eslintrc.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
module.exports = {
  root: true,
  env: {
    node: true
  },
  'extends': [
    'plugin:vue/vue3-essential',
    'eslint:recommended'
  ],
  parserOptions: {
    parser: 'babel-eslint'
  },
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
  },
  overrides: [
    {
      files: [
        '**/__tests__/*.{j,t}s?(x)',
        '**/tests/unit/**/*.spec.{j,t}s?(x)'
      ],
      env: {
        mocha: true
      }
    }
  ]
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/.gitignore
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/README.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
# vol.vue3
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Run your unit tests
```
npm run test:unit
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
### npm run serve启动异常:
    ä½¿ç”¨cmd输入node -v查看版本,如果是18.+版本,请将package.json中第五行scripts中的内容替换为:
"scripts": {
    "serve": " SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
    "build": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "lint": "vue-cli-service lint"
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/babel.config.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/config/buttons.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,159 @@
let buttons = [{
    name: "查 è¯¢",
    value: 'Search',
    icon: 'el-icon-search',
    class: '',
    type: 'primary',
    onClick: function () {
        this.search();
    }
},
{
    name: "新 å»º",
    icon: 'el-icon-plus',
    value: 'Add',
    class: '',
    //  plain:true,
    type: 'success',
    // plain:true,
    onClick: function () {
        this.add();
    }
},
{
    name: "编 è¾‘",
    icon: 'el-icon-edit',
    value: 'Update',
    // plain:true,
    class: '',
    type: 'primary',
    onClick: function () {
        this.edit();
    }
},
{
    name: "删 é™¤",
    icon: 'el-icon-delete',
    class: '',
    value: 'Delete',
    type: 'danger',
    onClick: function () {
        this.del();
    }
},
{
    name: "审 æ ¸",
    icon: 'el-icon-check',
    class: '',
    value: 'Audit',
    plain: true,
    type: 'primary',
    onClick: function () {
        this.audit();
    }
},
{
    name: "导 å…¥",
    icon: 'el-icon-top',
    class: '',
    type: 'success',
    plain: true,
    value: 'Import',
    onClick: function () {
        this.import();
    }
},
{
    name: "导 å‡º",
    icon: 'el-icon-bottom',
    type: 'success',
    plain: true,
    value: 'Export',
    onClick: function () {
        this.export();
    }
},{
    name: "启 ç”¨",
    icon: '',
    class: '',
    value: 'Enable',
    type: 'primary',
    onClick: function () {
    }
},
{
    name: "禁 ç”¨",
    icon: '',
    class: '',
    value: 'Disable',
    type: 'danger',
    onClick: function () {
    }
},
{
    name: "手 åЍ å®Œ æˆ",
    icon: '',
    class: '',
    value: 'TaskHandCompleted',
    onClick: function () {
    }
},
{
    name: "取 æ¶ˆ ä»» åŠ¡",
    icon: '',
    class: '',
    value: 'TaskHandCancel',
    onClick: function () {
    }
},
{
    name: "任务恢复",
    icon: '',
    class: '',
    value: 'TaskRecovery',
    type: 'danger',
    onClick: function () {
    }
},
{
    name: "查看完整路由",
    icon: '',
    class: '',
    value: 'ViewAllRouter',
    type: 'info',
    onClick: function () {
    }
},
{
    name: "路由配置",
    icon: '',
    class: '',
    value: 'AddRouters',
    type: 'success',
    onClick: function () {
    }
},
{
    name: "回滚到上一步",
    icon: '',
    class: '',
    value: 'Previous',
    type: 'danger',
    onClick: function () {
    }
},
{
    name: "跳转到下一步",
    icon: '',
    class: '',
    value: 'Next',
    type: 'warning',
    onClick: function () {
    }
},
]
export default buttons
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/package-lock.json
¶Ô±ÈÐÂÎļþ
ÎļþÌ«´ó
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/package.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
{
  "name": "wideseawcs",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@element-plus/icons-vue": "^2.1.0",
    "@microsoft/signalr": "^6.0.4",
    "ali-oss": "^6.17.1",
    "axios": "^0.21.1",
    "core-js": "^3.6.5",
    "echarts": "^5.0.2",
    "element-plus": "^2.2.14",
    "less": "^4.1.1",
    "vue": "^3.2.37",
    "vue-draggable-next": "^2.0.1",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0"
  },
  "devDependencies": {
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-unit-mocha": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "@vue/test-utils": "^2.0.0-0",
    "babel-eslint": "^10.1.0",
    "chai": "^4.1.2",
    "cross-env": "^7.0.3",
    "less": "^4.1.1",
    "less-loader": "^7.3.0",
    "sass": "^1.78.0",
    "sass-loader": "^16.0.1",
    "stylus": "^0.54.7",
    "stylus-loader": "^3.0.2"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "@vue/standard"
    ],
    "rules": {
      "indent": [
        1,
        4
      ]
    },
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "eslintIgnore": [
    "*"
  ]
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/public/index.html
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
<!DOCTYPE html>
<html lang="">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <meta name="keywords" content=".netccore,dotnet core,vue,element,element plus,vue3" />
  <meta name="description" content="" />
  <link rel="icon" href="<%= BASE_URL %>wms_d.png">
  <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
  <noscript>
    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
      Please enable it to continue.</strong>
  </noscript>
  <div id="app"></div>
  <!-- built files will be auto injected -->
</body>
</html>
<style>
  html,
  body {
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
  }
  * {
    box-sizing: border-box;
  }
  .el-loading {
    z-index: 999999;
  }
  .el-table th {
    display: table-cell !important;
  }
  .el-loading .el-loading-spinner {
    padding: 7px;
    background: #ececec;
    width: 200px;
    color: red;
    left: 0;
    right: 0;
    margin: 0 auto;
    border-radius: 5px;
    border: 1px solid #a0a0a0;
  }
  h1,
  h2,
  h3,
  h4 {
    margin: 0;
  }
  .v-dialog {
    border-radius: 5px;
    top: 50%;
    /* margin-top: -220px !important; */
  }
  .v-dialog .el-dialog__header {
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
    padding: 0px 13px;
    line-height: 53px;
    border-bottom: 1px solid #e2e2e2;
    height: 50px;
    color: white;
    font-weight: bold;
    font-size: 14px;
    background-image: linear-gradient(135deg, #0cd7bd 10%, #50c3f7);
  }
  .v-dialog .el-dialog__header .el-dialog__headerbtn {
    top: 3px;
    right: 0px;
  }
  .v-dialog .el-dialog__header .el-dialog__headerbtn .el-dialog__close {
    font-size: 19px;
    color: white;
  }
  .v-dialog .el-dialog__body {
    padding: 0;
  }
  .el-message {
    z-index: 3500 !important;
  }
  .v-date-range .el-input__inner {
    padding: 0 15px 0 8px
  }
  .v-date-range .el-input__suffix .el-input__icon {
    display: table-caption;
    background: white;
    margin: 1px;
    height: auto;
    margin-right: -4px;
    height: 33px;
    width: 19px;
    font-size: 13px;
    border-top-right-radius: 3px;
    border-bottom-right-radius: 3px;
  }
  .v-date-range .el-icon-circle-check {
    display: none !important;
  }
  .v-dialog .el-dialog__header {
    margin-right: 0;
  }
  .el-button {
    font-size: 12px !important;
  }
  .el-button--small {
    padding: 0px 15px !important;
    height: 32px;
  }
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/public/static/login_bg.png
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/public/wcslogo.png
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/public/wms_d.png
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/App.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
<template>
  <div id="nav"></div>
  <el-config-provider :locale="locale">
    <router-view />
  </el-config-provider>
</template>
<script>
import { ElConfigProvider } from "element-plus";
import zhCn from "element-plus/lib/locale/lang/zh-cn";
export default {
  name: "vol_app",
  components: {
    [ElConfigProvider.name]: ElConfigProvider, //添加组件
  },
  data() {
    return {
      locale: zhCn,
    };
  },
  created() {
  },
  methods: {
  },
};
</script>
<style lang="stylus">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  height: 100%;
  width: 100%;
}
.el-alert--error.is-light {
  border: 1px solid #ffe0e0;
}
.el-alert--error.is-light {
  color: #f74444 !important;
}
.el-alert--warning.is-light {
  border: 1px solid #ffe6c1;
}
.el-alert--info.is-light {
  border: 1px solid #e6e5e5;
}
.el-alert--info .el-alert__description {
  color: #6b6b6b !important;
}
.el-alert--warning.is-light {
  background-color: #fdf6ec;
  color: #d68409 !important;
}
.el-alert--success.is-light {
  border: 1px solid #cdf7b8;
}
.el-alert--success.is-light .el-alert__description {
  color: #3baf02 !important;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/api/http.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,324 @@
import axios from 'axios'
import store from '../store/index'
// import {getCurrentInstance} from 'vue'
import { useRouter, useRoute } from 'vue-router'
const router = useRouter();
axios.defaults.timeout = 50000;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
import { ElLoading as Loading, ElMessage as Message } from 'element-plus';
let loadingInstance;
let loadingStatus = false;
if (process.env.NODE_ENV == 'development') {
    axios.defaults.baseURL = 'http://127.0.0.1:9293/';
}
else if (process.env.NODE_ENV == 'debug') {
    axios.defaults.baseURL = 'http://127.0.0.1:8098/';
}
else if (process.env.NODE_ENV == 'production') {
    axios.defaults.baseURL = 'http://115.159.85.185:9291/';
}
if (!axios.defaults.baseURL.endsWith('/')) {
    axios.defaults.baseURL+="/";
}
let ipAddress = axios.defaults.baseURL;
axios.interceptors.request.use((config) => {
    return config;
}, (error) => {
    return Promise.reject(error);
});
axios.interceptors.response.use((res) => {
    closeLoading();
    checkResponse(res);
    return Promise.resolve(res);
}, (error) => {
    closeLoading();
    let httpMessage = '';
    if (error.response) {
        if (error.response.status == '401') {
            if (error.response.data && error.response.data.code == 401) {
                if (!localStorage.getItem('user')) {
                    Message.error({
                        showClose: true,
                        message: '登陆已过期',
                        type: 'error'
                    });
                }
                toLogin();
                return;
            }
        }
        if (error.response.status == '404') {
            httpMessage = "未找到请求地址";
        }
        else if (error.response.data && error.response.data.message) {
            httpMessage = error.response.data.message;
        }
    }
    else {
        httpMessage = '服务器处理异常'
    }
    redirect(httpMessage);
    return Promise.reject(error.response || {}, httpMessage);
});
function closeLoading () {
    if (loadingInstance) {
        loadingInstance.close();
    }
    if (loadingStatus) {
        loadingStatus = false;
        if (loadingInstance) {
            loadingInstance.close();
        }
    }
}
function checkResponse (res) {
    //刷新token
    if (!res.headers) {
        if (res.getResponseHeader("widesea_exp") == "1") {
            replaceToken();
        }
    }
    else if (res.headers.widesea_exp == "1") {
        replaceToken();
    }
}
const _Authorization = 'Authorization';
function showLoading (loading) {
    if (!loading || loadingStatus) {
        return;
    }
    loadingInstance = Loading.service({
        lock: true,
        text: 'Loading',
        customClass:"http-loading",
        background: typeof loading == "string" ? loading : '正在处理.....',
        background: 'rgba(58, 61, 63, 0.32)'
    });
}
function getToken () {
    return store.getters.getToken();
}
/*
  url
  params请求后台的参数,如:{name:123,values:['a','b','c']}
  loading是否显示遮罩层,可以传入true.false.及提示文本
  config配置信息,如{timeout:3000,headers:{token:123}}
*/
function post (url, params, loading, config) {
    showLoading(loading);
    axios.defaults.headers[_Authorization] = getToken();
    return new Promise((resolve, reject) => {
        axios.post(url, params, config)
            .then(response => {
                resolve(response.data);
            }, err => {
                reject(err && err.data && err.data.message ? err.data.message : '服务器处理异常');
            })
            .catch((error) => {
                reject(error)
            })
    })
}
//=true异步请求时会显示遮罩层,=字符串,异步请求时遮罩层显示当前字符串
function get (url, param, loading, config) {
    showLoading(loading);
    axios.defaults.headers[_Authorization] = getToken();
    return new Promise((resolve, reject) => {
        axios.get(url, config)
            .then(response => {
                // console.log(response)
                resolve(response.data)
            }, err => {
                reject(err)
            })
            .catch((error) => {
                reject(error)
            })
    })
}
//url:url地址
//params:请求参数
//fileName:下载的文件名
//loading:是否显示加载状态
function download (url, params, fileName, loading,callback) {
    fileName = fileName.replace(">", ">").replace("<", "<");
    post(url, params, loading, { responseType: 'blob' }).then(content => {
        const blob = new Blob([content])
        if ('download' in document.createElement('a')) { // éžIE下载
            const elink = document.createElement('a')
            elink.download = fileName
            elink.style.display = 'none'
            elink.href = URL.createObjectURL(blob)
            document.body.appendChild(elink)
            elink.click()
            URL.revokeObjectURL(elink.href) // é‡Šæ”¾URL å¯¹è±¡
            document.body.removeChild(elink)
        } else { // IE10+下载
            navigator.msSaveBlob(blob, fileName)
        }
        callback&&callback();
    })
}
function createXHR () {
    if (XMLHttpRequest) {
        return new XMLHttpRequest();
    }
    if (ActiveXObject) {
        if (typeof arguments.callee.activeXString != "string") {
            var versions = [
                "MSXML2.XMLHttp.6.0",
                "MSXML2.XMLHttp",
                "MSXML2.XMLHttp.3.0"
            ];
            for (var i = 0; i < versions.length; i++) {
                try {
                    new ActiveXObject(versions[i]);
                    arguments.callee.activeXString = versions[i];
                    break;
                } catch (e) {
                    console.log(e);
                }
            }
        }
        return new ActiveXObject(arguments.callee.activeXString);
    }
}
function redirect (responseText, message) {
    try {
        let responseData = typeof responseText == 'string' ? JSON.parse(responseText) : responseText;
        if ((responseData.hasOwnProperty('code') && responseData.code == 401)
            || (responseData.data && responseData.data.code == 401)) {
            closeLoading();
            toLogin();
        } else {
            if (message) {
                Message.error({
                    showClose: true,
                    message: message,
                    type: 'error'
                });
            }
        }
    } catch (error) {
        console.log(error);
        Message.error({
            showClose: true,
            message: responseText,
            type: 'error'
        });
    }
}
function toLogin () {
    //  const vueinstance=  getCurrentInstance();
    if (window.location.hash) {
        window.location.href = window.location.origin + '/#/login'
        return
    }
    window.location.href = window.location.origin + '/login'
    //  router.push({ path: '/login', params: { r: Math.random() } });
}
//动态刷新token
function replaceToken () {
    ajax({
        url: "/api/User/replaceToken",
        param: {},
        json: true,
        success: function (x) {
            if (x.status) {
                let userInfo = store.getters.getUserInfo();
                userInfo.token = x.data;
                store.commit('setUserInfo', userInfo);
            } else {
                console.log(x.message);
                toLogin();
            }
        },
        errror: function (ex) {
            console.log(ex);
            toLogin();
        },
        type: "post",
        async: false
    });
}
function ajax (param) {
    let httpParam =
        Object.assign({
            url: '', headers: {},
            param: {}, json: true,
            success: function () { },
            errror: function () { },
            type: 'post', async: true
        }, param);
    httpParam.url = axios.defaults.baseURL + httpParam.url.replace(/\/?/, '');
    httpParam.headers[_Authorization] = getToken();
    var xhr = createXHR();
    xhr.onreadystatechange = function () {
        if (xhr.status == 403 || xhr.status == 401) {
            redirect(xhr.responseText);
            return;
        }
        checkResponse(xhr);
        if (xhr.readyState == 4 && xhr.status == 200) {
            httpParam.success(httpParam.json ? JSON.parse(xhr.responseText) : xhr.responseText);
            return;
        }
        if (xhr.status != 0 && xhr.readyState != 1) {
            httpParam.errror(xhr);
        }
    };
    //初始化请求
    xhr.open(
        httpParam.type,
        httpParam.url,
        httpParam.async
    );
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    for (const key in httpParam.headers) {
        xhr.setRequestHeader(key, httpParam.headers[key]);
    }
    let dataStr = '';
    for (const key in httpParam.param) {
        dataStr += key + "=" + httpParam.param[key];
    }
    try {
        xhr.send(dataStr);
    } catch (error) {
        toLogin();
    }
}
ajax.post = function (url, param, success, errror) {
    ajax({ url: url, param: param, success: success, error: errror, type: 'post' })
}
ajax.get = function (url, param, success, errror) {
    ajax({ url: url, param: param, success: success, error: errror, type: 'get' })
}
export default { post, get,download, ajax, ipAddress }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/api/permission.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
import http from '@/../src/api/http.js'
import buttons from '@/../config/buttons.js'
import store from '../store/index'
import { useRouter } from 'vue-router'
let permission = {
    getMenu() {
        return http.get("/api/getTreeMenu");
    }, getButtons(path, extra, table, tableName) {//extra自定额外按钮
       //extra自定额外按钮
    //table获取指定表的权限
    if (table) {
        table = '/' + table;
      }
      let permission = store.getters.getPermission(table || path);
      if (!permission) {
        permission = store.getters.getPermission(path.substring(1));
        if (!permission) {
          if ((tableName || '').indexOf('/') != -1) {
            let arr = tableName.split('/');
            tableName = arr[arr.length - 1];
          }
          permission = store.getters.getPermission('/' + tableName);
          if (!permission) {
            permission = (store.state.permission||[]).find(x => x.tableName ==tableName);
            if (!permission) {
              to401();
              return;
            }
          }
        }
      }
      let permissions = permission.permission; //.split(',');
      let gridButtons = buttons.filter((item) => {
        return !item.value || permissions.indexOf(item.value) != -1;
      });
      if (extra && extra instanceof Array) {
        gridButtons.push(...extra);
      }
      return gridButtons;
    }, to401() {
        to401();
    }
}
function to401() {
    const router = useRouter();
    router.push({
        path: '/401'
    });
}
export default permission;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/api/useTest.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,9 @@
const tipxx = {
    install: function (vue) {
        alert(1);
        vue.prototype.$tip = function () {
            alert('测试use')
        };
    }
}
export default { tipxx }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/css/common.less
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
*{
    box-sizing:border-box;
    -moz-box-sizing:border-box; /* Firefox */
    -webkit-box-sizing:border-box; /* Safari */
}
.el-pager li{
    font-weight: 100;
    margin-right: 9px;
    border: 1px solid #eee;
    border-radius: 3px;
    min-width: 28px;
}
.el-pager li.active,.el-pager li:hover{
    background: #ed4014;
    color: white;
}
.el-pagination__editor.el-input .el-input__inner{
    height: 23px;
}
.animated {
    -webkit-animation-duration: 0.5s;
    animation-duration: 0.5s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
  }
  @media (print), (prefers-reduced-motion) {
    .animated {
      -webkit-animation: unset !important;
      animation: unset !important;
      -webkit-transition: none !important;
      transition: none !important;
    }
  }
  @-webkit-keyframes fadeInDown {
    from {
      opacity: 1;
      -webkit-transform: translate3d(0, -100%, 0);
      transform: translate3d(0, -100%, 0);
    }
    to {
      opacity: 1;
      -webkit-transform: translate3d(0, 0, 0);
      transform: translate3d(0, 0, 0);
    }
  }
  @keyframes fadeInDown {
    from {
      opacity: 0;
      -webkit-transform: translate3d(0, -100%, 0);
      transform: translate3d(0, -100%, 0);
    }
    to {
      opacity: 1;
      -webkit-transform: translate3d(0, 0, 0);
      transform: translate3d(0, 0, 0);
    }
  }
  .fadeInDown {
    -webkit-animation-name: fadeInDown;
    animation-name: fadeInDown;
  }
  .ivu-message{
    z-index: 999999999 !important;
  }
  .ivu-form-item-content{
    text-align: left;
  }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/element-icon/fonts/element-icons.ttf
Binary files differ
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/element-icon/fonts/element-icons.woff
Binary files differ
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/element-icon/icon.css
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
@font-face{font-family:element-icons;src:url(fonts/element-icons.woff) format("woff"),url(fonts/element-icons.ttf) format("truetype");font-weight:400;font-display:"auto";font-style:normal}[class*=" el-icon-"],[class^=el-icon-]{font-family:element-icons!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;vertical-align:baseline;display:inline-block;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-icon-ice-cream-round:before{content:"\e6a0"}.el-icon-ice-cream-square:before{content:"\e6a3"}.el-icon-lollipop:before{content:"\e6a4"}.el-icon-potato-strips:before{content:"\e6a5"}.el-icon-milk-tea:before{content:"\e6a6"}.el-icon-ice-drink:before{content:"\e6a7"}.el-icon-ice-tea:before{content:"\e6a9"}.el-icon-coffee:before{content:"\e6aa"}.el-icon-orange:before{content:"\e6ab"}.el-icon-pear:before{content:"\e6ac"}.el-icon-apple:before{content:"\e6ad"}.el-icon-cherry:before{content:"\e6ae"}.el-icon-watermelon:before{content:"\e6af"}.el-icon-grape:before{content:"\e6b0"}.el-icon-refrigerator:before{content:"\e6b1"}.el-icon-goblet-square-full:before{content:"\e6b2"}.el-icon-goblet-square:before{content:"\e6b3"}.el-icon-goblet-full:before{content:"\e6b4"}.el-icon-goblet:before{content:"\e6b5"}.el-icon-cold-drink:before{content:"\e6b6"}.el-icon-coffee-cup:before{content:"\e6b8"}.el-icon-water-cup:before{content:"\e6b9"}.el-icon-hot-water:before{content:"\e6ba"}.el-icon-ice-cream:before{content:"\e6bb"}.el-icon-dessert:before{content:"\e6bc"}.el-icon-sugar:before{content:"\e6bd"}.el-icon-tableware:before{content:"\e6be"}.el-icon-burger:before{content:"\e6bf"}.el-icon-knife-fork:before{content:"\e6c1"}.el-icon-fork-spoon:before{content:"\e6c2"}.el-icon-chicken:before{content:"\e6c3"}.el-icon-food:before{content:"\e6c4"}.el-icon-dish-1:before{content:"\e6c5"}.el-icon-dish:before{content:"\e6c6"}.el-icon-moon-night:before{content:"\e6ee"}.el-icon-moon:before{content:"\e6f0"}.el-icon-cloudy-and-sunny:before{content:"\e6f1"}.el-icon-partly-cloudy:before{content:"\e6f2"}.el-icon-cloudy:before{content:"\e6f3"}.el-icon-sunny:before{content:"\e6f6"}.el-icon-sunset:before{content:"\e6f7"}.el-icon-sunrise-1:before{content:"\e6f8"}.el-icon-sunrise:before{content:"\e6f9"}.el-icon-heavy-rain:before{content:"\e6fa"}.el-icon-lightning:before{content:"\e6fb"}.el-icon-light-rain:before{content:"\e6fc"}.el-icon-wind-power:before{content:"\e6fd"}.el-icon-baseball:before{content:"\e712"}.el-icon-soccer:before{content:"\e713"}.el-icon-football:before{content:"\e715"}.el-icon-basketball:before{content:"\e716"}.el-icon-ship:before{content:"\e73f"}.el-icon-truck:before{content:"\e740"}.el-icon-bicycle:before{content:"\e741"}.el-icon-mobile-phone:before{content:"\e6d3"}.el-icon-service:before{content:"\e6d4"}.el-icon-key:before{content:"\e6e2"}.el-icon-unlock:before{content:"\e6e4"}.el-icon-lock:before{content:"\e6e5"}.el-icon-watch:before{content:"\e6fe"}.el-icon-watch-1:before{content:"\e6ff"}.el-icon-timer:before{content:"\e702"}.el-icon-alarm-clock:before{content:"\e703"}.el-icon-map-location:before{content:"\e704"}.el-icon-delete-location:before{content:"\e705"}.el-icon-add-location:before{content:"\e706"}.el-icon-location-information:before{content:"\e707"}.el-icon-location-outline:before{content:"\e708"}.el-icon-location:before{content:"\e79e"}.el-icon-place:before{content:"\e709"}.el-icon-discover:before{content:"\e70a"}.el-icon-first-aid-kit:before{content:"\e70b"}.el-icon-trophy-1:before{content:"\e70c"}.el-icon-trophy:before{content:"\e70d"}.el-icon-medal:before{content:"\e70e"}.el-icon-medal-1:before{content:"\e70f"}.el-icon-stopwatch:before{content:"\e710"}.el-icon-mic:before{content:"\e711"}.el-icon-copy-document:before{content:"\e718"}.el-icon-full-screen:before{content:"\e719"}.el-icon-switch-button:before{content:"\e71b"}.el-icon-aim:before{content:"\e71c"}.el-icon-crop:before{content:"\e71d"}.el-icon-odometer:before{content:"\e71e"}.el-icon-time:before{content:"\e71f"}.el-icon-bangzhu:before{content:"\e724"}.el-icon-close-notification:before{content:"\e726"}.el-icon-microphone:before{content:"\e727"}.el-icon-turn-off-microphone:before{content:"\e728"}.el-icon-position:before{content:"\e729"}.el-icon-postcard:before{content:"\e72a"}.el-icon-message:before{content:"\e72b"}.el-icon-chat-line-square:before{content:"\e72d"}.el-icon-chat-dot-square:before{content:"\e72e"}.el-icon-chat-dot-round:before{content:"\e72f"}.el-icon-chat-square:before{content:"\e730"}.el-icon-chat-line-round:before{content:"\e731"}.el-icon-chat-round:before{content:"\e732"}.el-icon-set-up:before{content:"\e733"}.el-icon-turn-off:before{content:"\e734"}.el-icon-open:before{content:"\e735"}.el-icon-connection:before{content:"\e736"}.el-icon-link:before{content:"\e737"}.el-icon-cpu:before{content:"\e738"}.el-icon-thumb:before{content:"\e739"}.el-icon-female:before{content:"\e73a"}.el-icon-male:before{content:"\e73b"}.el-icon-guide:before{content:"\e73c"}.el-icon-news:before{content:"\e73e"}.el-icon-price-tag:before{content:"\e744"}.el-icon-discount:before{content:"\e745"}.el-icon-wallet:before{content:"\e747"}.el-icon-coin:before{content:"\e748"}.el-icon-money:before{content:"\e749"}.el-icon-bank-card:before{content:"\e74a"}.el-icon-box:before{content:"\e74b"}.el-icon-present:before{content:"\e74c"}.el-icon-sell:before{content:"\e6d5"}.el-icon-sold-out:before{content:"\e6d6"}.el-icon-shopping-bag-2:before{content:"\e74d"}.el-icon-shopping-bag-1:before{content:"\e74e"}.el-icon-shopping-cart-2:before{content:"\e74f"}.el-icon-shopping-cart-1:before{content:"\e750"}.el-icon-shopping-cart-full:before{content:"\e751"}.el-icon-smoking:before{content:"\e752"}.el-icon-no-smoking:before{content:"\e753"}.el-icon-house:before{content:"\e754"}.el-icon-table-lamp:before{content:"\e755"}.el-icon-school:before{content:"\e756"}.el-icon-office-building:before{content:"\e757"}.el-icon-toilet-paper:before{content:"\e758"}.el-icon-notebook-2:before{content:"\e759"}.el-icon-notebook-1:before{content:"\e75a"}.el-icon-files:before{content:"\e75b"}.el-icon-collection:before{content:"\e75c"}.el-icon-receiving:before{content:"\e75d"}.el-icon-suitcase-1:before{content:"\e760"}.el-icon-suitcase:before{content:"\e761"}.el-icon-film:before{content:"\e763"}.el-icon-collection-tag:before{content:"\e765"}.el-icon-data-analysis:before{content:"\e766"}.el-icon-pie-chart:before{content:"\e767"}.el-icon-data-board:before{content:"\e768"}.el-icon-data-line:before{content:"\e76d"}.el-icon-reading:before{content:"\e769"}.el-icon-magic-stick:before{content:"\e76a"}.el-icon-coordinate:before{content:"\e76b"}.el-icon-mouse:before{content:"\e76c"}.el-icon-brush:before{content:"\e76e"}.el-icon-headset:before{content:"\e76f"}.el-icon-umbrella:before{content:"\e770"}.el-icon-scissors:before{content:"\e771"}.el-icon-mobile:before{content:"\e773"}.el-icon-attract:before{content:"\e774"}.el-icon-monitor:before{content:"\e775"}.el-icon-search:before{content:"\e778"}.el-icon-takeaway-box:before{content:"\e77a"}.el-icon-paperclip:before{content:"\e77d"}.el-icon-printer:before{content:"\e77e"}.el-icon-document-add:before{content:"\e782"}.el-icon-document:before{content:"\e785"}.el-icon-document-checked:before{content:"\e786"}.el-icon-document-copy:before{content:"\e787"}.el-icon-document-delete:before{content:"\e788"}.el-icon-document-remove:before{content:"\e789"}.el-icon-tickets:before{content:"\e78b"}.el-icon-folder-checked:before{content:"\e77f"}.el-icon-folder-delete:before{content:"\e780"}.el-icon-folder-remove:before{content:"\e781"}.el-icon-folder-add:before{content:"\e783"}.el-icon-folder-opened:before{content:"\e784"}.el-icon-folder:before{content:"\e78a"}.el-icon-edit-outline:before{content:"\e764"}.el-icon-edit:before{content:"\e78c"}.el-icon-date:before{content:"\e78e"}.el-icon-c-scale-to-original:before{content:"\e7c6"}.el-icon-view:before{content:"\e6ce"}.el-icon-loading:before{content:"\e6cf"}.el-icon-rank:before{content:"\e6d1"}.el-icon-sort-down:before{content:"\e7c4"}.el-icon-sort-up:before{content:"\e7c5"}.el-icon-sort:before{content:"\e6d2"}.el-icon-finished:before{content:"\e6cd"}.el-icon-refresh-left:before{content:"\e6c7"}.el-icon-refresh-right:before{content:"\e6c8"}.el-icon-refresh:before{content:"\e6d0"}.el-icon-video-play:before{content:"\e7c0"}.el-icon-video-pause:before{content:"\e7c1"}.el-icon-d-arrow-right:before{content:"\e6dc"}.el-icon-d-arrow-left:before{content:"\e6dd"}.el-icon-arrow-up:before{content:"\e6e1"}.el-icon-arrow-down:before{content:"\e6df"}.el-icon-arrow-right:before{content:"\e6e0"}.el-icon-arrow-left:before{content:"\e6de"}.el-icon-top-right:before{content:"\e6e7"}.el-icon-top-left:before{content:"\e6e8"}.el-icon-top:before{content:"\e6e6"}.el-icon-bottom:before{content:"\e6eb"}.el-icon-right:before{content:"\e6e9"}.el-icon-back:before{content:"\e6ea"}.el-icon-bottom-right:before{content:"\e6ec"}.el-icon-bottom-left:before{content:"\e6ed"}.el-icon-caret-top:before{content:"\e78f"}.el-icon-caret-bottom:before{content:"\e790"}.el-icon-caret-right:before{content:"\e791"}.el-icon-caret-left:before{content:"\e792"}.el-icon-d-caret:before{content:"\e79a"}.el-icon-share:before{content:"\e793"}.el-icon-menu:before{content:"\e798"}.el-icon-s-grid:before{content:"\e7a6"}.el-icon-s-check:before{content:"\e7a7"}.el-icon-s-data:before{content:"\e7a8"}.el-icon-s-opportunity:before{content:"\e7aa"}.el-icon-s-custom:before{content:"\e7ab"}.el-icon-s-claim:before{content:"\e7ad"}.el-icon-s-finance:before{content:"\e7ae"}.el-icon-s-comment:before{content:"\e7af"}.el-icon-s-flag:before{content:"\e7b0"}.el-icon-s-marketing:before{content:"\e7b1"}.el-icon-s-shop:before{content:"\e7b4"}.el-icon-s-open:before{content:"\e7b5"}.el-icon-s-management:before{content:"\e7b6"}.el-icon-s-ticket:before{content:"\e7b7"}.el-icon-s-release:before{content:"\e7b8"}.el-icon-s-home:before{content:"\e7b9"}.el-icon-s-promotion:before{content:"\e7ba"}.el-icon-s-operation:before{content:"\e7bb"}.el-icon-s-unfold:before{content:"\e7bc"}.el-icon-s-fold:before{content:"\e7a9"}.el-icon-s-platform:before{content:"\e7bd"}.el-icon-s-order:before{content:"\e7be"}.el-icon-s-cooperation:before{content:"\e7bf"}.el-icon-bell:before{content:"\e725"}.el-icon-message-solid:before{content:"\e799"}.el-icon-video-camera:before{content:"\e772"}.el-icon-video-camera-solid:before{content:"\e796"}.el-icon-camera:before{content:"\e779"}.el-icon-camera-solid:before{content:"\e79b"}.el-icon-download:before{content:"\e77c"}.el-icon-upload2:before{content:"\e77b"}.el-icon-upload:before{content:"\e7c3"}.el-icon-picture-outline-round:before{content:"\e75f"}.el-icon-picture-outline:before{content:"\e75e"}.el-icon-picture:before{content:"\e79f"}.el-icon-close:before{content:"\e6db"}.el-icon-check:before{content:"\e6da"}.el-icon-plus:before{content:"\e6d9"}.el-icon-minus:before{content:"\e6d8"}.el-icon-help:before{content:"\e73d"}.el-icon-s-help:before{content:"\e7b3"}.el-icon-circle-close:before{content:"\e78d"}.el-icon-circle-check:before{content:"\e720"}.el-icon-circle-plus-outline:before{content:"\e723"}.el-icon-remove-outline:before{content:"\e722"}.el-icon-zoom-out:before{content:"\e776"}.el-icon-zoom-in:before{content:"\e777"}.el-icon-error:before{content:"\e79d"}.el-icon-success:before{content:"\e79c"}.el-icon-circle-plus:before{content:"\e7a0"}.el-icon-remove:before{content:"\e7a2"}.el-icon-info:before{content:"\e7a1"}.el-icon-question:before{content:"\e7a4"}.el-icon-warning-outline:before{content:"\e6c9"}.el-icon-warning:before{content:"\e7a3"}.el-icon-goods:before{content:"\e7c2"}.el-icon-s-goods:before{content:"\e7b2"}.el-icon-star-off:before{content:"\e717"}.el-icon-star-on:before{content:"\e797"}.el-icon-more-outline:before{content:"\e6cc"}.el-icon-more:before{content:"\e794"}.el-icon-phone-outline:before{content:"\e6cb"}.el-icon-phone:before{content:"\e795"}.el-icon-user:before{content:"\e6e3"}.el-icon-user-solid:before{content:"\e7a5"}.el-icon-setting:before{content:"\e6ca"}.el-icon-s-tools:before{content:"\e7ac"}.el-icon-delete:before{content:"\e6d7"}.el-icon-delete-solid:before{content:"\e7c9"}.el-icon-eleme:before{content:"\e7c7"}.el-icon-platform-eleme:before{content:"\e7ca"}.el-icon-loading{-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.el-icon--right{margin-left:5px}.el-icon--left{margin-right:5px}@-webkit-keyframes rotating{0%{-webkit-transform:rotateZ(0);transform:rotateZ(0)}100%{-webkit-transform:rotateZ(360deg);transform:rotateZ(360deg)}}@keyframes rotating{0%{-webkit-transform:rotateZ(0);transform:rotateZ(0)}100%{-webkit-transform:rotateZ(360deg);transform:rotateZ(360deg)}}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/imgs/error-img.png
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/imgs/error.png
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/imgs/wms_d.png
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/imgs/wms_x.png
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/logo.png
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/script/common.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2 @@
var test1 = function () { alert(11) }
export { test1 }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/script/extend.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
//对vue参数进行扩展
var extend = function (param) {
    console.log(param)
 }
export { extend }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/assets/script/testFormExtend.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
//对vue参数进行扩展
var extend = function ($vueParam) {
    $vueParam.methods.volBoxFrom = function () {
        this.$Message.info("扩展js,增加弹出消息");
        this.$refs.volBoxFrom.show();
    }
    //修改data属性:
    let data = $vueParam.data();
    data.formFileds['extend'] = "动态扩展字段";
    data.formOptions.splice(0,0,{ filed: "extend", title: "动态增加字段", type: "text", required: true });
    $vueParam.data = function () {
        return data;
    }
}
export { extend }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/AsyncLoading.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
<template>
  <div style="text-align: center;font-size: 16px;padding: 20px;">正在加载资源...</div>
</template>
<script>
export default {
  created() {
    //  console.log('loading')
  }
};
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/Audit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
<template>
  <el-alert
    :title="'当前选中' + auditParam.rows + '条记录待审核..'"
    type="success"
    :closable="false"
  >
  </el-alert>
  <div class="item">
    <label>审核结果:</label>
    <el-radio-group v-model="auditParam.status">
      <el-radio
        v-for="item in auditParam.data"
        :key="item.status"
        :label="item.status"
      >
        <span>{{ item.text }}</span>
      </el-radio>
    </el-radio-group>
  </div>
  <div class="item">
    <label style="margin-right: 13px;">备&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; æ³¨ï¼š</label>
    <el-input
      v-model="auditParam.reason"
      type="textarea"
      style="margin-right: 13px;"
      :autosize="{ minRows: 4, maxRows: 10 }"
      placeholder="审核备注..."
    ></el-input>
  </div>
</template>
<script>
export default {
  props: {
    auditParam: {
      type: Object,
      default: () => {
        return {
          auditParam: {
            rows: 0,
            model: false,
            status: -1,
            reason: "",
            data: [], //[{ text: "通过", status: 1 }, { text: "拒绝", status: 2 }]
          },
        };
      },
    },
  },
};
</script>
<style lang="less" scoped>
.item{
  margin-top: 20px;
  display: flex;
  > label{
    width: 86px;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/Empty.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
<template>
  <div></div>
</template>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ErrorMsg.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
<template>
    <div id="test"></div>
</template>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/Icons.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,345 @@
<template>
  <div data-v-394040b0 class="icons">
    <div
      @click="select(index)"
      v-for="(item, index) in icons"
      :key="index"
      class="icons-item"
    >
      <i
        :class="[item, selectIndex == index ? 'active' : '']"
        style="font-size: 32px"
      ></i>
      <p>{{ item }}</p>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    onSelect: {
      type: Function,
      default: () => {
        return "";
      },
    },
  },
  methods: {
    select(index) {
      this.selectIndex = index;
      this.onSelect(index < 0 ? "" : this.icons[index]);
    },
  },
  data() {
    return {
      selectIndex: -1,
      icons: [
        //ivu-icon ivu-icon-ios-add
        "el-icon-menu",
        "el-icon-platform-eleme",
        "el-icon-eleme",
        "el-icon-delete-solid",
        "el-icon-delete",
        "el-icon-s-tools",
        "el-icon-setting",
        "el-icon-user-solid",
        "el-icon-user",
        "el-icon-phone",
        "el-icon-phone-outline",
        "el-icon-more",
        "el-icon-more-outline",
        "el-icon-star-on",
        "el-icon-star-off",
        "el-icon-s-goods",
        "el-icon-goods",
        "el-icon-warning",
        "el-icon-warning-outline",
        "el-icon-question",
        "el-icon-info",
        "el-icon-remove",
        "el-icon-circle-plus",
        "el-icon-success",
        "el-icon-error",
        "el-icon-zoom-in",
        "el-icon-zoom-out",
        "el-icon-remove-outline",
        "el-icon-circle-plus-outline",
        "el-icon-circle-check",
        "el-icon-circle-close",
        "el-icon-s-help",
        "el-icon-help",
        "el-icon-minus",
        "el-icon-plus",
        "el-icon-check",
        "el-icon-close",
        "el-icon-picture",
        "el-icon-picture-outline",
        "el-icon-picture-outline-round",
        "el-icon-upload",
        "el-icon-upload2",
        "el-icon-download",
        "el-icon-camera-solid",
        "el-icon-camera",
        "el-icon-video-camera-solid",
        "el-icon-video-camera",
        "el-icon-message-solid",
        "el-icon-bell",
        "el-icon-s-cooperation",
        "el-icon-s-order",
        "el-icon-s-platform",
        "el-icon-s-fold",
        "el-icon-s-unfold",
        "el-icon-s-operation",
        "el-icon-s-promotion",
        "el-icon-s-home",
        "el-icon-s-release",
        "el-icon-s-ticket",
        "el-icon-s-management",
        "el-icon-s-open",
        "el-icon-s-shop",
        "el-icon-s-marketing",
        "el-icon-s-flag",
        "el-icon-s-comment",
        "el-icon-s-finance",
        "el-icon-s-claim",
        "el-icon-s-custom",
        "el-icon-s-opportunity",
        "el-icon-s-data",
        "el-icon-s-check",
        "el-icon-s-grid",
        "el-icon-share",
        "el-icon-d-caret",
        "el-icon-caret-left",
        "el-icon-caret-right",
        "el-icon-caret-bottom",
        "el-icon-caret-top",
        "el-icon-bottom-left",
        "el-icon-bottom-right",
        "el-icon-back",
        "el-icon-right",
        "el-icon-bottom",
        "el-icon-top",
        "el-icon-top-left",
        "el-icon-top-right",
        "el-icon-arrow-left",
        "el-icon-arrow-right",
        "el-icon-arrow-down",
        "el-icon-arrow-up",
        "el-icon-d-arrow-left",
        "el-icon-d-arrow-right",
        "el-icon-video-pause",
        "el-icon-video-play",
        "el-icon-refresh",
        "el-icon-refresh-right",
        "el-icon-refresh-left",
        "el-icon-finished",
        "el-icon-sort",
        "el-icon-sort-up",
        "el-icon-sort-down",
        "el-icon-rank",
        "el-icon-loading",
        "el-icon-view",
        "el-icon-c-scale-to-original",
        "el-icon-date",
        "el-icon-edit",
        "el-icon-edit-outline",
        "el-icon-folder",
        "el-icon-folder-opened",
        "el-icon-folder-add",
        "el-icon-folder-remove",
        "el-icon-folder-delete",
        "el-icon-folder-checked",
        "el-icon-tickets",
        "el-icon-document-remove",
        "el-icon-document-delete",
        "el-icon-document-copy",
        "el-icon-document-checked",
        "el-icon-document",
        "el-icon-document-add",
        "el-icon-printer",
        "el-icon-paperclip",
        "el-icon-takeaway-box",
        "el-icon-search",
        "el-icon-monitor",
        "el-icon-attract",
        "el-icon-mobile",
        "el-icon-scissors",
        "el-icon-umbrella",
        "el-icon-headset",
        "el-icon-brush",
        "el-icon-mouse",
        "el-icon-coordinate",
        "el-icon-magic-stick",
        "el-icon-reading",
        "el-icon-data-line",
        "el-icon-data-board",
        "el-icon-pie-chart",
        "el-icon-data-analysis",
        "el-icon-collection-tag",
        "el-icon-film",
        "el-icon-suitcase",
        "el-icon-suitcase-1",
        "el-icon-receiving",
        "el-icon-collection",
        "el-icon-files",
        "el-icon-notebook-1",
        "el-icon-notebook-2",
        "el-icon-toilet-paper",
        "el-icon-office-building",
        "el-icon-school",
        "el-icon-table-lamp",
        "el-icon-house",
        "el-icon-no-smoking",
        "el-icon-smoking",
        "el-icon-shopping-cart-full",
        "el-icon-shopping-cart-1",
        "el-icon-shopping-cart-2",
        "el-icon-shopping-bag-1",
        "el-icon-shopping-bag-2",
        "el-icon-sold-out",
        "el-icon-sell",
        "el-icon-present",
        "el-icon-box",
        "el-icon-bank-card",
        "el-icon-money",
        "el-icon-coin",
        "el-icon-wallet",
        "el-icon-discount",
        "el-icon-price-tag",
        "el-icon-news",
        "el-icon-guide",
        "el-icon-male",
        "el-icon-female",
        "el-icon-thumb",
        "el-icon-cpu",
        "el-icon-link",
        "el-icon-connection",
        "el-icon-open",
        "el-icon-turn-off",
        "el-icon-set-up",
        "el-icon-chat-round",
        "el-icon-chat-line-round",
        "el-icon-chat-square",
        "el-icon-chat-dot-round",
        "el-icon-chat-dot-square",
        "el-icon-chat-line-square",
        "el-icon-message",
        "el-icon-postcard",
        "el-icon-position",
        "el-icon-turn-off-microphone",
        "el-icon-microphone",
        "el-icon-close-notification",
        "el-icon-bangzhu",
        "el-icon-time",
        "el-icon-odometer",
        "el-icon-crop",
        "el-icon-aim",
        "el-icon-switch-button",
        "el-icon-full-screen",
        "el-icon-copy-document",
        "el-icon-mic",
        "el-icon-stopwatch",
        "el-icon-medal-1",
        "el-icon-medal",
        "el-icon-trophy",
        "el-icon-trophy-1",
        "el-icon-first-aid-kit",
        "el-icon-discover",
        "el-icon-place",
        "el-icon-location",
        "el-icon-location-outline",
        "el-icon-location-information",
        "el-icon-add-location",
        "el-icon-delete-location",
        "el-icon-map-location",
        "el-icon-alarm-clock",
        "el-icon-timer",
        "el-icon-watch-1",
        "el-icon-watch",
        "el-icon-lock",
        "el-icon-unlock",
        "el-icon-key",
        "el-icon-service",
        "el-icon-mobile-phone",
        "el-icon-bicycle",
        "el-icon-truck",
        "el-icon-ship",
        "el-icon-basketball",
        "el-icon-football",
        "el-icon-soccer",
        "el-icon-baseball",
        "el-icon-wind-power",
        "el-icon-light-rain",
        "el-icon-lightning",
        "el-icon-heavy-rain",
        "el-icon-sunrise",
        "el-icon-sunrise-1",
        "el-icon-sunset",
        "el-icon-sunny",
        "el-icon-cloudy",
        "el-icon-partly-cloudy",
        "el-icon-cloudy-and-sunny",
        "el-icon-moon",
        "el-icon-moon-night",
        "el-icon-dish",
        "el-icon-dish-1",
        "el-icon-food",
        "el-icon-chicken",
        "el-icon-fork-spoon",
        "el-icon-knife-fork",
        "el-icon-burger",
        "el-icon-tableware",
        "el-icon-sugar",
        "el-icon-dessert",
        "el-icon-ice-cream",
        "el-icon-hot-water",
        "el-icon-water-cup",
        "el-icon-coffee-cup",
        "el-icon-cold-drink",
        "el-icon-goblet",
        "el-icon-goblet-full",
        "el-icon-goblet-square",
        "el-icon-goblet-square-full",
        "el-icon-refrigerator",
        "el-icon-grape",
        "el-icon-watermelon",
        "el-icon-cherry",
        "el-icon-apple",
        "el-icon-pear",
        "el-icon-orange",
        "el-icon-coffee",
        "el-icon-ice-tea",
        "el-icon-ice-drink",
        "el-icon-milk-tea",
        "el-icon-potato-strips",
        "el-icon-lollipop",
        "el-icon-ice-cream-square",
        "el-icon-ice-cream-round",
      ],
    };
  },
};
</script>
<style lang="less" scoped>
.icons-item {
  float: left;
  margin: 6px 6px 6px 0;
  width: 115px;
  text-align: center;
  list-style: none;
  cursor: pointer;
  height: 100px;
  color: #5c6b77;
  transition: all 0.2s ease;
  position: relative;
  padding-top: 10px;
}
.active {
  border: 1px solid;
  background: #f44336;
  color: white;
  font-size: 32px;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/QuickSearch.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,152 @@
<template>
  <div>
    <el-select
      style="width: 150px"
      v-if="['select', 'selectList'].indexOf(singleSearch.type) != -1"
      v-model="searchFormFields[singleSearch.field]"
      :filterable="
        singleSearch.filter || singleSearch.data.length > 10 ? true : false
      "
      :placeholder="'请选择' + singleSearch.title"
      clearable
    >
      <el-option
        v-for="item in singleSearch.data"
        :key="item.key"
        :label="item.value"
        :value="item.key"
      >
      </el-option>
    </el-select>
    <div
      class="date-range"
      v-else-if="['date', 'datetime'].indexOf(singleSearch.type) != -1"
    >
      <el-date-picker
        style="width: 210px"
        :clearable="false"
        unlink-panels
        v-model="searchFormFields[singleSearch.field]"
        type="daterange"
        :value-format="getDateFormat(singleSearch)"
        :placeholder="singleSearch.title"
      >
      </el-date-picker>
      <i
        class="el-icon-circle-close"
        @click="dateRangeClear(singleSearch.field)"
      ></i>
    </div>
    <el-cascader
      style="width: 210px"
      clearable
      v-model="searchFormFields[singleSearch.field]"
      v-else-if="singleSearch.type == 'cascader'"
      :options="singleSearch.data"
      :props="{ checkStrictly: true }"
    >
    </el-cascader>
    <el-input
      clearable
      v-else
      style="width: 150px"
      size="default"
      v-model="searchFormFields[singleSearch.field]"
      :placeholder="singleSearch.title"
      @keypress="tiggerPress"
    />
  </div>
</template>
<script>
export default {
  props: {
    singleSearch: {
      type: Object,
      default: {},
    },
    searchFormFields: {
      type: Object,
      default: () => {
        return {};
      },
    },
    tiggerPress: {
      type: Function,
      default: () => {},
    },
  },
  methods: {
    compareDate(date1, date2) {
      if (!date2) {
        return true;
      }
      return (
        date1.valueOf() <
        (typeof date2 == "number" ? date2 : new Date(date2).valueOf())
      );
    },
    getDateFormat(item) {
      //见https://day.js.org/docs/zh-CN/display/format
      return item.type == "date" ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss";
    },
    getDateOptions(date, item) {
      if ((!item.min && !item.max) || !date) {
        return false;
      }
      if (item.min && item.min.indexOf(" ") == -1) {
        //不设置时分秒,后面会自动加上 08:00
        item.min = item.min + " 00:00:000";
      }
      return (
        this.compareDate(date, item.min) || !this.compareDate(date, item.max)
      );
    },
    dateRangeClear(field) {
      this.searchFormFields[field]=[undefined,undefined];
    },
  },
  created() {
    this.singleSearch.dateType = this.singleSearch.type + "range";
    if (
      this.singleSearch.type == "date" ||
      this.singleSearch.type == "datetime"
    ) {
      var _dateVal = this.searchFormFields[this.singleSearch.field];
      if (
        typeof this.singleSearch.range == "boolean" &&
        !this.singleSearch.range
      ) {
        this.searchFormFields[this.singleSearch.field] = "";
        this.singleSearch.dateType = this.singleSearch.type;
        return this.singleSearch.dateType;
      } else if (!(_dateVal instanceof Array)) {
        this.searchFormFields[this.singleSearch.field] = ["", ""];
      } else if (_dateVal.length != 2) {
        _dateVal.splice(0);
        _dateVal.push(...["", ""]);
      }
    }
  },
};
</script>
<style lang="less" scoped>
.date-range{
  position: relative;
  > i{
    display: none;
    height: 27px;
    line-height: 27px;
    right: 1px;
    top: 3px;
    font-size: 13px;
    color: #b4adad;
    position: absolute;
    padding: 0 6px 0 3px;
    background: #ffff;
    cursor: pointer;
  }
}
.date-range:hover > i{
  display: inline-block;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/RouterLoading.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,105 @@
<template>
  <div class="router-loading" style="background: #eeeeee5c;">
    <div class="spanner">
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {};
  }
};
</script>
<style scoped>
.router-loading {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  font-size: 100px;
  text-align: center;
  padding-top: 200px;
  color: #808080;
  z-index: 9999;
}
.spanner {
  width: 100px;
  height: 100px;
  position: relative;
  margin: 0 auto;
}
.router-loading span {
  display: inline-block;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #66b1ff;
  position: absolute;
  animation: r_load 1.04s ease infinite;
}
@keyframes r_load {
  0% {
    transform: scale(1.2);
    opacity: 1;
  }
  100% {
    transform: scale(0.3);
    opacity: 0.5;
  }
}
.router-loading span:nth-child(1) {
  left: 0;
  top: 50%;
  margin-top: -10px;
  animation-delay: 0.13s;
}
.router-loading span:nth-child(2) {
  left: 14px;
  top: 14px;
  animation-delay: 0.26s;
}
.router-loading span:nth-child(3) {
  left: 50%;
  top: 0;
  margin-left: -10px;
  animation-delay: 0.39s;
}
.router-loading span:nth-child(4) {
  top: 14px;
  right: 14px;
  animation-delay: 0.52s;
}
.router-loading span:nth-child(5) {
  right: 0;
  top: 50%;
  margin-top: -10px;
  animation-delay: 0.65s;
}
.router-loading span:nth-child(6) {
  right: 14px;
  bottom: 14px;
  animation-delay: 0.78s;
}
.router-loading span:nth-child(7) {
  bottom: 0;
  left: 50%;
  margin-left: -10px;
  animation-delay: 0.91s;
}
.router-loading span:nth-child(8) {
  bottom: 14px;
  left: 14px;
  animation-delay: 1.04s;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/UploadExcel.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,221 @@
<template>
  <div class="upload-container">
    <a :href="template.url" ref="template"></a>
    <div class="button-group">
      <el-upload
        style="float: left"
        ref="uploadFile"
        :max-size="maxSize"
        :on-change="clearMsg"
        :before-upload="beforeUpload"
        :action="url"
      >
        <el-button size="small"
          ><i class="el-icon-folder-opened"></i>选择文件</el-button
        >
      </el-upload>
      <el-button
        v-if="template.url"
        style="margin-left: 10px"
        type="primary"
        size="small"
        @click="dowloadTemplate"
        :loading="loadingStatus"
      >
     <i class="el-icon-bottom"></i>
        ä¸‹è½½æ¨¡æ¿</el-button
      >
      <el-button
        type="success"
        size="small"
        @click="upload"
        :loading="loadingStatus"
      >
          <i class="el-icon-top"></i>
        ä¸Šä¼ æ–‡ä»¶</el-button
      >
    </div>
    <div class="alert">
      <el-alert title="上传说明" type="warning" :closable="false" show-icon
        >只能上传excel文件,文件大小不超过{{ maxSize }}M</el-alert
      >
    </div>
    <div v-if="file">
      <h3>文件列表</h3>
      <div class="file-info">
        <span>文件名:{{ file.name }}</span>
        <span>大小{{ (file.size / 1024).toFixed(2) }}KB</span>
      </div>
    </div>
    <div v-show="message" class="v-r-message">
      <h3 class="title">上传结果</h3>
      <div class="text" :class="resultClass" v-html="message"></div>
    </div>
    <slot></slot>
  </div>
</template>
<script>
//目前只支持单个Excel上传,其他功能开发中...
export default {
  components: {},
  props: {
    url: {
      type: String,
      default: ''
    },
    template: {
      //下载模板配置
      type: Object,
      default: () => {
        return {
          url: '', //模板下载路径,如果没有模板路径,则不显示下载模板功能
          fileName: '未定义文件名' //下载模板的文件名
        };
      }
    },
    importExcelBefore: {
      type: Function,
      default: (file) => {
        return true;
      }
    }
  },
  data() {
    return {
      maxSize: 100,
      model: true,
      file: null,
      loadingStatus: false,
      message: '',
      resultClass: ''
    };
  },
  methods: {
    clearMsg() {
      this.message = '';
    },
    reset() {
      this.file = null;
      this.message = '';
      this.resultClass = '';
    },
    getFileType() {
      let fileName =
        this.file.name
          .split('.')
          .pop()
          .toLocaleLowerCase() || '';
      if (['numbers', 'csv', 'xls', 'xlsx'].indexOf(fileName) == -1) {
        this.$Message.error('只能选择excel文件');
        return false;
      }
      return true;
    },
    beforeUpload(file) {
      this.file = file;
      if (!this.getFileType()) {
        return false;
      }
      return false;
    },
    upload() {
      let _url = this.url;
      if (!_url) {
        return this.$Message.error('没有配置好Url');
      }
      if (!this.file) {
        return this.$Message.error('请选择文件');
      }
      var formData = new FormData();
      formData.append('fileInput', this.file);
      if (!this.importExcelBefore(formData)) {
        return;
      }
      this.loadingStatus = true;
      this.http.post(_url, formData).then(
        (x) => {
          // this.$refs.uploadFile.clearFiles();
          this.loadingStatus = false;
          this.file = null;
          if (x.status) {
            this.$emit('importExcelAfter', x);
          }
          this.message = x.message;
          this.resultClass = x.status ? 'v-r-success' : 'v-r-error';
        },
        (error) => {
          this.loadingStatus = false;
        }
      );
    },
    dowloadTemplate() {
      let url = this.template.url;
      let xmlResquest = new XMLHttpRequest();
      xmlResquest.open('GET', url, true);
      xmlResquest.setRequestHeader('Content-type', 'application/json');
      xmlResquest.setRequestHeader(
        'Authorization',
        this.$store.getters.getToken()
      );
      let fileName = this.template.fileName + '.xlsx';
      let elink = this.$refs.template;
      xmlResquest.responseType = 'blob';
      let $_vue = this;
      this.loadingStatus = true;
      xmlResquest.onload = function(oEvent) {
        $_vue.loadingStatus = false;
        if (xmlResquest.response.type == 'application/json') {
          return $_vue.message.error('未找到下载文件');
        }
        let content = xmlResquest.response;
        elink.download = fileName;
        let blob = new Blob([content]);
        elink.href = URL.createObjectURL(blob);
        elink.click();
      };
      xmlResquest.send();
    }
  }
};
</script>
<style lang="less" scoped>
.upload-container {
  min-height: 270px !important;
  display: inline-block;
  width: 100%;
  padding: 10px;
  border: 1px dashed #989898;
  min-height: 250px;
  border-radius: 5px;
  .alert {
    margin-top: 12px;
  }
  .el-button-group > * {
    display: flex;
  }
  h3 {
    margin: 9px 0px;
  }
  .file-info > span {
    margin-right: 20px;
  }
  .v-r-message {
    margin-top: 10px;
    .title {
      margin-bottom: 2px;
    }
    > .text {
      font-size: 13px;
    }
    .v-r-success {
      color: #02b702;
    }
    .v-r-error {
      color: #dc0909;
    }
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/AuditHis.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
<template>
  <vol-table
    :tableData="tableData"
    :columns="columns"
    :height="411"
    :pagination-hide="true"
    :load-key="false"
    :text-inline="false"
    :ck="false"
  ></vol-table>
</template>
<script>
import VolTable from '@/components/basic/VolTable.vue';
import {
  defineComponent,
  ref,
  reactive,
  toRefs,
  getCurrentInstance
} from 'vue';
export default defineComponent({
  components: {
    VolTable
  },
  props: {
    tableData: {
      type: Array,
      default: () => {
        return [];
      }
    }
  },
  setup() {
    const columns = reactive([
      { title: '节点', field: 'stepName' },
      { title: '审批人', field: 'auditor' },
      { title: '审批结果', field: 'auditStatus' },
      { title: '审批时间', field: 'auditDate',width:150 },
      { title: '备注', field: 'remark' }
    ]);
    return {
        columns
    }
  }
});
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/ViewGrid.less
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,178 @@
.view-container {
  // padding: 15px;
  background: white;
  .grid-search {
    padding-top: 15px;
    //padding: 15px 15px 0 15px;
  }
  .grid-container,
  .grid-body {
    padding: 0 15px;
  }
  .view-header {
    padding-left: 15px;
    padding-right: 15px;
  }
  .fs-line {
    height: 9px;
    background: #f1f1f1;
    margin-top: -10px;
    margin-bottom: 10px;
  }
}
.view-header {
  height: 45px;
  position: relative;
  padding-bottom: 11px;
  display: flex;
  .search-line {
    min-width: 150px;
  }
  .search-line > div {
    margin-left: 5px;
    margin-right: 10px;
  }
  .search-line > div > div {
    width: 200px;
    text-align: left;
  }
  .search-line > div:first-child {
    flex: 1;
  }
  .search-line > div .ivu-select-dropdown {
    max-height: 300px;
  }
  .btn-group {
    white-space: nowrap;
    button {
      margin-left: 10px;
      // padding: 5px 16px;
    }
  }
  .btn-group .ivu-dropdown-item {
    text-align: left !important;
  }
  .btn-group .ivu-dropdown-item:not(:last-child) {
    border-bottom: 1px dotted #eee;
  }
  .desc-text {
    margin-top: 5px;
    font-weight: bold;
    margin-bottom: 3px;
    font-size: 14px;
    color: #313131;
    white-space: nowrap;
    border-bottom: 2px solid #646565;
    i {
      font-size: 16px;
      position: relative;
      top: 1px;
      margin-right: 2px;
    }
  }
  .search-box {
    background: #fefefe;
    margin-top: 45px;
    border: 1px solid #ececec;
    position: absolute;
    z-index: 999;
    left: 0;
    right: 0;
    padding: 25px 40px;
    padding-bottom: 0;
    box-shadow: 0px 7px 18px -12px #bdc0bb;
  }
  .notice {
    font-size: 13px;
    color: #6b6b6b;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    position: relative;
    top: 12px;
    flex: 1;
    left: 10px;
    margin-right: 20px;
  }
}
.table-info-cell-title {
  background-color: #f5f5f5 !important;
}
.box-com {
  > div.item {
    // margin-bottom: 10px;
    padding: 15px 17px 0 8px;
    margin-bottom: 12px;
    background: white;
  }
  > div.form-item {
    padding: 19px 16px 0px 5px;
    //box-shadow: 0 1px 7px rgb(199, 199, 199);
  }
  > div.table-item {
    padding: 0 10px;
    border-top: 1.5px solid #eaeaea;
  }
  .v-text {
    line-height: 27px;
  }
  .form-text {
    position: relative;
    border-bottom: 1px solid #eee;
    font-size: 14px;
    margin-bottom: 14px;
  }
}
.form-closex {
  text-align: right;
  padding-bottom: 24px;
}
.form-closex button {
  margin-left: 10px;
  padding: 4px 13px;
}
.toolbar {
  padding: 3px 0px;
  width: 100%;
  display: flex;
  .title {
    line-height: 29px;
    border-bottom: none;
    font-size: 13px;
    font-weight: bolder;
    margin-bottom: 0;
    color: #5d5c5c;
    .icon {
      color: #009688;
      font-size: 18px;
    }
    i {
      line-height: 29px;
      border-bottom: none;
      font-weight: bolder;
      margin-bottom: 0;
      color: #5d5c5c;
      position: relative;
      margin-top: -4px;
      font-size: 14px;
    }
  }
  .btns {
    line-height: 28px;
    flex: 1;
    text-align: right;
    button {
      // border: none;
      // margin-left:15px;
      border: 0px;
      padding: 0px 9px;
      color: #292929;
    }
    button:hover{
      color: #0089f6;
    }
  }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/ViewGrid.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,806 @@
<template>
  <div class="layout-container">
    <a :href="exportHref" ref="export"></a>
    <!--开启懒加载2020.12.06 -->
    <vol-box
      :on-model-close="closeCustomModel"
      v-model="viewModel"
      :height="520"
      :width="500"
      :padding="0"
      :lazy="true"
      title="设置"
    >
      <template #content>
        <custom-column :view-columns="viewColumns"></custom-column>
      </template>
      <template #footer>
        <div style="text-align: center">
          <el-button type="default" size="small" @click="closeCustomModel"
            ><i class="el-icon-close"></i>取消</el-button
          >
          <el-button type="success" size="small" @click="initViewColumns(true)"
            ><i class="el-icon-refresh"></i>重置</el-button
          >
          <el-button type="primary" size="small" @click="saveColumnConfig"
            ><i class="el-icon-check"></i>确定</el-button
          >
        </div>
      </template>
    </vol-box>
    <ViewGridAudit @auditClick="saveAudit" :option="table" ref="audit">
    </ViewGridAudit>
    <!--开启懒加载2020.12.06 -->
    <!--审核(异步点击按钮时才加载待完)-->
    <!-- <vol-box
      v-model="auditParam.model"
      :height="auditParam.height"
      :width="750"
      :lazy="true"
      :padding="0"
      title="审批"
    >
      <template #content>
        <el-tabs type="card">
          <el-tab-pane label="当前审批">
            <div class="v-steps">
              <div
                :class="{ 'step-current': item.isCurrent }"
                class="step-item"
                v-for="(item, index) in workFlowSteps"
                :key="index"
              >
                <div class="left-item">
                  <div>审批时间</div>
                  <div class="left-date">{{ item.auditDate || '待审批' }}</div>
                </div>
                <div class="right-item">
                  <div class="step-line"></div>
                  <i class="step-circle"></i>
                  <div class="step-title">
                    {{ item.stepName }}
                  </div>
                  <div class="step-text">审批人:{{ item.auditor }}</div>
                  <div class="step-text">
                    çж æ€ï¼š {{ getAuditStatus(item.auditStatus) }}
                  </div>
                  <div class="step-text">备 æ³¨ï¼š {{ item.remark || '-' }}</div>
                </div>
              </div>
              <div
                :style="{
                  'margin-top': workFlowSteps.length ? '20px' : '-17px'
                }"
                class="audit-content"
                v-show="auditParam.showAction"
              >
                <div style="margin-bottom:10px;">
                  å®¡æ‰¹ï¼š
                  <el-radio-group
                    style="margin-left:15px"
                    v-model="auditParam.value"
                  >
                    <el-radio
                      v-for="item in auditParam.data"
                      :key="item.value"
                      :label="item.value"
                    >
                      <span>{{ item.text }}</span>
                    </el-radio>
                  </el-radio-group>
                </div>
                <el-input
                  v-model="auditParam.reason"
                  type="textarea"
                  style="margin-right: 13px;"
                  :autosize="{ minRows: 4, maxRows: 10 }"
                  placeholder="请输入备注..."
                ></el-input>
              </div>
            </div>
          </el-tab-pane>
          <el-tab-pane v-if="workFlowSteps.length" label="审批记录">
            <audit-his :table-data="auditParam.auditHis"></audit-his>
          </el-tab-pane>
        </el-tabs>
      </template>
      <template #footer>
        <div style="text-align: center;">
          <el-button size="small" @click="auditParam.model = false"
            ><i class="el-icon-close"></i>关闭</el-button
          >
          <el-button
            type="primary"
            v-show="auditParam.showAction"
            size="small"
            @click="saveAudit"
            ><i class="el-icon-check"></i>审核</el-button
          >
        </div>
      </template>
    </vol-box> -->
    <!--导入excel功能-->
    <!--2020.10.31添加导入前的方法-->
    <!--开启懒加载2020.12.06 -->
    <!-- 2022.01.08增加明细表导入判断 -->
    <vol-box
      v-if="upload.url"
      v-model="upload.excel"
      :height="350"
      :width="600"
      :lazy="true"
      :title="(boxModel ? detailOptions.cnName : table.cnName) + '-导入'"
    >
      <UploadExcel
        ref="upload_excel"
        @importExcelAfter="importExcelAfter"
        :importExcelBefore="importExcelBefore"
        :url="upload.url"
        :template="upload.template"
      ></UploadExcel>
    </vol-box>
    <!--头部自定义组件-->
    <component
      :is="dynamicComponent.gridHeader"
      ref="gridHeader"
      @parentCall="parentCall"
    ></component>
    <!--主界面查询与table表单布局-->
    <div class="view-container">
      <!-- 2020.09.11增加固定查询表单 -->
      <!--查询条件-->
      <div class="grid-search">
        <div
          :class="[fiexdSearchForm ? 'fiexd-search-box' : 'search-box']"
          v-show="searchBoxShow"
        >
          <!-- 2020.09.13增加formFileds拼写错误兼容处理 -->
          <vol-form
            ref="searchForm"
            :load-key="false"
            style="padding: 0 15px"
            :label-width="labelWidth"
            :formRules="searchFormOptions"
            :formFields="searchFormFields"
            :select2Count="select2Count"
          >
            <template #footer>
              <div v-if="!fiexdSearchForm" class="form-closex">
                <el-button size="small" type="primary" plain @click="search">
                  <i class="el-icon-search" />查询
                </el-button>
                <el-button
                  size="small"
                  type="success"
                  plain
                  @click="resetSearch"
                >
                  <i class="el-icon-refresh-right" />重置
                </el-button>
                <el-button
                  size="small"
                  plain
                  @click="searchBoxShow = !searchBoxShow"
                >
                  <i class="el-icon-switch-button" />关闭
                </el-button>
              </div>
            </template>
          </vol-form>
          <div v-if="fiexdSearchForm" class="fs-line"></div>
        </div>
        <div class="view-header">
          <div class="desc-text">
            <i class="el-icon-s-grid" />
            <span>{{ table.cnName }}</span>
          </div>
          <div class="notice">
            <a class="text" :title="extend.text">{{ extend.text }}</a>
          </div>
          <!--快速查询字段-->
          <div class="search-line" v-if="!fiexdSearchForm">
            <QuickSearch
              v-if="singleSearch"
              :singleSearch="singleSearch"
              :searchFormFields="searchFormFields"
              :tiggerPress="quickSearchKeyPress"
            ></QuickSearch>
          </div>
          <!--操作按钮组-->
          <!-- 2020.11.29增加查询界面hidden属性 -->
          <div class="btn-group">
            <template
              :key="bIndex"
              v-for="(btn, bIndex) in buttons.slice(0, maxBtnLength)"
            >
              <el-dropdown size="small" v-if="btn.data" :split-button="false">
                <el-button
                  :color="btn.color"
                  :dark="false"
                  :type="btn.type"
                  :plain="btn.plain"
                >
                  {{ btn.name }}<i class="el-icon-arrow-down el-icon--right"></i
                ></el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item
                      v-for="(item, index) in btn.data"
                      :key="index"
                    >
                      <div @click="onClick(item.onClick)">
                        <i :class="item.icon"></i>
                        {{ item.name }}
                      </div>
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
              <el-button
                v-else
                :type="btn.type"
                size="small"
                :color="btn.color"
                :dark="false"
                :class="btn.class"
                :plain="btn.plain"
                v-show="!btn.hidden"
                @click="onClick(btn.onClick)"
              >
                <i :class="btn.icon"></i> {{ btn.name }}
              </el-button>
            </template>
            <!-- è®¾ç½®åˆ—按钮 -->
            <el-button
              type="default"
              style="padding: 0px 10px"
              size="small"
              :plain="true"
              v-if="showCustom"
              @click="showCustomModel"
            >
              <i class="el-icon-s-grid"></i>
            </el-button>
            <el-dropdown
              size="small"
              @click="changeDropdown"
              v-if="buttons.length > maxBtnLength"
            >
              <el-button type="primary" plain size="small">
                æ›´å¤š<i class="el-icon-arrow-down el-icon--right"></i>
              </el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item
                    @click="changeDropdown(item.name)"
                    :name="item.name"
                    v-show="!item.hidden"
                    v-for="(item, dIndex) in buttons.slice(
                      maxBtnLength,
                      buttons.length
                    )"
                    :key="dIndex"
                  >
                    <i :class="item.icon"></i> {{ item.name }}</el-dropdown-item
                  >
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
        </div>
        <!-- åˆ†å‰²ä½ç½® -->
        <vol-box
          v-if="boxInit"
          v-model="boxModel"
          :title="boxOptions.title"
          :width="boxOptions.width"
          :height="boxOptions.height"
          :modal="boxOptions.modal"
          :draggable="boxOptions.draggable"
          :padding="0"
          :on-model-close="onGridModelClose"
          @fullscreen="fullscreen"
        >
          <!--明细头部自定义组件-->
          <template #content>
            <div class="box-com">
              <component
                :is="dynamicComponent.modelHeader"
                ref="modelHeader"
                @parentCall="parentCall"
              ></component>
              <!-- <div v-show="isBoxAudit" class="flow-step">
                <div v-for="(item, index) in workFlowSteps" :key="index">
                  {{ item.stepName }}
                </div>
              </div> -->
              <div class="item form-item">
                <vol-form
                  ref="form"
                  :editor="editor"
                  :load-key="false"
                  :label-width="boxOptions.labelWidth"
                  :formRules="editFormOptions"
                  :formFields="editFormFields"
                  :select2Count="select2Count"
                ></vol-form>
              </div>
              <!--明细body自定义组件-->
              <component
                :is="dynamicComponent.modelBody"
                ref="modelBody"
                @parentCall="parentCall"
              ></component>
              <div
                v-show="hasDetail"
                v-if="detail.columns && detail.columns.length > 0"
                class="grid-detail table-item item"
              >
                <div class="toolbar">
                  <div class="title form-text">
                    <span>
                      <i class="el-icon-menu" />
                      {{ detail.cnName }}
                    </span>
                  </div>
                  <!--明细表格按钮-->
                  <div class="btns" v-show="!isBoxAudit">
                    <el-button
                      v-for="(btn, bIndex) in detailOptions.buttons"
                      :key="bIndex"
                      :plain="btn.plain"
                      v-show="!(typeof btn.hidden == 'boolean' && btn.hidden)"
                      @click="onClick(btn.onClick)"
                      size="small"
                      ><i :class="btn.icon"></i>{{ btn.name }}</el-button
                    >
                  </div>
                </div>
                <vol-table
                  ref="detail"
                  @loadBefore="loadInternalDetailTableBefore"
                  @loadAfter="loadDetailTableAfter"
                  @rowChange="detailRowOnChange"
                  @rowClick="detailRowOnClick"
                  :url="detailOptions.url"
                  :load-key="false"
                  :index="true"
                  :tableData="detailOptions.data"
                  :columns="detailOptions.columns"
                  :pagination="detailOptions.pagination"
                  :height="detailOptions.height"
                  :single="detailOptions.single"
                  :pagination-hide="false"
                  :defaultLoadPage="detailOptions.load"
                  :beginEdit="detailOptions.beginEdit"
                  :endEditBefore="detailOptions.endEditBefore"
                  :endEditAfter="detailOptions.endEditAfter"
                  :summary="detailOptions.summary"
                  :click-edit="detailOptions.clickEdit"
                  :double-edit="detailOptions.doubleEdit"
                  :column-index="detailOptions.columnIndex"
                  :ck="detailOptions.ck"
                  :text-inline="detailOptions.textInline"
                  :select2Count="select2Count"
                  :selectable="detailSelectable"
                ></vol-table>
              </div>
              <!--明细footer自定义组件-->
              <component
                :is="dynamicComponent.modelFooter"
                ref="modelFooter"
                @parentCall="parentCall"
              ></component>
            </div>
          </template>
          <template #footer>
            <div style="text-align: center;" v-show="isBoxAudit">
              <el-button
                size="small"
                type="primary"
                plain
                @click="onGridModelClose(false)"
              >
                <i class="el-icon-close">关闭</i>
              </el-button>
              <el-button
                size="small"
                type="primary"
                v-show="auditParam.showViewButton"
                @click="auditParam.model = true"
              >
                <i class="el-icon-view">审批</i>
              </el-button>
            </div>
            <div v-show="!isBoxAudit">
              <el-button
                v-for="(btn, bIndex) in boxButtons"
                :key="bIndex"
                :type="btn.type"
                size="small"
                :plain="btn.plain"
                v-show="!(typeof btn.hidden == 'boolean' && btn.hidden)"
                :disabled="btn.hasOwnProperty('disabled') && !!btn.disabled"
                @click="onClick(btn.onClick)"
              >
                <i :class="btn.icon"> {{ btn.name }}</i>
              </el-button>
              <el-button
                size="small"
                type="primary"
                plain
                @click="onGridModelClose(false)"
              >
                <i class="el-icon-close">关闭</i>
              </el-button>
            </div>
          </template>
        </vol-box>
      </div>
      <!--body自定义组件-->
      <div class="grid-body">
        <component
          :is="dynamicComponent.gridBody"
          ref="gridBody"
          @parentCall="parentCall"
        ></component>
      </div>
      <!--table表格-->
      <div class="grid-container">
        <!-- 2021.05.02增加树形结构 rowKey -->
        <vol-table
          ref="table"
          :single="single"
          :rowKey="rowKey"
          :loadTreeChildren="loadTreeTableChildren"
          @loadBefore="loadTableBefore"
          @loadAfter="loadTableAfter"
          @rowChange="rowOnChange"
          @rowClick="rowOnClick"
          @rowDbClick="rowOnDbClick"
          :tableData="[]"
          :linkView="linkData"
          :columns="columns"
          :pagination="pagination"
          :height="height"
          :max-height="tableMaxHeight"
          :pagination-hide="false"
          :url="url"
          :load-key="false"
          :defaultLoadPage="load"
          :summary="summary"
          :double-edit="doubleEdit"
          :index="doubleEdit"
          :beginEdit="tableBeginEdit"
          :endEditBefore="tableEndEditBefore"
          :click-edit="true"
          :column-index="columnIndex"
          :text-inline="textInline"
          :ck="ck"
          :select2Count="select2Count"
          :selectable="selectable"
        ></vol-table>
      </div>
    </div>
    <!--footer自定义组件-->
    <component
      :is="dynamicComponent.gridFooter"
      ref="gridFooter"
      @parentCall="parentCall"
    ></component>
  </div>
</template>
<script>
const _const = {
  EDIT: 'update',
  ADD: 'Add',
  VIEW: 'view',
  PAGE: 'getPageData',
  AUDIT: 'audit',
  DEL: 'del',
  EXPORT: 'Export', //导出操作返回加密后的路径
  DOWNLOAD: 'DownLoadFile', //导出文件
  DOWNLOADTEMPLATE: 'DownLoadTemplate', //下载导入模板
  IMPORT: 'Import', //导入(导入表的Excel功能)
  UPLOAD: 'Upload' //上传文件
};
import Empty from '@/components/basic/Empty.vue';
import VolTable from '@/components/basic/VolTable.vue';
import VolForm from '@/components/basic/VolForm.vue';
import {
  defineAsyncComponent,
  defineComponent,
  ref,
  shallowRef,
  toRaw
} from 'vue';
var vueParam = {
  components: {
    'vol-form': VolForm,
    'vol-table': VolTable,
    VolBox: defineAsyncComponent(() => import('@/components/basic/VolBox.vue')),
    QuickSearch: defineAsyncComponent(() =>
      import('@/components/basic/QuickSearch.vue')
    ),
    Audit: defineAsyncComponent(() => import('@/components/basic/Audit.vue')),
    UploadExcel: defineAsyncComponent(() =>
      import('@/components/basic/UploadExcel.vue')
    ),
    'custom-column': defineAsyncComponent(() =>
      import('./ViewGridCustomColumn.vue')
    ),
    'vol-header': defineAsyncComponent(() => import('./../VolHeader.vue')),
     ViewGridAudit: defineAsyncComponent(() => import('./ViewGridAudit.vue'))
  },
  props: {},
  setup(props) {
    //2021.07.17调整扩展组件组件
    const dynamicCom = {
      gridHeader: Empty,
      gridBody: Empty,
      gridFooter: Empty,
      modelHeader: Empty,
      modelBody: Empty,
      modelFooter: Empty
    };
    //合并扩展组件
    if (props.extend.components) {
      for (const key in props.extend.components) {
        if (props.extend.components[key]) {
          dynamicCom[key] = toRaw(props.extend.components[key]);
        }
      }
    }
    const dynamicComponent = shallowRef(dynamicCom);
    return { dynamicComponent };
  },
  data() {
    return {
      isBoxAudit: false,
      formFieldsType: [],
      workFlowSteps: [],
      //树形结构的主键字段,如果设置值默认会开启树形table;注意rowKey字段的值必须是唯一(2021.05.02)
      rowKey: undefined,
      fiexdSearchForm: false, //2020.09.011是否固定查询表单,true查询表单将固定显示在表单的最上面
      _inited: false,
      doubleEdit: false, //2021.03.19是否开启查询界面表格双击编辑
      single: false, //表是否单选
      const: _const, //增删改查导入导出等对应的action
      boxInit: false, //新建或编辑的弹出框初化状态,默认不做初始化,点击新建或编辑才初始化弹出框
      searchBoxShow: false, //高级查询(界面查询后的下拉框点击触发)
      singleSearch: {}, //快速查询字段
      exportHref: '',
      currentAction: _const.ADD, //当新建或编辑时,记录当前的状态:如当前操作是新建
      currentRow: {}, //当前编辑或查看数据的行
      closable: false,
      boxModel: false, //弹出新建、编辑框
      width: 700, //弹出框查看表数据结构
      labelWidth: 100, //高级查询的标签宽度
      viewModel: false, //查看表结构的弹出框
      viewColumns: [], //查看表结构的列数据
      viewColumnsClone: [],
      showCustom: true, //是否显示自定义配置列按钮2022.05.27
      // viewData: [], //查看表结构信息
      maxBtnLength: 8, //界面按钮最多显示的个数,超过的数量都显示在更多中
      buttons: [], //查询界面按钮  å¦‚需要其他操作按钮,可在表对应的.js中添加(如:Sys_User.js中buttons添加其他按钮)
      splitButtons: [],
      uploadfiled: [], //上传文件图片的字段
      boxButtons: [], //弹出框按钮 å¦‚需要其他操作按钮,可在表对应的.js中添加
      dicKeys: [], //当前界面所有的下拉框字典编号及数据源
      hasKeyField: [], //有字典数据源的字段
      keyValueType: { _dinit: false },
      url: '', //界面表查询的数据源的url
      hasDetail: false, //是否有从表(明细)表格数据
      initActivated: false,
      load: true, //是否默认加载表数据
      activatedLoad: false, //页面触发actived时是否刷新页面数据
      summary: false, //查询界面table是否显示合计
      //需要从远程绑定数据源的字典编号,如果字典数据源的查询结果较多,请在onInit中将字典编号添加进来
      //只对自定sql有效
      remoteKeys: [],
      columnIndex: true, //2020.11.01是否显示行号
      ck: true, //2020.11.01是否显示checkbox
      continueAdd: false, //2021.04.11新建时是否可以连续新建操作
      continueAddName: '保存后继续添加', //2021.04.11按钮名称
      // detailUrl: "",
      detailOptions: {
        //弹出框从表(明细)对象
        //从表配置
        buttons: [], //弹出框从表表格操作按钮,目前有删除行,添加行,刷新操作,如需要其他操作按钮,可在表对应的.js中添加
        cnName: '', //从表名称
        key: '', //从表主键名
        data: [], //数据源
        columns: [], //从表列信息
        edit: true, //明细是否可以编辑
        single: false, //明细表是否单选
        load: false, //
        delKeys: [], //当编辑时删除当前明细的行主键值
        url: '', //从表加载数据的url
        pagination: { total: 0, size: 100, sortName: '' }, //从表分页配置数据
        height: 0, //默认从表高度
        textInline: true, //明细表行内容显示在一行上,如果需要换行显示,请设置为false
        doubleEdit: true, //使用双击编辑
        clickEdit: false, //是否开启点击单元格编辑,点击其他行时结束编辑
        currentReadonly: false, //当前用户没有编辑或新建权限时,表单只读(可用于判断用户是否有编辑或新建权限)
        //开启编辑时
        beginEdit: (row, column, index) => {
          return true;
        },
        //结束编辑前
        endEditBefore: (row, column, index) => {
          return true;
        },
        //结束编辑后
        endEditAfter: (row, column, index) => {
          return true;
        },
        columnIndex: false, //2020.11.01明细是否显示行号
        ck: true //2020.11.01明细是否显示checkbox
      },
      auditParam: {
        //审核对象
        rows: 0, //当前选中审核的行数
        model: false, //审核弹出框
        value: -1, //审核结果
        status: -1,
        reason: '', //审核原因
        height: 500,
        showViewButton: true,
        auditHis: [],
        showAction: false, //是否显示审批操作(当前节点为用户审批时显示)
        //审核选项(可自行再添加)
        data: [
          { text: '通过', value: 1 },
          { text: '拒绝', value: 2 },
          { text: '驳回', value: 3 }
        ]
      },
      upload: {
        //导入上传excel对象
        excel: false, //导入的弹出框是否显示
        url: '', //导入的路径,如果没有值,则不渲染导入功能
        template: {
          //下载模板对象
          url: '', //下载模板路径
          fileName: '' //模板下载的中文名
        },
        init: false //是否有导入权限,有才渲染导入组件
      },
      height: 0, //表高度
      tableHeight: 0, //查询页面table的高度
      tableMaxHeight: 0, //查询页面table的最大高度
      textInline: true, //table内容超出后是否不换行2020.01.16
      pagination: { total: 0, size: 30, sortName: '' }, //从分页配置数据
      boxOptions: {
        title: '', //弹出框显示的标题2022.08.01
        saveClose: true,
        labelWidth: 100,
        height: 0,
        width: 0,
        summary: false, //弹出框明细table是否显示合计
        draggable: false, //2022.09.12弹出框拖动功能
        modal: true //2022.09.12弹出框背景遮罩层
      }, //saveClose新建或编辑成功后是否关闭弹出框//弹出框的标签宽度labelWidth
      editor: {
        uploadImgUrl: '', //上传路径
        upload: null //上传方法
      },
      numberFields: [],
      //2022.09.26增加自定义导出文件名
      downloadFileName: null,
      select2Count: 500 //超出500数量显示select2组件
    };
  },
  methods: {},
  activated() {
     this.initFlowQuery();
    //2020.06.25增加activated方法
    this.onActivated && this.onActivated();
    if (!this._inited) {
      this._inited = true;
      return;
    }
    if (this.activatedLoad) {
      this.refresh();
    }
  },
  mounted() {
    this.mounted();
    // this.$refs.searchForm.forEach()
  },
  unmounted() {
    this.destroyed();
  },
  created: function() {
    //合并自定义业务扩展方法
    Object.assign(this, this.extend.methods);
    //如果没有指定排序字段,则用主键作为默认排序字段
    this.pagination.sortName = this.table.sortName || this.table.key;
    this.initBoxButtons(); //初始化弹出框与明细表格按钮
    this.initAuditColumn();
    this.onInit(); //初始化前,如果需要做其他处理在扩展方法中覆盖此方法
    this.getButtons();
    //初始化自定义表格列
    this.initViewColumns();
    //初始编辑框等数据
    this.initBoxHeightWidth();
    this.initDicKeys(); //初始下框数据源
    this.onInited(); //初始化后,如果需要做其他处理在扩展方法中覆盖此方法
  },
  beforeUpdate: function() {},
  updated: function() {}
};
import props from './props.js';
import methods from './methods.js';
//合并属性
vueParam.props = Object.assign(vueParam.props, props);
//合并方法
vueParam.methods = Object.assign(
  vueParam.methods,
  methods,
  props.extend.methods
);
export default defineComponent(vueParam);
</script>
<style lang="less" scoped>
@import './ViewGrid.less';
</style>
<style lang="less" scoped>
.btn-group ::v-deep(.ivu-select-dropdown) {
  padding: 0px !important;
  right: 3px;
}
.btn-group ::v-deep(.ivu-select-dropdown .ivu-dropdown-menu) {
  min-width: 100px;
  right: -2px;
  position: absolute;
  background: white;
  width: 130px;
  border-radius: 5px;
  border: 1px solid #e7e5e5;
}
.vertical-center-modal ::v-deep(.srcoll-content) {
  padding: 0;
}
.view-model-content {
  background: #eee;
}
.grid-detail ::v-deep(.v-table .el-table__header th) {
  height: 44px;
}
</style>
<style lang="less" scoped>
.grid-search {
  position: relative;
  .search-box {
    background: #fefefe;
    margin-top: 33px;
    border: 1px solid #eae8e8;
    position: absolute;
    z-index: 999;
    left: 15px;
    right: 15px;
    padding: 25px 20px;
    padding-bottom: 0;
    border-top: 0;
    box-shadow: 0 7px 18px -12px #bdc0bb;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/ViewGridAudit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,427 @@
<template>
  <vol-box :footer="false" v-model="model" :height="height" :width="width" :padding="0" :lazy="true" title="审核">
    <div class="audit-model-content" :style="{ height: height - 100 + 'px' }">
      <el-descriptions class="desc-top" :column="3" size="default" :border="true">
        <el-descriptions-item v-for="(item, index) in formData" :key="index">
          <template #label>
            <div class="cell-item">
              {{ item.name }}
            </div>
          </template>
          {{ item.value }}
        </el-descriptions-item>
      </el-descriptions>
      <el-radio-group v-show="hasFlow" style="padding-left: 15px;" v-model="activeName" class="ml-4">
        <el-radio label="audit" size="large">审核</el-radio>
        <el-radio label="log" size="large">审核记录</el-radio>
      </el-radio-group>
      <div v-show="activeName == 'audit' || !hasFlow" class="audit-content">
        <div class="fx-left" v-if="hasFlow">
          <div class="v-steps">
            <div v-for="(item, index) in workFlowSteps" :key="index">
              <div class="step-item" :class="{'step-item-ad':item.auditId||item.stepAttrType=='start'}" v-if="item.stepAttrType == 'start'">
                <div class="left-item">
                  <div>流程开始</div>
                  <div class="left-date">{{ item.createDate }}</div>
                </div>
                <div class="right-item">
                  <div class="step-line"></div>
                  <i class="step-circle"></i>
                  <div class="step-title">
                    {{ item.stepName }}
                  </div>
                  <div class="step-text">发起人:{{ item.creator }}</div>
                </div>
              </div>
              <div class="step-item" v-else-if="item.stepAttrType == 'end'">
                <div class="left-item">
                  <div>流程结束</div>
                </div>
                <div class="right-item">
                  <div class="step-line"></div>
                  <i class="step-circle"></i>
                  <div class="step-title">
                    {{ item.stepName }}
                  </div>
                </div>
              </div>
              <div v-else :class="{ 'step-current': item.isCurrent }" class="step-item">
                <div class="left-item">
                  <div>审批时间</div>
                  <div class="left-date">{{ item.auditDate || '待审批' }}</div>
                </div>
                <div class="right-item">
                  <div class="step-line"></div>
                  <i class="step-circle"></i>
                  <div class="step-title">
                    {{ item.stepName }}
                  </div>
                  <div class="step-text">审批人:{{ item.auditor }}</div>
                  <div class="step-text">
                    çж æ€ï¼š {{ getAuditStatus(item.auditStatus) }}
                  </div>
                  <div class="step-text">备 æ³¨ï¼š {{ item.remark || '-' }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="fx-right" :style="{ width: !hasFlow ? '100%' : '400px' }" v-if="isCurrentUser || !hasFlow">
          <div v-if="!hasFlow">
            <el-alert :title="'当前选中【' + rowLen + '】条记录待审核..'" type="success" :closable="false" />
          </div>
          <div class="rd">
            <span>审批:</span>
            <el-radio-group style="margin-left:15px" v-model="auditParam.value">
              <el-radio v-for="item in auditParam.data" :key="item.value" :label="item.value">
                <span>{{ item.text }}</span>
              </el-radio>
            </el-radio-group>
          </div>
          <el-input style="padding-top: 10px;" v-model="auditParam.reason" type="textarea"
            :autosize="{ minRows: 4, maxRows: 10 }" placeholder="请输入备注..."></el-input>
          <div class="btn">
            <el-button type="primary" @click="auditClick" icon="Check">审批</el-button>
          </div>
        </div>
      </div>
      <div v-show="activeName == 'log'">
        <vol-table :tableData="tableData" :columns="columns" :height="height - 250" :pagination-hide="true"
          :load-key="false" :text-inline="false" :ck="false"></vol-table>
      </div>
    </div>
  </vol-box>
</template>
<script>
import VolTable from '@/components/basic/VolTable.vue';
import VolBox from '@/components/basic/VolBox.vue';
import http from '@/../src/api/http.js';
import { defineComponent, ref, reactive, getCurrentInstance } from 'vue';
export default defineComponent({
  components: {
    VolTable,
    VolBox
  },
  props: {
    option: { //生成vue文件的table参数
      type: Object,
      default: {
        key: '',
        cnName: '',
        name: '',
        url: ""
      }
    }
  },
  setup(props, { emit }) {
    const height = ref(500);
    const width = ref(820);
    const model = ref(false)
    const workFlowSteps = reactive([]);
    const hasFlow = ref(false)
    const formData = reactive([]);
    const auditParam = reactive({
      //审核对象
      rows: 0, //当前选中审核的行数
      model: false, //审核弹出框
      value: -1, //审核结果
      reason: '', //审核原因
      //审核选项(main.js里面可以添加其他选项)
      data: []
    })
    const { proxy } = getCurrentInstance();
    auditParam.data = proxy.$global.audit.data;
    const tableData = reactive([]);
    const columns = reactive([
      { title: '节点', field: 'stepName', width: 100 },
      { title: '审批人', field: 'auditor', width: 80 },
      { title: '审批结果', field: 'auditStatus', width: 70, bind: { data: [] } },
      { title: '审批时间', field: 'auditDate', width: 145 },
      { title: '备注', field: 'remark', width: 120 }
    ]);
    const isCurrentUser = ref(null);
    const activeName = ref('audit')
    const auditDic = reactive([]);
    const getAuditStatus = (key) => {
      return (auditDic.find(x => { return x.key === key + '' }) || { value: key }).value;
    }
    const rowLen = ref(0)
    let currentRows = []
    const getAuditInfo = (option) => {
      const table = option.table; //props.option.url.replaceAll('/', '');
      const url = `api/Sys_WorkFlow/getSteps?tableName=${table}`
      //  let ids = currentRows.map(x => { return x[props.option.key] });
      let ids = currentRows.map(x => { return x[option.key] });
      // ['498043c1-fbd0-4a35-a870-523823912a9b']
      http.post(url, ids, true).then(result => {
        if (!result.status) {
          proxy.$message.error(result.message);
          return;
        }
        hasFlow.value = !!(result.list || []).length;
        if (!hasFlow.value) {
          let auditStatus = Object.keys(currentRows[0]).find(x => { return x.toLowerCase() === 'auditstatus' });
          let checkStatus = currentRows.every((x) => {
            return proxy.$global.audit.status.some(c => { return c === x[auditStatus] || !x[auditStatus] })
          });
          if (!checkStatus) {
            proxy.$message.error('只能选择待审批或审核中的数据');
            return;
          }
          rowLen.value = currentRows.length;
          model.value = true;
          width.value = 430;
          height.value = 330;
          isCurrentUser.value = true;
          //没有审批流程的数据只显示
          return;
        }
        model.value = true;
        height.value = document.body.clientHeight * 0.95;
        width.value = 820;
        if (!auditDic.length) {
          auditDic.push(...(result.auditDic || []))
          columns.forEach(item => {
            if (item.field == 'auditStatus') {
              item.bind.data = auditDic;
            }
          })
        }
        isCurrentUser.value = result.list.some(x => { return x.isCurrentUser })
        workFlowSteps.length = 0;
        workFlowSteps.push(...result.list);
        tableData.length = 0;
        tableData.push(...result.log)
        formData.length = 0;
        formData.push(...(result.form || []))
      })
    }
    //
    const auditClick = () => {
      if (auditParam.value == -1) {
        proxy.$message.error('请选择审批项');
        return;
      }
      if (!isFlow.value) {
        emit("auditClick", auditParam, currentRows, (result) => {
          if (result.status) {
            model.value = false;
            tableData.length = 0;
          }
        });
        return;
      }
      //我的流程中点击审批
      //保存审核
      let keys = currentRows.map(x => { return x[currentOption.key] });
      let url = `api/${currentOption.table}/audit?auditReason=${auditParam.reason}&auditStatus=${auditParam.value}`
      http.post(url, keys, '审核中....').then((x) => {
        if (!x.status) {
          proxy.$message.error(x.message);
          return;
        }
        model.value = false;
        proxy.$parent.search()
        proxy.$message.success(x.message)
      });
    }
    const isFlow = ref(false);
    let currentOption = {};
    const open = (rows, flow) => {
      isFlow.value = !!flow;
      currentRows = rows;
      activeName.value = 'audit'
      auditParam.reason = '';
      auditParam.value = -1;
      if (flow) {
        currentOption = {
          table: rows[0].WorkTable,
          key: "WorkTableKey"// rows[0].WorkTableKey
        }
      } else {
        currentOption = {
          table: props.option.url.replaceAll('/', ''),
          key: props.option.key
        }
      }
      getAuditInfo(currentOption);
    }
    return {
      columns,
      height,
      width,
      model,
      workFlowSteps,
      getAuditInfo,
      getAuditStatus,
      activeName,
      reactive,
      tableData,
      auditParam,
      auditClick,
      open,
      isCurrentUser,
      hasFlow,
      rowLen,
      formData,
      isFlow
    }
  }
});
</script>
<style lang="less" scoped>
.audit-model-content {
  padding: 10px;
}
.step-item {
  background: #fff;
  display: flex;
}
.left-item {
  min-width: 180px;
  text-align: right;
  padding-right: 25px;
  padding-top: 8px;
  .left-date {
    font-size: 13px;
    padding-top: 7px;
    color: #6c6c6c;
  }
}
.right-item {
  cursor: pointer;
  position: relative;
  border-bottom: 1px solid #f3f3f3;
  padding: 5px 0 5px 5px;
}
.left-item,
.right-item {
  padding-bottom: 10px;
}
.right-item:last-child {
  border-bottom: 0;
}
.step-line {
  top: 16px;
  left: -10px;
  width: 1px;
  height: 100%;
  position: absolute;
  background-color: #ebedf0;
}
.step-circle {
  position: absolute;
  top: 17px;
  left: -9px;
  z-index: 2;
  font-size: 12px;
  line-height: 1;
  transform: translate(-50%, -50%);
  width: 7px;
  height: 7px;
  background-color: #a1a1a1;
  border-radius: 50%;
}
.right-item::before {
  content: '';
}
.step-content {
  padding-top: 2px;
  font-size: 14px;
  color: #828282;
  line-height: 1.5;
}
.step-title {
  font-weight: bold;
  padding-top: 3px;
}
.step-text {
  font-size: 13px;
  color: #999999;
  padding-top: 6px;
}
.step-current {
  * {
    color: #2f95ff !important;
  }
  .step-circle {
    background: #2f95ff !important;
  }
  // border-radius: 5px;
  // border: 1px solid #d6eaff;
  font-size: 13px;
  padding-top: 6px;
  // background-color: #eff7ffd9;
  color: black;
}
.audit-content {
  // background: #f9f9f9;
  padding: 10px;
  border-radius: 4px;
  display: flex;
  .fx-left {
    flex: 1;
    width: 0;
    .rd {
      display: flex;
      align-items: baseline;
    }
  }
  .fx-right {
    // width: 400px;
    .btn {
      margin-top: 10px;
      text-align: center;
    }
  }
}
.cell-item {
  font-weight: 500;
}
.desc-top {
  padding: 5px 10px 0 10px;
}
.step-item-ad{
  *{
    color: #9f9898 !important;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/ViewGridCustomColumn.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,151 @@
export default {
  initViewColumns(isReset) {
    //初始化自定列配置
    if (isReset) {
      this.resetViewColumns();
    }
    if (!this.orginColumnFields) {
      this.orginColumnFields = this.columns.map((c) => {
        return c.field;
      });
    }
    this.viewColumns = this.columns
      .filter((c) => {
        return !c.hidden && !c.render;
      })
      .map((c) => {
        return { field: c.field, title: c.title, show: !c.hidden };
      });
    if (isReset) {
      return;
    }
    this.getCacheViewColumn();
  },
  getViewCacheKey(){
    return 'custom:column'+this.table.name;
  },
  getCacheViewColumn() {
    try {
      let columns = localStorage.getItem(this.getViewCacheKey());
      if (!columns) return;
      columns = JSON.parse(columns);
      if (columns.some(x=>{return !this.viewColumns.some(c=> {return c.field==x.field})})||
          this.viewColumns.some(x=>{return !columns.some(c=> {return c.field==x.field})})
      ) {
          localStorage.removeItem(this.getViewCacheKey())
          return;
      }
      let sortTableColumns = [];
      //弹出框的列
      let _viewColumns = [];
      columns.forEach((column) => {
        let _column = this.viewColumns.find((c) => {
          return c.field == column.field;
        });
        if (_column) {
          _column.show = column.show;
          _viewColumns.push(_column);
        }
        let tableColumn = this.columns.find((c) => {
          return c.field == column.field;
        });
        if (tableColumn) {
          tableColumn.hidden = !column.show;
          sortTableColumns.push(tableColumn);
        }
      });
      //重新排版弹出框自定义列
      let otherColumns = this.viewColumns.filter((c) => {
        return !_viewColumns.some((s) => {
          return c.field == s.field;
        });
      });
            //重新排版弹出框自定义列
      _viewColumns.push(...otherColumns);
      this.viewColumns.splice(0);
      this.viewColumns.push(..._viewColumns);
      this.sortViewColumns(sortTableColumns);
    } catch (error) {
      console.log('设置默认自定义列异常:' + error.message);
    }
  },
  sortViewColumns(sortColumns) {
    if (sortColumns.length) {
      let hiddenColumns = this.columns.filter((c) => {
        return !sortColumns.some((s) => {
          return c.field == s.field;
        });
      });
      sortColumns.push(...hiddenColumns);
      this.columns.splice(0);
      this.columns.push(...sortColumns);
    }
  },
  resetViewColumns() {
    if (!this.orginColumnFields) {
      return;
    }
    let _columns = [];
    this.orginColumnFields.forEach((x) => {
      _columns.push(
        this.columns.find((c) => {
          return c.field == x;
        })
      );
    });
    let otherColumns = this.columns.filter((c) => {
      return !this.orginColumnFields.some((s) => {
        return c.field == s;
      });
    });
    _columns.push(...otherColumns);
    this.columns.splice(0);
    this.columns.push(..._columns);
  },
  showCustomModel() {
    if (!this.viewColumns.length) {
      this.initViewColumns();
    }
    this.viewColumnsClone = JSON.parse(JSON.stringify(this.viewColumns));
    this.viewModel = true;
  },
  closeCustomModel() {
    this.viewModel=false;
    if (this.checkColumnChanged()) {
      this.viewColumns = JSON.parse(JSON.stringify(this.viewColumnsClone));
    }
  },
  checkColumnChanged() {
    return (
      JSON.stringify(this.viewColumns) != JSON.stringify(this.viewColumnsClone)
    );
  },
  saveColumnConfig() {
    let hasShowColumn = this.viewColumns.some((x) => {
      return x.show;
    });
    if (!hasShowColumn) {
      return this.$message.error('至少选择一列显示');
    }
    this.viewModel = false;
    if (this.checkColumnChanged()) {
      let sortColumns = [];
      this.viewColumns.forEach((column) => {
        let _column = this.columns.find((c) => {
          return c.field == column.field;
        });
        if (_column) {
          _column.hidden = !column.show;
          sortColumns.push(_column);
        }
      });
      this.sortViewColumns(sortColumns);
    }
    try {
      localStorage.setItem(this.getViewCacheKey(), JSON.stringify(this.viewColumns));
    } catch (error) {
      console.log('获取自定义列异常:' + error.message);
    }
  }
};
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/ViewGridCustomColumn.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
<template>
  <el-alert
    title="拖动列名可调整表格列显示顺序"
    type="success"
    :show-icon="false"
  >
  </el-alert>
  <div class="view-column view-column-title">
    <div class="view-column-index">#</div>
    <div class="view-column-left">列名</div>
    <div class="view-column-right">是否显示</div>
  </div>
  <draggable
    class="list-group"
    tag="transition-group"
    :component-data="componentData"
    :list="viewColumns"
    v-bind="dragOptions"
    item-key="order"
  >
    <transition-group class="drag-center-item">
      <div
        class="view-column"
        v-for="(column, index) in viewColumns"
        :key="index"
      >
        <div class="view-column-index">{{ index + 1 }}</div>
        <div class="view-column-left">{{ column.title }}</div>
        <div class="view-column-right">
          <el-checkbox v-model="column.show">
            <div style="height: 100%; width: 250px"></div
          ></el-checkbox>
        </div>
      </div>
    </transition-group>
  </draggable>
</template>
<script>
import { VueDraggableNext } from 'vue-draggable-next';
import { defineComponent, ref, reactive } from 'vue';
export default defineComponent({
  props: {
    viewColumns: {
      type: Array,
      default: () => {
        return [];
      }
    }
  },
  components: {
    draggable: VueDraggableNext
  },
  data() {
    return {};
  },
  setup(props, context) {
    const dragOptions = reactive({
      animation: 200,
      group: 'description',
      disabled: false,
      ghostClass: 'ghost'
    });
    const componentData = reactive({
      tag: 'ul',
      type: 'transition-group'
    });
    return { dragOptions, componentData };
  }
});
</script>
<style lang="less" scoped>
.view-column {
  cursor: pointer;
  display: flex;
  padding: 10px;
  border-bottom: 1px solid #f3f3f3;
  .view-column-index {
    width: 50px;
  }
  .view-column-left {
    width: 120px;
    padding: 0 10px;
  }
  .view-column-right {
    flex: 1;
  }
}
.view-column-title {
  font-weight: bold;
}
.view-column:last-child {
  border-bottom: 0;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/detailMethods.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
//从表方法
let detailMethods = {
  //查询从表前先做内部处理
  loadInternalDetailTableBefore(param, callBack) {
    //加载明细表数据之前,需要设定查询的主表的ID
    //每次只要加载明细表格数据就重置删除明细的值
    if (this.detailOptions.delKeys.length > 0) {
      this.detailOptions.delKeys = [];
    }
    let key = this.table.key;
    if (this.currentRow && this.currentRow.hasOwnProperty(key)) {
      param.value = this.currentRow[key];
    }
    return this.loadDetailTableBefore(param, callBack);
  },
  detailRowOnChange(row) {
    this.detailRowChange(row);
  },
  detailRowChange(row) {
    //checkbox选中行事件
  },
  detailRowOnClick({ row, column, event }) {
    //明细表点击行事件2020.11.07
    this.detailRowClick({ row, column, event });
  },
  detailRowClick({ row, column, event }) {},
  resetDetailTable(row) {
    //编辑和查看明细时重置从表数据
    if (!this.detailOptions.columns || this.detailOptions.columns.length == 0) {
      return;
    }
    let key = this.table.key;
    let query = { value: row ? row[key] : this.currentRow[key] };
    this.$nextTick(() => {
      if (this.$refs.detail) {
        this.$refs.detail.reset();
        this.$refs.detail.load(query);
      }
    });
  },
  //从后面加载从表数据
  refreshRow() {
    this.resetDetailTable();
  },
  addRow() {
    this.$refs.detail.addRow({});
    this.$refs.detail.edit.rowIndex=-1;
    this.updateDetailTableSummaryTotal();
  },
  delRow() {
    let rows = this.$refs.detail.getSelected();
    if (!rows || rows.length == 0) {
      return this.$message.error('请选择要删除的行!');
    }
    if (!this.delDetailRow(rows)) {
      return false;
    }
    let tigger = false;
    this.$confirm('确认要删除选择的数据吗?', '警告', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
      center: true
    }).then(() => {
      if (tigger) return;
      tigger = true;
      rows = this.$refs.detail.delRow();
      let key = this.detailOptions.key;
      //记录删除的行数据
      rows.forEach((x) => {
        if (x.hasOwnProperty(key) && x[key]) {
          this.detailOptions.delKeys.push(x[key]);
        }
      });
      this.updateDetailTableSummaryTotal();
    });
  },
  updateDetailTableSummaryTotal() {
    //2021.09.25增加明细表删除、修改时重新计算行数与汇总
    //2021.12.12增加明细表判断(强制刷新合计时会用到)
    if (!this.$refs.detail) {
      return;
    }
    //删除或新增行时重新设置显示的总行数
    this.$refs.detail.paginations.total = this.$refs.detail.rowData.length;
    //重新设置合计
    if (this.$refs.detail.summary) {
      this.$refs.detail.columns.forEach((column) => {
        if (column.summary) {
          this.$refs.detail.getInputSummaries(null, null, null, column);
        }
      });
    }
  },
  detailSelectable(row, index){
    //明细表CheckBox æ˜¯å¦å¯ä»¥å‹¾é€‰
       return true;
  }
};
export default detailMethods;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
import Grid from './ViewGrid.vue'
const ViewGrid = {
    install: function (app) {
        app.component('ViewGrid', Grid)
    }
}
export default ViewGrid
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/methods.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1684 @@
import detailMethods from './detailMethods.js';
//业务处理方法,全部可以由开发覆盖
import serviceFilter from './serviceFilter.js';
let methods = {
  //当添加扩展组件gridHeader/gridBody/gridFooter及明细modelHeader/modelBody/modelFooter时,
  //如果要获取父级Vue对象,请使用此方法进行回调
  parentCall(fun) {
    if (typeof fun != 'function') {
      return console.log('扩展组件需要传入一个回调方法才能获取父级Vue对象');
    }
    fun(this);
  },
  getCurrentAction() {
    if (this.currentReadonly) {
      return '';
    }
    return '--' + (this.currentAction == this.const.ADD ? '新增' : '编辑');
  },
  quickSearchKeyPress($event) {
    //查询字段为input时,按回车查询
    if ($event.keyCode == 13) {
      if (this.searchFormFields[this.singleSearch.field] != '') {
        this.search();
      }
    }
  },
  getButtons() {
    //生成ViewGrid界面的操作按钮及更多选项
    let searchIndex = this.buttons.findIndex((x) => {
      return x.value == 'Search';
    });
    //添加高级查询
    let hasOneFormItem =
      this.searchFormOptions.length == 1 &&
      this.searchFormOptions[0].length == 1;
    if (searchIndex != -1 && !hasOneFormItem) {
      this.buttons.splice(searchIndex + 1, 0, {
        icon: this.fiexdSearchForm ? 'el-icon-refresh-left' : 'el-icon-search',
        name: this.fiexdSearchForm ? '重置' : '高级查询',
        plain: true,
        type: this.buttons[searchIndex].type,
        onClick: () => {
          if (this.fiexdSearchForm) {
            return this.resetSearch();
          }
          this.searchBoxShow = !this.searchBoxShow;
        }
      });
    }
    if (hasOneFormItem) {
      this.fiexdSearchForm = false;
    }
    this.maxBtnLength += searchIndex == -1 ? 0 : 1;
    // if (this.buttons.length <= this.maxBtnLength) {
    //   return this.buttons;
    // }
    // let btns = this.buttons.slice(0, this.maxBtnLength);
    // btns[this.maxBtnLength - 1].last = true;
    // return btns;
  },
  extendBtn(btns, source) {
    //btns权限按钮,source为扩展按钮
    if (!btns || !(source && source instanceof Array)) {
      return;
    }
    //source通过在表的扩展js文件中buttons对应按钮的属性index决定按钮所放位置
    source.forEach((x) => {
      //通过按钮的Index属性,放到指定的位置
      btns.splice(x.index == undefined ? btns.length : x.index, 0, x);
    });
    // if (this.extend.buttons.view) {
    //     this.extend.buttons.view.forEach((x) => {
    //         //通过按钮的Index属性,放到指定的位置
    //         this.buttons.splice(x.index == undefined ? this.buttons.length : x.index, 0, x);
    //     })
    // }
  },
  initBoxButtons() {
    //初始化ViewGird与弹出框/明细表按钮
    let path = this.$route.path;
    //通过菜单获取用户所对应菜单需要显示的按钮
    let permissionButtons = this.permission.getButtons(
      path,
      null,
      this.extend.tableAction,
      this.table.name
    );
    if (permissionButtons) {
      //2020.03.31添加深拷贝按钮组
      permissionButtons.forEach((p) => {
        let _obj = {};
        for (const key in p) {
          _obj[key] = p[key];
        }
        this.buttons.push(_obj);
      });
      // this.buttons.push(...permissionButtons);
    }
    if (!this.extend) {
      this.extend = {};
    }
    if (!this.extend.buttons) {
      this.extend.buttons = {};
    }
    //查询界面扩展按钮(扩展按钮可自行通过设置按钮的Index属性显示到具体位置)
    if (this.extend.buttons.view) {
      this.extendBtn(this.buttons, this.extend.buttons.view);
    }
    //弹出框按钮
    let boxButtons = [];
    let saveBtn = this.buttons.some((x) => {
      if (
        x.value &&
        (x.value.toLowerCase() == this.const.ADD.toLowerCase() ||
          x.value.toLowerCase() == this.const.EDIT.toLowerCase())
      )
        return true;
    });
    this.currentReadonly = !saveBtn;
    //从表表格操作按钮
    let detailGridButtons = {
      name: '刷新',
      type: 'info',
      icon: 'el-icon-refresh',
      onClick() {
        //如果明细表当前的状态为新建时,禁止刷新
        if (this.currentAction == this.const.ADD) {
          return;
        }
        this.refreshRow();
      }
    };
    let importExcel = this.buttons.some((x) => {
      if (x.value == this.const.IMPORT) return true;
    });
    //如果有导入权限,则需要初始化导入组件
    if (importExcel) {
      this.upload.url = this.getUrl(this.const.IMPORT);
      //定义下载模板的文件名
      this.upload.template.fileName = this.table.cnName;
      //定义下载模板的Url路径
      this.upload.template.url =
        this.http.ipAddress + this.getUrl(this.const.DOWNLOADTEMPLATE, true);
    }
    // disabled
    //如果当前角色没有编辑或新建功能,查看明细时字段设置全部只读
    //只有明细表,将明细表也设置为不可能编辑,并且不显示添加行、删除行
    if (!saveBtn) {
      this.editFormOptions.forEach((row) => {
        row.forEach((x) => {
          x.disabled = true;
        });
      });
      //没有新增编辑权限的,弹出框都设置为只读
      this.detail.columns.forEach((column) => {
        if (column.hasOwnProperty('edit')) {
          column.readonly = true;
          // row['edit'] = false;
        }
      });
      //弹出框扩展按钮
      this.extendBtn(boxButtons, this.extend.buttons.box);
      //弹出弹框按钮(2020.04.21),没有编辑或新建权限时,也可以通过buttons属性添加自定义弹出框按钮
      this.boxButtons.push(...boxButtons);
      this.detailOptions.buttons.push(detailGridButtons);
      this.detailOptions.buttons.forEach((button) => {
        if (!button.hasOwnProperty('hidden')) {
          button.hidden = false;
        }
      });
      //弹出框扩展明细表按钮
      this.extendBtn(this.detailOptions.buttons, this.extend.buttons.detail);
      return boxButtons;
    }
    this.detailOptions.edit = true;
    boxButtons.push(
      ...[
        {
          name: '保 å­˜',
          icon: 'el-icon-check',
          type: 'danger',
          disabled: false,
          value: 'save',
          onClick() {
            this.save();
          }
        }
        // {
        //   name: '重 ç½®',
        //   icon: 'el-icon-refresh-right',
        //   type: 'primary',
        //   disabled: false,
        //   onClick() {
        //     this.resetEdit();
        //   }
        // }
      ]
    );
    //从表表格操作按钮
    this.detailOptions.buttons.push(
      ...[
        {
          name: '添加行',
          icon: 'el-icon-plus',
          type: 'primary',
          hidden: false,
          plain: true,
          onClick() {
            this.addRow();
          }
        },
        {
          type: 'danger',
          plain: true,
          name: '删除行',
          hidden: false,
          icon: 'el-icon-delete',
          onClick() {
            this.delRow();
          }
        },
        //2022.01.08增加明细表导入导出功能
        //注意需要重写后台明细表接口的导入与下载模板、导出的权限,Sys_DictionaryListController.cs/SellOrderListController.cs
        {
          type: 'danger',
          plain: true,
          name: '导入',
          value: 'import',
          hidden: false,
          icon: 'el-icon-upload2',
          onClick() {
            this.upload.url = `${this.http.ipAddress}api/${this.detail.table}/${this.const.IMPORT}?table=1`;
            this.upload.template.url = `${this.http.ipAddress}api/${this.detail.table}/${this.const.DOWNLOADTEMPLATE}`;
            //定义下载模板的文件名
            this.upload.template.fileName = this.detail.cnName;
            this.upload.excel = true;
          }
        },
        {
          type: 'danger',
          plain: true,
          name: '导出',
          value: 'export',
          icon: 'el-icon-download',
          hidden: false,
          onClick() {
            this.export(true);
          }
        }
      ]
    );
    this.detailOptions.buttons.forEach((button) => {
      if (button.hasOwnProperty('hidden')) {
        button.hidden = false;
      }
    });
    //弹出框扩展按钮
    this.extendBtn(boxButtons, this.extend.buttons.box);
    //弹出框扩展明细表按钮
    this.detailOptions.buttons.push(detailGridButtons);
    this.extendBtn(this.detailOptions.buttons, this.extend.buttons.detail);
    //弹出弹框按钮
    this.boxButtons.push(...boxButtons);
  },
  onClick(click) {
    click.apply(this);
  },
  changeDropdown(btnName, v1) {
    let button = this.buttons.filter((x) => {
      return x.name == btnName;
    });
    if (button && button.length > 0) {
      button[0].onClick.apply(this);
    }
  },
  emptyValue(value) {
    if (typeof value == 'string' && value.trim() === '') {
      return true;
    }
    if (value instanceof Array && !value.length) {
      return true;
    }
    return value === null || value === undefined || value === '';
  },
  getSearchParameters() {
    //获取查询参数
    // 2020.09.11增加固定查询表单,如果设置固定了查询表单,点击查询时,不再关闭
    if (!this.fiexdSearchForm) {
      this.searchBoxShow = false;
    }
    let query = { wheres: [] };
    for (const key in this.searchFormFields) {
      let value = this.searchFormFields[key];
      if (this.emptyValue(value)) continue;
      if (typeof value == 'number') {
        value = value + '';
      }
      let displayType = this.getSearchItem(key);
      //联级只保留选中节点的最后一个值
      if (displayType == 'cascader') {
        //查询下面所有的子节点,如:选中的是父节点,应该查询下面所有的节点数据--待完
        value = value.length ? value[value.length - 1] + '' : '';
      }
      //2021.05.02增加区间查询
      if (
        typeof value == 'string' ||
        ['date', 'datetime', 'range'].indexOf(displayType) == -1
      ) {
        query.wheres.push({
          name: key,
          value:
            typeof value == 'string' ? (value + '').trim() : value.join(','),
          displayType: displayType
        });
        continue;
      }
      for (let index = 0; index < value.length; index++) {
        if (!this.emptyValue(value[index])) {
          query.wheres.push({
            name: key,
            value: (value[index] + '').trim(),
            displayType: (() => {
              if (['date', 'datetime', 'range'].indexOf(displayType) != -1) {
                return index ? 'lessorequal' : 'thanorequal';
              }
              return displayType;
            })()
          });
        }
      }
    }
    return query;
  },
  search() {
    //查询
    // let query = this.getSearchParameters();
    // this.$refs.table.load(query, true);
    this.$refs.table.load(null, true);
  },
  loadTableBefore(param, callBack) {
    //查询前设置查询条件及分页信息
    let query = this.getSearchParameters();
    if (query) {
      param = Object.assign(param, query);
    }
    if (this.$route.query.viewflow && this.$route.query.id) {
      param.wheres.push({
        name: this.table.key,
        value: this.$route.query.id
      });
    }
    // if (this.isViewFlow() && data && data.length) {
    //   let query = JSON.parse(JSON.stringify(this.$route.query));
    //   query.viewflow = 0;
    //   this.$router.replace({ path: this.$route.path, query: query });
    //   this.$nextTick(() => {
    //     this.getWorkFlowSteps(data[0]);
    //   });
    // }
    let status = this.searchBefore(param);
    callBack(status);
  },
  loadTableAfter(data, callBack, result) {
    //查询后
    //2020.10.30增加查询后返回所有的查询信息
    let status = this.searchAfter(data, result);
    callBack(status);
    //自动弹出框审批详情
  },
  loadDetailTableBefore(param, callBack) {
    //明细查询前
    //新建时禁止加载明细
    if (this.currentAction == this.const.ADD) {
      callBack(false);
      return false;
    }
    let status = this.searchDetailBefore(param);
    callBack(status);
  },
  loadDetailTableAfter(data, callBack) {
    //明细查询后
    let status = this.searchDetailAfter(data);
    callBack(status);
  },
  getSearchItem(field) {
    //获取查询的参数
    let data;
    for (let index = 0; index < this.searchFormOptions.length; index++) {
      if (data) return data.type;
      const item = this.searchFormOptions[index];
      data = item.find((x) => {
        return x.field == field;
      });
    }
    return (data || {}).type;
  },
  resetSearch() {
    //重置查询对象
    this.resetSearchForm();
    //2020.10.17增加重置后方法
    this.resetSearchFormAfter && this.resetSearchFormAfter();
  },
  resetEdit() {
    //重置编辑的数据
    let isEdit = this.currentAction != this.const.ADD;
    //重置之前
    if (!this[isEdit ? 'resetUpdateFormBefore' : 'resetAddFormBefore']()) {
      return;
    }
    let objKey = {};
    //编辑状态下,不需要重置主键,创建时间创建人
    if (isEdit) {
      objKey[this.table.key] = this.editFormFields[this.table.key];
    }
    this.resetEditForm(objKey);
    //重置之后
    if (!this[isEdit ? 'resetUpdateFormAfter' : 'resetAddFormAfter']()) {
      return;
    }
  },
  resetSearchForm(sourceObj) {
    //重置查询表
    this.resetForm('searchForm', sourceObj);
  },
  resetEditForm(sourceObj) {
    if (this.hasDetail && this.$refs.detail) {
      // this.$refs.detail.rowData.splice(0);
      this.$refs.detail.reset();
    }
    this.resetForm('form', sourceObj);
    if (this.$refs.form && this.$refs.form.$refs.volform) {
      setTimeout(() => {
        this.$refs.form.$refs.volform.clearValidate();
      }, 100);
    }
  },
  getKeyValueType(formData, isEditForm) {
    try {
      let keyLeft = (isEditForm ? 'e' : 's') + '_b_';
      formData.forEach((item) => {
        item.forEach((x) => {
          if (this.keyValueType.hasOwnProperty(keyLeft + x.field)) {
            return true;
          }
          let data;
          if (x.type == 'switch') {
            this.keyValueType[x.field] = 1;
          } else if (x.bind && x.bind.data) {
            data = x.bind.data;
          } else if (x.data) {
            if (x.data instanceof Array) {
              data = x.data;
            } else if (x.data.data && x.data.data instanceof Array) {
              data = x.data.data;
            }
          }
          if (
            data &&
            data.length > 0 &&
            !this.keyValueType.hasOwnProperty(x.field)
          ) {
            this.keyValueType[x.field] = data[0].key;
            this.keyValueType[keyLeft + x.field] = x.type;
          }
        });
      });
    } catch (error) {
      console.log(error.message);
    }
  },
  resetForm(formName, sourceObj) {
    //   return;
    //重置表单数据
    if (this.$refs[formName]) {
      this.$refs[formName].reset();
    }
    if (!sourceObj) return;
    let form, keyLeft;
    if (formName == 'searchForm') {
      form = this.searchFormFields;
      keyLeft = 's' + '_b_';
    } else {
      form = this.editFormFields;
      keyLeft = 'e' + '_b_';
    }
    //获取数据源的data类型,否则如果数据源data的key是数字,重置的值是字符串就无法绑定值
    if (!this.keyValueType._dinit) {
      this.getKeyValueType(this.editFormOptions, true);
      this.getKeyValueType(this.searchFormOptions, false);
      this.keyValueType._dinit = true;
    }
    var _cascaderParentTree;
    for (const key in form) {
      if (sourceObj.hasOwnProperty(key)) {
        let newVal = sourceObj[key];
        let kv_type = this.keyValueType[keyLeft + key];
        if (
          kv_type == 'selectList' ||
          kv_type == 'checkbox' ||
          kv_type == 'cascader' ||
          kv_type == 'treeSelect'
        ) {
          // 2020.05.31增加iview组件Cascader
          // 2020.11.01增加iview组件Cascader表单重置时查询所有的父节点
          if (kv_type == 'cascader' || kv_type == 'treeSelect') {
            var treeDic = this.dicKeys.find((dic) => {
              return dic.fileds && dic.fileds.indexOf(key) != -1;
            });
            if (treeDic && treeDic.orginData && treeDic.orginData.length) {
              let keyIsNum = typeof treeDic.orginData[0].id == 'number';
              if (kv_type == 'cascader') {
                newVal = keyIsNum ? newVal * 1 || 0 : newVal + '';
                if (kv_type == 'cascader') {
                  _cascaderParentTree = this.base.getTreeAllParent(
                    newVal,
                    treeDic.orginData
                  );
                  if (_cascaderParentTree) {
                    newVal = _cascaderParentTree.map((x) => {
                      return x.id;
                    });
                  }
                }
              } else {
                if (newVal === null || newVal === undefined) {
                  newVal = [];
                } else if (typeof newVal == 'string') {
                  newVal = newVal.split(',');
                }
                if (keyIsNum) {
                  if (Array.isArray(newVal)) {
                    newVal = newVal.map((x) => {
                      return x * 1 || 0;
                    });
                  }
                } else if (typeof newVal == 'number') {
                  newVal = [newVal + ''];
                }
              }
            } else {
              newVal = [newVal];
            }
          } else if (
            newVal != '' &&
            newVal != undefined &&
            typeof newVal == 'string'
          ) {
            newVal = newVal.split(',');
          } else if (kv_type == 'checkbox') {
            newVal = [];
          }
        } else if (
          this.keyValueType.hasOwnProperty(key) &&
          typeof this.keyValueType[key] == 'number' &&
          newVal * 1 == newVal
        ) {
          newVal = newVal * 1;
        } else {
          if (newVal == null || newVal == undefined) {
            newVal = '';
          } else if (this.numberFields.indexOf(key) != -1) {
            newVal = newVal * 1 || 0;
          } else {
            newVal += '';
          }
        }
        if (newVal instanceof Array) {
          if (form[key]) {
            form[key] = [];
          }
          form[key] = newVal;
        } else {
          form[key] = newVal;
        }
      } else {
        form[key] = form[key] instanceof Array ? [] : '';
      }
    }
  },
  onBtnClick(param) {
    this[param.method](param.data);
  },
  refresh() {
    //刷新
    this.search();
    // this.$refs.table.load();
  },
  saveBefore(formData) {
    return true;
  },
  saveAfter(formData, result) {
    return true;
  },
  save() {
    //新增或编辑时保存
    // if (!this.$refs.form.validate()) return;
    this.$refs.form.validate((result) => {
      if (result) {
        this.saveExecute();
      }
    });
  },
  async saveExecute() {
    let editFormFields = {};
    //上传文件以逗号隔开
    for (const key in this.editFormFields) {
      if (
        this.uploadfiled &&
        this.uploadfiled.length > 0 &&
        this.uploadfiled.indexOf(key) != -1 &&
        this.editFormFields[key] instanceof Array
      ) {
        let allPath = this.editFormFields[key].map((x) => {
          return x.path;
        });
        editFormFields[key] = allPath.join(',');
      } else if (typeof this.editFormFields[key] == 'function') {
        try {
          editFormFields[key] = this.editFormFields[key]();
        } catch (error) { }
      } else {
        //2021.05.30修复下拉框清除数据后后台不能保存的问题
        if (
          this.editFormFields[key] === undefined &&
          this.dicKeys.some((x) => {
            return x.fileds && x.fileds.indexOf(key) != -1;
          })
        ) {
          editFormFields[key] = null;
        } else {
          editFormFields[key] = this.editFormFields[key];
        }
      }
    }
    //将数组转换成string
    //2020.11.01增加级联处理
    for (const key in editFormFields) {
      if (editFormFields[key] instanceof Array) {
        var iscascader = this.dicKeys.some((x) => {
          return (
            x.type == 'cascader' && x.fileds && x.fileds.indexOf(key) != -1
          );
        });
        if (iscascader && editFormFields[key].length) {
          editFormFields[key] =
            editFormFields[key][editFormFields[key].length - 1];
        } else {
          editFormFields[key] = editFormFields[key].join(',');
        }
      }
    }
    let formData = {
      mainData: editFormFields,
      detailData: null,
      delKeys: null
    };
    //获取明细数据(前台数据明细未做校验,待完.后台已经校验)
    if (this.hasDetail) {
      formData.detailData = this.$refs.detail.rowData;
      let _fields = this.detail.columns
        .filter((c) => {
          return (
            c.type == 'selectList' || (c.edit && c.edit.type == 'selectList')
          );
        })
        .map((c) => {
          return c.field;
        });
      //2022.06.20增加保存时对明细表下拉框多选的判断
      if (_fields.length) {
        formData.detailData = JSON.parse(JSON.stringify(formData.detailData));
        formData.detailData.forEach((row) => {
          for (let index = 0; index < _fields.length; index++) {
            const _field = _fields[index];
            if (Array.isArray(row[_field])) {
              row[_field] = row[_field].join(',');
            }
          }
        });
      }
    }
    if (this.detailOptions.delKeys.length > 0) {
      formData.delKeys = this.detailOptions.delKeys;
    }
    //保存前拦截
    let _currentIsAdd = this.currentAction == this.const.ADD;
    if (_currentIsAdd) {
      //2020.12.06增加新建前异步处理方法
      //2021.08.16修复异步语法写错的问题
      if (!this.addBefore(formData) || !(await this.addBeforeAsync(formData)))
        return;
    } else {
      //2020.12.06增加修改前异步处理方法
      if (
        !this.updateBefore(formData) ||
        !(await this.updateBeforeAsync(formData))
      )
        return;
    }
    let url = this.getUrl(this.currentAction);
    this.http.post(url, formData, true).then((x) => {
      //保存后
      if (_currentIsAdd) {
        if (!this.addAfter(x)) return;
        //连续添加
        if (this.continueAdd && x.status) {
          this.$success(x.message);
          //新建
          this.currentAction = this.const.ADD;
          this.currentRow = {};
          this.resetAdd();
          this.refresh();
          return;
        }
      } else {
        if (!this.updateAfter(x)) return;
      }
      if (!x.status) return this.$error(x.message);
      this.$success(x.message || '操作成功');
      //如果保存成功后需要关闭编辑框,直接返回不处理后面
      if (this.boxOptions.saveClose) {
        this.boxModel = false;
        //2020.12.27如果是编辑保存后不重置分页页数,刷新页面时还是显示当前页的数据
        this.$refs.table.load(null, _currentIsAdd);
        //this.refresh();
        return;
      }
      let resultRow;
      if (typeof x.data == 'string' && x.data != '') {
        resultRow = JSON.parse(x.data);
      } else {
        resultRow = x.data;
      }
      if (this.currentAction == this.const.ADD) {
        //  this.currentRow=x.data;
        this.editFormFields[this.table.key] = '';
        this.currentAction = this.const.EDIT;
        this.currentRow = resultRow.data;
      }
      this.resetEditForm(resultRow.data);
      // console.log(resultRow);
      if (this.hasDetail) {
        this.detailOptions.delKeys = [];
        if (resultRow.list) {
          this.$refs.detail.rowData.push(...resultRow.list);
        }
      }
      this.$refs.table.load(null, _currentIsAdd);
      // this.refresh();
    });
  },
  del(rows) {
    if (rows) {
      if (!(rows instanceof Array)) {
        rows = [rows];
      }
    } else {
      rows = this.$refs.table.getSelected();
    }
    //删除数据
    if (!rows || rows.length == 0) return this.$error('请选择要删除的行!');
    let delKeys = rows.map((x) => {
      return x[this.table.key];
    });
    if (!delKeys || delKeys.length == 0)
      return this.$error('没有获取要删除的行数据!');
    //删除前
    if (!this.delBefore(delKeys, rows)) {
      return;
    }
    let tigger = false;
    this.$confirm('确认要删除选择的数据吗?', '警告', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
      center: true
    }).then(() => {
      if (tigger) return;
      tigger = true;
      let url = this.getUrl(this.const.DEL);
      this.http.post(url, delKeys, '正在删除数据....').then((x) => {
        if (!x.status) return this.$error(x.message);
        this.$success("删除成功");
        //删除后
        if (!this.delAfter(x)) {
          return;
        }
        this.refresh();
      });
    });
  },
  async modelOpenBeforeAsync(row) {
    return true;
  },
  async initBox() {
    //2022.01.08增加新建时隐藏明细表导出功能
    this.detailOptions.buttons.forEach((x) => {
      if (x.value == 'export') {
        x.hidden = this.currentAction == 'Add';
      }
    });
    //初始化新建、编辑的弹出框
    if (!(await this.modelOpenBeforeAsync(this.currentRow))) return false;
    this.modelOpenBefore(this.currentRow);
    if (!this.boxInit) {
      this.boxInit = true;
      this.boxModel = true;
      // this.detailUrl = this.url;
    }
    return true;
  },
  setEditForm(row) {
    // if (this.remoteColumns.length == 0 || !rows || rows.length == 0) return;
    let remoteColumns = this.$refs.table.remoteColumns;
    remoteColumns.forEach((column) => {
      this.editFormOptions.forEach((option) => {
        option.forEach((x) => {
          if (x.field == column.field) {
            x.data.data = Object.assign([], x.data, column.bind.data);
          }
        });
      });
    });
    this.editFormFields;
    //重置编辑表单数据
    this.editFormFields[this.table.key] = row[this.table.key];
    this.resetEditForm(row);
    this.currentAction = this.const.EDIT;
    this.boxModel = true;
  },
  async linkData(row, column) {
    this.boxOptions.title = this.table.cnName + '(编辑)';
    //点击table单元格快捷链接显示编辑数据
    this.currentAction = this.const.EDIT;
    this.currentRow = row;
    if (!(await this.initBox())) return;
    this.resetDetailTable(row);
    this.setEditForm(row);
    this.setContinueAdd(false);
    //设置远程查询表单的默认key/value
    this.getRemoteFormDefaultKeyValue();
    //点击编辑按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
    this.modelOpenProcess(row);
  },
  setContinueAdd(isAdd) {
    if (!this.continueAdd) return;
    var _button = this.boxButtons.find((x) => {
      return x.value == 'save';
    });
    if (_button) {
      _button.name = isAdd ? this.continueAddName : '保 å­˜';
    }
  },
  resetAdd() {
    if (this.hasDetail) {
      this.$refs.detail &&
        //  this.$refs.detail.rowData &&
        this.$refs.detail.reset();
    }
    let obj = {};
    //如果有switch标签,默认都设置为否
    this.editFormOptions.forEach((x) => {
      x.forEach((item) => {
        if (item.type == 'switch') {
          obj[item.field] = 0;
        }
      });
    });
    this.resetEditForm(obj);
  },
  async add() {
    this.boxOptions.title = this.table.cnName + '(新建)';
    //新建
    this.currentAction = this.const.ADD;
    this.currentRow = {};
    if (!(await this.initBox())) return;
    this.resetAdd();
    this.setContinueAdd(true);
    //  this.resetEditForm();
    this.boxModel = true;
    //点击新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
    this.modelOpenProcess();
    // this.modelOpenAfter();
  },
  async edit(rows) {
    this.boxOptions.title = '编辑';
    //编辑
    this.currentAction = this.const.EDIT;
    if (rows) {
      if (!(rows instanceof Array)) {
        rows = [rows];
      }
    } else {
      rows = this.$refs.table.getSelected();
    }
    if (rows.length == 0) {
      return this.$error('请选择要编辑的行!');
    }
    if (rows.length != 1) {
      return this.$error('只能选择一行数据进行编辑!');
    }
    //记录当前编辑的行
    this.currentRow = rows[0];
    //初始化弹出框
    if (!(await this.initBox())) return;
    this.setContinueAdd(false);
    //重置表单
    this.resetDetailTable();
    //设置当前的数据到表单上
    this.setEditForm(rows[0]);
    //设置远程查询表单的默认key/value
    this.getRemoteFormDefaultKeyValue();
    //点击编辑按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
    this.modelOpenProcess(rows[0]);
    // this.modelOpenAfter(rows[0]);
  },
  getRemoteFormDefaultKeyValue() {
    //设置表单远程数据源的默认key.value
    if (this.currentAction != this.const.EDIT || this.remoteKeys.length == 0)
      return;
    this.editFormOptions.forEach((x, xIndex) => {
      x.forEach((item, yIndex) => {
        if (item.remote) {
          let column = this.columns.find((x) => {
            return x.bind && x.bind.key == item.dataKey;
          });
          if (!column) return;
          let key = this.currentRow[item.field];
          let obj = column.bind.data.find((x) => {
            return x.key == key;
          });
          // obj ? obj.value : key如果没有查到数据源,直接使用原数据
          item.data = [{ key: key, value: obj ? obj.value : key }];
          this.editFormOptions[xIndex].splice(yIndex, 1, item);
          // this.$set(item, 'data', [{ key: key + '', value: obj.value }])
          //  item.data = [{ key: key + '', value: obj.value }];
        }
      });
    });
  },
  modelOpenProcess(row) {
    this.$nextTick(() => {
      this.modelOpenAfter(row);
    });
    return;
    // if (!this.$refs.form) {
    //     let timeOut = setTimeout(x => {
    //         this.modelOpenAfter(row);
    //     }, 500)
    //     return;
    // }
    // this.modelOpenAfter(row);
  },
  import() {
    //导入(上传excel),弹出导入组件UploadExcel.vue
    this.upload.excel = true;
    this.$refs.upload_excel && this.$refs.upload_excel.reset();
  },
  download(url, fileName) {
    //下载导出的文件
    let xmlResquest = new XMLHttpRequest();
    xmlResquest.open('GET', url, true);
    xmlResquest.setRequestHeader('Content-type', 'application/json');
    xmlResquest.setRequestHeader(
      'Authorization',
      this.$store.getters.getToken()
    );
    let elink = this.$refs.export;
    xmlResquest.responseType = 'blob';
    xmlResquest.onload = function (oEvent) {
      if (xmlResquest.status != 200) {
        this.$error('下载文件出错了..');
        return;
      }
      let content = xmlResquest.response;
      //  let elink = this.$refs.export;//document.createElement("a");
      elink.download = fileName; //+".xlsx";
      // elink.style.display = "none";
      let blob = new Blob([content]);
      elink.href = URL.createObjectURL(blob);
      //  document.body.appendChild(elink);
      elink.click();
      //  document.body.removeChild(elink);
    };
    xmlResquest.send();
  },
  getFileName(isDetail) {
    //2021.01.08增加导出excel时自定义文件名
    if (isDetail) {
      return this.detail.cnName + '.xlsx';
    }
    return this.table.cnName + '.xlsx';
  },
  export(isDetail) {
    //导出
    let url, query, param;
    if (isDetail) {
      //明细表导出时如果是新建状态,禁止导出
      if (this.currentAction == 'Add') {
        return;
      }
      url = `api/${this.detail.table}/${this.const.EXPORT}`;
      param = {
        wheres: [
          { name: this.table.key, value: this.editFormFields[this.table.key] }
        ]
      };
    } else {
      //主表导出
      url = this.getUrl(this.const.EXPORT);
      query = this.getSearchParameters();
      param = { order: this.pagination.order, wheres: query.wheres || [] };
    }
    //2020.06.25增加导出前处理
    if (!isDetail && !this.exportBefore(param)) {
      return;
    }
    if (param.wheres && typeof param.wheres == 'object') {
      param.wheres = JSON.stringify(param.wheres);
    }
    let $http = this.http;
    //2022.09.26增加自定义导出文件名
    let fileName = this.downloadFileName || this.getFileName(isDetail);
    //2021.01.08优化导出功能
    $http
      .post(url, param, '正在导出数据....', { responseType: 'blob' })
      .then((content) => {
        const blob = new Blob([content]);
        if ('download' in document.createElement('a')) {
          // éžIE下载
          const elink = document.createElement('a');
          elink.download = fileName;
          elink.style.display = 'none';
          elink.href = URL.createObjectURL(blob);
          document.body.appendChild(elink);
          elink.click();
          URL.revokeObjectURL(elink.href);
          document.body.removeChild(elink);
        } else {
          // IE10+下载
          navigator.msSaveBlob(blob, fileName);
        }
      });
    //.then(result => {
    // if (!result.status) {
    //   return this.$error(result.message);
    // }
    // let path = this.getUrl(this.const.DOWNLOAD);
    // path = path[0] == "/" ? path.substring(1) : path;
    // this.download(
    //   $http.ipAddress + path + "?path=" + result.data,
    //   this.table.cnName + ".xlsx" // filePath
    // );
    ///  window.open($http.ipAddress + path + "?fileName=" + filePath, "_self");
    // });
  },
  getSelectRows() {
    //获取选中的行
    return this.$refs.table.getSelected();
  },
  getDetailSelectRows() {
    //或获取明细选中的行
    if (!this.$refs.detail) {
      return [];
    }
    return this.$refs.detail.getSelected();
  },
  audit() {
    //审核弹出框
    let rows = this.$refs.table.getSelected();
    if (rows.length == 0) return this.$error('请选择要审核的行!');
    let auditStatus = Object.keys(rows[0]).find(x => { return x.toLowerCase() === 'auditstatus' });
    if (!auditStatus) {
      return this.$message.error(`表必须包括审核字段【AuditStatus】,并且是int类型`)
    }
    // let checkStatus = rows.every((x) => {
    //   return this.$global.audit.status.some(c => { return c === x[auditStatus] || !x[auditStatus] })
    // });
    // if (!checkStatus) return this.$error('只能选择待审批或审核中的数据!');
    this.$refs.audit.open(rows);
  },
  saveAudit(params, rows, callback) {
    //保存审核
    let keys = rows.map(x => { return x[this.table.key] });
    if (!this.auditBefore(keys, rows)) {
      return;
    }
    let url = `${this.getUrl(this.const.AUDIT)}?auditReason=${params.reason}&auditStatus=${params.value}`
    this.http.post(url, keys, '审核中....').then((x) => {
      if (!this.auditAfter(x, keys)) {
        return;
      }
      if (!x.status) return this.$error(x.message);
      callback && callback(x);
      this.$success(x.message);
      this.refresh();
    });
  },
  viewModelCancel() {
    //查看表结构
    this.viewModel = false;
  },
  initFormOptions(formOptions, keys, formFields, isEdit) {
    //初始化查询、编辑对象的下拉框数据源、图片上传链接地址
    //let defaultOption = { key: "", value: "请选择" };
    //有上传的字段
    //2020.05.03新增
    //编辑数据源的类型
    formOptions.forEach((item) => {
      item.forEach((d) => {
        if (d.type == 'number') {
          //2022.08.22优化表单类型为number时的默认值
          if (formFields[d.field] === '') {
            formFields[d.field] = undefined;
          }
          this.numberFields.push(d.field);
        }
        if (
          d.type == 'img' ||
          d.type == 'excel' ||
          d.type == 'file' ||
          d.columnType == 'img'
        ) {
          d.url = this.http.ipAddress + 'api' + this.table.url + 'Upload';
          this.uploadfiled.push(d.field);
        }
        if (!d.dataKey) return true;
        //2022.02.20强制开启联级可以选择某个节点
        if (d.type == 'cascader' && !d.hasOwnProperty('changeOnSelect')) {
          //强制开启联级可以选择某个节点
          d.changeOnSelect = true;
        }
        //开启远程搜索
        if (d.remote) {
          this.remoteKeys.push(d.dataKey);
          d.data = []; //{ dicNo: d.dataKey, data: [] };
          return true;
        }
        //2020.05.03增加编辑表单对checkbox的支持
        if (d.type == 'checkbox' && !(formFields[d.field] instanceof Array)) {
          formFields[d.field] = [];
        }
        if (keys.indexOf(d.dataKey) == -1) {
          //2020.05.03增加记录编辑字段的数据源类型
          keys.push(d.dataKey);
          //2020.05.03修复查询表单与编辑表单type类型变成强一致性的问题
          //this.dicKeys.push({ dicNo: d.dataKey, data: [], type: d.type });
          //  2020.11.01增加iview组件Cascader数据源存储
          let _dic = {
            dicNo: d.dataKey,
            data: [],
            fileds: [d.field],
            orginData: []
          };
          if (d.type == 'cascader') {
            _dic.type = 'cascader';
          }
          if (isEdit) {
            _dic['e_type'] = d.type;
          }
          this.dicKeys.push(_dic);
        } else if (d.type == 'cascader') {
          this.dicKeys.forEach((x) => {
            if (x.dicNo == d.dataKey) {
              x.type = 'cascader';
              x.fileds.push(d.field);
            }
          });
        }
        if (d.type != 'cascader') {
          //2020.01.30移除内部表单formOptions数据源配置格式data.data,所有参数改为与组件api格式相同
          Object.assign(
            d,
            this.dicKeys.filter((f) => {
              return f.dicNo == d.dataKey;
            })[0],
            { type: d.type }
          );
        }
      });
    });
  },
  //初始table与明细表的数据源指向dicKeys对象,再去后台加载数据源
  initColumns(scoure, dicKeys, keys) {
    if (!scoure || !(scoure instanceof Array)) return;
    scoure.forEach((item) => {
      if (!item.bind || (item.bind.data && item.bind.data.length > 0))
        return true;
      let key = item.bind.key || item.bind.dicNo;
      if (this.remoteKeys.indexOf(key) != -1) {
        item.bind.remote = true;
        return true;
      }
      if (this.hasKeyField.indexOf(item.field) == -1) {
        this.hasKeyField.push(item.field);
      }
      var dic = dicKeys.filter((x) => {
        return x.dicNo == key;
      });
      if (!dic || dic.length == 0) {
        dicKeys.push({ dicNo: key, data: [] });
        dic = [dicKeys[dicKeys.length - 1]];
        keys.push(key);
      }
      //2020.11.01增加级联处理
      if (dic[0].type == 'cascader' || dic[0].type == 'treeSelect') {
        item.bind = { data: dic[0].orginData, type: 'select', key: key };
      } else {
        item.bind = dic[0];
      }
      //2020.05.03优化table数据源checkbox与select类型从编辑列中选取
      item.bind.type = item.bind.e_type || 'string';
    });
  },
  bindOptions(dic) {
    //绑定下拉框的数据源
    //绑定后台的字典数据
    dic.forEach((d) => {
      if (d.data.length >= (this.select2Count || 500)) {
        if (
          !this.dicKeys.some((x) => {
            return (
              x.dicNo == d.dicNo &&
              (x.type == 'cascader' || x.type == 'treeSelect')
            );
          })
        ) {
          d.data.forEach((item) => {
            item.label = item.value;
            item.value = item.key;
          });
        }
      }
      this.dicKeys.forEach((x) => {
        if (x.dicNo != d.dicNo) return true;
        //2020.10.26增加级联数据源绑定处理
        if (x.type == 'cascader' || x.type == 'treeSelect') {
          // x.data=d.data;
          //生成tree结构
          let _data = JSON.parse(JSON.stringify(d.data));
          //2022.04.04增加级联字典数据源刷新后table没有变化的问题
          this.columns.forEach((column) => {
            if (column.bind && column.bind.key == d.dicNo) {
              column.bind.data = d.data;
            }
          });
          let arr = this.base.convertTree(_data, (node, data, isRoot) => {
            if (!node.inited) {
              node.inited = true;
              node.label = node.value;
              node.value = node.key;
            }
          });
          x.data.push(...arr);
          x.orginData.push(...d.data);
          //2021.10.17修复查询级联不能绑定数据源的问题
          this.searchFormOptions.forEach((searhcOption) => {
            searhcOption.forEach((_option) => {
              if (_option.type == 'cascader' && _option.dataKey == x.dicNo) {
                _option.data = arr;
                _option.orginData = d.data;
              }
            });
          });
          //2021.10.17修复级联不能二级刷新的问题
          this.editFormOptions.forEach((editOption) => {
            editOption.forEach((_option) => {
              if (
                (_option.type == 'cascader' || _option.type == 'treeSelect') &&
                _option.dataKey == x.dicNo
              ) {
                _option.data = arr;
                _option.orginData = d.data;
              }
            });
          });
        } else if (d.data.length > 0 && !d.data[0].hasOwnProperty('key')) {
          let source = d.data,
            newSource = new Array(source.length);
          for (let index = 0; index < source.length; index++) {
            newSource[index] = {
              //默认从字典数据读出来的key都是string类型,但如果数据从sql中查询的可能为非string,否是async-validator需要重置设置格式
              key: source['key'] + '', //source[index][x.config.valueField] + "",
              value: source['value'] //source[index][x.config.textField]
            };
          }
          x.data.push(...newSource);
        } else {
          //2020.06.06,如果是selectList数据源使用的自定义sql并且key是数字,强制转换成字符串
          if (
            x.e_type == 'selectList' &&
            d.data.length > 0 &&
            typeof d.data[0].key == 'number'
          ) {
            d.data.forEach((c) => {
              c.key = c.key + '';
            });
          }
          x.data.push(...d.data);
        }
        if (
          this.singleSearch &&
          this.singleSearch.dataKey &&
          this.singleSearch.dataKey == x.dicNo
        ) {
          this.singleSearch.data.splice(0, 1, ...x.data);
        }
      });
    });
  },
  getUrl(action, ingorPrefix) {
    //是否忽略前缀/  èŽ·å–æ“ä½œçš„url
    return (!ingorPrefix ? '/' : '') + 'api' + this.table.url + action;
  },
  initDicKeys() {
    //初始化字典数据
    let keys = [];
    //2022.04.17优化重新加载数据源
    this.dicKeys.forEach((item) => {
      item.data.splice(0);
      item.orginData && item.orginData.splice(0);
    });
    //this.dicKeys.splice(0);
    //初始化编辑数据源,默认为一个空数组,如果要求必填设置type=number/decimal的最小值
    this.initFormOptions(this.editFormOptions, keys, this.editFormFields, true);
    //初始化查询数据源,默认为一个空数组
    this.initFormOptions(
      this.searchFormOptions,
      keys,
      this.searchFormFields,
      false
    );
    //查询日期设置为可选开始与结果日期
    this.searchFormOptions.forEach((item) => {
      item.forEach((x) => {
        if (x.type == 'date' || x.type == 'datetime') x.range = true;
      });
    });
    //初始化datatable表数据源,默认为一个空数组,dicKeys为界面所有的数据字典编号
    this.initColumns(this.columns, this.dicKeys, keys);
    //2021.05.23默认开启查询页面所有字段排序,如果不需要排序,在onInited遍历columns设置sort=false
    //2021.09.25移除强制排序功能
    // this.columns.forEach(x => {
    //   x.sort = x.render ? false : true;
    // })
    if (this.detailOptions && this.detailOptions.columns) {
      this.initColumns(this.detailOptions.columns, this.dicKeys, keys);
    }
    //初始化快速查询字段,默认使用代码生成器配置的第一个查询字段
    if (this.searchFormOptions.length > 0) {
      this.singleSearch = {
        dataKey: this.searchFormOptions[0][0].dataKey,
        dicNo: this.searchFormOptions[0][0].dicNo,
        field: this.searchFormOptions[0][0].field,
        title: this.searchFormOptions[0][0].title,
        type: this.searchFormOptions[0][0].type,
        data: []
      };
      // this.singleSearch = this.searchFormOptions[0][0];
    }
    if (keys.length == 0) return;
    let $this = this;
    this.http.post('/api/Sys_Dictionary/GetVueDictionary', keys).then((dic) => {
      $this.bindOptions(dic);
      //2022.04.04增加字典加载完成方法
      $this.dicInited && $this.dicInited(dic);
    });
  },
  setFiexdColumn(columns, containerWidth) {
    //计算整个table的宽度,根据宽度决定是否启用第一行显示的列为固定列
    //2021.09.21移除强制固定第一列
    // let columnsWidth = 0;
    // columns.forEach(x => {
    //   if (!x.hidden && x.width) {
    //     columnsWidth += x.width;
    //   }
    // });
    // //启用第一列为固定列
    // if (columnsWidth > containerWidth) {
    //   let firstColumn = columns.find(x => !x.hidden);
    //   if (firstColumn) {
    //     firstColumn.fixed = true;
    //   }
    // }
  },
  initBoxHeightWidth() {
    //初始化弹出框的高度与宽度
    let clientHeight = document.documentElement.clientHeight;
    //弹出框高度至少250px
    clientHeight = clientHeight < 250 ? 250 : clientHeight;
    let clientWidth = document.documentElement.clientWidth;
    if (
      this.editFormOptions.some((x) => {
        return x.some((item) => {
          return item.type == 'editor';
        });
      })
    ) {
      this.editor.uploadImgUrl = this.getUrl('upload');
      this.boxOptions.height = clientHeight * 0.8;
      this.boxOptions.width = clientWidth * 0.8;
    } else {
      if (this.boxOptions.height) {
        //如果高度与宽度超过了获取到的可见高宽度,则设为默认的90%高宽
        if (this.boxOptions.height > clientHeight * 0.8) {
          this.boxOptions.height = clientHeight * 0.8;
        }
      }
      if (this.boxOptions.width) {
        //如果高度与宽度超过了获取到的可见高宽度,则设为默认的90%高宽
        if (this.boxOptions.width > clientWidth * 0.8) {
          this.boxOptions.width = clientWidth * 0.8;
        }
      }
    }
    //计算整个table的宽度,根据宽度决定是否启用第一行显示的列为固定列
    let maxTableWidth = clientWidth - 270;
    this.setFiexdColumn(this.columns, maxTableWidth);
    this.height = this.tableHeight || clientHeight - 206;
    this.url = this.getUrl(this.const.PAGE);
    //计算弹出框的高与宽度
    //如果有明细表,高度与宽带设置为0.9/0.82
    if (this.detail.columns && this.detail.columns.length > 0) {
      this.hasDetail = true;
      clientWidth = clientWidth * 0.8;
      clientHeight = clientHeight * 0.85;
      if (!this.detailOptions.height) {
        this.detailOptions.height =
          clientHeight - this.editFormOptions.length * 36 - 234;
        this.detailOptions.height =
          this.detailOptions.height < 240 ? 240 : this.detailOptions.height;
      }
      this.detailOptions.columns = this.detail.columns;
      this.detailOptions.pagination.sortName = this.detail.sortName;
      this.detailOptions.cnName = this.detail.cnName;
      this.detailOptions.key = this.detail.key;
      this.detailOptions.url = this.getUrl('getDetailPage');
      //计算弹出框整个table的宽度,根据宽度决定是否启用第一行显示的列为固定列
      this.setFiexdColumn(this.detail.columns, clientWidth);
    } else {
      let maxColumns = 1; //最大列数,根据列计算弹框的宽度
      this.editFormOptions.forEach((x) => {
        if (x.length > maxColumns) maxColumns = x.length;
      });
      let maxHeightRate = 0.7,
        maxWidthRate = 0.5;
      maxWidthRate = maxColumns / 10 + 0.3;
      maxHeightRate = (this.editFormOptions.length || 1) * 0.1 + 0.03;
      maxHeightRate = maxHeightRate > 0.9 ? 0.9 : maxHeightRate;
      clientWidth = clientWidth * maxWidthRate;
      clientHeight = clientHeight * maxHeightRate;
      // this.boxOptions.width = clientWidth * maxWidthRate;
      // this.boxOptions.height = clientHeight * maxHeightRate;
    }
    if (!this.boxOptions.height) {
      this.boxOptions.height = clientHeight + 10;
    }
    if (!this.boxOptions.width) {
      this.boxOptions.width = clientWidth + 30;
    }
  },
  rowOnChange(row) {
    this.rowChange(row);
  },
  rowChange(row) {
    //选中行checkbox行事件
  },
  rowOnClick({ row, column, event }) {
    this.rowClick({ row, column, event });
  },
  rowClick({ row, column, event }) {
    // ç‚¹å‡»è¡Œäº‹ä»¶(2020.11.07)
  },
  rowOnDbClick({ row, column, event }) {
    this.rowDbClick({ row, column, event });
  },
  rowDbClick({ row, column, event }) {
    // åŒå‡»å‡»è¡Œäº‹ä»¶(2021.05.23)
  },
  $error(message) {
    this.$message.error(message);
    // this.$message({
    //   type: 'error',
    //   content: message,
    //   duration: 5
    // });
  },
  $success(message) {
    this.$message.success(message);
  },
  setFiexdSearchForm(visiable) {
    //2020.09.011增加固定查询表单功能,visiable=true默认将查询表单展开
    this.fiexdSearchForm = true;
    let refreshBtn = this.buttons.find((x) => x.name == '刷 æ–°');
    if (visiable) {
      this.searchBoxShow = true;
    }
    if (refreshBtn) {
      refreshBtn.name = '重 ç½®';
      refreshBtn.onClick = function () {
        this.resetSearch();
      };
    }
  },
  tableBeginEdit(row, column, index) {
    //2021.03.19是否开启查询界面表格双击编辑结束方法,返回false不会结束编辑
    return this.beginEdit(row, column, index);
  },
  beginEdit(row, column, index) {
    //2021.03.19是否开启查询界面表格双击编辑结束方法,返回false不会结束编辑
    return true;
  },
  tableEndEditBefore(row, column, index) {
    return this.endEditBefore(row, column, index);
  },
  endEditBefore(row, column, index) {
    //2021.03.19是否开启查询界面表格双击编辑结束方法,返回false不会结束编辑
    return true;
  },
  filterPermission(tableName, permission) {
    //2021.03.19判断是否有某个表的按钮权限
    //:["Search","Add","Delete","Update","Import","Export","Upload","Audit"]
    const _result = (this.$store.state.permission || []).find((x) => {
      return x.url == '/' + tableName;
    });
    return _result && _result.permission.some((x) => x == permission);
  },
  destroyed() {
    //2021.04.11增加vue页面销毁方法,路由必须设置keepLive:false,设置方法见:前端开发文档-》[禁用页面缓存keepAlive]
  },
  loadTreeTableChildren(tree, treeNode, resolve) {
    this.loadTreeChildren.call(this, tree, treeNode, resolve);
  },
  loadTreeChildren(tree, treeNode, resolve) {
    //树形结构加载子节点(2021.05.02),在onInit中设置了rowKey主键字段后才会生效
    return resolve([]);
  },
  importDetailAfter(data) {
    //2022.01.08增加明细表导入后处理
  },
  importExcelAfter(data) {
    //2022.01.08增加明细表导入后方法判断
    if (!data.status) {
      return; // this.$message.error(data.message);
    }
    //明细表导入
    if (this.boxModel) {
      if (data.data) {
        data.data = JSON.parse(data.data);
      } else {
        data.data = [];
      }
      data.data.forEach((x) => {
        x[this.detail.key] = undefined;
        x[this.table.key] = undefined;
      });
      this.importDetailAfter(data); //增加明细表导入后处理
      this.$refs.detail.rowData.unshift(...data.data);
      this.upload.excel = false;
      return;
    }
    this.importAfter(data);
  },
  onGridModelClose(iconClick) {
    if (this.isBoxAudit) {
      this.initFormOptionType(false);
    }
    this.isBoxAudit = false;
    this.onModelClose(iconClick);
  },
  initAuditColumn() {
  },
  getWorkFlowSteps(row) {
    let table = this.table.url.replaceAll('/', '');
    let url = `api/Sys_WorkFlow/getSteps?tableName=${table}&id=${row[this.table.key]
      }`;
    this.http.get(url, {}, true).then((result) => {
      this.workFlowSteps.splice(0);
      //有可能没有配置审批流程
      if (!result.list || !result.list.length) {
        result.list = [];
        this.auditParam.showAction = true;
        this.auditParam.height = 240;
        this.auditParam.showViewButton = row.AuditStatus == 0;
      } else {
        this.auditParam.showAction = result.list.some((c) => {
          return c.isCurrentUser;
        });
        this.auditParam.height = 511;
        this.auditParam.showViewButton = true;
      }
      this.auditParam.reason = '';
      this.auditParam.status = -1;
      this.auditParam.value = -1;
      if (result.his) {
        result.his.forEach((item) => {
          item.auditStatus = this.getAuditStatus(item.auditStatus);
        });
      }
      this.auditParam.auditHis = result.his;
      this.workFlowSteps.push(...result.list);
      this.isBoxAudit = true;
      this.initFormOptionType(true);
      this.edit(row);
      this.boxOptions.title = '审核';
    });
  },
  initFormOptionType(isReadonly) {
    this.editFormOptions.forEach((options) => {
      options.forEach((option) => {
        if (isReadonly) {
          if (!option.readonly) {
            this.formFieldsType.push(option.field);
            option.readonly = true;
          }
        } else {
          if (this.formFieldsType.indexOf(option.field) != -1) {
            option.readonly = false;
          }
        }
      });
    });
  },
  getAuditStatus(status) {
    let data = this.auditParam.data.find((x) => {
      return x.value == status;
    });
    if (!data) {
      return '-';
      //   return `审核值不正确:${status}`
    }
    return data.text;
  },
  initFlowQuery() {
    if (this.$route.query.viewflow) {
      this.$refs.table && this.search();
    }
  },
  fullscreen(full) { //弹出框全屏方法
  }
};
import customColumns from './ViewGridCustomColumn.js';
//合并扩展方法
methods = Object.assign(methods, detailMethods, serviceFilter, customColumns);
export default methods;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/props.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
let props = {
  columns: {//当前表的配置信息
    type: Array,
    default: () => {
      return [];
    }
  },
  detail: {//从表明细配置
    type: Object,
    default: () => {
      return {
        columns: [],//从表列
        sortName: ""//从表排序字段
      };
    }
  },
  editFormFields: {//新建、编辑字段(key/value)
    type: Object,
    default: () => {
      return {};
    }
  },
  editFormOptions: {//新建、编辑配置信息
    type: Array,
    default: () => {
      return [];
    }
  },
  searchFormFields: {//查询字段(key/value)
    type: Object,
    default: () => {
      return {};
    }
  },
  searchFormOptions: {//查询配置信息(key/value)
    type: Array,
    default: () => {
      return [];
    }
  },
  table: {//表的配置信息:主键、排序等
    type: Object,
    default: () => {
      return {};
    }
  },
  extend: {//表的扩展方法与组件都合并到此属性中
    type: Object,
    default: () => {
      return {};
    }
  }
}
export default props;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/ViewGrid/serviceFilter.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
let serviceFilter = {
  onInit () { //对应created
    console.log('Create执行前')
  },
  onInited () { //对应created,在onInit与onInited中间会初始化界面数据对象
    console.log('Create执行后')
  },
  mounted () {
    console.log('mounted');
  },
  searchBefore (param) { //查询ViewGird表数据前,param查询参数
    // console.log('表' + this.table.cnName + '触发loadTableBefore');
    return true;
  },
  //2020.10.30增加查询后返回所有的查询信息
  searchAfter (param, result) { //查询ViewGird表数据后param查询参数,result回返查询的结果
    // console.log('表' + this.table.cnName + '触发loadTableAfter');
    return true;
  },
  searchDetailBefore (param) {//查询从表表数据前,param查询参数
    //console.log(this.detailOptions.cnName + '触发loadDetailTableBefore');
    return true;
  },
  searchDetailAfter (param, data) {//查询从表后param查询参数,result回返查询的结果
    // console.log(this.detailOptions.cnName + '触发loadDetailTableAfter');
    return true;
  },
  delBefore (ids, rows) { //查询界面的表删除前 ids为删除的id数组,,rows删除的行
    return true;
  },
  delAfter (result) {//查询界面的表删除后
    return true;
  },
  delDetailRow (rows) { //弹出框删除明细表的行数据(只是对table操作,并没有操作后台)
    return true;
  },
  addBefore (formData) { //新建保存前formData为对象,包括明细表
    return true;
  },
  async addBeforeAsync (formData) { //异步处理,功能同上(2020.12.06)
    return true;
  },
  addAfter (result) {//新建保存后result返回的状态及表单对象
    return true;
  },
  updateBefore (formData) { //编辑保存前formData为对象,包括明细表、删除行的Id
    return true;
  },
  async updateBeforeAsync (formData) { //异步处理,功能同上(2020.12.06)
    return true;
  },
  updateAfter (result) {//编辑保存后result返回的状态及表单对象
    return true;
  },
  auditBefore (ids, rows) {//审核前
    return true;
  },
  auditAfter (result, rows) {// å®¡æ ¸åŽ
    return true;
  },
  resetAddFormBefore () { //重置新建表单前的内容
    return true;
  },
  resetAddFormAfter () { //重置新建表单后的内容
    return true;
  },
  resetUpdateFormBefore () { //重置编辑表单前的内容
    return true;
  },
  resetUpdateFormAfter () { //重置编辑表单后的内容
    return true;
  },
  modelOpenBefore (row) { //点击编辑/新建按钮弹出框前,可以在此处写逻辑,如,从后台获取数据
  },
  modelOpenAfter (row) {  //点击编辑/新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
  },
  importAfter (data) { //导入excel后刷新table表格数据
    this.search();
  },
  //2020.10.31添加导入前的方法
  importExcelBefore (formData) { //导入excel导入前
    //往formData写一些其他参数提交到后台,
    // formData.append("val2", "xxx");
    //后台按下面方法获取请求的参数
    // Core.Utilities.HttpContext.Current.Request("val2");
    return true;
  },
  reloadDicSource () { //重新加载字典绑定的数据源
    this.initDicKeys();
  },
  exportBefore (param) { //2020.06.25增加导出前处理
    return true;
  },
  onModelClose(iconClick){
    //iconClick=true为点击左中上角X触发的关闭事件
    //如果返回 false不会关闭弹出框
    //return false;
    this.boxModel=false;
  },
  selectable(row, index){
    //表CheckBox æ˜¯å¦å¯ä»¥å‹¾é€‰
       return true;
  }
}
export default serviceFilter;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolBox.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,200 @@
<template>
  <div class="vol-dialog">
    <el-dialog v-model="vmodel" :close-on-click-modal="false" :close-on-press-escape="false" :width="width"
      :fullscreen="fullscreen" :draggable="draggable" :modal="modal" :before-close="handleClose">
      <template #header>
        <i :class="icon"></i> {{ title }}
        <button class="el-dialog__headerbtn" type="button" style="right: 35px; color: var(--el-color-info)" @click="handleFullScreen">
          <i class="el-icon el-icon-full-screen"></i>
        </button>
      </template>
      <el-scrollbar :max-height="contentHeight">
        <div v-if="inited" style="min-height: 50px;" class="srcoll-content" :style="{ padding: padding + 'px' }">
          <slot name="content"></slot>
          <slot></slot>
        </div>
      </el-scrollbar>
      <template #footer>
        <div class="dia-footer" v-if="footer">
          <slot name="footer"></slot>
          <el-button type="primary" v-if="!footer" size="mini" @click="handleClose()"><i
              class="el-icon-close"></i>关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import { defineComponent, ref, watch, watchEffect } from 'vue';
export default defineComponent({
  props: {
    modelValue: false,
    lazy: {
      //是否开启懒加载2020.12.06
      type: Boolean,
      default: false,
    },
    icon: {
      type: String,
      default: "el-icon-warning-outline",
    },
    title: {
      type: String,
      default: "基本信息",
    },
    height: {
      type: Number,
      default: 200,
    },
    width: {
      type: Number,
      default: 650,
    },
    padding: {
      type: Number,
      default: 16,
    },
    modal: {
      //是否需要遮罩层
      type: Boolean,
      default: true,
    },
    draggable: {
      //启用可拖拽功能
      type: Boolean,
      default: false,
    },
    mask: {
      type: Boolean,
      default: true,
    },
    onModelClose: {
      //2021.07.11增加弹出框关闭事件
      type: Function,
      default: (iconClick) => {
        return true;
      }
    },
    footer:{ //是否显示底部按钮
      type: Boolean,
      default: true
    }
  },
  setup(props, context) {
    const clientHeight = document.body.clientHeight * 0.95 - 60;
    const inited = ref(true);
    const vmodel = ref(false);
    const footer = ref(false);
    const top = ref(100);
    vmodel.value = props.modelValue;
    footer.value = !!context.slots.footer;
    const contentHeight = ref(200);
    contentHeight.value = props.height;
    const handleClose = (done, iconClose) => {
      let result = props.onModelClose(!!iconClose);
      if (result === false) return;
      vmodel.value = false;
      context.emit("update:modelValue", false);
      done && done();
    };
    const calcHeight = (val) => {
    //  if (props.height > clientHeight) {
    //  if(true){
        contentHeight.value = clientHeight - 30;
        return clientHeight / -2 + 'px';
    //  }
      // contentHeight.value = val || props.height;
      // return (props.height + 56) / -2 + 'px';
    };
    top.value = calcHeight();
    watch(
      () => props.modelValue,
      (newVal, oldVal) => {
        vmodel.value = newVal;
      }
    );
    watch(
      () => props.height,
      (newVal, oldVal) => {
        top.value = calcHeight();
      }
    );
    const fullscreen=ref(false);
    const handleFullScreen=()=> {
      fullscreen.value = !fullscreen.value;
      context.emit("fullscreen", fullscreen.value);
    }
    return {
      handleClose,
      inited,
      vmodel,
      footer,
      top,
      calcHeight,
      contentHeight,
      fullscreen,
      handleFullScreen
    };
  }
});
</script>
<style lang="less" scoped>
.dia-footer {
  text-align: right;
  width: 100%;
  border-top: 1px solid #e2e2e2;
  text-align: right;
  padding: 6px 8px;
}
</style>
<style scoped lang="less">
.vol-dialog ::v-deep(.el-overlay-dialog) {
  display: flex !important;
}
.vol-dialog ::v-deep(.el-dialog) {
  margin: auto;
}
.vol-dialog ::v-deep(.el-dialog) {
  border-top-left-radius: 4px;
  border-top-right-radius: 4px;
}
.vol-dialog ::v-deep(.el-dialog__header) {
  border-top-left-radius: 4px;
  border-top-right-radius: 4px;
  padding: 0px 13px;
  line-height: 53px;
  border-bottom: 1px solid #e6e6e6;
  height: 50px;
  color: rgb(79, 79, 79);
  font-weight: bold;
  font-size: 14px;
  margin: 0;
  // background-image: linear-gradient(135deg, #0cd7bd 10%, #50c3f7);
}
.vol-dialog ::v-deep(.el-dialog__footer),
.vol-dialog ::v-deep(.el-dialog__body) {
  padding: 0;
}
.vol-dialog ::v-deep(.el-dialog__headerbtn) {
  top: 0;
  padding-top: 8px;
  height: 50px;
  width: 0;
  padding-right: 30px;
  padding-left: 5px;
}
// .vol-dialog ::v-deep(.el-dialog__headerbtn .el-dialog__close) {
//   color: #fff;
// }
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolElementMenu.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,198 @@
<template>
  <div class="vol-el-menu">
    <el-menu
      close="vol-el-menu--vertical"
      :default-openeds="openedIds"
      :default-active="defaultActive"
      :unique-opened="true"
      @select="select"
      :collapse="isCollapse"
      @open="handleOpen"
      @close="handleClose"
      @contextmenu.prevent="bindRightClickMenu"
    >
      <template v-for="item in convertTree(list)">
        <el-sub-menu
          :key="item.id"
          :index="'' + item.id"
          v-if="item.children.length && (!enable || item.enable == 1)"
        >
          <template #title>
            <i class="menu-icon" :class="item.icon"></i>
            <span> {{ item.name }}</span>
          </template>
          <vol-element-menu-child
            :enable="enable"
            :list="item.children"
          ></vol-element-menu-child>
        </el-sub-menu>
        <template v-else>
          <el-menu-item
            class="menu-item-lv1"
            v-if="!enable || item.enable == 1"
            :key="item.id"
            :index="'' + item.id"
          >
            <i :class="item.icon"></i>
            <span> {{ item.name }}</span>
          </el-menu-item>
        </template>
      </template>
    </el-menu>
  </div>
</template>
<script>
import VolElementMenuChild from './VolElementMenuChild';
import { useRouter } from 'vue-router';
import {
  defineComponent,
  reactive,
  watch,
  ref,
  toRef,
  toRefs,
  getCurrentInstance
  // onMounted,
} from 'vue';
export default defineComponent({
  components: {
    'vol-element-menu-child': VolElementMenuChild
  },
  props: {
    enable: {
      type: Boolean,
      default: false //是否判断enable=1
    },
    isCollapse: {
      type: Boolean,
      default: false
    },
    onSelect: {
      type: Function,
      default: (x) => {}
    },
    openSelect: {
      //打开的时候是否触发选中事件
      type: Boolean,
      default: true
    },
    list: {
      type: Array,
      default: []
    },
    rootId: {
      type: String,
      default: '0'
    },
    currentMenuId: {
      type: Number,
      default: 0
    }
  },
  setup(props) {
    // const { list } = toRefs(props);
    //  const treeList = ref([]);
    const getTree = (id, node, data) => {
      if (!node.children) {
        node.children = [];
      }
      data.forEach((x) => {
        if (x.parentId == id && !node.children.some((c) => c.id === x.id)) {
          node.children.push(x);
          getTree(x.id, x, data);
        }
      });
    };
    let rootTreeId = !isNaN(props.rootId) ? ~~props.rootId : props.rootId;
    props.list.forEach((x) => {
      if (!x.icon || x.icon.substring(0, 3) != 'el-') {
        x.icon = 'el-icon-menu';
      }
      x.children = [];
      x.isRoot = x.parentId === rootTreeId;
    });
    const convertTree = (data) => {
      var root_data = [];
      data.forEach((x) => {
        if (x.parentId === rootTreeId) {
          if (!x.hasOwnProperty('enable')) x.enable = 1;
          root_data.push(x);
          getTree(x.id, x, data);
        }
      });
      return root_data;
    };
    const openedIds = reactive([props.currentMenuId]);
    const defaultActive = ref(props.currentMenuId + '');
    let _base = getCurrentInstance().appContext.config.globalProperties.base;
    watch(
      () => props.currentMenuId,
      (newVal, oldVal) => {
        defaultActive.value = newVal + '';
        openedIds.splice(0);
        openedIds.push(
          ..._base.getTreeAllParent(newVal, props.list).map((c) => {
            return c.id;
          })
        );
      }
    );
    const router = useRouter();
    let eventSelect = false;
    const select = (index, path) => {
      if (eventSelect) {
        return;
      }
      eventSelect = true;
      setTimeout(() => {
        eventSelect = false;
      }, 20);
      let _item = props.list.find((x) => {
        return x.id == index;
      });
      props.onSelect(index, _item);
      router.push({ path: _item.path || '' });
    };
    const handleOpen = (index, path) => {
      if (props.openSelect) {
        select(index, path);
      }
    };
    const handleClose = () => {};
    /**
     * èœå•导航右键事件
     * @param {*} enable æ˜¯å¦å¯ç”¨å³é”®äº‹ä»¶[true:启用;false:禁用;]
     */
    const bindRightClickMenu = (enable) => {
      if (!enable) return;
    };
    return {
      // treeList,
      // list,
      select,
      convertTree,
      handleOpen,
      handleClose,
      bindRightClickMenu,
      openedIds,
      defaultActive
    };
  }
});
</script>
<style lang="less" scoped>
.vol-el-menu {
  box-sizing: content-box;
  width: 100%;
  .menu-icon {
    font-size: 18px;
    margin-right: 6px;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolElementMenuChild.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
<template>
  <div class="vol-el-menu-item">
    <template v-for="(item) in list">
      <template v-if="item.children&&item.children.length">
        <el-menu-item :key="item.id"
                      :index="'' + item.id"
                      v-if="!item.children.length && (!enable || item.enable == 1)">
          <template #title></template>
          <span> {{ item.name }}</span>
        </el-menu-item>
        <el-sub-menu :key="item.id"
                    :index="'' + item.id"
                    v-if="item.children.length && (!enable || item.enable == 1)">
          <template #title>
            <span> {{ item.name }}</span>
          </template>
          <vol-element-menu-child :enable="enable" :list="item.children" />
        </el-sub-menu>
      </template>
      <template v-else>
        <el-menu-item :key="item.id"
                      :index="'' + item.id"
                      v-if="(!enable || item.enable == 1)">
          <template #title></template>
          <span> {{item.name }}</span>
        </el-menu-item>
      </template>
    </template>
  </div>
</template>
<script>
export default {
  name: "vol-element-menu-child",
  props: {
    list: {
      type: Array,
      default: [],
    },
    enable: {
      type: Boolean,
      default: false, //是否判断enable=1
    },
  },
};
</script>
<style scoped lang="less">
.vol-el-menu-item ::v-deep(.el-menu-item) {
  height: 42px !important;
  line-height: 42px !important;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolForm.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1487 @@
<template>
  <el-form
    style="display: inline-block; width: 100%"
    :inline="true"
    ref="volform"
    @submit.prevent
    :model="formFields"
    :label-width="labelWidth"
    :rules="rules"
  >
    <template v-for="(row, findex) in formRules" :key="findex">
      <div class="vol-form-item">
        <el-form-item
          :label="item.title ? item.title + ':' : ''"
          v-show="!item.hidden"
          v-for="(item, index) in row"
          :prop="item.field"
          :key="item.field + index"
          :style="{ width: getColWidth(item) + '%' }"
        >
          <!-- render -->
          <form-expand
            v-if="item.render && typeof item.render == 'function'"
            :render="item.render"
            :par="12"
          ></form-expand>
          <!-- 2021.10.17增加表单实时方法计算 -->
          <span
            v-else-if="
              item.readonly && typeof formFields[item.field] == 'function'
            "
            >{{ formFields[item.field]() }}</span
          >
          <!-- åªè¯»å›¾ç‰‡æˆ–文件  -->
          <div v-else-if="isReadonlyImgFile(item, formFields)">
            <div v-if="item.type == 'img'" class="form-imgs">
              <div
                class="img-item"
                v-for="(img, imgIndex) in formFields[item.field]"
                :key="imgIndex"
              >
                <img
                  :src="getSrc(img.path)"
                  :onerror="errorImg"
                  @click="previewImg(img.path)"
                />
              </div>
            </div>
            <div
              v-else
              class="form-file-list"
              v-for="(file, fileIndex) in formFields[item.field]"
              :key="fileIndex"
            >
              <a @click="dowloadFile(formFields[item.field][fileIndex])">{{
                file.name
              }}</a>
            </div>
          </div>
          <div v-else :class="{ 'form-item-extra': item.extra }">
            <!-- åªè¯»å±žæ€§ -->
            <label
              :style="item.inputStyle"
              v-if="item.type == 'label'"
              class="readonly-input"
              >{{ getText(formFields, item) }}</label
            >
            <!-- 20223.05.13集成el-tree-select -->
            <!-- :filter-method="(value)=>{filterMethod(value,item.data)}" -->
            <!-- :filterable="true" -->
            <el-tree-select
              style="width: 100%"
              v-else-if="item.type == 'treeSelect'"
              v-model="formFields[item.field]"
              :data="item.data"
              :multiple="item.multiple"
              :render-after-expand="false"
              :show-checkbox="false"
              :check-strictly="true"
              check-on-click-node
              node-key="key"
              :props="{ label: 'label' }"
            >
              <template #default="{data,node }">
                <!-- <el-checkbox v-model="node.checked"></el-checkbox> -->
               <!-- {{getNode(node, data)}} -->
               <!-- {{node.checked}} -->
               <!-- è¿™é‡Œè¿˜æœ‰ç‚¹é—®é¢˜ï¼ŒåŽé¢å¤„理 -->
                {{  data.label}}</template
              >
            </el-tree-select>
            <template
              v-else-if="['select', 'selectList'].indexOf(item.type) != -1"
            >
              <el-select-v2
                :disabled="item.readonly || item.disabled"
                v-show="!item.hidden"
                style="width: 100%"
                :size="size"
                v-if="item.data.length > select2Count"
                v-model="formFields[item.field]"
                filterable
                :multiple="item.type == 'select' ? false : true"
                :placeholder="item.placeholder ? item.placeholder : item.title"
                :allow-create="item.autocomplete"
                :options="item.data"
                @change="
                  (val) => {
                    item.onChange(val, item.data);
                  }
                "
                clearable
              >
                <template #default="{ item }">
                  {{ item.label }}
                </template>
              </el-select-v2>
              <el-select
                :disabled="item.readonly || item.disabled"
                v-show="!item.hidden"
                style="width: 100%"
                :size="size"
                v-else-if="item.remote || item.url"
                v-model="formFields[item.field]"
                filterable
                :multiple="item.type == 'select' ? false : true"
                :placeholder="item.placeholder ? item.placeholder : item.title"
                clearable
                :remote-method="
                  (val) => {
                    remoteSearch(item, formFields, val);
                  }
                "
              >
                <el-option
                  v-for="item in item.data"
                  :key="item.key"
                  :label="item.value"
                  :value="item.key"
                >
                </el-option>
              </el-select>
              <el-select
                :disabled="item.readonly || item.disabled"
                v-show="!item.hidden"
                style="width: 100%"
                :size="size"
                v-else
                v-model="formFields[item.field]"
                filterable
                :multiple="item.type == 'select' ? false : true"
                :placeholder="item.placeholder ? item.placeholder : item.title"
                :allow-create="item.autocomplete"
                @change="
                  (val) => {
                    item.onChange(val, item.data);
                  }
                "
                clearable
              >
                <el-option
                  v-show="!item.hidden"
                  :disabled="item.disabled"
                  v-for="item in item.data"
                  :key="item.key"
                  :label="item.value"
                  :value="item.key"
                >
                </el-option>
              </el-select>
            </template>
            <el-switch
              v-show="!item.hidden"
              v-else-if="item.type == 'switch'"
              v-model="formFields[item.field]"
              :disabled="item.readonly || item.disabled"
              active-color="#0f84ff"
              @change="item.onChange"
              inactive-color="rgb(194 194 194)"
              :active-value="
                typeof formFields[item.field] == 'boolean'
                  ? true
                  : typeof formFields[item.field] == 'string'
                  ? '1'
                  : 1
              "
              :inactive-value="
                typeof formFields[item.field] == 'boolean'
                  ? false
                  : typeof formFields[item.field] == 'string'
                  ? '0'
                  : 0
              "
            >
            </el-switch>
            <el-radio-group
              :disabled="item.readonly || item.disabled"
              v-show="!item.hidden"
              v-model="formFields[item.field]"
              v-else-if="item.type == 'radio'"
              @change="item.onChange"
            >
              <el-radio
                v-for="kv in item.data"
                :disabled="item.readonly || item.disabled"
                :key="kv.key"
                :label="kv.key"
                >{{ kv.value }}</el-radio
              >
            </el-radio-group>
            <el-checkbox-group
              :disabled="item.readonly || item.disabled"
              v-show="!item.hidden"
              v-model="formFields[item.field]"
              v-else-if="item.type == 'checkbox'"
              @change="item.onChange"
            >
              <el-checkbox
                v-for="kv in item.data"
                :key="kv.key"
                :disabled="item.readonly || item.disabled"
                :label="kv.key"
                >{{ kv.value }}</el-checkbox
              >
            </el-checkbox-group>
            <div
              class="v-date-range"
              style="display: flex"
              v-else-if="
                ['date', 'datetime'].indexOf(item.type) != -1 && item.range
              "
            >
              <el-date-picker
                :size="size"
                :disabled="item.readonly || item.disabled"
                style="flex: 1; width: auto"
                v-model="formFields[item.field][0]"
                :type="item.type == 'date' ? 'date' : 'datetime'"
                :disabledDate="(val) => getDateOptions(val, item)"
                placeholder="开始时间"
                @change="
                  (val) => {
                    dateRangeChange(val, item);
                  }
                "
                :value-format="getDateFormat(item)"
              >
              </el-date-picker>
              <span style="margin: 0px 5px; font-size: 13px; color: #6f6b6b"
                >至</span
              >
              <el-date-picker
                :size="size"
                :disabled="item.readonly || item.disabled"
                style="flex: 1; width: auto"
                v-model="formFields[item.field][1]"
                placeholder="结束时间"
                :type="item.type == 'date' ? 'date' : 'datetime'"
                :disabledDate="(val) => getDateOptions(val, item)"
                @change="
                  (val) => {
                    dateRangeChange(val, item);
                  }
                "
                :value-format="getDateFormat(item)"
              >
              </el-date-picker>
            </div>
            <!-- v-show不添加根节点就会报错没有根点节 -->
            <div
              v-show="!item.hidden"
              style="width: 100%"
              v-else-if="['date', 'datetime', 'month'].indexOf(item.type) != -1"
            >
              <el-date-picker
                :size="size"
                clearable
                :disabled="item.readonly || item.disabled"
                style="width: 100%"
                v-model="formFields[item.field]"
                @change="item.onChange"
                :type="item.type"
                :placeholder="
                  item.placeholder ? item.placeholder : '请选择' + item.title
                "
                :disabledDate="(val) => getDateOptions(val, item)"
                :value-format="getDateFormat(item)"
              >
              </el-date-picker>
            </div>
            <el-time-picker
              :size="size"
              v-else-if="item.type == 'time'"
              v-model="formFields[item.field]"
              :disabled="item.readonly || item.disabled"
              placeholder="请选择时间"
              :value-format="item.format || 'HH:mm:ss'"
              :format="item.format"
              style="width: 100%"
            >
            </el-time-picker>
            <el-scrollbar
              style="border: 1px solid #c7d8db; border-radius: 5px"
              :height="item.height || 150"
              v-else-if="
                item.type == 'editor' && (item.readonly || item.disabled)
              "
            >
              <div ref="editor" v-html="formFields[item.field]"></div>
            </el-scrollbar>
            <vol-wang-editor
              ref="editor"
              v-else-if="item.type == 'editor'"
              :url="item.url || editor.uploadImgUrl"
              :upload="item.upload || editor.upload"
              v-model="formFields[item.field]"
              :height="item.height || 350"
            ></vol-wang-editor>
            <vol-upload
              v-show="!item.hidden"
              v-else-if="isFile(item, formFields)"
              :desc="item.desc"
              :multiple="item.multiple"
              :max-file="item.maxFile"
              :max-size="item.maxSize"
              :autoUpload="item.autoUpload"
              :fileInfo="formFields[item.field]"
              :url="item.url"
              :img="item.type == 'img' || item.columnType == 'img'"
              :excel="item.type == 'excel'"
              :fileTypes="item.fileTypes ? item.fileTypes : []"
              :upload-before="item.uploadBefore"
              :upload-after="item.uploadAfter"
              :append="item.multiple"
              :on-change="
                (files) => {
                  return fileOnChange(files, item);
                }
              "
              :file-click="item.fileClick"
              :remove-before="item.removeBefore"
              :downLoad="item.downLoad ? true : false"
            ></vol-upload>
            <el-cascader
              :size="size"
              clearable
              style="width: 100%; margin-top: -3px"
              v-model="formFields[item.field]"
              :disabled="item.readonly || item.disabled"
              v-else-if="item.type == 'cascader'"
              :options="item.data"
              :props="{
                checkStrictly: item.changeOnSelect || item.checkStrictly
              }"
              @change="item.onChange"
            >
            </el-cascader>
            <el-rate
              v-else-if="item.type == 'rate'"
              @change="
                (val) => {
                  item.onChange && item.onChange(val);
                }
              "
              :max="item.max"
              v-model="formFields[item.field]"
            />
            <div
              style="display: flex"
              v-else-if="item.type == 'range' || item.range"
            >
              <el-input
                :size="size"
                :disabled="item.readonly || item.disabled"
                style="flex: 1"
                v-model="formFields[item.field][0]"
                clearable
              />
              <span style="margin: 0 5px">-</span>
              <el-input
                :size="size"
                :disabled="item.readonly || item.disabled"
                style="flex: 1"
                v-model="formFields[item.field][1]"
                clearable
              />
            </div>
            <el-input
              :size="size"
              clearable
              :ref="item.field"
              :input-style="item.inputStyle"
              :disabled="item.readonly || item.disabled"
              v-else-if="item.type == 'textarea'"
              v-model="formFields[item.field]"
              type="textarea"
              :autosize="{
                minRows: item.minRows || 2,
                maxRows: item.maxRows || 10
              }"
              :placeholder="item.placeholder ? item.placeholder : item.title"
            />
            <el-input-number
              :size="size"
              style="width: 100%"
              :ref="item.field"
              :input-style="item.inputStyle"
              v-else-if="item.type == 'number'"
              v-model="formFields[item.field]"
              :min="item.min"
              :disabled="item.readonly || item.disabled"
              :max="item.max"
              controls-position="right"
            />
            <el-input
              :size="size"
              clearable
              :input-style="item.inputStyle"
              v-else-if="item.type == 'password'"
              type="password"
              v-model="formFields[item.field]"
              :disabled="item.readonly || item.disabled"
              v-show="!item.hidden"
              :placeholder="item.placeholder ? item.placeholder : item.title"
            />
            <!-- 2021.11.18修复el-input没有默认enter事件时回车异常 -->
            <el-input
              :size="size"
              clearable
              :ref="item.field"
              :input-style="item.inputStyle"
              v-else-if="item.onKeyPress"
              :placeholder="item.placeholder ? item.placeholder : item.title"
              :disabled="item.readonly || item.disabled"
              v-show="!item.hidden"
              v-model="formFields[item.field]"
              @keypress="
                ($event) => {
                  onKeyPress($event, item);
                }
              "
              @change="item.onKeyPress"
              @keyup.enter="item.onKeyPress"
            ></el-input>
            <el-input
              :size="size"
              clearable
              v-else
              :ref="item.field"
              :input-style="item.inputStyle"
              :placeholder="item.placeholder ? item.placeholder : item.title"
              :disabled="item.readonly || item.disabled"
              v-show="!item.hidden"
              v-model="formFields[item.field]"
            ></el-input>
            <div class="form-extra" v-if="item.extra">
              <form-expand
                v-if="item.extra.render"
                :render="item.extra.render"
              ></form-expand>
              <a
                v-else-if="item.extra.click"
                :style="item.extra.style"
                @click="item.extra.click(item, formFields[item.field])"
              >
                <i v-if="item.extra.icon" :class="item.extra.icon" />
                {{ item.extra.text }}
              </a>
              <a v-else :style="item.extra.style">
                <i v-if="item.extra.icon" :class="item.extra.icon" />
                {{ item.extra.text }}
              </a>
            </div>
          </div>
        </el-form-item>
      </div>
    </template>
    <slot></slot>
    <div style="width: 100%">
      <slot name="footer"></slot>
    </div>
  </el-form>
</template>
<script>
const rule = {
  change: [
    'checkbox',
    'select',
    'date',
    'datetime',
    'drop',
    'radio',
    'cascader'
  ], // 2020.05.31增加级联类型
  phone: /^[1][3,4,5,6,7,8,9][0-9]{9}$/,
  decimal: /(^[\-0-9][0-9]*(.[0-9]+)?)$/,
  number: /(^[\-0-9][0-9]*([0-9]+)?)$/
};
const inputTypeArr = ['text', 'string', 'mail', 'textarea', 'password'];
const types = {
  int: 'number',
  byte: 'number',
  decimal: 'number', // "float",
  string: 'string',
  bool: 'boolean',
  date: 'datetime',
  date: 'date',
  mail: 'email'
};
//表单验证注意:每次验证都必须执行callback,否则验证不执行回调方法
const colPow = Math.pow(10, 3);
import FormExpand from './VolForm/VolFormRender';
import {
  defineAsyncComponent,
  defineComponent,
  ref,
  reactive,
  toRefs,
  getCurrentInstance,
  onMounted,
  watch
} from 'vue';
export default defineComponent({
  components: {
    FormExpand,
    'vol-upload': defineAsyncComponent(() =>
      import('@/components/basic/VolUpload.vue')
    ),
    // 'vol-wang-editor': defineAsyncComponent(() =>
    //   import('@/components/editor/VolWangEditor.vue')
    // )
  },
  props: {
    loadKey: {
      // æ˜¯å¦åŠ è½½formRules字段配置的数据源
      type: Boolean,
      default: true
    },
    width: {
      // è¡¨å•宽度
      type: Number,
      default: 0
    },
    labelWidth: {
      // è¡¨å•左边label文字标签的宽度
      type: Number,
      default: 100
    },
    formRules: {
      // è¡¨å•配置规则,如字段类型,是否必填
      type: Array,
      default: []
    },
    formFields: {
      type: Object,
      default: () => {
        return {};
      }
    },
    editor: {
      // 2021.01.16编辑器信息 {uploadImgUrl:"",upload:null//上传方法}
      type: Object,
      default: () => {
        return {};
      }
    },
    size: {
      type: String, //large / default / small
      default: 'large'
    },
    select2Count: {
      //超出数量显示select2组件
      type: Number,
      default: 500
    }
  },
  computed: {
    rules() {
      let ruleResult = {};
      this.formRules.forEach((option, xIndex) => {
        option.forEach((item) => {
          ruleResult[item.field] = [this.getRule(item, this.formFields)];
        });
      });
      if (this.$refs.volform) {
        setTimeout(() => {
          this.$refs.volform.clearValidate();
        }, 100);
      }
      return ruleResult;
    }
  },
  setup(props, context) {
    const { appContext, proxy } = getCurrentInstance();
    const remoteCall = ref(true);
    const span = ref(1);
    const rangeFields = toRefs([]);
    const volform = ref(null);
    const numberFields = toRefs([]);
    onMounted(() => {});
    const initFormRules = (init) => {
      if (props.loadKey) {
        initSource();
      }
      props.formRules.forEach((row, xIndex) => {
        if (row.length > span.value) span.value = row.length;
        let _count = 0,
          _size = 0;
        row.forEach((x) => {
          if (x.colSize > 0) {
            _size = _size + x.colSize;
            _count++;
          }
        });
        if (_count > 0 && row.length - _count > 0) {
          let _cellSize = (12 - _size) / (row.length - _count);
          row.forEach((x) => {
            if (!x.colSize) {
              x.colSize = _cellSize;
            }
          });
        }
        row.forEach((item, yIndex) => {
          if (item.type == 'number') {
            numberFields.push(item.field);
          }
          // ç›®å‰åªæ”¯æŒselect单选远程搜索,remote远程从后台字典数据源进行搜索,url从指定的url搜索
          if (item.remote || item.url) {
            // item.remoteData = [];
            item.loading = false;
            item.point = { x: xIndex, y: yIndex };
          }
          // åˆå§‹åŒ–上传文件信息
          initUpload(item, init);
          // åˆå§‹åŒ–数据源空对象
          if (item.dataKey) {
            // ä¸‹æ‹‰æ¡†éƒ½å¼ºåˆ¶è®¾ç½®ä¸ºå­—符串类型
            item.columnType = 'string';
            if (!item.data) {
              item.data = [];
            }
          }
          if (item.range || item.type == 'range') {
            if (
              !(props.formFields[item.field] instanceof Array) ||
              props.formFields[item.field].length != 2
            ) {
              props.formFields[item.field] = ['', ''];
            }
            rangeFields.push(item.field);
          }
        });
      });
    };
    const initSource = () => {
      let keys = [],
        binds = [];
      // åˆå§‹åŒ–字典数据源
      props.formRules.forEach((item) => {
        item.forEach((x) => {
          if (x.dataKey && (!x.data || x.data.length == 0) && !x.remote) {
            x.data = [];
            binds.push({ key: x.dataKey, data: x.data, type: x.type });
            if (keys.indexOf(x.dataKey) == -1) {
              keys.push(x.dataKey);
            }
          }
        });
      });
      if (keys.length == 0) return;
      appContext.config.globalProperties.http
        .post('/api/Sys_Dictionary/GetVueDictionary', keys)
        .then((dic) => {
          bindOptions(dic, binds);
          proxy.$emit('dicInited', dic);
        });
    };
    const bindOptions = (dic, binds) => {
      dic.forEach((d) => {
        if (d.data.length > props.select2Count) {
          if (
            !binds.some((x) => {
              return x.key == d.dicNo && x.type == 'cascader';
            })
          ) {
            d.data.forEach((item) => {
              item.label = item.value;
              item.value = item.key;
            });
          }
        }
        binds.forEach((x) => {
          if (x.key != d.dicNo) return true;
          // å¦‚果有数据的则不查询
          if (x.data.length > 0) return true;
          //2022.03.13增加级联数据源自动转换
          if (x.type == 'cascader' || x.type == 'treeSelect') {
            let _data = JSON.parse(JSON.stringify(d.data));
            let cascaderArr = appContext.config.globalProperties.base.convertTree(
              _data,
              (node, data, isRoot) => {
                if (!node.inited) {
                  node.inited = true;
                  node.label = node.value;
                  node.value = node.key;
                }
              }
            );
            props.formRules.forEach((option) => {
              option.forEach((item) => {
                if (item.dataKey == x.key) {
                  item.orginData = x.data;
                  item.data = cascaderArr;
                }
              });
            });
          } else if (d.data.length > 0 && !d.data[0].hasOwnProperty('key')) {
            let source = d.data,
              newSource = new Array(source.length);
            for (let index = 0; index < source.length; index++) {
              newSource[index] = {
                key: source['key'] + '',
                value: source['value']
              };
            }
            x.data.push(...newSource);
          } else {
            x.data.push(...d.data);
          }
        });
      });
    };
    const initUpload = (item, init) => {
      if (!init) return;
      if (
        ['img', 'excel', 'file'].indexOf(item.type != -1) ||
        item.columnType == 'img'
      ) {
        // åªæ˜¯æ²¡è®¾ç½®æ˜¯å¦è‡ªåŠ¨ä¸Šä¼ çš„ï¼Œé»˜è®¤éƒ½æ˜¯é€‰æ‹©æ–‡ä»¶åŽè‡ªåŠ¨ä¸Šä¼ 
        if (!item.hasOwnProperty('autoUpload')) {
          item.autoUpload = true;
        }
        if (!item.hasOwnProperty('fileList')) {
          item.fileList = true;
        }
        if (!item.hasOwnProperty('downLoad')) {
          item.downLoad = true;
        }
        if (!item.removeBefore) {
          item.removeBefore = (index, file, files) => {
            return true;
          };
        }
        if (!item.fileClick) {
          item.fileClick = (index, file, files) => {
            return true;
          };
        }
        if (!item.onChange) {
          item.onChange = (files) => {
            return true;
          };
        }
        if (!item.uploadAfter) {
          item.uploadAfter = (result, files) => {
            return true;
          };
        }
        if (!item.uploadBefore) {
          item.uploadBefore = (files) => {
            return true;
          };
        }
      }
    };
    const validate = (callback) => {
      let result = true;
      volform.value.validate((valid) => {
        if (!valid) {
          appContext.config.globalProperties.$message.error('数据验证未通过!');
          result = false;
        } else if (typeof callback === 'function') {
          try {
            callback(valid);
          } catch (error) {
            let msg = `表单验证回调方法异常:${error.message}`;
            appContext.config.globalProperties.$message.error(msg);
            console.log(msg);
          }
        }
      });
      return result;
    };
    initFormRules(true);
    return {
      remoteCall,
      span,
      rangeFields,
      numberFields,
      validate,
      volform
      //  initFormRules,
      // initSource
    };
  },
  created() {
    this.formRules.forEach((rules) => {
      rules.forEach((option) => {
        if (option.type == 'treeSelect' && option.multiple === undefined) {
          option.multiple = true;
        }
      });
    });
  },
  data() {
    return {
      // remoteCall: true,
      errorImg: 'this.src="' + require('@/assets/imgs/error-img.png') + '"'
      // span: 1,
      // rangeFields: [],
    };
  },
  methods: {
    getColWidth(item) {
      //2021.08.30 å¢žåŠ åŠ¨æ€è®¡ç®—è¡¨å•å®½åº¦
      let _span = 0;
      this.formRules.forEach((row, xIndex) => {
        //2022.05.06 è¿½åŠ è¡¨å•ä¸­éšè—çš„å…ƒç´ ä¸å‚ä¸ŽåŠ¨æ€è®¡ç®—è¡¨å•å®½åº¦
        let rowLength = row.filter((item) => {
          return !item.hidden;
        }).length;
        if (rowLength > _span) _span = rowLength;
      });
      let rete =
        Math.round(((item.colSize || 12 / _span) / 0.12) * colPow, 10.0) /
        colPow;
      if (item.colSize) return rete.toFixed(3);
      return rete.toFixed(3);
      // return (100 - rete).toFixed(3);
    },
    previewImg(url) {
      this.base.previewImg(url, this.http.ipAddress);
    },
    getSrc(path) {
      if (!path) return;
      if (!this.base.isUrl(path) && path.indexOf('.') != -1) {
        return this.http.ipAddress + path;
      }
      return path;
    },
    // æ˜¯å¦ä¸ºå›¾ç‰‡æ–‡ä»¶ç­‰æ ¼å¼å¹¶å¯¹å­—段的转换成数组:[{name:'1.jpg',path:'127.0.0.1/ff/1.jpg'}]
    isFile(item, formFields) {
      if (
        item.type == 'img' ||
        item.columnType == 'img' ||
        item.type == 'excel' ||
        item.type == 'file'
      ) {
        this.convertFileToArray(item, formFields);
        return true;
      }
      return false;
    },
    isReadonlyImgFile(item, formFields) {
      if ((item.disabled || item.readonly) && this.isFile(item, formFields)) {
        return true;
      }
      return false;
    },
    convertFileToArray(item, formFields) {
      if (!item.maxFile) {
        item.maxFile = 1; // é»˜è®¤åªèƒ½ä¸Šä¼ ä¸€ä¸ªæ–‡ä»¶ï¼Œå¯ä»¥åœ¨onInit中设置
      }
      let fileInfo = formFields[item.field];
      if (fileInfo instanceof Array) {
        return;
      }
      if (fileInfo === null || fileInfo === undefined) {
        formFields[item.field] = [];
        return;
      }
      // å°†ä»¥é€—号隔开的文件分割成数组127.0.0.1/aa/1.jpg,将127.0.0.1/aa/2.jpg
      if (typeof fileInfo === 'string') {
        if (fileInfo.trim() === '') {
          formFields[item.field] = [];
          return;
        }
        // å¦‚果文件路径是字符串,则使用,拆分
        fileInfo = fileInfo.replace(/\\/g, '/');
        let files = fileInfo.split(',');
        formFields[item.field] = [];
        for (let index = 0; index < files.length; index++) {
          let file = files[index];
          let splitFile = file.split('/');
          formFields[item.field].push({
            name: splitFile.length > 0 ? splitFile[splitFile.length - 1] : file,
            path: file // this.base.isUrl(file) ? file : this.http.ipAddress + file,
          });
        }
      }
    },
    dowloadFile(file) {
      this.base.dowloadFile(
        file.path,
        file.name,
        {
          Authorization: this.$store.getters.getToken()
        },
        this.http.ipAddress
      );
    },
    validatorPhone(ruleOption, value, callback) {
      if (!ruleOption.required && !value && value != '0') {
        return callback();
      }
      if (!rule.phone.test((value || '').trim())) {
        return callback(new Error('请输入正确的手机号'));
      }
      callback();
    },
    validatorPwd(ruleOption, value, callback) {
      if (!ruleOption.required && !value && value != '0') {
        return callback();
      }
      if ((value + '').trim().length < 6) {
        return callback(new Error('密码长度不能小于6位'));
      }
      callback();
    },
    convertArrayValue(data, val) {
      // 2020.12.13增加表单多选只转换字典
      // ç¼–辑多选table显示
      //2023.04.20修复只读为label时原数据被字典替换了的问题
      let valArr = Array.isArray(val)
        ? val.map((x) => {
            return x;
          })
        : val.split(',');
      for (let index = 0; index < valArr.length; index++) {
        var _item = data.find((x) => {
          return x.key && x.key != '0' && x.key + '' == valArr[index] + '';
        });
        if (_item) {
          valArr[index] = _item.value;
        }
      }
      return valArr.join(',');
    },
    getText(formFields, item) {
      // 2019.10.24修复表单select组件为只读的属性时没有绑定数据源
      let text = formFields[item.field];
      if (typeof text === 'function') return text(formFields);
      if (text === 'null' || text === '' || text === null || text === undefined)
        return '--';
      //2021.03.02增加只读时日期处理
      if (item.type == 'date') {
        return text.replace('T', ' ').split(' ')[0];
      }
      //2021.03.31修复表单switch只读时没有转换值的问题
      if (item.type == 'switch') {
        return text ? '是' : '否';
      }
      if (!item.data) return text;
      if (item.type == 'selectList' || item.type == 'checkbox') {
        return this.convertArrayValue(item.data, text);
      }
      var _item = item.data.find((x) => {
        return x.key == text;
      });
      return _item ? _item.value : text;
    },
    onClear(item, formFields) {
      // è¿œç¨‹select标签清空选项
      item.data.splice(0);
      // console.log(2);
    },
    onChange(item, value) {
      if (item.onChange && typeof item.onChange === 'function') {
        item.onChange(value, item);
      }
    },
    onRemoteChange(item, value) {
      // ç¬¬äºŒæ¬¡æ‰“开时,默认值成了undefined,待查viewgrid中重置代码
      if (value == undefined && item.data.length > 0) {
        this.formFields[item.field] = item.data[0].key;
        //  console.log('undefined');
      }
      this.remoteCall = false;
      if (item.onChange && typeof item.onChange === 'function') {
        item.onChange(value, item);
      }
    },
    getData(item) {
      return item.data;
    },
    // è¿œç¨‹æœç´¢(打开弹出框时应该禁止搜索)
    remoteSearch(item, formFields, val) {
      if (!item.remote && !item.url) {
        return;
      }
      if (
        val == '' ||
        (item.data.length == 1 &&
          (val == item.data[0].key || val == item.data[0].value))
      ) {
        return;
      }
      // å¼¹å‡ºæ¡†æˆ–初始化表单时给data设置数组默认值2
      // 2020.09.26修复远程搜索自定义url不起作用的问题
      let url;
      if (typeof item.url === 'function') {
        url = item.url(val, item.dataKey, item);
      } else {
        url =
          (item.url || '/api/Sys_Dictionary/GetSearchDictionary') +
          '?dicNo=' +
          item.dataKey +
          '&value=' +
          val;
      }
      this.http.post(url).then((dicData) => {
        //this.$set(item, "loading", false);
        item.loading = false;
        item.data = dicData;
        this.formRules[item.point.x].splice(item.point.y, 1, item);
      });
    },
    getObject(date) {
      if (typeof date === 'object') {
        return date;
      }
      return new Date(date);
    },
    reset(sourceObj) {
      // é‡ç½®è¡¨å•时,禁用远程查询
      this.$refs['volform'].resetFields();
      if (this.rangeFields.length) {
        this.rangeFields.forEach((key) => {
          this.formFields[key].splice(0);
          this.formFields[key] = [null, null];
        });
      }
      if (!sourceObj) return;
      for (const key in this.formFields) {
        if (sourceObj.hasOwnProperty(key)) {
          this.formFields[key] = sourceObj[key];
          if (this.numberFields.indexOf(key) != -1) {
            this.formFields[key] = sourceObj[key] * 1 || 0;
          }
        }
      }
      //  this.remoteCall = true;
    },
    fileOnChange(files, item) {
      this.$refs.volform.clearValidate(item.field);
      if (item.onChange) {
        return item.onChange(files);
      }
      return true;
    },
    isReadonly(item) {
      return item.readonly || item.disabled;
    },
    getRule(item, formFields) {
      //2021.07.17增加只读表单不验证
      //range与swtich暂时不做校验
      if (
        // item.readonly ||
        // item.disabled ||
        item.type == 'switch' ||
        item.type == 'range'
      )
        return { required: false };
      // ç”¨æˆ·è®¾ç½®çš„自定义方法
      if (item.validator && typeof item.validator === 'function') {
        return {
          validator: (rule, val, callback) => {
            // ç”¨æˆ·è‡ªå®šä¹‰çš„æ–¹æ³•,如果返回了值,直接显示返回的值,验证不通过
            let message = item.validator(rule, val);
            if (message) return callback(new Error(message + ''));
            return callback();
          },
          required: item.required,
          trigger: rule.change.indexOf(item.type) != -1 ? 'change' : 'blur'
        };
      }
      if (['img', 'excel', 'file'].indexOf(item.type) != -1) {
        return {
          validator: (rule, val, callback) => {
            //2021.09.05移除文件上传默认必填
            if (
              item.required &&
              !this.isReadonly(item) &&
              (!val || !val.length)
            ) {
              return callback(
                new Error(item.type == 'img' ? '请上传照片' : '请上传文件')
              );
            }
            return callback();
          },
          required: item.required,
          trigger: 'change'
        };
      }
      // è®¾ç½®æ•°å­—的最大值民最小值
      if (
        item.type == 'number' ||
        item.columnType == 'number' ||
        item.columnType == 'int' ||
        item.type == 'decimal'
      ) {
        // å¦‚果是必填项的数字,设置一个默认最大与最值小
        if (item.required && typeof item.min !== 'number') {
          item.min = 0; //item.type == "decimal" ? 0.1 : 1;
        }
        return {
          required: item.required,
          message: item.title + '只能是数字',
          title: item.title,
          trigger: 'blur',
          min: item.min,
          max: item.max,
          type: item.columnType || item.type,
          validator: (ruleObj, value, callback) => {
            if (!ruleObj.min && !ruleObj.max) {
              if (ruleObj.required) {
                if ((!value && value != '0') || !rule.decimal.test(value)) {
                  return callback(new Error('只能是数字'));
                }
              }
              return callback();
            }
            if (this.isReadonly(item)) return callback();
            if (ruleObj.type == 'number') {
              if (!rule.number.test(value)) {
                ruleObj.message = ruleObj.title + '只能是整数';
                return callback(new Error(ruleObj.message));
              }
            } else {
              if (!rule.decimal.test(value)) {
                ruleObj.message = ruleObj.title + '只能是数字';
                return callback(new Error(ruleObj.message));
              }
            }
            if (
              ruleObj.min !== undefined &&
              typeof ruleObj.min === 'number' &&
              value < ruleObj.min
            ) {
              ruleObj.message = ruleObj.title + '不能小于' + ruleObj.min;
              return callback(new Error(ruleObj.message));
            }
            if (
              ruleObj.max !== undefined &&
              typeof ruleObj.max === 'number' &&
              value > ruleObj.max
            ) {
              ruleObj.message = ruleObj.title + '不能大于' + ruleObj.max;
              return callback(new Error(ruleObj.message));
            }
            return callback();
          }
        };
      }
      // æ‰‹æœºã€å¯†ç éªŒè¯
      if (item.type == 'password' || item.type == 'phone') {
        return {
          validator:
            item.type == 'phone' ? this.validatorPhone : this.validatorPwd,
          required: item.required,
          trigger: 'blur'
        };
      }
      if (!item.required && item.type != 'mail') return { required: false };
      if (!item.hasOwnProperty('type')) item.type = 'text';
      if (inputTypeArr.indexOf(item.type) != -1) {
        let message =
          item.title +
          (item.type == 'mail' ? '必须是一个邮箱地址' : '不能为空');
        let type = item.type == 'mail' ? 'email' : types[item.columnType];
        let _rule = {
          required: true,
          message: message,
          trigger: 'blur',
          type: type,
          validator: (ruleObj, value, callback) => {
            if (
              !this.isReadonly(item) &&
              (value === '' || value === undefined || value === null)
            ) {
              return callback(new Error(ruleObj.message));
            }
            return callback();
          }
        };
        if (item.type == 'mail') {
          _rule.validator = undefined;
          return _rule;
        }
        if (item.min) {
          _rule.min = item.min;
          _rule.message = item.title + '至少' + item.min + '个字符!';
        }
        if (item.max) {
          return [
            _rule,
            {
              max: item.max,
              required: true,
              message: item.title + '最多' + item.max + '个字符!',
              trigger: 'blur'
            }
          ];
        }
        return _rule;
      }
      if (item.type == 'radio') {
        return {
          required: item.required,
          message: '请选择' + item.title,
          trigger: 'change',
          type: 'string'
        };
      }
      if (
        item.type == 'date' ||
        item.type == 'datetime' ||
        item.type == 'month' ||
        item.type == 'time'
      ) {
        return {
          required: true,
          message: '请选择' + item.title,
          trigger: 'change',
          type: item.range ? 'array' : 'string',
          validator: (rule, val, callback) => {
            if (this.isReadonly(item)) return callback();
            // ç”¨æˆ·è‡ªå®šä¹‰çš„æ–¹æ³•,如果返回了值,直接显示返回的值,验证不通过
            if (!val || (item.range && !val.length)) {
              return callback(new Error('请选择日期'));
            }
            return callback();
          }
        };
      }
      if (item.type == 'cascader') {
        return {
          type: 'array',
          required: true,
          min: item.min || 1,
          // message: "请选择" + item.title,
          trigger: 'change',
          validator: (rule, val, callback) => {
            if (this.isReadonly(item)) return callback();
            // ç”¨æˆ·è‡ªå®šä¹‰çš„æ–¹æ³•,如果返回了值,直接显示返回的值,验证不通过
            let _arr = this.formFields[item.field];
            if (!_arr || !_arr.length) {
              return callback(new Error('请选择' + item.title));
            }
            return callback();
          }
        };
      }
      if (
        ['select', 'selectList', 'checkbox', 'cascader', 'treeSelect'].indexOf(
          item.type
        ) != -1
      ) {
        let _rule = {
          type: item.type == 'select' ? 'string' : 'array',
          required: true,
          min: item.min || 1,
          message: '请选择' + item.title,
          trigger: 'change',
          validator: (rule, value, callback) => {
            if (this.isReadonly(item)) return callback();
            //2021.11.27修复多选没有提示的问题
            if (value == undefined || value === '') {
              return callback(new Error(rule.message));
            } else if (
              (item.type == 'checkbox' ||
                item.type == 'selectList' ||
                item.type == 'treeSelect') &&
              (!(value instanceof Array) || !value.length)
            ) {
              return callback(new Error(rule.message));
            }
            return callback();
          }
        };
        if (_rule.max) {
          _rule.nax = item.max;
          _rule.message = '最多只能选择' + item.max + '项';
        }
        return _rule;
      }
      return {};
    },
    compareDate(date1, date2) {
      if (!date2) {
        return true;
      }
      return (
        date1.valueOf() <
        (typeof date2 == 'number' ? date2 : new Date(date2).valueOf())
      );
    },
    getDateOptions(date, item) {
      //2021.07.17设置时间可选范围
      if ((!item.min && !item.max) || !date) {
        return false;
      }
      if (item.min && item.min.indexOf(' ') == -1) {
        //不设置时分秒,后面会自动加上 08:00
        item.min = item.min + ' 00:00:000';
      }
      return (
        this.compareDate(date, item.min) || !this.compareDate(date, item.max)
      );
    },
    getDateFormat(item) {
      if (item.type == 'month') {
        return 'YYYY-MM';
      }
      // if (item.type=='time') {
      //     return 'HH:mm:ss'
      // }
      //见https://day.js.org/docs/zh-CN/display/format
      return item.type == 'date' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss';
    },
    dateRangeChange(val, item) {
      if (!val) {
        this.$emit('update:formFields');
        return;
      }
      item.onChange && item.onChange(val);
    },
    onKeyPress($event, item) {
      if ($event.keyCode == 13) {
        return;
      }
      item.onKeyPress($event);
    },
    filterMethod(value, data) {
      return data.label.includes(value);
    },
    getNode( label,node, data){
      console.log(label)
    }
  }
});
</script>
<style lang="less" scoped>
.el-form-item {
  margin-right: 0;
}
.el-form-item {
  .form-imgs {
    img {
      float: left;
      cursor: pointer;
      object-fit: cover;
      margin: 0 10px 10px 0;
      width: 65px;
      height: 65px;
      border: 1px solid #c7c7c7;
      overflow: hidden;
      border-radius: 5px;
      box-sizing: content-box;
    }
  }
}
.el-form-item ::v-deep(.el-form-item__label) {
  padding: 0 0px 0 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.el-form-item ::v-deep(.el-range-separator) {
  text-align: center;
  width: 13px;
  padding: 0px 1px;
  font-size: 12px;
}
.el-form-item ::v-deep(.el-range__close-icon) {
  margin-right: -10px;
}
.form-item-extra {
  > *:first-child {
    flex: 1;
  }
  display: flex;
  .form-extra {
    padding-left: 7px;
    line-height: 36px;
  }
}
.vol-form-item {
  width: 100%;
}
.vol-form-item ::v-deep(.el-form-item__content) {
  display: unset !important;
}
.vol-form-item ::v-deep(.el-input--large .el-input__inner) {
  height: 34px !important;
}
.vol-form-item ::v-deep(.el-input-number--large .el-input-number__increase) {
  border-top: 1px solid #d4d4d4;
}
.vol-form-item ::v-deep(.el-input-number--large .el-input-number__decrease) {
  border-bottom: 1px solid #d4d4d4;
}
.vol-form-item ::v-deep(.el-input--large.el-date-editor) {
  height: 36px;
}
.v-date-range ::v-deep(.el-input__prefix) {
  display: none;
}
.v-date-range ::v-deep(.el-input__inner) {
  padding: 0;
}
.el-form-item ::v-deep(.el-checkbox) {
  margin-right: 8px;
}
.el-form-item ::v-deep(.el-checkbox .el-checkbox__label) {
  padding-left: 5px;
}
.el-form-item ::v-deep(textarea) {
  font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
    'Microsoft YaHei', '微软雅黑', Arial, sans-serif !important;
}
.el-form-item ::v-deep(.el-select .el-select__tags > span) {
  display: flex;
}
.el-form-item ::v-deep(.el-select-v2__combobox-input) {
  height: 30px;
}
.el-form-item ::v-deep(.el-select__tags) {
  overflow: hidden;
  height: 30px;
}
.el-form-item ::v-deep(.el-select-tags-wrapper) {
  position: absolute;
}
.el-form-item {
  vertical-align: top !important;
}
.form-file-list {
  a {
    color: #3ea9ff;
  }
  a:hover {
    cursor: pointer;
    color: #0281e7;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolForm/VolFormRender.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
import { h } from 'vue';
export default {
  name: "FormExpand",
  functional: true,
  props: {
    render: Function,
    par: {}//测试参数
  },
  render: ({ render, par }) => {
    return render(h, { par }); //h();
  }
};
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/DownloadForm.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,156 @@
import templateCode from './templateCode'
export default function () {
    let code = templateCode;
    let _formOptions = this.options.formOptions.map(m => {
        let _op = m.map((m1, i) => {
            let _obj;
            //.data[0].hasOwnProperty("key")
            if (m1.data && m1.data.length && !m1.dataKey) {
                let m2 = JSON.parse(JSON.stringify(m1));
                m2.data = m2.data.map(c => {
                    return { key: c.label || c.key, value: c.label }
                })
                _obj = JSON.stringify(m2)
            } else {
                _obj = JSON.stringify(m1)
            }
            return (i === 0 ? '' : '\n\t\t\t\t') + _obj
        }).join(',');
        //return JSON.stringify(m, null, '')
        return _op;
    })
    code = code.replace('{#fields}', JSON.stringify(this.options.fields))
        .replace('{#formOptions}', '[' + _formOptions.join('],\n\t\t\t\t[') + ']');
    code = code.replace('}],', '\t\t\t\t\t}],')
        .replace("[{#tableOptions}]", JSON.stringify(this.options.tables, null, '\t'))
        .replace("[{#tabsOptions}]", JSON.stringify(this.options.tabs, null, '\t'))
    // fields: {#fields},
    //     formOptions: [{#formOptions}],
    //     tables: [{#tables}],
    //     tabs: [{#tabs}]
    var tabsText = this.options.tabs.length ? ` <div class="tables"
     style="padding-bottom: 10px">
  <el-tabs v-model="tabsModel"
           @tab-click="() => {}">
    <el-tab-pane style="padding: 0"
                 class="table-item"
                 v-for="(item, index) in tabs"
                 :label="item.name"
                 :name="index+''"
                 :key="index">
      <div class="table-header">
        <div class="header-text">
          {{ item.name }}
        </div>
        <div class="header-btns">
          <el-button type="primary"
                     size="mini"
                     :key="bindex"
                     :icon="btnItem.icon"
                     plain
                     @click="tabsTableBtnClick(item, bindex, index)"
                     v-for="(btnItem, bindex) in item.buttons">
            {{ btnItem.name }}
          </el-button>
        </div>
      </div>
      <vol-table :url="item.url"
                 :load-key="false"
                 :index="true"
                 :ref="'tabsTable' + index"
                 :tableData="item.tableData"
                 :columns="item.columns"
                 :max-height="250"
                 :pagination-hide="item.pagination"
                 :column-index="true"
                 :ck="true"></vol-table>
    </el-tab-pane>
  </el-tabs>
</div>`: ''
    code = code.replace('{#tabs}', tabsText);
    if (this.options.tables.length || this.options.tabs.length) {
        code = code.replace("{import_VolTable}", "import VolTable from '@/components/basic/VolTable'")
        code = code.replace(",{component_table}", ",'vol-table': VolTable")
    } else {
        code = code.replace("{import_VolTable}", '')
        code = code.replace("{component_table}", '')
    }
    if (this.options.tables.length) {
        code = code.replace('{table_ms}', `
      tableBtnClick (item, btnIndex, index) {
          if (item.buttons[btnIndex].value == "add") {
              this.$refs["table" + index][0].addRow({});
              return;
          }
          if (item.buttons[btnIndex].value == "del") {
              this.$refs["table" + index][0].delRow();
              return;
          }
      },
      tabsTableBtnClick (item, btnIndex, index) {
          if (item.buttons[btnIndex].value == "add") {
              this.$refs["tabsTable" + index][0].addRow({});
              return;
          }
          if (item.buttons[btnIndex].value == "del") {
              this.$refs["tabsTable" + index][0].delRow();
              return;
          }
      },`)
        code = code.replace('{#tables}',
            `
      <!--table配置 -->
      <div class="tables">
          <div class="table-item"
              v-for="(item, index) in tables"
              :key="index">
          <div class="table-header">
              <div class="header-text">
              {{ item.name }}
              </div>
              <div class="header-btns">
              <el-button type="primary"
                          size="mini"
                          :key="bindex"
                          plain
                          @click="tableBtnClick(item, bindex, index)"
                          :icon="btnItem.icon"
                          v-for="(btnItem, bindex) in item.buttons">
                  {{ btnItem.name }}
              </el-button>
              </div>
          </div>
          <vol-table :url="item.url"
                      :load-key="false"
                      :index="true"
                      :ref="'table' + index"
                      :tableData="item.tableData"
                      :columns="item.columns"
                      :max-height="250"
                      :pagination-hide="item.pagination"
                      :column-index="true"
                      :ck="true"></vol-table>
          </div>
      </div>`);
    } else {
        code = code.replace('{table_ms}', '')
        code = code.replace('{#tables}', '');
    }
    const blob = new Blob([code], { type: "text/plain;charset=utf-8" })
    if ('download' in document.createElement('a')) { // éžIE下载
        const elink = document.createElement('a')
        elink.download = `code${new Date().valueOf()}.vue`;
        elink.style.display = 'none'
        elink.href = URL.createObjectURL(blob)
        document.body.appendChild(elink)
        elink.click()
        URL.revokeObjectURL(elink.href) // é‡Šæ”¾URL å¯¹è±¡
        document.body.removeChild(elink)
    } else {
        navigator.msSaveBlob(blob, fileName)
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/VolFormDraggable.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1159 @@
<template>
  <div class="drag-container">
    <!-- @start="onStart" -->
    <div class="drag-left">
      <div class="left-title">组件列表</div>
      <draggable
        v-model="components"
        @end="end1"
        class="left-draggable-item"
        :group="{ name: 'componentsGroup', pull: 'clone', put: false }"
        animation="300"
        @start="onStart"
        :sort="false"
        :move="onMove1"
      >
        <transition-group>
          <div
            :class="item.id == 1 ? 'item forbid' : 'item'"
            v-for="item in components"
            :key="item.id"
          >
            <i :class="item.icon"></i> {{ item.name }}
          </div>
        </transition-group>
      </draggable>
      <div class="example">
        <div @click="example1">示例一<i class="el-icon-arrow-right"></i></div>
        <div @click="example2">示例二<i class="el-icon-arrow-right"></i></div>
        <div @click="example3">示例三<i class="el-icon-arrow-right"></i></div>
      </div>
    </div>
    <div class="drag-center">
      <div class="center-top">
        <span>
          <!-- <i class="el-icon-warning-outline"></i>高效的表单配置 -->
        </span>
        <el-button type="primary" size="mini" plain @click="save"
          ><i class="el-icon-check"> </i>保存</el-button
        >
        <el-button type="primary" size="mini" plain @click="preview(true)"
          ><i class="el-icon-view"> </i>预览</el-button
        >
        <el-button type="primary" size="mini" plain @click="download"
          ><i class="el-icon-view"> </i>下载</el-button
        >
        <el-button type="primary" @click="clearItems" size="mini" plain
          ><i class="el-icon-delete"> </i>清空</el-button
        >
        <a
          style="margin-left: 15px"
          href="http://v2.volcore.xyz/document/api"
          target="_blank"
          >设计器基于框架volform、voltable、volupload、volbox定制开发</a
        >
      </div>
      <div>
        <el-alert
          title="关于表单设计器"
          type="success"
          :show-icon="true"
          :closable="false"
        >
          <div>
            1、表单设计器基于draggable开发,为本框架自定义页面功能的补充,框架仍以可视化代码生成器为核心
          </div>
          <div>
            2、支持可视化设计1对1、1对多及表单下拉框自动绑定、table自动加载数据(分页、编辑)、自动上传文件、富文本编辑
          </div>
        </el-alert>
      </div>
      <el-scrollbar style="flex: 1">
        <div class="tips" key="empty" v-show="!currentComponents.length">
          è¯·å°†å·¦è¾¹ç»„件拖入此容器中
        </div>
        <el-form label-position="top">
          <draggable
            class="draggable-container"
            v-model="currentComponents"
            @end="end2"
            animation="300"
            :move="onMove"
            group="componentsGroup"
          >
            <transition-group class="drag-center-item">
              <div
                class="item2"
                :class="{ actived: index === currentIndex }"
                @click="itemClick(item, index)"
                :style="{ width: item.width + '%' }"
                v-for="(item, index) in currentComponents"
                :key="index"
              >
                <i
                  class="el-icon-document-copy"
                  @click.stop="copyItem(item)"
                ></i>
                <i class="el-icon-delete" @click.stop="removeItem(index)"> </i>
                <el-form-item
                  :required="item.required"
                  label-position="top"
                  style="width: 100%"
                  :label="item.type == 'line' ? '' : item.name"
                >
                  <el-col>
                    <!-- <div></div> -->
                    <!-- {{ item.name }} -->
                    <el-input
                      v-if="item.type == 'text'"
                      placeholder="请输入内容"
                      v-model="item.value"
                      :disabled="item.readonly"
                      size="medium"
                    ></el-input>
                    <el-input
                      v-else-if="item.type == 'textarea'"
                      type="textarea"
                      v-model="item.value"
                      :disabled="item.readonly"
                      placeholder="请输入内容"
                    ></el-input>
                    <el-date-picker
                      v-else-if="item.type == 'date'"
                      align="right"
                      v-model="item.value"
                      type="date"
                      :disabled="item.readonly"
                      size="medium"
                      placeholder="选择日期"
                    >
                    </el-date-picker>
                    <el-radio-group
                      :disabled="item.readonly"
                      v-else-if="item.type == 'radio'"
                      v-model="item.value"
                    >
                      <el-radio
                        v-for="item in item.data"
                        :key="item.key"
                        :label="item.value"
                        :value="item.key"
                      >
                      </el-radio>
                      <!-- <el-radio :label="1">是</el-radio>
                      <el-radio :label="0">否</el-radio> -->
                    </el-radio-group>
                    <el-checkbox-group
                      v-model="item.values"
                      :disabled="item.readonly"
                      style="width: 100%; display: inline-block"
                      v-else-if="item.type == 'checkbox'"
                    >
                      <el-checkbox
                        v-for="item in item.data"
                        :key="item.key"
                        :label="item.value"
                        :value="item.key"
                      >
                      </el-checkbox>
                      <!-- <el-checkbox label="复选框 A"></el-checkbox>
                      <el-checkbox label="复选框 B"></el-checkbox>
                      <el-checkbox label="复选框 C"></el-checkbox> -->
                    </el-checkbox-group>
                    <el-select
                      style="width: 100%"
                      :disabled="item.readonly"
                      v-model="item.value"
                      size="medium"
                      v-else-if="item.type == 'select'"
                      placeholder="请选择"
                    >
                      <el-option
                        v-for="item in item.data"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                      >
                      </el-option>
                    </el-select>
                    <el-select
                      style="width: 100%"
                      :disabled="item.readonly"
                      v-model="item.values"
                      size="medium"
                      :multiple="true"
                      v-else-if="item.type == 'selectList'"
                      placeholder="请选择"
                    >
                      <el-option
                        v-for="item in item.data"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                      >
                      </el-option>
                    </el-select>
                    <el-cascader
                      :disabled="item.readonly"
                      style="width: 100%"
                      v-else-if="item.type == 'cascader'"
                      v-model="item.values"
                      :options="item.data"
                      @change="() => {}"
                    ></el-cascader>
                    <el-switch
                      :disabled="item.readonly"
                      v-model="item.value"
                      style="width: 100%"
                      v-else-if="item.type == 'switch'"
                      active-color="#13ce66"
                      inactive-color="#0e7ef3"
                      :active-value="1"
                      :inactive-value="0"
                    >
                    </el-switch>
                    <div class="col-line" v-else-if="item.type == 'line'">
                      {{ item.name }}
                    </div>
                    <vol-upload
                      v-else-if="
                        item.type == 'img' ||
                        item.type == 'excel' ||
                        item.type == 'file'
                      "
                      :fileInfo="item.fileInfo"
                      :url="item.url"
                      :img="item.type == 'img'"
                      :excel="item.type == 'excel'"
                      :multiple="item.multiple"
                      :max-size="item.maxSize"
                      :max-file="item.maxFile"
                      :autoUpload="item.autoUpload"
                    >
                    </vol-upload>
                    <vol-wang-editor
                      v-else-if="item.type == 'editor'"
                      :url="item.url"
                      v-model="item.value"
                      :height="item.height"
                    ></vol-wang-editor>
                    <vol-table
                      v-else-if="item.type == 'table'"
                      :url="item.url"
                      :load-key="true"
                      :index="item.edit"
                      :tableData="item.tableData"
                      :columns="item.columns"
                      :height="item.height"
                      :pagination-hide="true"
                      :column-index="item.columnIndex"
                      :ck="item.ck"
                    ></vol-table>
                    <el-button
                      @click="model = true"
                      v-else-if="item.type == 'box'"
                      type="primary"
                      size="small"
                      >{{ item.name }}</el-button
                    >
                  </el-col>
                </el-form-item>
              </div>
            </transition-group>
          </draggable>
        </el-form>
      </el-scrollbar>
    </div>
    <div class="drag-right">
      <div class="left-title">组件属性</div>
      <div class="attr" v-show="currentIndex != -1">
        <div class="attr-item">
          <div class="text">字段名称</div>
          <el-input size="medium" v-model="currentItem.name" />
        </div>
        <div class="attr-item">
          <div class="text">字段(唯一字段)</div>
          <el-input size="medium" v-model="currentItem.field" />
        </div>
        <div class="attr-item" v-show="currentItem.type == 'table'">
          <div class="text">后台返回数据接口地址</div>
          <el-input
            size="medium"
            placeholder="例:api/表名/getPageData"
            v-model="currentItem.url"
          />
        </div>
        <div
          class="attr-item"
          v-show="
            currentItem.type != 'table' && currentItem.hasOwnProperty('url')
          "
        >
          <div class="text">上传接口地址(后台接口)</div>
          <el-input
            size="medium"
            placeholder="可用框架地址:api/表名/upload"
            v-model="currentItem.url"
          />
          <div class="text" style="margin-top: 10px">文件大小限制(M)</div>
          <el-input size="medium" v-model="currentItem.maxSize" />
          <div class="text" style="margin-top: 10px">是否多文件上传</div>
          <el-switch
            v-model="currentItem.multiple"
            style="width: 100%"
            active-color="#13ce66"
            inactive-color="rgb(165 165 165)"
            :active-value="true"
            :inactive-value="false"
          >
          </el-switch>
          <div class="text" style="margin-top: 10px">是否自动上传</div>
          <el-switch
            v-model="currentItem.autoUpload"
            style="width: 100%"
            active-color="#13ce66"
            inactive-color="rgb(165 165 165)"
            :active-value="true"
            :inactive-value="false"
          >
          </el-switch>
        </div>
        <div class="attr-item" v-show="currentItem.data">
          <div class="text">数据源(下拉框绑定设置中维护)</div>
          <!-- dicList -->
          <el-select
            style="width: 100%"
            v-model="currentItem.key"
            size="medium"
            @change="dicChange"
            placeholder="请选择数据源字典"
          >
            <el-option
              v-for="item in dicList"
              :key="item.key"
              :label="item.value"
              :value="item.key"
            >
            </el-option>
          </el-select>
        </div>
        <div class="attr-item" v-show="currentItem.type != 'table'">
          <div class="text">标签宽度</div>
          <el-slider
            style="width: 90%"
            :min="20"
            v-model="colWidth"
            :step="10"
            show-stops
          >
          </el-slider>
        </div>
        <div class="attr-item attr2" v-show="currentItem.type != 'table'">
          <div>
            <div class="text">必填</div>
            <el-switch
              v-model="currentItem.required"
              style="width: 100%"
              active-color="#13ce66"
              inactive-color="rgb(165 165 165)"
              :active-value="true"
              :inactive-value="false"
            >
            </el-switch>
          </div>
          <div>
            <!-- active-text="是"
              inactive-text="否" -->
            <div class="text">只读</div>
            <el-switch
              v-model="currentItem.readonly"
              style="width: 100%"
              active-color="#13ce66"
              inactive-color="rgb(165 165 165)"
              :active-value="true"
              :inactive-value="false"
            >
            </el-switch>
          </div>
        </div>
        <div v-show="currentItem.type == 'table'">
          <div class="attr-item">
            <div class="text">是否使用选项卡(tabs)</div>
            <div>
              <el-switch
                v-model="currentItem.tabs"
                style="width: 100%"
                active-text="是"
                inactive-text="否"
                active-color="#13ce66"
                inactive-color="rgb(165 165 165)"
                :active-value="true"
                :inactive-value="false"
              >
              </el-switch>
            </div>
          </div>
          <div class="attr-item attr2">
            <el-button
              style="width: 100%"
              @click="openTableModel"
              type="primary"
              size="medium"
              >table配置</el-button
            >
          </div>
        </div>
      </div>
    </div>
  </div>
  <vol-box
    v-model="model"
    :height="300"
    :width="550"
    :lazy="true"
    title="弹出框"
  >
    <template #content>
      <div>弹出框内容</div>
    </template>
    <template #footer>
      <div>
        <el-button type="primary" size="mini" @click="model = false"
          ><i class="el-icon-close"></i>点击关闭</el-button
        >
        <el-button size="mini" @click="model = false"
          ><i class="el-icon-close"></i>关闭</el-button
        >
      </div>
    </template>
  </vol-box>
  <vol-box
    v-model="previewModel"
    :height="600"
    :width="1300"
    :lazy="true"
    :padding="1"
    :close="false"
    title="预览"
  >
    <preview style="height:600px" :options="viewFormData"></preview>
  </vol-box>
  <vol-box
    v-model="tableModel"
    :height="600"
    :width="1300"
    :lazy="true"
    :padding="0"
    :title="currentItem.name"
  >
    <template #content>
      <div style="height:600px" >
      <el-alert title="关于table配置" type="info" :closable="false" show-icon>
        æ­¤å¤„table是对框架voltable基本操作的配置,如果需要事件触发、数据加载等更多功能,请在生成后的代码添加需要的功能,完整配置见文档<a
          href="http://v2.volcore.xyz/document/api"
          style="color: #1e88e5; margin-left: 9px"
          target="_blank"
          >voltable</a
        >
      </el-alert>
      <div class="btns">
        <div class="btns-left">
          è¡¨æ ¼é»˜è®¤åŠŸèƒ½æŒ‰é’®ï¼š
          <el-checkbox
            v-for="item in currentItem.buttons"
            :label="item.name"
            :key="item.name"
            >{{ item.name }}</el-checkbox
          >
        </div>
        <div class="btns-right">
          <el-button type="primary" size="mini" @click="addRow"
            ><i class="el-icon-plus"></i>添加字段</el-button
          >
          <el-button type="primary" size="mini" @click="delRow"
            ><i class="el-icon-delete"></i>删除字段</el-button
          >
          <el-button type="primary" size="mini" @click="sortRow"
            ><i class="el-icon-sort"></i>重新排列</el-button
          >
        </div>
      </div>
      <vol-table
        :load-key="true"
        :tableData="currnetTableData"
        :columns="currentTableOption"
        :height="448"
        ref="table"
        :index="true"
        :pagination-hide="true"
        :column-index="true"
        :ck="true"
      ></vol-table>
    </div>
    </template>
    <template #footer>
      <div style="text-align: center">
        <el-button size="mini" @click="tableModel = false"
          ><i class="el-icon-close"></i>关闭</el-button
        >
        <el-button type="primary" size="mini" @click="saveConfigOptions"
          ><i class="el-icon-check"></i>保存</el-button
        >
      </div>
    </template>
  </vol-box>
</template>
<script>
import { h, resolveComponent } from "vue";
// import draggable from "vuedraggable";
import { VueDraggableNext } from "vue-draggable-next";
// import VolWangEditor from "@/components/editor/VolWangEditor.vue";
import VolUpload from "./../VolUpload";
import VolTable from "./../VolTable";
import VolBox from "./../VolBox";
import VolFormPreview from "./VolFormPreview";
import { components, tableOption } from "./options";
import { options1, options2, options3 } from "./formTemplate";
import downloadForm from "./DownloadForm";
export default {
  props: {
    userComponents: {
      type: Array,
      default: () => {
        return [];
      },
    },
  },
  components: {
    draggable: VueDraggableNext,
    "vol-upload": VolUpload,
    // "vol-wang-editor": VolWangEditor,
    "vol-table": VolTable,
    "vol-box": VolBox,
    preview: VolFormPreview,
  },
  data() {
    return {
      options:{},
      options1: options1,
      options2: options2,
      options3: options3,
      colWidth: 100,
      currentIndex: -1,
      currentItem: {},
      currnetTableData: [],
      currentTableOption: tableOption,
      //定义要被拖拽对象的数组
      components: components,
      currentComponents: [],
      dicList: [],
      model: false,
      tableModel: false,
      previewModel: false,
      viewFormData: { fields: {}, formOptions: [], tables: [] },
    };
  },
  watch: {
    colWidth(newVal) {
      if (this.currentIndex != -1) {
        this.currentComponents[this.currentIndex].width = newVal;
      }
    },
    userComponents: {
      handler(newVal) {
        this.currentComponents = newVal;
      },
      immediate: true,
      deep: true,
    },
  },
  created() {
    this.currentComponents = this.userComponents;
    this.http
      .post("api/Sys_Dictionary/GetBuilderDictionary", {}, false)
      .then((x) => {
        this.dicList = x.map((c) => {
          return { key: c, value: c };
        });
      });
  },
  methods: {
    getFormOptions(item) {
      let _option = {};
      _option.field = item.field;
      _option.title = item.name;
      _option.type = item.type;
      _option.required = item.required;
      _option.readonly = item.readonly;
      if (item.type == "line") {
        _option.title = "";
        let title = item.name;
        _option.render = (h) => {
          return h(
            "div",
            {
              style: {
                "line-height": "25px",
                "font-weight": "bold",
                "margin-left": "15px",
                "border-bottom": "1px solid #dadada",
              },
            },
            title
            //也可以在这里放一些组件,例如:
            // resolveComponent("el-tooltip"),
            // {
            //   content: "这里是提示的内容",
            //   props: { effect: "dark", placement: "top-start" },
            //   style: {},
            // },
            // [h("a", { style: { color: "#2a92ff" } }, "提示信息")]
          );
        };
      }
      if (item.type == "editor") {
        _option.height = item.height;
      }
      if (item.width == 100) {
        _option.colSize = 12;
      } else {
        _option.colSize = (_option.width * 12) / 100;
      }
      if (["img", "excel", "file"].indexOf(item.type) != -1) {
        _option.maxSize = item.maxSize;
        _option.fileInfo = item.fileInfo;
        _option.multiple = item.multiple;
        _option.autoUpload = item.autoUpload;
        _option.maxFile = item.maxFile;
      }
      if (
        ["img", "excel", "file", "editor", "table"].indexOf(item.type) != -1
      ) {
        _option.url = item.url;
      }
      if (item.data) {
        _option.data = item.data;
        _option.dataKey = item.key;
      }
      return _option;
    },
    getLineFormOptions(index) {
      let _index = index;
      let endIndex = index;
      let width = 0;
      let _options = [];
      for (index; index < this.filterCurrentComponents().length; index++) {
        const item = this.currentComponents[index];
        if (item.width + width <= 100) {
          width = item.width + width;
          endIndex = index;
          _options.push(this.getFormOptions(item));
        }
      }
      return { options: _options, index: _index, endIndex: endIndex };
    },
    filterCurrentComponents() {
      return this.currentComponents.filter((x) => {
        return x.type != "table";
      });
    },
    setSpan() {},
    preview(isPre) {
      let _fields = {};
      let _formOptions = [];
      let endIndex = -1;
      this.filterCurrentComponents().forEach((item, index) => {
        if (item.hasOwnProperty("values")) {
          _fields[item.field] = [];
        } else {
          _fields[item.field] = null;
        }
        if (item.width == 100) {
          _formOptions.push([this.getFormOptions(item)]);
        } else {
          if (endIndex == -1) {
            let lineOptions = this.getLineFormOptions(index);
            endIndex = lineOptions.endIndex;
            _formOptions.push(lineOptions.options);
            endIndex--;
          } else {
            endIndex--;
          }
        }
        // _fields[item.field] = null;xc
        // let _option = {};
        // _option.field = item.field;
        // _option.title = item.name;
        // _option.type = item.type;
        // _option.required = item.required;
        // _option.readonly = item.readonly;
        // if (["img", "excel", "file"].indexOf(item.type) != -1) {
        //   _option.maxSize = item.maxSize;
        //   _option.fileInfo = item.fileInfo;
        //   _option.multiple = item.multiple;
        //   _option.autoUpload = item.autoUpload;
        //   _option.maxFile = item.maxFile;
        // }
        // if (
        //   ["img", "excel", "file", "editor", "table"].indexOf(item.type) != -1
        // ) {
        //   _option.url = item.url;
        // }
        // if (item.data) {
        //   _option.data = item.data;
        //   _option.dataKey = item.key;
        // }
        // _formOptions.push(_option);
      });
      this.viewFormData.fields = _fields;
      // console.log(JSON.stringify(_formOptions))
      this.viewFormData.formOptions = _formOptions;
      if (isPre) {
        this.previewModel = true;
      }
      let tableIndex = 0;
      let keys = [];
      let tables = this.currentComponents
        .filter((x) => {
          return x.type == "table";
        })
        .map((m) => {
          m.pagination = !m.url;
          if (m.name == "表格") {
            tableIndex++;
          }
          return {
            name: m.name + (m.name == "表格" ? tableIndex : ""),
            url: m.url,
            tabs: m.tabs,
            pagination: m.pagination,
            buttons: m.buttons,
            columns: m.columns.map((c) => {
              let obj = {
                title: c.title,
                field: c.field,
                hidden: !c.show,
                width: c.width,
                required: c.required,
              };
              if (c.dataSource) {
                obj.bind = { key: c.dataSource, data: [] };
              }
              if (c.dataSource) {
                keys.push(c.dataSource);
              }
              if (c.edit) {
                if (!obj.bind) {
                  obj.bind = { key: "", data: [] };
                }
                obj.edit = { type: c.editType };
              }
              return obj;
            }),
            tableData: [{}, {}, {}],
          };
        });
      this.viewFormData.tables = tables.filter((x) => {
        return !x.tabs;
      });
      this.viewFormData.tabs = tables.filter((x) => {
        return x.tabs;
      });
      this.getDicKeys(keys);
          this.options = this.viewFormData;
    },
    getDicKeys(keys) {
      if (!keys.length) {
        return;
      }
      debugger
      this.http
        .post("api/Sys_Dictionary/GetVueDictionary", keys, true)
        .then((result) => {
          result.forEach((c) => {
            this.viewFormData.tables.forEach((t) => {
              let _option = t.columns.find((x) => {
                return x.bind && x.bind.key == c.dicNo;
              });
              if (_option) {
                _option.bind.data = c.data;
              }
            });
            this.viewFormData.tabs.forEach((t) => {
              let _option = t.columns.find((x) => {
                return x.bind && x.bind.key == c.dicNo;
              });
              if (_option) {
                _option.bind.data = c.data;
              }
            });
          });
        });
    },
    save() {
      this.preview(false);
      this.$emit("save", {
        daraggeOptions: this.currentComponents,
        formOptions: this.viewFormData,
      });
    },
    download() {
      this.preview(false);
      downloadForm.call(this);
    },
    openTableModel() {
      let dataSource = this.currentTableOption.find((x) => {
        return x.field == "dataSource";
      });
      if (!dataSource.bind.data.length) {
        dataSource.bind.data = this.dicList;
      }
      this.currnetTableData = JSON.parse(
        JSON.stringify(this.currentItem.columns)
      );
      this.tableModel = true;
    },
    addRow() {
      this.currnetTableData.push({ field: this.getField() });
    },
    delRow() {
      this.$confirm("确认要删除选择的数据吗?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        center: true,
      }).then(() => {
        this.$refs.table.delRow();
      });
    },
    sortRow() {
      this.currnetTableData = this.currnetTableData.sort((a, b) => {
        return a.orderNo - b.orderNo;
      }); //.reverse();
      this.$Message.success("列显示顺序已重新排列,点击预览可查看");
    },
    saveConfigOptions() {
      this.currentItem.columns = JSON.parse(
        JSON.stringify(this.currnetTableData)
      );
      this.tableModel = false;
    },
    copyItem(item) {
      let itemClone = JSON.parse(JSON.stringify(item));
      itemClone.field = "field" + new Date().valueOf();
      this.currentComponents.push(itemClone);
    },
    removeItem(index) {
      this.currentComponents.splice(index, 1);
      this.colWidth = 100;
      this.currentIndex = -1;
      this.currentItem = {};
    },
    clearItems() {
      this.currentComponents.length = 0;
      this.colWidth = 100;
      this.currentIndex = -1;
      this.currentItem = {};
    },
    itemClick(item, index) {
      this.currentIndex = index;
      this.colWidth = this.currentComponents[this.currentIndex].width;
      this.currentItem = this.currentComponents[this.currentIndex];
    },
    //开始拖拽事件
    onStart(e, e1) {
      this.drag = true;
    },
    getField() {
      return "field" + new Date().valueOf();
    },
    //左边往右边拖动时的事件
    end1(e) {
      if (1 == 1 && e.from !== e.to) {
        let obj = JSON.parse(JSON.stringify(this.components[e.oldIndex]));
        obj.field = this.getField();
        obj.width = 100;
        obj.readonly = false;
        obj.required = false;
        this.currentComponents.splice(e.newIndex, 1, obj);
        this.userComponents.splice(0);
        this.userComponents.push(...this.currentComponents);
        // this.currentComponents = this.currentComponents.filter((x) => {
        //   return x.hasOwnProperty("field");
        // });
        this.colWidth = 100;
        this.currentIndex = e.newIndex; //this.currentComponents.length - 1;
        this.currentItem = this.currentComponents[this.currentIndex];
      }
    },
    //右边往左边拖动时的事件
    end2(e) {},
    onMove1(e, originalEvent) {
      // this.moveId = e.relatedContext.element.id;
      return true;
    },
    //move回调方法
    onMove(e, originalEvent) {
      console.log(JSON.stringify(this.currentComponents));
      return true;
    },
    dicChange(key) {
      debugger
      this.http
        .post("api/Sys_Dictionary/GetVueDictionary", [key], true)
        .then((result) => {
          this.currentItem.data = result[0].data;
          if (result[0].data.length) {
            if (this.currentItem.type == "select") {
              this.currentItem.value = result[0].data[0].value;
            } else {
              this.currentItem.values = [result[0].data[0].value];
            }
          }
        });
    },
    example1() {
      this.currentComponents = this.options1;
    },
    example2() {
      this.currentComponents = this.options2;
    },
    example3() {
      this.currentComponents = this.options3;
    },
  },
  computed: {
    tabsTable() {
      return this.currentComponents.filter((x) => {
        return x.type == "table" && x.tabs == true;
      });
    },
  },
};
</script>
<style lang="less" scoped>
* {
  box-sizing: border-box;
}
.drag-container {
  /* padding: 20px; */
  display: flex;
  height: 100%;
  position: absolute;
  width: 100%;
  box-sizing: border-box;
}
.drag-left {
  width: 250px;
  display: flex;
  border-right: 1px solid #eee;
  flex-direction: column;
}
.left-title {
  height: 42px;
  text-align: left;
  border-right: 1px solid #eee;
  padding: 10px 0 10px 11px;
  border-bottom: 1px solid #eee;
}
.drag-center {
  display: flex;
  flex-direction: column;
  flex: 1;
}
.left-draggable-item {
  //   flex: 1;
  display: inline-block;
  padding: 5px;
  //   border-right: 1px solid #eee;
}
.left-draggable-item .item {
  cursor: move;
  float: left;
  width: 111px;
  /* height: 20px; */
  text-align: center;
  border: 1px solid #eeeeee;
  padding: 2px 13px;
  text-align: left;
  line-height: 28px;
  margin: 4px;
  border-radius: 3px;
  background: #f0f9eb;
  font-size: 13px;
}
// .drag-center-item {
//   display: inline-block;
//   width: 100%;
//   height: calc(100vh - 122px);
//   padding: 10px;
// }
.draggable-container {
  display: inline-block;
  width: 100%;
  height: calc(100vh - 215px);
  padding: 10px 0;
}
.item2 {
  position: relative;
  cursor: move;
  padding: 18px 10px 10px 10px;
  text-align: left;
  float: left;
  margin-bottom: 10px;
}
.item2 .el-icon-delete,
.item2 .el-icon-document-copy {
  position: absolute;
  right: 10px;
  top: 2px;
  padding: 5px;
  display: none;
  color: red;
  cursor: pointer;
}
.item2 .el-icon-document-copy {
  right: 35px;
}
.item2:hover,
.actived {
  background: #f0f9eb;
}
.item:hover {
  border: 1px dashed #787be8;
  color: #787be8;
}
.item2:hover .el-icon-delete,
.item2:hover .el-icon-document-copy {
  display: block;
}
.drag-right {
  background: #f7fbff3d;
  width: 250px;
  border-left: 1px solid #eee;
}
.center-top {
  height: 42px;
  line-height: 41px;
  background: #f2f5fb;
  border-bottom: 1px solid #eee;
  text-align: left;
  padding: 0 10px;
  font-size: 12px;
  color: #3391f3;
}
.center-top span {
  margin-right: 10px;
}
.attr {
  padding: 0px 15px 15px 15px;
}
.attr-item {
  text-align: left;
  margin-top: 12px;
  font-size: 14px;
}
.attr-item .text {
  padding: 0 0 5px 5px;
}
.attr2 {
  display: flex;
}
.attr2 > div {
  flex: 1;
}
.tips {
  position: absolute;
  font-size: 26px;
  letter-spacing: 6px;
  left: 0px;
  right: 0px;
  top: 150px;
  width: 500px;
  margin: auto;
  color: #c5c5c5;
}
.col-line {
  line-height: 25px;
  font-weight: bold;
  border-bottom: 1px solid rgb(218 218 218);
}
.drag-container ::v-deep(.el-col) {
  width: 100%;
}
.drag-center ::v-deep(.el-form-item__label) {
  line-height: 0 !important;
}
.drag-center ::v-deep(.el-scrollbar__wrap) {
  overflow-x: hidden;
}
.drag-center ::v-deep(.el-form-item) {
  margin-bottom: 10px;
}
.drag-center ::v-deep(.el-date-editor) {
  width: 100%;
}
.drag-center ::v-deep(.el-checkbox) {
  margin-right: 15px;
}
.drag-center ::v-deep(.el-checkbox__label) {
  padding-left: 5px;
}
.drag-center ::v-deep(.hello > div) {
  z-index: 500 !important;
}
.drag-center ::v-deep(th),
.drag-center ::v-deep(td) {
  padding: 6px 0;
}
.example {
  margin-top: 8px;
  > div {
    cursor: pointer;
    padding: 14px 20px;
    border-top: 1px solid #eee;
    font-size: 13px;
    color: #646465;
    position: relative;
  }
  > div:hover {
    background: rgb(231, 231, 231);
  }
  i {
    position: absolute;
    right: 20px;
  }
}
.btns {
  padding: 8px 0;
  display: flex;
  > div {
    flex: 1;
  }
  .btns-left {
    padding-top: 8px;
    color: black;
    font-weight: bold;
  }
  .btns-right {
    text-align: right;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/VolFormPreview.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,206 @@
<template>
  <div style="padding: 15px 20px 15px 5px">
    <div class="pre-text">{{ text }}</div>
    <vol-form
      ref="form"
      :labelWidth="80"
      :load-key="false"
      :formFields="options.fields"
      :formRules="options.formOptions"
    >
    </vol-form>
    <div class="tables">
      <div
        class="table-item"
        v-for="(item, index) in options.tables"
        :key="index"
      >
        <div class="table-header">
          <div class="header-text">
            {{ item.name }}
          </div>
          <div class="header-btns">
            <el-button
              type="primary"
              size="small"
              :key="bindex"
              plain
              @click="tableBtnClick(item, bindex, index)"
              :icon="btnItem.icon"
              v-for="(btnItem, bindex) in item.buttons"
            >
              {{ btnItem.name }}
            </el-button>
          </div>
        </div>
        <vol-table
          :url="item.url"
          :load-key="false"
          :index="true"
          :ref="'table' + index"
          :tableData="item.tableData"
          :columns="item.columns"
          :max-height="250"
          :pagination-hide="item.pagination"
          :column-index="true"
          :ck="true"
        ></vol-table>
      </div>
    </div>
    <div class="tables" style="padding-bottom: 10px">
      <el-tabs
        v-model="tabsModel"
        v-show="options.tabs.length"
        @tab-click="() => {}"
      >
        <el-tab-pane
          style="padding: 0"
          class="table-item"
          v-for="(item, index) in options.tabs"
          :label="item.name"
          :name="index"
          :key="index"
        >
          <div class="table-header">
            <div class="header-text">
              {{ item.name }}
            </div>
            <div class="header-btns">
              <el-button
                type="primary"
                size="small"
                :key="bindex"
                :icon="btnItem.icon"
                plain
                @click="tabsTableBtnClick(item, bindex, index)"
                v-for="(btnItem, bindex) in item.buttons"
              >
                {{ btnItem.name }}
              </el-button>
            </div>
          </div>
          <vol-table
            :url="item.url"
            :load-key="false"
            :index="true"
            :ref="'tabsTable' + index"
            :tableData="item.tableData"
            :columns="item.columns"
            :max-height="250"
            :pagination-hide="item.pagination"
            :column-index="true"
            :ck="true"
          ></vol-table>
        </el-tab-pane>
      </el-tabs>
    </div>
    <div class="form-btns">
      <el-button type="primary" @click="submit" icon="el-icon-check" size="small"
        >提交</el-button
      >
      <el-button
        type="primary"
        @click="reset"
        plain
        icon="el-icon-refresh-right"
        size="small"
        >重置</el-button
      >
      <el-button
        type="primary"
        @click="download"
        plain
        icon="el-icon-refresh-right"
        size="small"
        >下载代码</el-button
      >
    </div>
  </div>
</template>
<script>
import VolTable from "./../VolTable";
import VolBox from "./../VolBox";
import VolForm from "./../VolForm";
import downloadForm from "./DownloadForm";
export default {
  props: {
    options: {
      type: Object,
      default: () => {
        return { fields: {}, formOptions: [], tables: [], tabs: [] };
      },
    },
  },
  data() {
    return {
      text: "",
      tabsModel: 0,
    };
  },
  created() {},
  methods: {
    tableBtnClick(item, btnIndex, index) {
      if (item.buttons[btnIndex].value == "add") {
        this.$refs["table" + index].addRow({});
        return;
      }
      if (item.buttons[btnIndex].value == "del") {
        this.$refs["table" + index].delRow();
        return;
      }
    },
    tabsTableBtnClick(item, btnIndex, index) {
      if (item.buttons[btnIndex].value == "add") {
        this.$refs["tabsTable" + index].addRow({});
        return;
      }
      if (item.buttons[btnIndex].value == "del") {
        this.$refs["tabsTable" + index].delRow();
        return;
      }
    },
    submit() {},
    reset() {
      this.$refs.form.reset();
      this.$Message.success("表单已重置");
    },
    download() {
      downloadForm.call(this);
    },
  },
  components: {
    "vol-table": VolTable,
    "vol-box": VolBox,
    "vol-form": VolForm,
  },
};
VolForm;
</script>
<style lang="less" scoped>
.form-btns {
  text-align: center;
}
.tables {
  padding-left: 15px;
  .table-item {
    padding: 10px;
  }
  .table-header {
    display: flex;
    margin-bottom: 8px;
  }
  .header-text {
    position: relative;
    bottom: -9px;
    flex: 1;
    font-weight: bold;
  }
  .header-btns {
    text-align: right;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/formTemplate.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,664 @@
let options1 = [
    {
        "id": 1,
        "name": "输入框",
        "type": "text",
        "value": "",
        "icon": "el-icon-document",
        "field": "field1630258884671",
        "width": 20,
        "readonly": false,
        "required": false
    },
    {
        "id": 3,
        "name": "日期",
        "type": "date",
        "icon": "el-icon-date",
        "value": null,
        "field": "field1630258891760",
        "width": 20,
        "readonly": false,
        "required": false
    },
    {
        "id": 7,
        "name": "下拉框",
        "value": null,
        "key": "",
        "data": [
            {
                "label": "请设置数据源",
                "value": "请设置数据源"
            }
        ],
        "type": "select",
        "icon": "el-icon-arrow-down",
        "field": "field1630258904862",
        "width": 30,
        "readonly": false,
        "required": false
    },
    {
        "id": 8,
        "name": "下拉多选",
        "type": "selectList",
        "key": "",
        "values": [],
        "data": [
            {
                "label": "请设置数据源",
                "value": "请设置数据源"
            }
        ],
        "icon": "el-icon-arrow-down",
        "field": "field1630258924442",
        "width": 30,
        "readonly": false,
        "required": false
    },
    {
        "id": 81,
        "name": "级联",
        "type": "cascader",
        "icon": "el-icon-share",
        "values": [],
        "key": "",
        "data": [
            {
                "value": "请配置数据源",
                "label": "请配置数据源",
                "children": [
                    {
                        "value": "具体",
                        "label": "菜单:下拉框绑定设置"
                    },
                    {
                        "value": "color",
                        "label": "可参照字典编号[tree_roles]"
                    }
                ]
            }
        ],
        "field": "field1630259518082",
        "width": 20,
        "readonly": false,
        "required": false
    },
    {
        "id": 6,
        "name": "多选",
        "values": [
            "发货"
        ],
        "type": "checkbox",
        "key": "ordertype",
        "data": [
            {
                "key": "1",
                "value": "发货"
            },
            {
                "key": "2",
                "value": "退货"
            },
            {
                "key": "3",
                "value": "返单"
            }
        ],
        "icon": "el-icon-circle-check",
        "field": "field1630259033241",
        "width": 30,
        "readonly": false,
        "required": false
    },
    {
        "id": 5,
        "name": "单选",
        "type": "radio",
        "icon": "el-icon-aim",
        "value": 0,
        "data": [
            {
                "key": "0",
                "value": "否"
            },
            {
                "key": "2",
                "value": "xx11"
            },
            {
                "key": "1",
                "value": "是"
            }
        ],
        "key": "enable",
        "field": "field1630259538490",
        "width": 30,
        "readonly": false,
        "required": false,
        "values": [
            "否"
        ]
    },
    {
        "id": 4,
        "name": "switch",
        "type": "switch",
        "icon": "el-icon-turn-off",
        "value": 0,
        "field": "field1630259172794",
        "width": 20,
        "readonly": false,
        "required": false
    },
    {
        "id": 12,
        "name": "分段信息",
        "type": "line",
        "icon": "el-icon-guide",
        "field": "field1630259600186",
        "width": 100,
        "readonly": false,
        "required": false
    },
    {
        "id": 9,
        "name": "图片",
        "type": "img",
        "url": "api/SellOrder/upload",
        "maxSize": 3,
        "fileInfo": [],
        "multiple": false,
        "autoUpload": false,
        "maxFile": 5,
        "icon": "el-icon-picture-outline",
        "field": "field1630259295154",
        "width": 100,
        "readonly": false,
        "required": false
    },
    {
        "id": 10,
        "name": "excel",
        "url": "api/SellOrder/upload",
        "maxSize": 3,
        "multiple": false,
        "autoUpload": true,
        "maxFile": 5,
        "fileInfo": [],
        "type": "excel",
        "icon": "el-icon-upload",
        "field": "field1630259610476",
        "width": 100,
        "readonly": false,
        "required": false
    },
    {
        "id": 5,
        "name": "单选",
        "type": "radio",
        "icon": "el-icon-aim",
        "value": 0,
        "data": [
            {
                "key": "0",
                "value": "审核中"
            },
            {
                "key": "1",
                "value": "审核通过"
            },
            {
                "key": "2",
                "value": "审核未通过"
            }
        ],
        "key": "audit",
        "field": "field1630258969346",
        "width": 40,
        "readonly": false,
        "required": false,
        "values": [
            "审核中"
        ]
    }
];
let options2=[
    {
        "id": 1,
        "name": "输入框",
        "type": "text",
        "value": "",
        "icon": "el-icon-document",
        "field": "field1630258884671",
        "width": 20,
        "readonly": false,
        "required": false
    },
    {
        "id": 3,
        "name": "日期",
        "type": "date",
        "icon": "el-icon-date",
        "value": null,
        "field": "field1630258891760",
        "width": 20,
        "readonly": false,
        "required": false
    },
    {
        "id": 7,
        "name": "下拉框",
        "value": null,
        "key": "",
        "data": [
            {
                "label": "请设置数据源",
                "value": "请设置数据源"
            }
        ],
        "type": "select",
        "icon": "el-icon-arrow-down",
        "field": "field1630258904862",
        "width": 30,
        "readonly": false,
        "required": false
    },
    {
        "id": 8,
        "name": "下拉多选",
        "type": "selectList",
        "key": "",
        "values": [],
        "data": [
            {
                "label": "请设置数据源",
                "value": "请设置数据源"
            }
        ],
        "icon": "el-icon-arrow-down",
        "field": "field1630258924442",
        "width": 30,
        "readonly": false,
        "required": false
    },
    {
        "id": 2,
        "name": "textarea",
        "type": "textarea",
        "value": "",
        "icon": "el-icon-document-copy",
        "field": "field1630260207393",
        "width": 100,
        "readonly": false,
        "required": false
    },
    {
        "id": 13,
        "name": "表格",
        "type": "table",
        "tabs": true,
        "columns": [
            {
                "title": "运单号",
                "field": "TranNo",
                "show": true,
                "required": false,
                "edit": true,
                "dataType": null,
                "dataSource": null,
                "width": "140",
                "orderNo": null,
                "elementIndex": 0
            },
            {
                "title": "销售订单号",
                "field": "SellNo",
                "show": true,
                "required": false,
                "edit": true,
                "dataType": null,
                "dataSource": null,
                "width": "140",
                "orderNo": null,
                "elementIndex": 1
            },
            {
                "title": "订单类型",
                "field": "OrderType",
                "show": true,
                "required": false,
                "edit": true,
                "dataType": null,
                "dataSource": "ordertype",
                "width": 120,
                "orderNo": null,
                "elementIndex": 2,
                "editType": "select"
            },
            {
                "title": "销售数量",
                "field": "Qty",
                "show": true,
                "required": false,
                "edit": true,
                "dataType": null,
                "dataSource": null,
                "width": "80",
                "orderNo": null,
                "elementIndex": 3
            },
            {
                "field": "CreateDate",
                "elementIndex": 4,
                "show": 1,
                "required": 0,
                "edit": 0,
                "title": "订单时间",
                "dataType": "date",
                "width": "100"
            }
        ],
        "tableData": [
            {
                "field1": "field1",
                "field2": "field2",
                "field3": "field3",
                "field4": "field4"
            },
            {
                "field1": "field1",
                "field2": "field2",
                "field3": "field3",
                "field4": "field4"
            },
            {
                "field1": "field1",
                "field2": "field2",
                "field3": "field3",
                "field4": "field4"
            }
        ],
        "height": 200,
        "icon": "el-icon-c-scale-to-original",
        "url": "api/SellOrder/getPageData",
        "index": false,
        "columnIndex": false,
        "ck": true,
        "buttons": [
            {
                "name": "添加行",
                "ck": false,
                "icon": "el-icon-plus",
                "value": "add"
            },
            {
                "name": "删除行",
                "ck": false,
                "icon": "el-icon-delete",
                "value": "del"
            },
            {
                "name": "刷新",
                "ck": false,
                "icon": "el-icon-refresh-right",
                "value": "ref"
            }
        ],
        "field": "field1630260242867",
        "width": 100,
        "readonly": false,
        "required": false,
        "pagination": false
    },
    {
        "id": 13,
        "name": "表格",
        "type": "table",
        "tabs": true,
        "columns": [
            {
                "title": "字段1",
                "field": "field1",
                "show": true,
                "required": false,
                "edit": false,
                "dataType": null,
                "dataSource": null,
                "width": 120,
                "orderNo": null
            },
            {
                "title": "字段2",
                "field": "field2",
                "show": true,
                "required": false,
                "edit": false,
                "dataType": null,
                "dataSource": null,
                "width": 120,
                "orderNo": null
            },
            {
                "title": "字段3",
                "field": "field3",
                "show": true,
                "required": false,
                "edit": false,
                "dataType": null,
                "dataSource": null,
                "width": 120,
                "orderNo": null
            },
            {
                "title": "字段4",
                "field": "field4",
                "show": true,
                "required": false,
                "edit": false,
                "dataType": null,
                "dataSource": null,
                "width": 120,
                "orderNo": null
            }
        ],
        "tableData": [
            {
                "field1": "field1",
                "field2": "field2",
                "field3": "field3",
                "field4": "field4"
            },
            {
                "field1": "field1",
                "field2": "field2",
                "field3": "field3",
                "field4": "field4"
            },
            {
                "field1": "field1",
                "field2": "field2",
                "field3": "field3",
                "field4": "field4"
            }
        ],
        "height": 200,
        "icon": "el-icon-c-scale-to-original",
        "url": null,
        "index": false,
        "columnIndex": false,
        "ck": true,
        "buttons": [
            {
                "name": "添加行",
                "ck": false,
                "icon": "el-icon-plus",
                "value": "add"
            },
            {
                "name": "删除行",
                "ck": false,
                "icon": "el-icon-delete",
                "value": "del"
            },
            {
                "name": "刷新",
                "ck": false,
                "icon": "el-icon-refresh-right",
                "value": "ref"
            }
        ],
        "field": "field1630260481283",
        "width": 100,
        "readonly": false,
        "required": false,
        "pagination": true
    }
]
let options3=[
    {
        "id": 1,
        "name": "输入框",
        "type": "text",
        "value": "",
        "icon": "el-icon-document",
        "field": "field1630258884671",
        "width": 20,
        "readonly": false,
        "required": false
    },
    {
        "id": 3,
        "name": "日期",
        "type": "date",
        "icon": "el-icon-date",
        "value": null,
        "field": "field1630258891760",
        "width": 20,
        "readonly": false,
        "required": false
    },
    {
        "id": 7,
        "name": "下拉框",
        "value": null,
        "key": "",
        "data": [
            {
                "label": "请设置数据源",
                "value": "请设置数据源"
            }
        ],
        "type": "select",
        "icon": "el-icon-arrow-down",
        "field": "field1630258904862",
        "width": 30,
        "readonly": false,
        "required": false
    },
    {
        "id": 8,
        "name": "下拉多选",
        "type": "selectList",
        "key": "",
        "values": [],
        "data": [
            {
                "label": "请设置数据源",
                "value": "请设置数据源"
            }
        ],
        "icon": "el-icon-arrow-down",
        "field": "field1630258924442",
        "width": 30,
        "readonly": false,
        "required": false
    },
    {
        "id": 5,
        "name": "单选",
        "type": "radio",
        "icon": "el-icon-aim",
        "value": 0,
        "data": [
            {
                "key": "0",
                "value": "否"
            },
            {
                "key": "2",
                "value": "xx11"
            },
            {
                "key": "1",
                "value": "是"
            }
        ],
        "key": "enable",
        "field": "field1630260669595",
        "width": 50,
        "readonly": false,
        "required": false,
        "values": [
            "否"
        ]
    },
    {
        "id": 6,
        "name": "多选",
        "values": [
            "否"
        ],
        "type": "checkbox",
        "key": "enable",
        "data": [
            {
                "key": "0",
                "value": "否"
            },
            {
                "key": "2",
                "value": "xx11"
            },
            {
                "key": "1",
                "value": "是"
            }
        ],
        "icon": "el-icon-circle-check",
        "field": "field1630260695322",
        "width": 50,
        "readonly": false,
        "required": false
    },
    {
        "id": 2,
        "name": "textarea",
        "type": "textarea",
        "value": "",
        "icon": "el-icon-document-copy",
        "field": "field1630260207393",
        "width": 100,
        "readonly": false,
        "required": false
    },
    {
        "id": 13,
        "name": "编辑器",
        "type": "editor",
        "value": "",
        "url": "",
        "height": 200,
        "icon": "el-icon-notebook-2",
        "field": "field1630260646842",
        "width": 100,
        "readonly": false,
        "required": false
    }
]
export { options1, options2,options3 }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
import VolFormDraggable from './VolFormDraggable'
 export default VolFormDraggable;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/options.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,226 @@
const components = [
    {
        id: 1,
        name: "输入框",
        type: "text",
        value: "",
        icon: "el-icon-document",
    },
    {
        id: 2,
        name: "textarea",
        type: "textarea",
        value: "",
        icon: "el-icon-document-copy",
    },
    {
        id: 3,
        name: "日期",
        type: "date",
        icon: "el-icon-date",
        value: null,
    },
    {
        id: 4,
        name: "switch",
        type: "switch",
        icon: "el-icon-turn-off",
        value: 0,
    },
    { id: 5, name: "单选", type: "radio", icon: "el-icon-aim", value: 0, data: [{ label: "0", value: "请设置数据源1" }, { label: "1", value: "请设置数据源2" }], key: "" },
    {
        id: 6,
        name: "多选",
        values: [],
        type: "checkbox",
        key: "",
        data: [{ label: "请设置数据源", value: "请设置数据源" }],
        icon: "el-icon-circle-check",
    },
    {
        id: 7,
        name: "下拉框",
        value: null,
        key: "",
        data: [{ label: "请设置数据源", value: "请设置数据源" }],
        type: "select",
        icon: "el-icon-arrow-down",
    },
    {
        id: 8,
        name: "下拉框多选",
        type: "selectList",
        key: "",
        values: [],
        data: [{ label: "请设置数据源", value: "请设置数据源" }],
        icon: "el-icon-arrow-down",
    },
    {
        id: 81,
        name: "级联",
        type: "cascader",
        icon: "el-icon-share",
        values: [],
        key: "",
        data: [
            {
                value: "请配置数据源",
                label: "请配置数据源",
                children: [
                    {
                        value: "具体",
                        label: "菜单:下拉框绑定设置",
                    },
                    {
                        value: "color",
                        label: "可参照字典编号[tree_roles]",
                    }
                ],
            },
        ],
    },
    {
        id: 9,
        name: "图片上传",
        type: "img",
        url: "",
        maxSize: 3,
        fileInfo: [],
        multiple: false,
        autoUpload: false,
        maxFile: 5,
        icon: "el-icon-picture-outline",
    },
    {
        id: 10,
        name: "excel上传",
        url: "",
        maxSize: 3,
        multiple: false,
        autoUpload: false,
        maxFile: 5, //最多可上传5个文件
        fileInfo: [],
        type: "excel",
        icon: "el-icon-upload",
    },
    {
        id: 11,
        name: "文件上传",
        type: "file",
        url: "",
        maxSize: 3,
        multiple: false,
        autoUpload: false,
        maxFile: 5,
        fileInfo: [],
        icon: "el-icon-folder-opened",
    },
    {
        id: 12,
        name: "分段信息",
        type: "line",
        icon: "el-icon-guide",
    },
    {
        id: 13,
        name: "编辑器",
        type: "editor",
        value: "",
        url: "",
        height: 200,
        icon: "el-icon-notebook-2",
    },
    {
        id: 13,
        name: "弹出框",
        type: "box",
        value: "",
        url: "",
        height: 250,
        icon: "el-icon-notebook-2",
    },
    {
        id: 13,
        name: "表格",
        type: "table",
        tabs: false,
        columns: [
            { title: "字段1", field: "field1", show: true, required: false, edit: false, dataType: null, dataSource: null, width: 120, orderNo: null },
            { title: "字段2", field: "field2", show: true, required: false, edit: false, dataType: null, dataSource: null, width: 120, orderNo: null },
            { title: "字段3", field: "field3", show: true, required: false, edit: false, dataType: null, dataSource: null, width: 120, orderNo: null },
            { title: "字段4", field: "field4", show: true, required: false, edit: false, dataType: null, dataSource: null, width: 120, orderNo: null },
            // { title: "字段5", field: "Field5", width: 120 },
        ],
        tableData: [
            {
                field1: "field1",
                field2: "field2",
                field3: "field3",
                field4: "field4",
            },
            {
                field1: "field1",
                field2: "field2",
                field3: "field3",
                field4: "field4",
            },
            {
                field1: "field1",
                field2: "field2",
                field3: "field3",
                field4: "field4",
            },
        ],
        height: 150,
        icon: "el-icon-c-scale-to-original",
        url: null,
        index: false, //item.index,
        height: 200,
        index: false,
        columnIndex: false,
        ck: true,
        buttons: [
            { name: '添加行', ck: false, icon: 'el-icon-plus',value:'add' },
        { name: '删除行', ck: false, icon: 'el-icon-delete',value:'del' },
        { name: '刷新', ck: false ,icon:'el-icon-refresh-right',value:'ref'}],
    },
]
const tableOption = [
    { field: 'field', title: '字段', edit: { type: "text", keep: true }, width: 160 },
    { field: 'title', title: '字段中文名', edit: { type: "text", keep: true }, width: 120 },
    { field: 'show', title: '是否显示', edit: { type: "switch", keep: true }, width: 90 },
    {
        field: 'dataType', title: '显示类型', edit: { type: "select", keep: true }, width: 120, bind: {
            key: '', data: [
                { "key": "switch", "value": "单选" },
                { "key": "date", "value": "年月日" },
                { "key": "img", "value": "图片" },
                { "key": "excel", "value": "excel" },
                { "key": "file", "value": "文件" }
            ]
        }
    },
    { field: 'required', title: '是否必填', edit: { type: "switch", keep: true }, width: 90 },
    { field: 'edit', title: '是否可编辑', edit: { type: "switch", keep: true }, width: 90 },
    {
        field: 'editType', title: '编辑类型', edit: { type: "select", keep: true, }, width: 120, bind: {
            key: '', data: [{ "key": "text", "value": "输入框" },
            { "key": "switch", "value": "单选" },
            { "key": "select", "value": "下拉框" },
            { "key": "selectList", "value": "下拉框多选" },
            { "key": "date", "value": "日期" },
            { "key": "datetime", "value": "日期时分秒" },
            { "key": "checkbox", "value": "复选框多选" },
            { "key": "mail", "value": "邮箱地址" },
            { "key": "number", "value": "数字" },
            { "key": "decimal", "value": "小数" },
            { "key": "phone", "value": "手机号" },
            ]
        }
    },
    { field: 'dataSource', title: '数据源', edit: { type: "select", keep: true, data: [] }, bind: { key: '', data: [] }, width: 120 },
    { field: 'width', title: '列宽度', edit: { type: "text", keep: true }, width: 80 },
    { field: 'orderNo', title: '列显示顺序', edit: { type: "text", keep: true }, width: 100 }
];
export { components, tableOption }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolFormDraggable/templateCode.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
var code = `<template>
<div style="padding: 15px 20px 15px 5px">
  <div class="pre-text">{{ text }}</div>
  <vol-form ref="form"
            :labelWidth="80"
            :load-key="false"
            :formFields="fields"
            :formRules="formOptions">
  </vol-form>
 {#tables}
 {#tabs}
  <div class="form-btns">
    <el-button type="primary"
               @click="submit"
               icon="el-icon-check"
               size="mini">提交</el-button>
    <el-button type="primary"
               @click="reset"
               plain
               icon="el-icon-refresh-right"
               size="mini">重置</el-button>
  </div>
</div>
</template>
<script>
// ä½¿ç”¨æ–¹å¼ï¼š
// 1、新建一个vue页面,把此页面内容复制进去
// 2、router->index.js配置路由,页面上输入地址即可看到数据(也可以把菜单配置上)
// 3、或者参照表单设计页面做动态页面
//**表单设计器的table下载还在开发中
{import_VolTable}
import VolForm from '@/components/basic/VolForm'
export default {
    components: {"vol-form": VolForm,{component_table}},
    data () {
        return {
            text: "",
            tabsModel: "0",
            fields: {#fields},
            formOptions: [{#formOptions}],
            tables: [{#tableOptions}],
            tabs: [{#tabsOptions}]
        };
    },
    created () {
    },
    methods: {{table_ms}
        submit () {
            this.$Message.success("submit")
            return;
            this.http.post("url",this.fields,true).then(result=>{
            })
        },
        reset () {
            this.$refs.form.reset();
            this.$Message.success("表单已重置")
        },
        download () {
            this.$Message.info("111")
        }
    }
};
VolForm;
</script>
<style lang="less" scoped>
.form-btns {
text-align: center;
}
.tables {
padding-left: 15px;
.table-item {
  padding: 10px;
}
.table-header {
  display: flex;
  margin-bottom: 8px;
}
.header-text {
  position: relative;
  bottom: -9px;
  flex: 1;
  font-weight: bold;
}
.header-btns {
  text-align: right;
}
}
</style>`
export default code
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolHeader.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
<template>
  <div class="v-header">
    <div class="v-left-text">
      <!-- <i size="20" :class="icon" class="h-icon"/> -->
      <span>{{ title || text }}</span>
    </div>
    <div class="content">
      <slot name="content"></slot>
    </div>
    <div class="v-right-content">
      <slot></slot>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    icon: {
      type: String,
      default: ''
    },
    title: {
      type: String,
      default: ''
    },
    text: {
      type: String,
      default: '未定义名称'
    }
  }
};
</script>
<style lang="less" scoped>
.v-header {
  display: flex;
  border-bottom: 1px solid #dcdee2;
  .v-left-text {
    margin-top: 3px;
    padding-bottom: 6px;
    font-weight: bold;
    font-size: 15px;
    color: #484848;
    white-space: nowrap;
    border-bottom: 2px solid #676767;
    margin-bottom: -1px;
    letter-spacing: 1px;
    > span {
      position: relative;
      top: 2px;
    }
  }
  .content {
    line-height: 25px;
    padding-left: 10px;
    padding: 6px 0 0 10px;
  }
  .v-right-content {
    flex: 1;
    text-align: right;
  }
  .h-icon {
    position: relative;
    top: 2px;
    margin-right: 3px;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolTable.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1874 @@
<template>
  <!-- 2021.11.18移除voltable方法@cell-mouse-leave="rowEndEdit" -->
  <div
    class="vol-table"
    :class="[
      textInline ? 'text-inline' : '',
      fxRight ? 'fx-right' : '',
      isChrome ? 'chrome' : '',
    ]"
  >
    <div class="mask" v-show="loading"></div>
    <div class="message" v-show="loading">加载中.....</div>
    <el-table
      :show-summary="summary"
      :summary-method="getSummaryData"
      :row-key="rowKey"
      :key="randomTableKey"
      lazy
      stripe
      :load="loadTreeChildren"
      @select="userSelect"
      @select-all="userSelect"
      @selection-change="selectionChange"
      @row-dblclick="rowDbClick"
      @row-click="rowClick"
      @header-click="headerClick"
      :highlight-current-row="highlightCurrentRow"
      ref="table"
      class="v-table"
      @sort-change="sortChange"
      tooltip-effect="dark"
      :height="realHeight"
      :max-height="realMaxHeight"
      :data="url ? rowData : tableData"
      border
      :row-class-name="initIndex"
      :cell-style="getCellStyle"
      style="width: 100%"
      :scrollbar-always-on="true"
    >
      <el-table-column
        v-if="ck"
        type="selection"
        :fixed="fixed"
        :selectable="selectable"
        width="55"
      ></el-table-column>
      <el-table-column
        v-if="columnIndex"
        type="index"
        :fixed="fixed"
        label="序号"
        width="55"
      ></el-table-column>
      <!-- 2020.10.10移除table第一行强制排序 -->
      <el-table-column
        v-for="(column, cindex) in filterColumns"
        :prop="column.field"
        :label="column.title"
        :min-width="column.width"
        :formatter="formatter"
        :fixed="column.fixed"
        :key="column.field + cindex"
        :align="column.align"
        :sortable="column.sort ? 'custom' : false"
        :show-overflow-tooltip="true"
      >
        <template #header>
          <span
            v-if="(column.require || column.required) && column.edit"
            class="column-required"
            >*</span
          >{{ column.title }}
        </template>
        <template #default="scope">
          <!-- 2022.01.08增加多表头,现在只支持常用功能渲染,不支持编辑功能(涉及到组件重写) -->
          <el-table-column
            style="border: none"
            v-for="columnChildren in filterChildrenColumn(column.children)"
            :key="columnChildren.field"
            :min-width="columnChildren.width"
            :class-name="columnChildren.class"
            :prop="columnChildren.field"
            :align="columnChildren.align"
            :label="columnChildren.title"
          >
            <template #default="scopeChildren">
              <a
                href="javascript:void(0)"
                style="text-decoration: none"
                @click="link(scopeChildren.row, columnChildren, $event)"
                v-if="column.link"
                v-text="scopeChildren.row[columnChildren.field]"
              ></a>
              <div
                v-else-if="columnChildren.formatter"
                @click="
                  columnChildren.click &&
                    columnChildren.click(
                      scopeChildren.row,
                      columnChildren,
                      scopeChildren.$index
                    )
                "
                v-html="
                  columnChildren.formatter(
                    scopeChildren.row,
                    columnChildren,
                    scopeChildren.$index
                  )
                "
              ></div>
              <div v-else-if="column.bind">
                {{ formatter(scopeChildren.row, columnChildren, true) }}
              </div>
              <span v-else-if="column.type == 'date'">{{
                formatterDate(scopeChildren.row, columnChildren)
              }}</span>
              <template v-else>
                {{ scopeChildren.row[columnChildren.field] }}
              </template>
            </template>
          </el-table-column>
          <!-- 2020.06.18增加render渲染自定义内容 -->
          <table-render
            v-if="column.render && typeof column.render == 'function'"
            :row="scope.row"
            key="rd-01"
            :index="scope.$index"
            :column="column"
            :render="column.render"
          ></table-render>
          <!-- å¯ç”¨åŒå‡»ç¼–辑功能,带编辑功能的不会渲染下拉框文本背景颜色 -->
          <!-- @click="rowBeginEdit(scope.$index,cindex)" -->
          <!-- 2021.09.21增加编辑时对readonly属性判断 -->
          <template
            v-else-if="
              column.edit &&
              !column.readonly &&
              ['file', 'img', 'excel'].indexOf(column.edit.type) != -1
            "
          >
            <div style="display: flex; align-items: center" @click.stop>
              <i
                style="
                  padding: 3px;
                  margin-right: 10px;
                  color: #8f9293;
                  cursor: pointer;
                "
                @click="showUpload(scope.row, column)"
                class="el-icon-upload"
              ></i>
              <img
                v-show="column.edit.type == 'img'"
                v-for="(file, imgIndex) in getFilePath(
                  scope.row[column.field],
                  column
                )"
                :key="imgIndex"
                :onerror="defaultImg"
                @click="viewImg(scope.row, column, file.path, $event)"
                class="table-img"
                :src="file.path"
              />
              <a
                style="margin-right: 8px"
                v-show="column.edit.type != 'img'"
                class="t-file"
                v-for="(file, fIndex) in getFilePath(
                  scope.row[column.field],
                  column
                )"
                :key="fIndex"
                @click="dowloadFile(file)"
                >{{ file.name }}</a
              >
            </div>
          </template>
          <div
            v-else-if="
              column.edit &&
              !column.readonly &&
              (column.edit.keep || edit.rowIndex == scope.$index)
            "
            class="edit-el"
          >
            <div @click.stop class="e-item">
              <div>
                <!-- 2020.07.24增加日期onChange事件 -->
                <el-date-picker
                  clearable
                  size="default"
                  style="width: 100%"
                  v-if="['date', 'datetime'].indexOf(column.edit.type) != -1"
                  v-model="scope.row[column.field]"
                  @change="
                    (val) => {
                      column.onChange &&
                        column.onChange(scope.row, column, val);
                    }
                  "
                  :type="column.edit.type"
                  :placeholder="column.placeholder || column.title"
                  :disabledDate="(val) => getDateOptions(val, column)"
                  :value-format="getDateFormat(column)"
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                </el-date-picker>
                <el-time-picker
                  clearable
                  size="default"
                  style="width: 100%"
                  v-else-if="column.edit.type == 'time'"
                  v-model="scope.row[column.field]"
                  @change="
                    (val) => {
                      column.onChange &&
                        column.onChange(scope.row, column, val);
                    }
                  "
                  :placeholder="column.placeholder || column.title"
                  :value-format="column.format || 'HH:mm:ss'"
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                </el-time-picker>
                <el-switch
                  v-else-if="column.edit.type == 'switch'"
                  v-model="scope.row[column.field]"
                  active-color="#0f84ff"
                  inactive-color="rgb(194 194 194)"
                  @change="
                    (val) => {
                      switchChange(val, scope.row, column);
                    }
                  "
                  :active-value="
                    typeof scope.row[column.field] == 'boolean'
                      ? true
                      : typeof scope.row[column.field] == 'string'
                      ? '1'
                      : 1
                  "
                  :inactive-value="
                    typeof scope.row[column.field] == 'boolean'
                      ? false
                      : typeof scope.row[column.field] == 'string'
                      ? '0'
                      : 0
                  "
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                </el-switch>
                <template
                  v-else-if="
                    ['select', 'selectList'].indexOf(column.edit.type) != -1
                  "
                >
                  <el-select-v2
                    style="width: 100%"
                    :size="size"
                    v-if="column.bind.data.length >= select2Count"
                    v-model="scope.row[column.field]"
                    filterable
                    :multiple="column.edit.type == 'select' ? false : true"
                    :placeholder="column.placeholder || column.title"
                    :autocomplete="column.autocomplete"
                    :options="column.bind.data"
                    @change="
                      column.onChange && column.onChange(scope.row, column)
                    "
                    clearable
                    :disabled="initColumnDisabled(scope.row, column)"
                  >
                    <template #default="{ item }">
                      {{ item.label }}
                    </template>
                  </el-select-v2>
                  <el-select
                    size="default"
                    style="width: 100%"
                    v-else
                    v-model="scope.row[column.field]"
                    :filterable="
                      column.filter || column.bind.data.length > 10
                        ? true
                        : false
                    "
                    :multiple="column.edit.type == 'select'"
                    :placeholder="column.placeholder || column.title"
                    :autocomplete="column.autocomplete"
                    @change="
                      column.onChange && column.onChange(scope.row, column)
                    "
                    clearable
                    :disabled="initColumnDisabled(scope.row, column)"
                  >
                    <el-option
                      v-for="item in column.bind.data"
                      :key="item.key"
                      v-show="!item.hidden"
                      :disabled="item.disabled"
                      :label="item.value"
                      :value="item.key"
                      >{{ item.value }}
                    </el-option>
                  </el-select>
                </template>
                <el-input
                  v-else-if="column.edit.type == 'textarea'"
                  type="textarea"
                  :placeholder="column.placeholder || column.title"
                  v-model="scope.row[column.field]"
                  :disabled="initColumnDisabled(scope.row, column)"
                >
                </el-input>
                <input
                  class="table-input"
                  v-else-if="!column.summary && !column.onKeyPress"
                  v-model.lazy="scope.row[column.field]"
                  :disabled="initColumnDisabled(scope.row, column)"
                />
                <el-input
                  v-else
                  @change="inputKeyPress(scope.row, column, $event)"
                  @input="inputKeyPress(scope.row, column, $event)"
                  @keyup.enter="inputKeyPress(scope.row, column, $event)"
                  size="default"
                  v-model="scope.row[column.field]"
                  :placeholder="column.placeholder || column.title"
                  :disabled="initColumnDisabled(scope.row, column)"
                ></el-input>
              </div>
              <div
                class="extra"
                v-if="column.extra && edit.rowIndex == scope.$index"
              >
                <a
                  :style="column.extra.style"
                  style="text-decoration: none"
                  @click="extraClick(scope.row, column)"
                >
                  <i v-if="column.extra.icon" :class="[column.extra.icon]" />
                  {{ column.extra.text }}
                </a>
              </div>
            </div>
          </div>
          <!--没有编辑功能的直接渲染标签-->
          <template v-else>
            <a
              href="javascript:void(0)"
              style="text-decoration: none"
              @click="link(scope.row, column, $event)"
              v-if="column.link"
              v-text="scope.row[column.field]"
            ></a>
            <img
              v-else-if="column.type == 'img'"
              v-for="(file, imgIndex) in getFilePath(
                scope.row[column.field],
                column
              )"
              :key="imgIndex"
              :onerror="defaultImg"
              @click="viewImg(scope.row, column, file.path, $event)"
              class="table-img"
              :src="file.path"
            />
            <a
              style="margin-right: 8px"
              v-else-if="column.type == 'file' || column.type == 'excel'"
              class="t-file"
              v-for="(file, fIndex) in getFilePath(
                scope.row[column.field],
                column
              )"
              :key="fIndex"
              @click="dowloadFile(file)"
              >{{ file.name }}</a
            >
            <span v-else-if="column.type == 'date'">{{
              formatterDate(scope.row, column)
            }}</span>
            <div
              v-else-if="column.formatter"
              @click="formatterClick(scope.row, column, $event)"
              v-html="column.formatter(scope.row, column)"
            ></div>
            <!-- 2021.11.18修复table数据源设置为normal后点击行$event缺失的问题 -->
            <div
              v-else-if="column.bind && (column.normal || column.edit)"
              @click="formatterClick(scope.row, column, $event)"
              :style="column.getStyle && column.getStyle(scope.row, column)"
            >
              {{ formatter(scope.row, column, true) }}
            </div>
            <div
              v-else-if="column.click && !column.bind"
              @click="formatterClick(scope.row, column)"
            >
              {{ scope.row[column.field] }}
            </div>
            <div
              @click="
                () => {
                  column.click && formatterClick(scope.row, column);
                }
              "
              v-else-if="column.bind"
            >
              <el-tag
                v-if="useTag"
                :class="[isEmptyTag(scope.row, column)]"
                :type="getColor(scope.row, column)"
                :effect="column.effect"
                >{{ formatter(scope.row, column, true) }}</el-tag
              >
              <template v-else>{{
                formatter(scope.row, column, true)
              }}</template>
            </div>
            <span v-else>{{ formatter(scope.row, column, true) }}</span>
          </template>
        </template>
      </el-table-column>
    </el-table>
    <template v-if="!paginationHide">
      <div class="block pagination" key="pagination-01" style="display: flex">
        <div style="flex: 1"></div>
        <el-pagination
          key="pagination-02"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="paginations.page"
          :page-sizes="paginations.sizes"
          :page-size="paginations.size"
          layout="total, sizes, prev, pager, next, jumper"
          :total="paginations.total"
        ></el-pagination>
      </div>
    </template>
  </div>
  <VolBox
    v-model="uploadModel"
    title="上传"
    :height="228"
    :width="500"
    :padding="15"
    lazy
  >
    <!-- ä¸Šä¼ å›¾ç‰‡ã€excel或其他文件、文件数量、大小限制都可以,参照volupload组件api -->
    <div style="height: 200px; display: flex; align-items: center">
      <VolUpload
        style="text-align: center"
        :autoUpload="currentColumn.edit.autoUpload"
        :multiple="currentColumn.edit.multiple"
        :url="uploadUrl"
        :max-file="currentColumn.edit.maxFile"
        :img="currentColumn.edit.type == 'img'"
        :excel="currentColumn.edit.type == 'excel'"
        :fileTypes="
          currentColumn.edit.fileTypes ? currentColumn.edit.fileTypes : []
        "
        :fileInfo="fileInfo"
        :upload-after="uploadAfter"
      >
        <div>{{ currentColumn.message }}</div>
      </VolUpload>
    </div>
    <template #footer>
      <div style="text-align: center">
        <el-button type="default" size="small" @click="uploadModel = false"
          >关闭</el-button
        >
        <el-button type="primary" size="small" @click="saveUpload"
          >保存</el-button
        >
      </div>
    </template>
  </VolBox>
</template>
<script>
import VolTableRender from "./VolTable/VolTableRender";
let _errMsg;
import { defineComponent, defineAsyncComponent } from "vue";
export default defineComponent({
  //https://github.com/element-plus/element-plus/issues/1483
  //没有原先的selection属性了,看issue上使用select/selectall获取
  //监听数组长度,如果删除了数据,现在只能被迫清除所有选中的行
  watch: {
    "tableData.length": {
      handler(newLen, oldLen) {
        this.watchRowSelectChange(newLen, oldLen);
      },
    },
    "rowData.length": {
      handler(newLen, oldLen) {
        this.watchRowSelectChange(newLen, oldLen);
      },
    },
  },
  components: {
    "table-render": VolTableRender,
    VolUpload: defineAsyncComponent(() =>
      import("@/components/basic/VolUpload.vue")
    ),
    VolBox: defineAsyncComponent(() => import("@/components/basic/VolBox.vue")),
  },
  props: {
    rowKey: {
      // æ ‘形结构的主键字段,如果设置值默认会开启树形table;注意rowKey字段的值必须是唯一(2021.05.02)
      typeof: String,
      default: undefined,
    },
    loadTreeChildren: {
      // æ ‘形结构加载子节点
      type: Function,
      default: (tree, treeNode, resolve) => {
        return resolve([]);
      },
    },
    textInline: {
      // è¡¨æ ¼å†…容超出后是否换行显示(2020.01.16)
      type: Boolean,
      default: true,
    },
    tableData: {
      // è¡¨æ•°æ®æº,配置了url就不用传这个参数了
      type: Array,
      default: () => {
        return [];
      },
    },
    columns: {
      type: Array,
      default: [],
    },
    height: {
      type: Number,
      default: 0,
    },
    maxHeight: {
      type: Number,
      default: 0,
    },
    linkView: {
      type: Function,
      default: function () {
        return 1;
      },
    },
    pagination: {
      type: Object,
      default: function () {
        return { total: 0, size: 30, sortName: "" };
      },
    },
    url: {
      type: String,
      default: "",
    },
    paginationHide: {
      type: Boolean,
      default: true,
    },
    color: {
      type: Boolean,
      default: true,
    },
    index: {
      // æ˜¯å¦åˆ›å»ºç´¢å¼•号,如果需要表格编辑功能,这里需要设置为true
      type: Boolean,
      default: false,
    },
    allowEmpty: {
      // è¡¨æ ¼æ•°æ®ä¸ºç©ºæ—¶æ˜¯å¦é»˜è®¤ä¸º--
      type: Boolean,
      default: true,
    },
    defaultLoadPage: {
      // ä¼ å…¥äº†url,是否默认加载表格数据
      type: Boolean,
      default: true,
    },
    loadKey: {
      // æ˜¯å¦è‡ªåŠ¨ä»ŽåŽå°åŠ è½½æ•°æ®æº
      type: Boolean,
      default: true,
    },
    single: {
      type: Boolean, // æ˜¯å¦å•选
      default: false,
    },
    doubleEdit: {
      type: Boolean, // æ˜¯å¦åŒå‡»å¯ç”¨ç¼–辑功能
      default: true,
    },
    beginEdit: {
      // ç¼–辑开始
      type: Function,
      default: function (row, column, index) {
        return true;
      },
    },
    endEditBefore: {
      // ç»“束编辑前
      type: Function,
      default: function (row, column, index) {
        return true;
      },
    },
    endEditAfter: {
      // ç»“束编辑前
      type: Function,
      default: function (row, column, index) {
        return true;
      },
    },
    ck: {
      // æ˜¯å¦æ˜¾ç¤ºcheckbox
      type: Boolean,
      default: true,
    },
    columnIndex: {
      // æ˜¯å¦æ˜¾ç¤ºè¡Œå·(2020..11.1)
      type: Boolean,
      default: true,
    },
    highlightCurrentRow: {
      //增加选中行高亮显示(2022.10.07)
      type: Boolean,
      default: true,
    },
    select2Count: {
      //超出数量显示select2组件
      type: Number,
      default: 500,
    },
    selectable: {
      type: Function,
      default: (row, index) => {
        return true;
      },
    },
  },
  data() {
    return {
      fixed: false, //是固定行号与checkbox
      clickEdit: true, //2021.07.17设置为点击行结束编辑
      randomTableKey: 1,
      visiblyColumns: [],
      key: "",
      realHeight: 0,
      realMaxHeight: 0,
      enableEdit: false, // æ˜¯å¦å¯è¡¨æ ¼ç”¨ç¼–辑功能
      empty: this.allowEmpty ? "" : "--",
      defaultImg: 'this.src="' + require("@/assets/imgs/error.png") + '"',
      loading: false,
      footer: {},
      total: 0,
      formatConfig: {},
      // defaultColor: "",
      // 2020.09.06调整table列数据源的背景颜色
      colors: ["", "warning", "success", "danger", "info"],
      rule: {
        phone: /^[1][3,4,5,6,7,8,9][0-9]{9}$/,
        decimal: /(^[\-0-9][0-9]*(.[0-9]+)?)$/,
        number: /(^[\-0-9][0-9]*([0-9]+)?)$/,
      },
      columnNames: [],
      rowData: [],
      paginations: {
        sort: "",
        order: "desc",
        Foots: "",
        total: 0,
        // 2020.08.29增加自定义分页条大小
        sizes: [30, 60, 100, 120],
        size: 30, // é»˜è®¤åˆ†é¡µå¤§å°
        Wheres: [],
        page: 1,
        rows: 30,
      },
      errorFiled: "",
      edit: { columnIndex: -1, rowIndex: -1 }, // å½“前双击编辑的行与列坐标
      editStatus: {},
      summary: false, // æ˜¯å¦æ˜¾ç¤ºåˆè®¡
      // ç›®å‰åªæ”¯æŒä»ŽåŽå°è¿”回的summaryData数据
      summaryData: [],
      summaryIndex: {},
      remoteColumns: [], // éœ€è¦æ¯æ¬¡åˆ·æ–°æˆ–分页后从后台加载字典数据源的列配置
      cellStyleColumns: {}, // æœ‰èƒŒæ™¯é¢œè‰²çš„配置
      fxRight: false, //是否有右边固定表头
      selectRows: [], //当前选中的行
      isChrome: false,
      //vol-table带数据源的单元格是否启用tag标签(下拉框等单元格以tag标签显示)
      //2023.04.02更新voltable与main.js
      useTag: true,
      currentRow: {},
      currentColumn: [],
      fileInfo: [],
      uploadUrl: "",
      uploadModel: false,
    };
  },
  created() {
    try {
      this.useTag = this.$global.table.useTag;
    } catch (error) {
      console.log(error.message);
    }
    //2021.06.19判断谷歌内核浏览重新计算table高度
    // if (
    //   navigator.userAgent.indexOf('Chrome') != -1 ||
    //   navigator.userAgent.indexOf('Edge') != -1
    // ) {
    //   this.isChrome = true;
    // }
    this.realHeight = this.getHeight();
    this.realMaxHeight = this.getMaxHeight();
    this.fxRight = this.columns.some((x) => {
      return x.fixed == "right";
    });
    //2021.09.21移除强制固定行号与checkbox列
    if (
      this.columns.some((x) => {
        return x.fixed && x.fixed != "right";
      })
    ) {
      this.fixed = true;
    }
    //2022.04.06优化table合计固定列显示
    // if (
    //   this.columns.some((x) => {
    //     return x.summary;
    //   })
    // ) {
    //   this.columns.forEach((x) => {
    //     if (x.fixed && x.fixed != 'right') {
    //       x.fixed = false;
    //     }
    //   });
    //   this.fixed = false;
    // }
    // ä»ŽåŽå°åŠ ä¸‹æ‹‰æ¡†çš„[是否启用的]数据源
    let keys = [];
    let columnBind = [];
    this.summaryData.push("合计");
    if (this.columnIndex) {
      this.summaryData.push(" ");
    }
    this.columns.forEach((x, _index) => {
      if (x.cellStyle) {
        this.cellStyleColumns[x.field] = x.cellStyle;
      }
      if (!x.hidden) {
        // this.summaryIndex[x.field] = _index;
        // 2020.10.11修复求和列错位的问题
        this.summaryData.push("");
        this.summaryIndex[x.field] = this.summaryData.length - 1;
      }
      // æ±‚å’Œ
      if (x.summary && !this.summary) {
        this.summary = true;
      }
      if (x.bind && x.bind.key && (!x.bind.data || x.bind.data.length == 0)) {
        // å†™å…¥è¿œç¨‹
        if (!x.bind.data) x.bind.data = [];
        if (x.bind.remote) {
          this.remoteColumns.push(x);
        } else if (this.loadKey) {
          keys.push(x.bind.key);
          x.bind.valueTyoe = x.type;
          columnBind.push(x.bind);
        }
      }
    });
    if (keys.length > 0) {
      this.http
        .post("/api/Sys_Dictionary/GetVueDictionary", keys)
        .then((dic) => {
          dic.forEach((x) => {
            if (x.data.length > this.select2Count) {
              x.data.forEach((item) => {
                item.label = item.value;
                item.value = item.key;
              });
            }
            columnBind.forEach((c) => {
              // è½¬æ¢æ•°æ®æºçš„类型与列的类型一致(2020.04.04)
              if (
                c.key == x.dicNo &&
                (c.valueTyoe == "int" || c.valueTyoe == "sbyte")
              ) {
                x.data.forEach((d) => {
                  // 2020.09.01增加对数字类型的二次判断
                  if (!isNaN(d.key)) {
                    d.key = ~~d.key;
                  }
                });
              }
              if (c.key == x.dicNo) c.data.push(...x.data);
            });
          });
        });
    }
    this.paginations.sort = this.pagination.sortName;
    // 2020.08.29增加自定义分页条大小
    Object.assign(this.paginations, this.pagination);
    if (this.pagination.size) {
      this.paginations.rows = this.pagination.size;
    }
    this.enableEdit = this.columns.some((x) => {
      return x.hasOwnProperty("edit");
    });
    let keyColumn = this.columns.find((x) => {
      return x.isKey;
    });
    if (keyColumn) {
      this.key = keyColumn.field;
    }
    this.defaultLoadPage && this.load();
  },
  computed: {
    filterColumns() {
      return this.columns.filter((x, index) => {
        if (!x.field) {
          x.field = x.title + index;
        }
        return !x.hidden;
      });
    },
  },
  methods: {
    watchRowSelectChange(newLen, oldLen) {
      if (newLen < oldLen && this.selectRows.length) {
        this.selectRows = [];
        this.$refs.table.clearSelection();
      }
    },
    switchChange(val, row, column) {
      //这里在初始化的时候也会触发change事件
      if (Object.keys(row).length <= 1) {
        return;
      }
      if (column.onChange) {
        column.onChange(val, row, column);
      }
    },
    inputKeyPress(row, column, $event, $e) {
      column.onKeyPress && column.onKeyPress(row, column, $event);
      this.getInputSummaries(null, null, $event, column);
    },
    extraClick(row, column) {
      column.extra.click &&
        column.extra.click(
          row,
          column,
          this.url ? this.rowData : this.tableData
        );
    },
    headerClick(column, event) {
      if (this.clickEdit && this.edit.rowIndex != -1) {
        if (
          this.rowEndEdit(
            this.url
              ? this.rowData[this.edit.rowIndex]
              : this.tableData[this.edit.rowIndex],
            column
          )
        ) {
          this.edit.rowIndex = -1;
        }
      }
      // this.edit.rowIndex = -1;
    },
    rowDbClick(row, column, event) {
      //2021.05.23增加双击行事件
      this.$emit("rowDbClick", { row, column, event });
    },
    rowClick(row, column, event) {
      //2022.02.20增加点击时表格参数判断
      if (!column) {
        return;
      }
      //正在编辑时,禁止出发rowClick事件
      if (this.edit.rowIndex == -1) {
        this.$emit("rowClick", { row, column, event });
      }
      // ç‚¹å‡»è¡Œäº‹ä»¶(2020.11.07)
      if (!this.doubleEdit) {
        return;
      }
      // ç‚¹å‡»å…¶ä»–行时,如果点击的行与正在编辑的行相同,保持编辑状态
      if (this.clickEdit && this.edit.rowIndex != -1) {
        if (row.elementIndex == this.edit.rowIndex) {
          // ç‚¹å‡»çš„单元格如果不可以编辑,直接结束编辑
          // 2020.10.12修复结束编辑时,element table高版本属性获取不到的问题
          let _col = this.columns.find((x) => {
            return x.field == ((event && event.property) || column.property);
          });
          if (_col && (!_col.edit || _col.readonly)) {
            if (this.rowEndEdit(row, event)) {
              this.edit.rowIndex = -1;
            }
          }
          return;
        }
        if (this.rowEndEdit(row, event && event.property ? event : column)) {
          this.edit.rowIndex = -1;
        }
        //当正在编辑,且点击到其他行时,在原编辑的行结束编辑后,触发新行的rowClick事件
        //正在编辑时,禁止出发rowClick事件
        if (this.edit.rowIndex == -1) {
          this.$emit("rowClick", { row, column, event });
        }
      }
      this.rowBeginEdit(row, column);
    },
    dowloadFile(file) {
      this.base.dowloadFile(
        file.path,
        file.name,
        {
          Authorization: this.$store.getters.getToken(),
        },
        this.http.ipAddress
      );
    },
    getFilePath(pathSring, column) {
      // èŽ·å–è¡¨çš„å›¾ç‰‡ä¸Žæ–‡ä»¶æ˜¾ç¤º
      if (!pathSring) return [];
      // å¢žåŠ å›¾ç‰‡è‡ªå®šä¹‰æ“ä½œ
      // è¿”回格式必须是[{name:"文件名",path:"图片全路径或base64格式"}]
      if (column.formatter) {
        return column.formatter(pathSring);
      }
      let filePath;
      if (column.base64 && pathSring.indexOf("data") != -1) {
        filePath = ("," + pathSring)
          .split(",data")
          .filter((x) => {
            return x;
          })
          .map((m) => {
            return "data" + m;
          });
      } else {
        filePath = pathSring.replace(/\\/g, "/").split(",");
      }
      let fileInfo = [];
      for (let index = 0; index < filePath.length; index++) {
        let file = filePath[index];
        // 2020.12.19增加base64图片显示
        if (column.base64) {
          fileInfo.push({
            name: "",
            path:
              (file.indexOf("data") == -1 ? "data:image/png;base64," : "") +
              file,
          });
        } else if (file.indexOf(".") != -1) {
          let splitFile = file.split("/");
          if (splitFile.length > 0) {
            fileInfo.push({
              name: splitFile[splitFile.length - 1],
              path: this.base.isUrl(file) ? file : this.http.ipAddress + file,
            });
          }
        }
      }
      return fileInfo;
    },
    // é‡ç½®table
    reset() {
      if (this.tableData && this.tableData.length > 0) {
        this.tableData.splice(0);
      }
      if (this.rowData && this.rowData.length > 0) {
        this.rowData.splice(0);
      }
      if (!this.paginationHide) {
        this.paginations.page = 1;
        // this.paginations.rows = 30;
        if (this.paginations.wheres && this.paginations.wheres.length > 0) {
          this.paginations.wheres.splice(0);
        }
      }
      this.errorFiled = "";
      this.edit.columnIndex = -1;
      this.edit.rowIndex = -1;
    },
    getHeight() {
      // æ²¡æœ‰å®šä¹‰é«˜åº¦ä¸Žæœ€å¤§é«˜åº¦ï¼Œä½¿ç”¨table默认值
      if (!this.height && !this.maxHeight) {
        return null;
      }
      // å®šä¹‰äº†æœ€å¤§é«˜åº¦åˆ™ä¸ä½¿ç”¨é«˜åº¦
      if (this.maxHeight) {
        return null;
      }
      // ä½¿ç”¨å½“前定义的高度
      return this.height;
    },
    getMaxHeight() {
      // æ²¡æœ‰å®šä¹‰é«˜åº¦ä¸Žæœ€å¤§é«˜åº¦ï¼Œä½¿ç”¨table默认值
      if (!this.height && !this.maxHeight) {
        return null;
      }
      // å®šä¹‰äº†æœ€å¤§é«˜åº¦ä½¿ç”¨æœ€å¤§é«˜åº¦
      if (this.maxHeight) {
        return this.maxHeight;
      }
      // ä¸ä½¿ç”¨æœ€å¤§é«˜åº¦
      return null;
    },
    getSelectedOptions(column) {
      if (column.bind && column.bind.data && column.bind.data.length > 0) {
        return column.bind.data;
      }
      return [];
    },
    formatterClick(row, column, event) {
      if (column.click) {
        column.click(row, column, event);
        event.stopPropagation && event.stopPropagation();
      } else {
        this.rowClick(row, column, event);
      }
    },
    initIndex({ row, rowIndex }) {
      if (this.index) {
        row.elementIndex = rowIndex;
      }
      // if (rowIndex%2!==0) {
      //  return "even-row";
      // }
      return;
    },
    toggleEdit(event) {},
    setEditStatus(status) {
      // this.columns.forEach((x) => {
      //   if (x.hasOwnProperty("edit")) {
      //     this.$set(x.edit, "status", status);
      //   }
      // });
    },
    // é€šè¿‡button按钮启用编辑
    beginWithButtonEdit(scope) {
      // url?rowData:tableData
      this.rowBeginEdit(scope.row, this.columns[scope.$index]);
    },
    rowBeginEdit(row, column) {
      if (this.edit.rowIndex != -1) {
        return;
      }
      let _row = this.columns.find((x) => x.field == column.property);
      if (_row) {
        if (_row.readonly) {
          return;
        }
        if (
          //不能编辑的字段、switch,点击不开启启编辑功能
          !_row.edit ||
          (_row.edit.keep && _row.edit.type == "switch")
        ) {
          return;
        }
      }
      if (!this.enableEdit) return;
      _errMsg = "";
      // ç¼–辑前
      this.columns
        .filter((x) => {
          return x.bind && x.bind.data && x.bind.data.length;
        })
        .forEach((column) => {
          let val = row[column.field];
          if (typeof column.bind.data[0].key == "string") {
            if (typeof val == "number") {
              row[column.field] = row[column.field] + "";
            }
          } else {
            if (typeof val == "string" && val) {
              let _val = val * 1;
              if (_val + "" === val) {
                row[column.field] = _val;
              }
            }
          }
        });
      if (!this.beginEdit(row, column, row.elementIndex)) return;
      if (row.hasOwnProperty("elementIndex")) {
        if (this.edit.rowIndex == row.elementIndex) {
          return;
        }
        this.edit.rowIndex = row.elementIndex;
      }
    },
    rowEndEdit(row, column, event) {
      if (this.clickEdit && event) {
        return true;
      }
      if (!this.enableEdit) {
        if (!this.errorFiled) {
          if (
            this.edit.rowIndex != -1 &&
            !this.endEditAfter(row, column, this.edit.rowIndex)
          ) {
            return false;
          }
          this.edit.rowIndex = -1;
        }
        return true;
      }
      if (!this.doubleEdit && event) {
        return true;
      }
      let _row = this.url
        ? this.rowData[this.edit.rowIndex]
        : this.tableData[this.edit.rowIndex];
      // ç»“束编辑前
      if (!this.endEditBefore(_row, column, this.edit.rowIndex)) return false;
      if (this.edit.rowIndex != -1) {
        //2022.06.26修复表格内容切换后行数不一致时不能编辑的问题
        if (this.edit.rowIndex - 1 > (this.rowData || this.tableData).length) {
          this.edit.rowIndex = -1;
          return;
        }
        let row = (this.url ? this.rowData : this.tableData)[
          this.edit.rowIndex
        ];
        for (let index = 0; index < this.columns.length; index++) {
          const _column = this.columns[index];
          if (_column.edit) {
            if (!this.validateRow(row, _column)) {
              return;
            }
          }
        }
      }
      if (!this.endEditAfter(_row, column, this.edit.rowIndex)) return false;
      this.edit.rowIndex = -1;
      return true;
    },
    validateRow(row, option1) {
      if (!this.validateColum(option1, row)) {
        this.errorFiled = option1.field;
        // 2022.05.06 ä¿®æ”¹é”™è¯¯ä¿¡æ¯é‡å¤çš„问题
        this.$message.error(option1.title + _errMsg);
        return false;
      }
      this.errorFiled = "";
      return true;
    },
    validateColum(option, data) {
      if (option.hidden || option.bind) return true;
      let val = data[option.field];
      if (option.require || option.required) {
        if (val != "0" && (val === "" || val === undefined)) {
          if (!this.errorFiled) {
            _errMsg = "不能为空";
          }
          return false;
        }
      }
      if (!option.edit) {
        return true;
      }
      let editType = option.edit.type;
      // éªŒè¯æ•°å­—
      if (editType == "int" || editType == "decimal" || editType == "number") {
        if (val == "" || val == undefined) return true;
        if (editType == "decimal") {
          if (!this.rule.decimal.test(val)) {
            _errMsg = "只能是数字";
            return false;
          }
        } else if (!this.rule.decimal.test(val)) {
          _errMsg = "只能是数字";
          return false;
        }
        if (
          option.edit.min != undefined &&
          typeof option.edit.min === "number" &&
          val < option.edit.min
        ) {
          _errMsg = "不能小于" + option.edit.min;
          return false;
        }
        if (
          option.edit.max != undefined &&
          typeof option.edit.max === "number" &&
          val > option.edit.max
        ) {
          _errMsg = "不能大于" + option.edit.max;
          return false;
        }
        return true;
      }
      // éªŒè¯å­—符串
      if (val && (editType == "text" || editType == "string")) {
        if (
          option.edit.min != undefined &&
          typeof option.edit.min === "number" &&
          val.length < option.edit.min
        ) {
          _errMsg = "至少" + option.edit.min + "个字符";
          return false;
        }
        if (
          option.edit.max != undefined &&
          typeof option.edit.max === "number" &&
          val.length > option.edit.max
        ) {
          _errMsg = "最多" + option.edit.max + "个字符";
          return false;
        }
      }
      return true;
    },
    delRow() {
      let rows = this.getSelected();
      if (rows.length == 0) return this.$Message.error("请选择要删除的行!");
      let data = this.url ? this.rowData : this.tableData;
      let indexArr = this.getSelectedIndex();
      if (indexArr.length == 0) {
        return this.$Message.error(
          "删除操作必须设置VolTable的属性index='true'"
        );
      }
      // if (indexArr.length == 0 || !this.key) {
      //   return this.$message.error(
      //     "请设置index=true属性或指columns的字段为key"
      //   );
      // }
      if (indexArr.length == 0) {
        // let keyValues=[]
        // rows.forEach(x=>{
        //   if (x[this.key]) {
        //   }
        //   keyValues.push(x[this.key])
        // })
        // data.find(x=>)
      } else {
        for (let i = data.length - 1; i >= 0; i--) {
          if (indexArr.indexOf(i) != -1) {
            data.splice(i, 1);
          }
        }
      }
      this.edit.rowIndex = -1;
      return rows;
    },
    addRow(row) {
      if (!row) {
        row = {};
      }
      this.columns.forEach((x) => {
        // 2022.05.06 æ·»åŠ è¡Œæ—¶ï¼Œå¦‚æžœåˆ—æœ‰ç¼–è¾‘å±žæ€§ï¼Œè®¾ç½®å¼€å¯ç¼–è¾‘(避免关闭编辑后,无法再次启用编辑)??
        //x.readonly = false;
        if (!row.hasOwnProperty(x.field)) {
          if (x.edit && x.edit.type == "switch") {
            row[x.field] = x.type == "bool" ? false : 0;
          } else if (!row.hidden) {
            // 2020.09.06添加行时,设置默认字段
            row[x.field] = undefined;
          }
        }
      });
      if (!this.url) {
        this.tableData.push(row);
        return;
      }
      this.rowData.push(row);
    },
    viewImg(row, column, url, $event) {
      $event.stopPropagation();
      this.base.previewImg(url);
      // window.open(row[column.field]);
    },
    link(row, column, $e) {
      $e.stopPropagation();
      this.$props.linkView(row, column);
    },
    getSelected() {
      return this.selectRows;
    },
    getSelectedIndex() {
      if (!this.index) {
        // åªæœ‰è®¾ç½®äº†å±žæ€§index才有索引行
        return [];
      }
      let indexArr = this.selectRows.map((x) => {
        return x.elementIndex;
      });
      return indexArr || [];
    },
    GetTableDictionary(rows) {
      // åˆ†é¡µæˆ–刷新或重新绑定数据源
      if (this.remoteColumns.length == 0 || !rows || rows.length == 0) return;
      let remoteInfo = {};
      for (let index = 0; index < this.remoteColumns.length; index++) {
        const column = this.remoteColumns[index];
        //  column.bind.data.splice(0);
        let key = column.bind.key;
        let data = [];
        rows.forEach((row) => {
          if (row[column.field] || row[column.field] == "0") {
            if (data.indexOf(row[column.field]) == -1) {
              data.push(row[column.field]);
            }
          }
        });
        if (data.length > 0) {
          remoteInfo[key] = data;
        }
      }
      if (remoteInfo.length == 0) return;
      // ha= Object.assign([], ha, hb)
      this.http
        .post("/api/Sys_Dictionary/GetTableDictionary", remoteInfo)
        .then((dic) => {
          dic.forEach((x) => {
            this.remoteColumns.forEach((column) => {
              if (column.bind.key == x.key) {
                column.bind.data = Object.assign([], column.bind.data, x.data);
                // column.bind.data.push(...x.data);
              }
            });
          });
          this.$emit("dicInited", dic);
        });
    },
    load(query, isResetPage) {
      // isResetPage重置分页数据
      if (!this.url) return;
      if (isResetPage) {
        this.resetPage();
      }
      let param = {
        page: this.paginations.page,
        rows: this.paginations.rows,
        sort: this.paginations.sort,
        order: this.paginations.order,
        wheres: [], // æŸ¥è¯¢æ¡ä»¶ï¼Œæ ¼å¼ä¸º[{ name: "字段", value: "xx" }]
      };
      let status = true;
      // åˆå¹¶æŸ¥è¯¢ä¿¡æ¯(包查询分页、排序、查询条件等)
      if (query) {
        param = Object.assign(param, query);
      }
      /* æŸ¥è¯¢å‰å¤„理(如果需要查询条件,实现组件方法loadBefore方法即可:
        loadBefore=(param, callBack)=>{
          param.wheres = [{ name: "PhoneNo", value: "13419098211" }];
          callBack(true);
        })
      */
      this.$emit("loadBefore", param, (result) => {
        status = result;
      });
      if (!status) return;
      if (param.wheres && param.wheres instanceof Array) {
        param.wheres = JSON.stringify(param.wheres);
      }
      this.loading = true;
      this.http.post(this.url, param).then(
        (data) => {
          //2021.06.04修复tree不刷新的问题
          if (this.rowKey) {
            this.randomTableKey++;
            this.rowData.splice(0);
          }
          this.loading = false;
          // æŸ¥è¯¢è¿”回结果后处理
          // 2020.10.30增加查询后返回所有的查询信息
          this.$emit(
            "loadAfter",
            data.rows || [],
            (result) => {
              status = result;
            },
            data
          );
          if (!status) return;
          this.GetTableDictionary(data.rows);
          this.rowData = data.rows || [];
          this.paginations.total = data.total;
          // åˆè®¡
          this.getSummaries(data);
          // this.$nextTick(() => {
          //   this.$refs.table.doLayout();
          // });
        },
        (error) => {
          this.loading = false;
          // this.$Message.error(error || "网络异常");
        }
      );
    }, // èŽ·å–ç»Ÿè®¡
    getSummaries(data) {
      if (!this.summary || !data.summary) return;
      this.summaryData.splice(0);
      // å¼€å¯äº†è¡Œå·çš„,+1
      if (this.columnIndex) {
        this.summaryData.push("");
      }
      // å¦‚果有checkbox,应该算作是第一行
      if (this.ck) {
        this.summaryData.push("");
      }
      this.columns.forEach((col) => {
        if (col.children && col.children.length) {
          col.children.forEach((item) => {
            this.getColumnSummaries(item, data);
          });
        } else {
          this.getColumnSummaries(col, data);
        }
      });
      if (this.summaryData.length > 0 && this.summaryData[0] == "") {
        this.summaryData[0] = "合计";
      }
    },
    getColumnSummaries(col, data) {
      if (!col.hidden) {
        if (data.summary.hasOwnProperty(col.field)) {
          let sum = data.summary[col.field];
          if (sum) {
            sum =
              (sum * 1.0).toFixed(col.numberLength || 2).replace(".00", "") *
              1.0;
          }
          this.summaryData.push(sum);
        } else {
          this.summaryData.push("");
        }
      }
    },
    getInputChangeSummaries() {},
    handleSizeChange(val) {
      this.paginations.size = val;
      this.paginations.rows = val;
      this.load();
    },
    handleCurrentChange(val) {
      this.paginations.page = val;
      this.load();
    },
    sortChange(sort) {
      this.paginations.sort = sort.prop;
      this.paginations.order = sort.order == "ascending" ? "asc" : "desc";
      this.load();
    },
    resetPage() {
      // é‡ç½®æŸ¥è¯¢åˆ†é¡µ
      // this.paginations.rows = 30;
      this.paginations.page = 1;
    },
    selectionChange(selection) {
      // console.log(selection);
      // é€‰æ‹©è¡Œäº‹ä»¶,只有单选才触发
      this.selectRows = selection;
      if (this.single) {
        if (selection.length == 1) {
          this.$emit("rowChange", selection[0]);
        }
        if (selection.length > 1) {
          let _row = selection[selection.length - 1];
          this.$refs.table.toggleRowSelection(selection[0]);
          this.selectRows = [_row];
        }
      }
      // å°†selectionchange暴露出去
      this.$emit("selectionChange", selection);
    },
    getColor(row, column) {
      let val = row[column.field];
      if (column.getColor && typeof column.getColor === "function") {
        let _color = column.getColor(row, column);
        if (_color) {
          return _color;
        }
      }
      if (!val && val != "0") {
        return "";
      }
      if (!this.formatConfig[column.field]) {
        this.formatConfig[column.field] = [val];
        return this.colors[0];
      }
      let index = this.formatConfig[column.field].indexOf(val);
      if (index != -1) {
        return this.colors[index];
      }
      if (this.formatConfig[column.field].length > 5) {
        return "";
      }
      if (index == -1) {
        this.formatConfig[column.field].push(val);
        index = this.formatConfig[column.field].length - 1;
      }
      return this.colors[index];
    },
    formatterDate(row, column) {
      return (row[column.field] || "").substr(0, 10);
    },
    formatter(row, column, template) {
      if (!template) return row[column.property];
      let val = row[column.field];
      if (!val && val != 0) return val;
      // æ˜¯å¦å€¼
      if (column.edit && column.edit.type == "switch") {
        return val ? "是" : "否";
      }
      if (!column.bind || !column.bind.data) {
        return row[column.field];
      }
      if (
        column.edit &&
        (column.edit.type == "selectList" || column.edit.type == "treeSelect")
      ) {
        if (!Array.isArray(val)) {
          row[column.field] = val.split(",");
        } else {
          val = val.join(",");
        }
        return this.getSelectFormatter(column, val);
      }
      // ç¼–辑多选table显示
      if (
        column.bind.type == "selectList" ||
        column.bind.type == "checkbox" ||
        column.bind.type == "treeSelect"
      ) {
        // if (typeof val === 'string' && val.indexOf(',') != -1) {
        return this.getSelectFormatter(column, val + "");
        //  }
      }
      let source = column.bind.data.filter((x) => {
        // return x.key != "" && x.key == val;
        // 2020.06.06修复单独使用table组件时,key为数字0时转换成文本失败的问题
        return x.key !== "" && x.key !== undefined && x.key + "" === val + "";
      });
      if (source && source.length > 0) val = source[0].label || source[0].value;
      return val;
    },
    getSelectFormatter(column, val) {
      // ç¼–辑多选table显示
      let valArr = val.split(",");
      for (let index = 0; index < valArr.length; index++) {
        (column.bind.orginData && column.bind.orginData.length
          ? column.bind.orginData
          : column.bind.data
        ).forEach((x) => {
          // 2020.06.06修复数据源为selectList时,key为数字0时不能转换文本的问题
          if (
            x.key !== "" &&
            x.key !== undefined &&
            x.key + "" == valArr[index] + ""
          ) {
            valArr[index] = x.label || x.value;
          }
        });
      }
      return valArr.join(",");
    },
    onChange(scope, val, event, column) {
      // 2020.09.03修复onChange不触发的问题
      let row = scope.row;
      if (column.onChange && !column.onChange(row, val, event)) {
        return;
      }
      // è¾“入框求和实时计算
      this.getInputSummaries(scope, val, event, column);
    },
    // input输入实时求和
    getInputSummaries(scope, val, event, column) {
      // column列设置了summary属性的才计算值
      if (!column.summary) return;
      let sum = 0;
      //  let _index = 0;
      (this.url ? this.rowData : this.tableData).forEach((x, index) => {
        if (x.hasOwnProperty(column.field) && !isNaN(x[column.field])) {
          // _index = index;
          sum += x[column.field] * 1;
        }
      });
      if (sum) {
        if (column.summary == "avg") {
          sum = sum / (this.rowData.length || this.tableData.length || 1);
        }
        sum =
          (sum * 1.0).toFixed(column.numberLength || 2).replace(".00", "") *
          1.0;
      }
      this.summaryData[this.summaryIndex[column.field]] = sum;
    },
    getSummaryData({ columns, data }) {
      return this.summaryData;
    },
    getCellStyle(row) {
      // 2020.12.13增加设置单元格颜色
      if (row.column.property) {
        return (
          this.cellStyleColumns[row.column.property] &&
          this.cellStyleColumns[row.column.property](
            row.row,
            row.rowIndex,
            row.columnIndex
          )
        );
      }
    },
    compareDate(date1, date2) {
      if (!date2) {
        return true;
      }
      return (
        date1.valueOf() <
        (typeof date2 == "number" ? date2 : new Date(date2).valueOf())
      );
    },
    getDateOptions(date, item) {
      //2021.07.17设置时间可选范围
      if ((!item.min && !item.max) || !date) {
        return false;
      }
      if (item.min && item.min.indexOf(" ") == -1) {
        //不设置时分秒,后面会自动加上 08:00
        item.min = item.min + " 00:00:000";
      }
      return (
        this.compareDate(date, item.min) || !this.compareDate(date, item.max)
      );
    },
    getDateFormat(column) {
      //见https://day.js.org/docs/zh-CN/display/format
      return column.edit.type == "date" ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss";
    },
    userSelect(selection, row) {
      this.selectRows = selection;
      if (!this.single) {
        this.$emit("rowChange", { row, selection });
      }
    },
    isEmptyTag(row, column) {
      if (!row[column.field] && row[column.field] != "0") {
        return "empty-tag";
      }
      return "";
    },
    filterChildrenColumn(children) {
      if (!children) {
        return [];
      }
      return children.filter((x) => {
        return !x.hidden;
      });
    },
    initColumnDisabled(row, column) {
      return column.getDisabled && column.getDisabled(row, column);
    },
    showUpload(row, column) {
      this.fileInfo = (row[column.field] || "")
        .split(",")
        .filter((x) => {
          return x;
        })
        .map((item) => {
          return { path: item, name: "" };
        });
      this.currentRow = row;
      this.currentColumn = column;
      if (this.currentColumn.edit.autoUpload === undefined) {
        this.currentColumn.edit.autoUpload = true;
      }
      if (this.currentColumn.edit.multiple === undefined) {
        this.currentColumn.edit.multiple = false;
      }
      if (this.currentColumn.edit.url === undefined) {
        this.uploadUrl =
          "api/" +
          (this.url || "").replace("/api", "api").split("/")[1] +
          "/upload";
      } else {
        this.uploadUrl = this.currentColumn.edit.url;
      }
      this.uploadModel = true;
    },
    uploadAfter(result, files) {
      this.currentColumn.uploadAfter &&
        this.currentColumn.uploadAfter(result, files);
      return true;
    },
    saveUpload() {
      //生成保存后返回的路径
      let arr = this.fileInfo.map((x) => {
        if (x.path) {
          return x.path;
        }
        return result.data + x.name;
      });
      this.currentRow[this.currentColumn.field] = arr.join(",");
      this.uploadModel = false;
      return true;
    },
  },
});
</script>
<style lang="less" scoped>
.vol-table {
  position: relative;
  .mask {
    opacity: 0.2;
    position: absolute;
    width: 100%;
    height: 100%;
    background: #d0d0d0;
    z-index: 100;
  }
  .message {
    text-align: center;
    color: #635c5c;
    font-size: 15px;
    font-weight: 600;
    background: #eee;
    transform: translateY(-50%);
    top: 50%;
    position: absolute;
    z-index: 200;
    left: 0;
    right: 0;
    width: 150px;
    margin: 0 auto;
    line-height: 40px;
    border-radius: 4px;
    border: 1px solid #a09e9e;
  }
}
.e-item {
  display: flex;
  > div:first-child {
    flex: 1;
  }
}
.vol-table ::v-deep(.el-pager .number) {
  padding: 0 7px;
  border-radius: 5px;
  border: 1px solid #e6e6e6;
  margin-left: 8px;
  font-weight: 500;
  min-width: 28px;
}
.vol-table ::v-deep(.el-pager .number.active) {
  background: #ed4014;
  color: #fff;
}
.vol-table .t-file {
  color: #1e8cff;
  cursor: pointer;
  border-bottom: 1px solid;
  padding-bottom: 2px;
}
.vol-table .empty-tag {
  border: none;
  background: none;
}
.v-table ::v-deep(.el-date-editor .el-icon-date),
.v-table ::v-deep(.el-date-editor .el-icon-time) {
  width: 10px;
}
.column-required {
  position: relative;
  color: #f20303;
  font-size: 14px;
  top: 2px;
  right: 2px;
}
</style>
<style scoped>
/* .v-table ::v-deep(.even-row){
  background: rgb(245,247,250);
} */
.pagination {
  text-align: right;
  padding: 2px 28px;
  border: 1px solid #eee;
  border-top: 0px;
}
/* .v-table ::v-deep(.el-input .el-input__inner) {
  padding: 0 7px;
} */
.v-table ::v-deep(.el-table__header th) {
  /* padding: 0px !important; */
  background-color: #f8f8f9 !important;
  font-size: 13px;
  height: 46px;
  color: #616161;
}
.v-table ::v-deep(.el-table__header th.is-sortable) {
  padding: 3px !important;
}
.vol-table.text-inline ::v-deep(.el-table__body .cell),
.vol-table.text-inline ::v-deep(.el-table__header-wrapper .cell) {
  word-break: inherit !important;
  white-space: nowrap !important;
}
/* .v-table  ::v-deep(.el-table__body td) {
  padding: 9px 0 !important;
} */
.v-table ::v-deep(.el-table__footer td) {
  padding: 7px 0 !important;
}
.vol-table ::v-deep(.el-table-column--selection .cell) {
  display: inline;
}
.vol-table.text-inline ::v-deep(.el-table th > .cell) {
  white-space: nowrap !important;
}
.vol-table .table-img {
  height: 40px;
  border-radius: 5px;
  margin-right: 10px;
  width: 40px;
  object-fit: cover;
}
.vol-table .table-img:hover {
  cursor: pointer;
}
.vol-table ::v-deep(.cell) {
  padding: 2px 10px;
}
.vol-table ::v-deep(.cell .el-tag) {
  padding: 5px 9px;
}
.table-input {
  color: rgb(104, 103, 103);
  padding: 3px 10px;
  height: 32px;
  line-height: 32px;
  width: 100%;
  border-radius: 4px;
  border: 1px solid #dcdcdc;
}
.table-input:focus {
  outline: 1px solid #49a3fd;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolTable/VolTableRender.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
import { h } from 'vue';
export default {
  name: "TableExpand",
  functional: true,
  props: {
    render: Function,
    row: {},//当前行的数据
    column: {},//当前行的配置信息
    index: { type: Number, default: 0 }//当前所在行
  },
  render: ({ render,row ,column,index }) => {
    return render(h, {row ,column,index}); //h();
  }
};
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/basic/VolUpload.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,880 @@
<template>
  <div class="upload-container">
    <div>
      <div class="input-btns" style="margin-bottom: 10px">
        <input
          ref="input"
          type="file"
          style="display: none"
          @change="handleChange"
          :multiple="multiple"
        />
        <div v-if="img" class="upload-img">
          <!-- v-for="(file,index) in fileInfo.length>0?fileInfo: files" -->
          <div v-for="(file, index) in files" :key="index" class="img-item">
            <div class="operation">
              <div class="action">
                <i class="el-icon-view view" @click="previewImg(index)"></i>
                <i class="el-icon-delete remove" @click="removeFile(index)"></i>
              </div>
              <div class="mask"></div>
            </div>
            <img :src="getImgSrc(file, index)" :onerror="errorImg" />
          </div>
          <div
            v-show="!autoUpload || (autoUpload && files.length < maxFile)"
            class="img-selector"
            :class="getSelector()"
          >
            <div class="selector" @click="handleClick">
              <i class="el-icon-camera-solid"></i>
            </div>
            <div
              v-if="!autoUpload"
              class="s-btn"
              :class="{ readonly: changed }"
              @click="upload"
            >
              <div>{{ loadText }}</div>
            </div>
          </div>
        </div>
        <el-button v-else @click="handleClick"
          >选择{{ img ? '图片' : '文件' }}</el-button
        >
        <el-button
          v-if="!autoUpload && !img"
          type="info"
          :disabled="changed"
          @click="upload(true)"
          :loading="loadingStatus"
          >上传文件</el-button
        >
      </div>
      <slot></slot>
      <div v-if="desc">
        <el-alert
          :title="getText() + '文件大小不超过' + (maxSize || 50) + 'M'"
          type="info"
          show-icon
        >
        </el-alert>
      </div>
      <slot name="content"></slot>
      <div v-if="!img">
        <ul class="upload-list" v-show="fileList">
          <li class="list-file" v-for="(file, index) in files" :key="index">
            <a>
              <span @click="fileOnClick(index, file)">
                <i :class="format(file)"></i>
                {{ file.name }}
              </span>
            </a>
            <span @click="removeFile(index)" class="file-remove">
              <i class="el-icon-close"></i>
            </span>
          </li>
        </ul>
      </div>
      <slot name="tip"></slot>
    </div>
  </div>
</template>
<script>
let OSS = require('ali-oss');
export default {
  components: {},
  props: {
    desc: {
      //是否显示默认介绍
      //是否多选
      type: Boolean,
      default: false
    },
    fileInfo: {
      //用于接收上传的文件,也可以加以默认值,显示已上传的文件,用户上传后会覆盖默认值
      type: Array,
      default: () => {
        return [];
      } //格式[{name:'1.jpg',path:'127.0.01/1.jpg'}]
    },
    downLoad: {
      //是否可以点击文件下载
      type: Boolean,
      default: true
    },
    multiple: {
      //是否多选
      type: Boolean,
      default: false
    },
    maxFile: {
      //最多可选文件数量,必须multiple=true,才会生效
      type: Number,
      default: 5
    },
    maxSize: {
      //文件限制大小3M
      type: Number,
      default: 50
    },
    autoUpload: {
      //选择文件后是否自动上传
      type: Boolean,
      default: true
    },
    img: {
      //图片类型  img>excel>fileTypes三种文件类型优先级
      type: Boolean,
      default: false
    },
    excel: {
      //excel文件
      type: Boolean,
      default: false
    },
    fileTypes: {
      //指定上传文件的类型
      type: Array,
      default: () => {
        return [];
      }
    },
    url: {
      //上传的url
      type: String,
      default: ''
    },
    uploadBefore: {
      //返回false会中止执行
      //上传前
      type: Function,
      default: (files) => {
        return true;
      }
    },
    uploadAfter: {
      //返回false会中止执行
      //上传后
      type: Function,
      default: (result, files) => {
        return true;
      }
    },
    onChange: {
      //选择文件时  //返回false会中止执行
      type: Function,
      default: (files) => {
        return true;
      }
    },
    // clear: {
    //   //上传完成后是否清空文件列表
    //   type: Boolean,
    //   default: true
    // },
    fileList: {
      //是否显示选择的文件列表
      type: Boolean,
      default: true
    },
    fileClick: {
      //点击文件事件
      type: Function,
      default: (index, file, files) => {
        return true;
      }
    },
    removeBefore: {
      //移除文件事件
      type: Function,
      default: (index, file, files) => {
        return true;
      }
    },
    append: {
      //此属性已废弃,多文件上传,默认追加文件
      type: Boolean,
      default: false
    },
    compress: {
      //开启图片压缩,后面根据需要再完善
      type: Boolean,
      default: true
    },
    compressMinSize: {
      //压缩的最小比例
      type: Number,
      default: 0.1
    }
  },
  data() {
    return {
      errorImg: 'this.src="' + require('@/assets/imgs/error-img.png') + '"',
      changed: false, //手动上传成功后禁止重复上传,必须重新选择
      model: true,
      files: [],
      bigImg: '',
      imgTypes: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp', 'jfif'],
      loadingStatus: false,
      loadText: '上传文件'
    };
  },
  created() {
    //默认有图片的禁止上传操作
    if (this.fileInfo) {
      this.changed = true;
    }
    this.cloneFile(this.fileInfo);
  },
  watch: {
    fileInfo: {
      handler(files) {
        this.cloneFile(files);
      },
      deep: true
    }
  },
  methods: {
    cloneFile(files) {
      this.files = files.map((x) => {
        return {
          name: x.name || this.getFileName(x.path),
          path: x.path
        };
      });
    },
    getFileName(path) {
      if (!path) {
        return '未定义文件名';
      }
      let _index = path.lastIndexOf('/');
      return path.substring(_index + 1);
    },
    previewImg(index) {
      //查看大图预览模式待完
      this.base.previewImg(this.getImgSrc(this.files[index]));
      //  window.open(this.getImgSrc((this.files.length>0?this.files:this.fileInfo)[index]));
    },
    getSelector() {
      if (this.autoUpload) {
        return 'auto-selector';
      }
      return 'submit-selector';
    },
    getImgSrc(file, index) {
      if (file.hasOwnProperty('path')) {
        if (this.base.isUrl(file.path)) {
          return file.path;
        }
        //2020.12.27增加base64图片操作
        if (file.path.indexOf('/9j/') != -1) {
          return 'data:image/jpeg;base64,' + file.path;
        }
        if (file.path.substr(0, 1) == '/') {
          file.path = file.path.substr(1);
        }
        return this.http.ipAddress + file.path;
      }
      return window.URL.createObjectURL(file);
    },
    fileOnClick(index, file) {
      if (!this.fileClick(index, file, this.files)) {
        return;
      }
      //点击不下载
      if (!this.downLoad) {
        return;
      }
      if (!file.path) {
        this.$message.error('请先上传文件');
        return;
      }
      this.base.dowloadFile(
        file.path,
        file.name,
        {
          Authorization: this.$store.getters.getToken()
        },
        this.http.ipAddress
      );
    },
    getText() {
      if (this.img) {
        return '只能上传图片,';
      } else if (this.excel) {
        return '只能上传excel文件,';
      }
    },
    handleClick() {
      this.$refs.input.click();
    },
    handleChange(e) {
      //this.compress开启图片压缩,后面根据需要再完善
      // this.clearFiles();
      var result = this.checkFile(e.target.files);
      if (!result) {
        return;
      }
      this.changed = false;
      //如果传入了FileInfo需要自行处理移除FileInfo
      if (!this.onChange(e.target.files)) {
        return;
      }
      for (let index = 0; index < e.target.files.length; index++) {
        const element = e.target.files[index];
        element.input = true;
      }
      if (!this.multiple) {
        this.files.splice(0);
      }
      this.files.push(...e.target.files);
      this.$refs.input.value = null;
      if (this.autoUpload && result) {
        this.upload(false);
      }
    },
    removeFile(index) {
      //如果传入了FileInfo需要自行处理移除FileInfo
      //t移除文件
      let removeFile = this.files[index];
      //删除的还没上传的文件
      if (removeFile.input) {
        this.files.splice(index, 1);
      } else {
        this.fileInfo.splice(index, 1);
      }
      if (!this.removeBefore(index, removeFile, this.fileInfo)) {
        return;
      }
    },
    clearFiles() {
      this.files.splice(0);
    },
    getFiles() {
      return this.files;
    },
    convertToFile(dataurl, filename) {
      let arr = dataurl.split(',');
      let mime = arr[0].match(/:(.*?);/)[1];
      let suffix = mime.split('/')[1];
      let bstr = atob(arr[1]);
      let n = bstr.length;
      let u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      // new File返回File对象 ç¬¬ä¸€ä¸ªå‚数是 ArraryBuffer æˆ– Bolb æˆ–Arrary ç¬¬äºŒä¸ªå‚数是文件名
      // ç¬¬ä¸‰ä¸ªå‚数是 è¦æ”¾åˆ°æ–‡ä»¶ä¸­çš„内容的 MIME ç±»åž‹
      return new File([u8arr], `${filename}.${suffix}`, {
        type: mime,
        input: true
      });
    },
    async compressImg(file) {
      let fileSize = file.size / 1024 / 1024;
      let read = new FileReader();
      read.readAsDataURL(file);
      return new Promise((resolve, reject) => {
        read.onload = (e) => {
          let img = new Image();
          img.src = e.target.result;
          let _this = this;
          img.onload = function() {
            //默认按比例压缩
            let w = this.width;
            let h = this.height;
            let canvas = document.createElement('canvas');
            let ctx = canvas.getContext('2d');
            canvas.setAttribute('width', w);
            canvas.setAttribute('height', h);
            ctx.drawImage(this, 0, 0, w, h);
            let rate = 0.3;
            if (fileSize > 2) {
              rate = 0.1;
            } else if (fileSize > 1) {
              rate = 0.1;
            }
            if (_this.compressMinSize > rate) {
              rate = _this.compressMinSize;
            }
            // rate=1;
            let base64 = canvas.toDataURL('image/jpeg', rate);
            resolve(_this.convertToFile(base64, file.name));
          };
        };
      });
    },
    async uploadOSS() {
      this.http.get('api/alioss/getAccessToken', {}, false).then(async (x) => {
        if (!x.status) return this.$Message.error(x.message);
        let client = new OSS({
          // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
          region: x.data.region,
          // ä»ŽSTS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
          accessKeyId: x.data.accessKeyId,
          accessKeySecret: x.data.accessKeySecret,
          // ä»ŽSTS服务获取的安全令牌(SecurityToken)。
          stsToken: x.data.securityToken,
          // å¡«å†™Bucket名称。
          bucket: x.data.bucket
        });
        console.log(this.files);
        for (let index = 0; index < this.files.length; index++) {
          const file = this.files[index];
          if (file.input) {
            let result = await client.put(
              x.data.bucketFolder + '/' + x.data.unique + file.name,
              file
            );
            file.path = result.url;
            file.newName = x.data.unique + file.name;
          }
        }
        this.fileInfo.splice(0);
        // }
        let _files = this.files.map((file) => {
          return {
            name: file.newName || file.name,
            path: file.path
          };
        });
        this.fileInfo.push(..._files);
        //2021.09.25修复文件上传后不能同时下载的问题
        this.files = _files;
      });
      return;
    },
    async upload(vail) {
      if (vail && !this.checkFile()) return false;
      if (!this.url) {
        return this.$message.error('没有配置好Url');
      }
      if (!this.files || this.files.length == 0) {
        return this.$message.error('请选择文件');
      }
      //增加上传时自定义参数,后台使用获取Utilities.HttpContext.Current.Request.Query["字段"]
      let params={};
      if (!this.uploadBefore(this.files,params)) {
        return;
      }
      let paramText="";
      if (Object.keys(params).length) {
        paramText="?1=1";
        for (const key in params) {
          let value=params[key];
          if(typeof(value)=='object'){
            value=JSON.stringify(value)
          }
          paramText+=`&${key}=${value}`
        }
      }
      this.loadingStatus = true;
      this.loadText = '上传中..';
      if (window.oss && window.oss.ali.use) {
        await this.uploadOSS();
        this.loadingStatus = false;
        this.loadText = '上传文件';
        if (!this.uploadAfter({status:true}, this.files)) {
          this.changed = false;
          return;
        } else {
          this.changed = true;
        }
        this.$message.success('上传成功');
        return;
      }
      var forms = new FormData();
      for (let index = 0; index < this.files.length; index++) {
        let file = this.files[index];
        if (file.input) {
          let name = file.name.split('.');
          name = name[name.length - 1].toLocaleLowerCase();
          let isImg = this.imgTypes.indexOf(name) != -1;
          if (isImg && (name == 'jpg' || name == 'jpeg')) {
            //>200KB的开启压缩
            if (isImg && file.size / 1024 / 1024 > 0.2) {
              console.log('压缩前' + file.size);
              file = await this.compressImg(file);
              file.compress = true;
              this.files[index] = file;
              this.files[index].input = true;
              console.log('压缩后' + file.size);
            }
          }
          forms.append('fileInput', file, file.name);
        }
      }
      // forms.append("fileInput", this.files);
      this.http
        .post(this.url+paramText, forms, this.autoUpload ? '正在上传文件' : '')
        .then(
          (x) => {
            // this.$refs.uploadFile.clearFiles();
            this.loadingStatus = false;
            this.loadText = '上传文件';
            if (!this.uploadAfter(x, this.files)) {
              this.changed = false;
              return;
            } else {
              this.changed = true;
            }
            this.$message.success(x.message);
            this.changed = x.status;
            if (!x.status) {
              // this.files = null;
              return;
            }
            //单选清除以前的数据
            //  if (!this.multiple) {
            this.fileInfo.splice(0);
            // }
            let _files = this.files.map((file) => {
              return {
                name: file.name,
                path: file.path || x.data + file.name
              };
            });
            this.fileInfo.push(..._files);
            //2021.09.25修复文件上传后不能同时下载的问题
            this.files = _files;
          },
          (error) => {
            this.loadText = '上传文件';
            this.loadingStatus = false;
          }
        );
    },
    format(file, checkFileType) {
      const format =
        file.name
          .split('.')
          .pop()
          .toLocaleLowerCase() || '';
      let fileIcon = 'el-icon-document';
      if (this.fileTypes.length > 0 && checkFileType != undefined) {
        if (this.fileTypes.indexOf(format) != -1) {
          return true;
        }
        return false;
      }
      if (
        checkFileType &&
        !(checkFileType instanceof Array) &&
        checkFileType != 'img' &&
        checkFileType != 'excel'
      ) {
        if (checkFileType.indexOf(format) > -1) {
          return true;
        } else {
          return false;
        }
      }
      if (checkFileType == 'img' || this.imgTypes.indexOf(format) > -1) {
        if (checkFileType == 'img') {
          if (this.imgTypes.indexOf(format) > -1) {
            return true;
          } else {
            return false;
          }
        }
        fileIcon = 'el-icon-picture-outline';
      }
      if (
        ['mp4', 'm3u8', 'rmvb', 'avi', 'swf', '3gp', 'mkv', 'flv'].indexOf(
          format
        ) > -1
      ) {
        fileIcon = 'el-icon-document';
      }
      if (['mp3', 'wav', 'wma', 'ogg', 'aac', 'flac'].indexOf(format) > -1) {
        fileIcon = 'el-icon-document';
      }
      if (['doc', 'txt', 'docx', 'pages', 'epub', 'pdf'].indexOf(format) > -1) {
        fileIcon = 'el-icon-document';
      }
      if (
        checkFileType == 'excel' ||
        ['numbers', 'csv', 'xls', 'xlsx'].indexOf(format) > -1
      ) {
        if (checkFileType == 'excel') {
          if (['numbers', 'csv', 'xls', 'xlsx'].indexOf(format) > -1) {
            return true;
          } else {
            return false;
          }
        }
        fileIcon = 'el-icon-document';
      }
      return fileIcon;
    },
    beforeUpload() {},
    checkFile(inputFiles) {
      const files = this.files;
      if (
        this.multiple &&
        files.length + (inputFiles || []).length > (this.maxFile || 5)
      ) {
        this.$message.error(
          '最多只能选【' +
            (this.maxFile || 5) +
            '】' +
            (this.img ? '张图片' : '个文件') +
            ''
        );
        return false;
      }
      if (!inputFiles) {
        inputFiles = this.files.filter((x) => {
          return x.input;
        });
      }
      let names = [];
      for (let index = 0; index < inputFiles.length; index++) {
        const file = inputFiles[index];
        if (names.indexOf(file.name) != -1) {
          file.name = '(' + index + ')' + file.name;
        }
        names.push(file.name);
        if (this.img && !this.format(file, 'img')) {
          this.$message.error('选择的文件【' + file.name + '】只能是图片格式');
          return false;
        }
        if (this.excel && !this.format(file, 'excel')) {
          this.$message.error('选择的文件【' + file.name + '】只能是excel文件');
          return false;
        }
        if (
          this.fileTypes &&
          this.fileTypes.length > 0 &&
          !this.format(file, this.fileTypes)
        ) {
          this.$message.error(
            '选择的文件【' +
              file.name +
              '】只能是【' +
              this.fileTypes.join(',') +
              '】格式'
          );
          return false;
        }
        if (file.size > (this.maxSize || 50) * 1024 * 1024) {
          this.$message.error(
            '选择的文件【' +
              file.name +
              '】不能超过:' +
              (this.maxSize || 50) +
              'M'
          );
          return false;
        }
      }
      return true;
    }
  }
};
</script>
<style lang="less" scoped>
.upload-list {
  padding-left: 0;
  list-style: none;
  .list-file {
    line-height: 20px;
    padding: 4px;
    color: #515a6e;
    border-radius: 4px;
    transition: background-color 0.2s ease-in-out;
    overflow: hidden;
    position: relative;
    font-size: 13px;
    .file-remove {
      display: none;
      right: 0;
      //  margin-left: 50px;
      color: #0e9286;
    }
  }
  .list-file:hover {
    cursor: pointer;
    .file-remove {
      display: initial;
    }
    color: #2d8cf0;
  }
}
.upload-container {
  display: inline-block;
  width: 100%;
  // padding: 10px;
  // min-height: 250px;
  border-radius: 5px;
  .alert {
    margin-top: 43px;
  }
  .button-group > * {
    float: left;
    margin-right: 10px;
  }
  .file-info > span {
    margin-right: 20px;
  }
}
.upload-img {
  display: inline-block;
  .img-item:hover .operation {
    display: block;
  }
  .img-item,
  .img-selector {
    position: relative;
    cursor: pointer;
    margin: 0 10px 10px 0;
    float: left;
    width: 65px;
    height: 65px;
    border: 1px solid #c7c7c7;
    overflow: hidden;
    border-radius: 5px;
    box-sizing: content-box;
    img {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
    .operation {
      display: none;
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      .action {
        opacity: 0.6;
        text-align: center;
        background: #151515de;
        font-size: 14px;
        position: absolute;
        z-index: 90;
        width: 100%;
        bottom: 3px;
        bottom: 0;
        color: #ded5d5;
        padding-right: 7px;
        padding-bottom: 3px;
        line-height: 20px;
        .el-icon-view {
          margin: 0 10px;
        }
      }
      .mask {
        opacity: 0.6;
        background: #9e9e9e;
        top: 0;
        width: 100%;
        height: 100%;
        position: absolute;
      }
    }
  }
  .img-selector {
    font-size: 50px;
    text-align: center;
    i {
      position: relative;
      font-size: 40px;
      color: #6f6f6f;
    }
  }
  .auto-selector {
    .selector {
      line-height: 64px;
    }
  }
  .selector {
    color: #a0a0a0;
  }
  .submit-selector {
    .s-btn {
      line-height: 22px;
      font-size: 12px;
      top: -6px;
      // padding: 2px;
      position: relative;
      background: #2db7f5;
      color: white;
    }
    .selector {
      line-height: 50px;
    }
    .readonly {
      background: #8c8c8c;
    }
  }
}
.big-model {
  width: 100%;
  height: 100%;
  position: relative;
  .m-img {
  }
  .mask {
    position: absolute;
    opacity: 0.6;
    background: #eee;
    top: 0;
    width: 100%;
    height: 100%;
    position: absolute;
  }
}
.auto-upload {
  z-index: 9999999;
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  .j-content {
    text-align: center;
    font-size: 17px;
    top: 40%;
    position: absolute;
    z-index: 999;
    left: 0;
    right: 0;
    width: 240px;
    /* height: 100%; */
    margin: auto;
    background: white;
    /* bottom: 30px; */
    line-height: 50px;
    border-radius: 6px;
    border: 1px solid #d2d2d2;
  }
  .mask {
    cursor: pointer;
    opacity: 0.6;
    width: 100%;
    height: 100%;
    background: #101010;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/redirect/401.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
<template>
  <div style="height: 100%">
    <redirect-error :text="text" message="请求确认是否配置权限" :errorNumber="errorNumber"></redirect-error>
  </div>
</template>
  <script>
import RedirectError from "./RedirectError";
export default {
  components: {
    RedirectError,
  },
  data() {
    return {
      errorNumber: "401",
      text: "抱歉,您没有权限进行此操作~",
    };
  },
};
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/redirect/404.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
<template>
  <div style="height:100%;">
    <redirect-error :text="text" :errorNumber="errorNumber"></redirect-error>
  </div>
</template>
  <script>
import RedirectError from "./RedirectError";
export default {
  components: {
    RedirectError
  },
  data() {
    return {
      errorNumber:'404',
      text: "抱歉,页面好像去火星了~"
    };
  }
};
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/redirect/Message.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
<template>
  <div class="middle-box">
    <div class="text-center animated fadeInDown">
      <i style="font-size: 50px;color: #67c23a;margin-top:40px;" class="el-icon-circle-check"></i>
      <div style="font-size: 20px;margin-top: 10px;" class="error-desc">{{ text }}</div>
    </div>
  </div>
</template>
  <script>
export default {
  props: {
    text: {
      type: String,
      default: "操作成功!",
    },
  },
  methods: {
  },
};
</script>
<style lang="less" scoped>
body {
  background-color: #fff;
}
.middle-box {
  text-align: center;
  padding-top: 80px;
  height: 100%;
  // background: #eee;
  h1 {
    font-size: 140px;
    font-weight: 100;
  }
  .back {
    padding: 10px;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/redirect/RedirectError.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
<template>
  <div class="middle-box">
    <div class="text-center animated fadeInDown">
      <h1>{{ errorNumber }}</h1>
      <h3 class="font-bold">{{message}}</h3>
      <slot></slot>
      <div class="error-desc">{{ text }}</div>
      <div class="back">
        <el-button  type="primary" @click="backHome" icon="md-arrow-round-back"
          >返回首页</el-button >
      </div>
    </div>
  </div>
</template>
  <script>
import { Script } from "vm";
export default {
  props: {
    errorNumber: {
      type: String,
      default: "500",
    },
    message: {
      type: String,
      default: "页面未找到!",
    },
    text: {
      type: String,
      default: "唉...好像出了点问题~",
    },
  },
  methods: {
    backHome: function () {
      this.$router.push({
        path: "/home",
      });
    },
  },
};
</script>
<style lang="less" scoped>
body {
  background-color: #fff;
}
.middle-box {
  text-align: center;
  padding-top: 80px;
  height: 100%;
  // background: #eee;
  h1 {
    font-size: 140px;
    font-weight: 100;
  }
  .back {
    padding: 10px;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/components/redirect/coding.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
<template>
  <div style="height:100%;">
    <redirect-error :text="text" :errorNumber="errorNumber">
      <div>
        <router-link to="SellOrder">
          <Button>点击查看[测试完整示例]</Button>
        </router-link>
      </div>
    </redirect-error>
  </div>
</template>
  <script>
import RedirectError from "./RedirectError";
export default {
  components: {
    RedirectError
  },
  data() {
    return {
      errorNumber: "用例正在整理中",
      text: "详细用例在正准备中,目前可参考[测试完整示例]的使用方法"
    };
  }
};
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/basic/CachePoint.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridBody: '',
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      let enableBtn = this.buttons.find(x => x.value == 'Enable');
      if (enableBtn) {
        enableBtn.onClick = function () {
          this.$message.success('自定义按钮点击事件');
        }
      }
      let disableBtn = this.buttons.find(x => x.value == 'Disable');
      if (disableBtn) {
        disableBtn.onClick = function () {
          this.$message.success('自定义按钮点击事件');
        }
      }
    },
    onInited() {
      //框架初始化配置后
      //如果要配置明细表,在此方法操作
      //this.detailOptions.columns.forEach(column=>{ });
    },
    searchBefore(param) {
      //界面查询前,可以给param.wheres添加查询参数
      //返回false,则不会执行查询
      return true;
    },
    searchAfter(result) {
      //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
      return true;
    },
    addBefore(formData) {
      //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
      return true;
    },
    updateBefore(formData) {
      //编辑保存前formData为对象,包括明细表、删除行的Id
      return true;
    },
    rowClick({ row, column, event }) {
      //查询界面点击行事件
      this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
    },
    modelOpenAfter(row) {
      //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
      //(1)判断是编辑还是新建操作: this.currentAction=='Add';
      //(2)给弹出框设置默认值
      //(3)this.editFormFields.字段='xxx';
      //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
      //看不懂就把输出看:console.log(this.editFormOptions)
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/basic/areaInfo.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridBody: '',
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      let enableBtn = this.buttons.find(x => x.value == 'Enable');
      if (enableBtn) {
        enableBtn.onClick = function () {
          this.$message.success('自定义按钮点击事件');
        }
      }
      let disableBtn = this.buttons.find(x => x.value == 'Disable');
      if (disableBtn) {
        disableBtn.onClick = function () {
          this.$message.success('自定义按钮点击事件');
        }
      }
    },
    onInited() {
      //框架初始化配置后
      //如果要配置明细表,在此方法操作
      //this.detailOptions.columns.forEach(column=>{ });
    },
    searchBefore(param) {
      //界面查询前,可以给param.wheres添加查询参数
      //返回false,则不会执行查询
      return true;
    },
    searchAfter(result) {
      //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
      return true;
    },
    addBefore(formData) {
      //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
      return true;
    },
    updateBefore(formData) {
      //编辑保存前formData为对象,包括明细表、删除行的Id
      return true;
    },
    rowClick({ row, column, event }) {
      //查询界面点击行事件
      this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
    },
    modelOpenAfter(row) {
      //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
      //(1)判断是编辑还是新建操作: this.currentAction=='Add';
      //(2)给弹出框设置默认值
      //(3)this.editFormFields.字段='xxx';
      //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
      //看不懂就把输出看:console.log(this.editFormOptions)
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/basic/areaRouter.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridBody: '',
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      let enableBtn = this.buttons.find(x => x.value == 'Enable');
      if (enableBtn) {
        enableBtn.onClick = function () {
          this.$message.success('自定义按钮点击事件');
        }
      }
      let disableBtn = this.buttons.find(x => x.value == 'Disable');
      if (disableBtn) {
        disableBtn.onClick = function () {
          this.$message.success('自定义按钮点击事件');
        }
      }
    },
    onInited() {
      //框架初始化配置后
      //如果要配置明细表,在此方法操作
      //this.detailOptions.columns.forEach(column=>{ });
    },
    searchBefore(param) {
      //界面查询前,可以给param.wheres添加查询参数
      //返回false,则不会执行查询
      return true;
    },
    searchAfter(result) {
      //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
      return true;
    },
    addBefore(formData) {
      //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
      return true;
    },
    updateBefore(formData) {
      //编辑保存前formData为对象,包括明细表、删除行的Id
      return true;
    },
    rowClick({ row, column, event }) {
      //查询界面点击行事件
      this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
    },
    modelOpenAfter(row) {
      //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
      //(1)判断是编辑还是新建操作: this.currentAction=='Add';
      //(2)给弹出框设置默认值
      //(3)this.editFormFields.字段='xxx';
      //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
      //看不懂就把输出看:console.log(this.editFormOptions)
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/basic/extend/GetLocationStatus.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,261 @@
<template>
    <div>
        <vol-box v-model="showDetialBox" :lazy="true" width="1500px" :padding="15" title="入库单据明细">
            <div class="box-table" style="margin-top: 1%">
                <el-table ref="singleTable" :data="tableData" style="width: 100%; height: 100%" highlight-current-row
                    @row-click="handleRowClick" height="500px" @selection-change="handleSelectionChange">
                    >
                    <el-table-column type="selection" width="55"> </el-table-column>
                    <el-table-column label="序号" type="index" fixed="left" width="55" align="center"></el-table-column>
                    <el-table-column v-for="(item, index) in tableColumns.filter((x) => !x.hidden)" :key="index"
                        :prop="item.field" :label="item.title" :width="item.width" align="center">
                        <template #default="scoped">
                            <div v-if="item.type == 'icon'">
                                <el-tooltip class="item" effect="dark" :content="item.title"
                                    placement="bottom"><el-button type="text"
                                        @click="tableButtonClick(scoped.row, item)"><i :class="item.icon"
                                            style="font-size: 22px"></i></el-button></el-tooltip>
                            </div>
                            <div v-else-if="item.type == 'tag'">
                                <el-tag size="small">
                                    {{ getDictionary(scoped.row, item) }}
                                </el-tag>
                            </div>
                        </template>
                    </el-table-column>
                </el-table>
            </div>
        </vol-box>
    </div>
</template>
<script>
import VolBox from "@/components/basic/VolBox.vue";
export default {
    components: { VolBox },
    data() {
        return {
            showDetialBox: false,
            row: null,
            tableData: [],
            tableColumns: [
                {
                    field: "locationId",
                    title: "货位主键",
                    type: "string",
                    width: 90,
                    align: "left",
                },
                {
                    field: "locationCode",
                    title: "货位编号",
                    type: "string",
                    width: 160,
                    align: "left",
                },
                {
                    field: "beforeStatus",
                    title: "变动前货位状态",
                    type: "tag",
                    width: 150,
                    align: "left",
                    bindKey: "locationStatusEnum"
                },
                {
                    field: "afterStatus",
                    title: "变动后货位状态",
                    type: "tag",
                    width: 150,
                    align: "left",
                    bindKey: "locationStatusEnum"
                },
                {
                    field: "changeType",
                    title: "变动类型",
                    type: "tag",
                    width: 100,
                    align: "left",
                    bindKey: "stockChangeType",
                },
                {
                    field: "orderId",
                    title: "单据主键",
                    type: "string",
                    width: 90,
                    align: "left",
                    hidden: true,
                },
                {
                    field: "orderNo",
                    title: "单据编号",
                    type: "int",
                    width: 160,
                    align: "left",
                },
                {
                    field: "orderDetailId",
                    title: "单据明细主键",
                    type: "string",
                    width: 200,
                    align: "left",
                    hidden: true,
                },
                {
                    field: "taskNum",
                    title: "任务号",
                    type: "string",
                    width: 180,
                    align: "left",
                },
                {
                    field: "creater",
                    title: "创建人",
                    type: "string",
                    width: 90,
                    align: "left",
                },
                {
                    field: "createDate",
                    title: "创建时间",
                    type: "datetime",
                    width: 160,
                    align: "left",
                    sort: true,
                },
                {
                    field: "modifier",
                    title: "修改人",
                    type: "string",
                    width: 100,
                    align: "left",
                    hidden: true,
                },
                {
                    field: "modifyDate",
                    title: "修改时间",
                    type: "datetime",
                    width: 160,
                    align: "left",
                    hidden: true,
                    sort: true,
                },
                {
                    field: "remark",
                    title: "备注",
                    type: "string",
                    width: 100,
                    align: "left",
                    hidden: true,
                },
            ],
            paginations: {
                sort: "CreateDate",
                order: "desc",
                Foots: "",
                total: 0,
                // 2020.08.29增加自定义分页条大小
                sizes: [30, 60, 100, 120],
                size: 30, // é»˜è®¤åˆ†é¡µå¤§å°
                Wheres: [],
                page: 1,
                rows: 30,
            },
            dictionaryList: null,
        };
    },
    methods: {
        open(row) {
            this.row = row;
            this.showDetialBox = true;
            this.getDetailData();
            this.getDictionaryData();
        },
        getDetailData() {
            this.http
                .post(
                    "/api/LocationStatusChangeRecord/GetLocationState?id=" + this.row.id,
                    {},
                    true
                )
                .then((x) => {
                    if (!x.status) return this.$message.error(x.message);
                    this.tableData = x.data;
                });
        },
        getDictionaryData() {
            if (this.dictionaryList) {
                return;
            }
            var param = [];
            this.tableColumns.forEach((x) => {
                if (x.type == "tag" && x.bindKey != "") {
                    param.push(x.bindKey);
                }
            });
            this.http
                .post("api/Sys_Dictionary/GetVueDictionary", param, "查询中")
                .then((x) => {
                    if (x.length > 0) {
                        this.dictionaryList = x;
                    }
                });
        },
        getDictionary(row, column) {
            if (this.dictionaryList) {
                var item = this.dictionaryList.find((x) => x.dicNo == column.bindKey);
                if (item) {
                    var dicItem = item.data.find((x) => x.key == row[column.field]);
                    console.log(dicItem);
                    if (dicItem) {
                        return dicItem.value;
                    }
                    else {
                        return row[column.field];
                    }
                } else {
                    return row[column.field];
                }
            }
        },
    },
    created() { },
};
</script>
<style scoped>
.el-col {
    border-radius: 4px;
}
.grid-content {
    border-radius: 4px;
    min-height: 36px;
}
.content-text {
    display: flex;
    align-items: center;
    justify-content: center;
}
.right-text {
    display: flex;
    align-items: center;
    justify-content: flex-end;
}
</style>
<style>
.el-table .warning-row {
    background: #e6a23c;
}
.el-table .success-row {
    background: #f0f9eb;
}
.el-table .error-row {
    background: #f56c6c;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/basic/locationInfo.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,103 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
import gridBody from './extend/GetLocationStatus.vue'
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridBody: gridBody,
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      let EnableBtn = this.buttons.find(x => x.value == 'Enable');
      if (EnableBtn) {
        EnableBtn.onClick = function () {
          let rows = this.$refs.table.getSelected();
          if (rows.length == 0) return this.$error("请选择数据!");
          var keys = rows.map(x => { return x.id });
          this.http
            .post("api/LocationInfo/LocationEnableStatus", keys, "数据处理中")
            .then((x) => {
              if (!x.status) return this.$message.error(x.message);
              this.$message.success("操作成功");
              this.refresh();
            });
        }
      }
      let DisableBtn = this.buttons.find(x => x.value == 'Disable');
      if (DisableBtn) {
        DisableBtn.onClick = function () {
          let rows = this.$refs.table.getSelected();
          if (rows.length == 0) return this.$error("请选择数据!");
          var keys = rows.map(x => { return x.id });
          this.http
            .post("api/LocationInfo/LocationDisableStatus", keys, "数据处理中")
            .then((x) => {
              if (!x.status) return this.$message.error(x.message);
              this.$message.success("操作成功");
              this.refresh();
            });
        }
      }
      this.columns.push({
        field: '操作',
        title: '操作',
        width: 90,
        fixed: 'right',
        align: 'center',
        formatter: (row) => {
          return (
            '<i style="cursor: pointer;color: #2d8cf0;"class="el-icon-view">查看明细</i>'
          );
        },
        click: (row) => {
          this.$refs.gridBody.open(row);
        }
      });
    },
    onInited() {
      //框架初始化配置后
      //如果要配置明细表,在此方法操作
      //this.detailOptions.columns.forEach(column=>{ });
    },
    searchBefore(param) {
      //界面查询前,可以给param.wheres添加查询参数
      //返回false,则不会执行查询
      return true;
    },
    searchAfter(result) {
      //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
      return true;
    },
    addBefore(formData) {
      //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
      return true;
    },
    updateBefore(formData) {
      //编辑保存前formData为对象,包括明细表、删除行的Id
      return true;
    },
    rowClick({ row, column, event }) {
      //查询界面点击行事件
      this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
    },
    modelOpenAfter(row) {
      //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
      //(1)判断是编辑还是新建操作: this.currentAction=='Add';
      //(2)给弹出框设置默认值
      //(3)this.editFormFields.字段='xxx';
      //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
      //看不懂就把输出看:console.log(this.editFormOptions)
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/basic/materielInfo.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/basic/roadwayInfo.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridBody: '',
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      this.boxOptions.labelWidth = 150;
      this.labelWidth=200;
      let enableBtn = this.buttons.find(x => x.value == 'Enable');
      if (enableBtn) {
        enableBtn.onClick = function () {
          this.$message.success('自定义按钮点击事件');
        }
      }
      let disableBtn = this.buttons.find(x => x.value == 'Disable');
      if (disableBtn) {
        disableBtn.onClick = function () {
          this.$message.success('自定义按钮点击事件');
        }
      }
    },
    onInited() {
      //框架初始化配置后
      //如果要配置明细表,在此方法操作
      //this.detailOptions.columns.forEach(column=>{ });
    },
    searchBefore(param) {
      //界面查询前,可以给param.wheres添加查询参数
      //返回false,则不会执行查询
      return true;
    },
    searchAfter(result) {
      //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
      return true;
    },
    addBefore(formData) {
      //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
      return true;
    },
    updateBefore(formData) {
      //编辑保存前formData为对象,包括明细表、删除行的Id
      return true;
    },
    rowClick({ row, column, event }) {
      //查询界面点击行事件
      this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
    },
    modelOpenAfter(row) {
      //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
      //(1)判断是编辑还是新建操作: this.currentAction=='Add';
      //(2)给弹出框设置默认值
      //(3)this.editFormFields.字段='xxx';
      //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
      //看不懂就把输出看:console.log(this.editFormOptions)
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/basic/warehouse.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridBody: '',
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      let enableBtn = this.buttons.find(x => x.value == 'Enable');
      if (enableBtn) {
        enableBtn.onClick = function () {
          this.$message.success('自定义按钮点击事件');
        }
      }
      let disableBtn = this.buttons.find(x => x.value == 'Disable');
      if (disableBtn) {
        disableBtn.onClick = function () {
          this.$message.success('自定义按钮点击事件');
        }
      }
    },
    onInited() {
      //框架初始化配置后
      //如果要配置明细表,在此方法操作
      //this.detailOptions.columns.forEach(column=>{ });
    },
    searchBefore(param) {
      //界面查询前,可以给param.wheres添加查询参数
      //返回false,则不会执行查询
      return true;
    },
    searchAfter(result) {
      //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
      return true;
    },
    addBefore(formData) {
      //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
      return true;
    },
    updateBefore(formData) {
      //编辑保存前formData为对象,包括明细表、删除行的Id
      return true;
    },
    rowClick({ row, column, event }) {
      //查询界面点击行事件
      this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
    },
    modelOpenAfter(row) {
      //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
      //(1)判断是编辑还是新建操作: this.currentAction=='Add';
      //(2)给弹出框设置默认值
      //(3)this.editFormFields.字段='xxx';
      //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
      //看不懂就把输出看:console.log(this.editFormOptions)
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/inbound/inboundOrderDetail.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/inbound/receiveOrder.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/SelectedStock.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,230 @@
<template>
  <div>
    <vol-box
      v-model="showDetialBox"
      :lazy="true"
      width="75%"
      :padding="15"
      title="出库详情"
    >
      <div class="box-head">
        <el-alert :closable="false" style="width: 100%">
          <el-row>
            <el-col :span="24">
              <span class="less-style">物料名称: {{ row.materielName }} </span>
              <el-divider direction="vertical"></el-divider>
              <span class="less-style">物料编号: {{ row.materielCode }} </span>
              <el-divider direction="vertical"></el-divider>
              <span class="less-style"
                >需求数量: {{ row.orderQuantity }}
              </span>
              <el-divider direction="vertical"></el-divider>
              <span class="less-style"
                >已分配数量: {{ row.lockQuantity }}
              </span>
            </el-col>
          </el-row>
        </el-alert>
      </div>
      <div class="box-table" style="margin-top: 1%">
        <el-table
          ref="singleTable"
          :data="tableData"
          style="width: 100%; height: 100%"
          highlight-current-row
          height="500px"
        >
          >
          <el-table-column
            label="序号"
            type="index"
            fixed="left"
            width="55"
            align="center"
          ></el-table-column>
          <el-table-column
            v-for="(item, index) in tableColumns.filter((x) => !x.hidden)"
            :key="index"
            :prop="item.prop"
            :label="item.title"
            :width="item.width"
            align="center"
          >
            <template #default="scoped" v-if="item.type == 'icon'">
              <el-tooltip
                class="item"
                effect="dark"
                :content="item.title"
                placement="bottom"
                ><el-button
                  type="text"
                  @click="tableButtonClick(scoped.row, item)"
                  ><i :class="item.icon" style="font-size: 22px"></i></el-button
              ></el-tooltip>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <template #footer>
        <!-- <el-button type="primary" size="small" @click="submit">确认</el-button> -->
        <el-button type="danger" size="small" @click="showDetialBox = false"
          >关闭</el-button
        >
      </template>
    </vol-box>
  </div>
</template>
    <script>
import VolBox from "@/components/basic/VolBox.vue";
export default {
  components: { VolBox },
  data() {
    return {
      row: null,
      showDetialBox: false,
      tableData: [],
      tableColumns: [
        {
          prop: "id",
          title: "主键",
          type: "string",
          width: 150,
          hidden: true,
        },
        {
          prop: "orderNo",
          title: "单据编号",
          type: "string",
          width: 150,
        },
        {
          prop: "orderDetailId",
          title: "单据明细主键",
          type: "string",
          width: 150,
          hidden: true,
        },
        {
          prop: "orderType",
          title: "单据类型",
          type: "string",
          width: 90,
        },
        {
          prop: "batchNo",
          title: "批次号",
          type: "string",
          width: 120,
        },
        {
          prop: "materielCode",
          title: "物料编号",
          type: "string",
          width: 150,
        },
        {
          prop: "materielName",
          title: "物料名称",
          type: "string",
          width: 150,
        },
        {
          prop: "stockId",
          title: "库存主键",
          type: "string",
          width: 150,
          hidden: true,
        },
        {
          prop: "originalQuantity",
          title: "原始库存量",
          type: "string",
          width: 100,
        },
        {
          prop: "assignQuantity",
          title: "分配出库量",
          type: "string",
          width: 100,
        },
        {
          prop: "palletCode",
          title: "托盘编号",
          type: "string",
          width: 150,
        },
        {
          prop: "locationCode",
          title: "货位编号",
          type: "string",
          width: 180,
        },
        {
          prop: "status",
          title: "状态",
          type: "string",
        },
      ],
    };
  },
  methods: {
    open(row) {
      this.row = row;
      this.showDetialBox = true;
      this.getData();
    },
    getData() {
      this.http
        .post(
          "api/OutStockLockInfo/GetByOrderDetailId?orderDetailId=" +
            this.row.id,
          null,
          "查询中"
        )
        .then((x) => {
          this.tableData = x;
        });
    },
  },
};
</script>
  <style scoped>
.less-style {
  color: black;
}
.equle-style {
  color: green;
}
.more-style {
  color: red;
}
</style>
  <style>
.text-button:hover {
  background-color: #f0f9eb !important;
}
.el-table .warning-row {
  background: oldlace;
}
.box-table .el-table tbody tr:hover > td {
  background-color: #d8e0d4 !important;
  /* color: #ffffff; */
}
.box-table .el-table tbody tr.current-row > td {
  background-color: #f0f9eb !important;
  /* color: #ffffff; */
}
.el-table .success-row {
  background: #f0f9eb;
}
.box-table .el-table {
  border: 1px solid #ebeef5;
}
.box-head .el-alert__content {
  width: 100%;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/StockSelect.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,251 @@
<template>
  <div>
    <vol-box v-model="showDetialBox" :lazy="true" width="60%" :padding="15" title="指定库存">
      <div class="box-head">
        <el-alert :closable="false" style="width: 100%">
          <el-row>
            <el-col :span="20">
              <span class="less-style">物料名称: {{ row.materielName }} </span>
              <el-divider direction="vertical"></el-divider>
              <span class="less-style">物料编号: {{ row.materielCode }} </span>
              <el-divider direction="vertical"></el-divider>
              <span class="less-style">需求数量: {{ row.orderQuantity }}
              </span>
              <el-divider direction="vertical"></el-divider>
              <span :class="selectionClass">已选数量: {{ selectionSum }}
              </span>
            </el-col>
            <el-col :span="2">
              <el-link type="primary" size="small" style="float: right; height: 20px"
                @click="getData">刷新</el-link></el-col>
            <el-col :span="2">
              <el-link type="primary" size="small" style="float: right; height: 20px"
                @click="revokeAssign">撤销分配</el-link></el-col>
          </el-row>
        </el-alert>
      </div>
      <div class="box-table" style="margin-top: 1%">
        <el-table ref="singleTable" :data="tableData" style="width: 100%; height: 100%" highlight-current-row
          @row-click="handleRowClick" height="500px" @selection-change="handleSelectionChange">
          >
          <el-table-column type="selection" width="55"> </el-table-column>
          <el-table-column label="序号" type="index" fixed="left" width="55" align="center"></el-table-column>
          <el-table-column v-for="(item, index) in tableColumns.filter((x) => !x.hidden)" :key="index" :prop="item.prop"
            :label="item.title" :width="item.width" align="center">
            <template #default="scoped" v-if="item.type == 'icon'">
              <el-tooltip class="item" effect="dark" :content="item.title" placement="bottom"><el-button type="text"
                  @click="tableButtonClick(scoped.row, item)"><i :class="item.icon"
                    style="font-size: 22px"></i></el-button></el-tooltip>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <template #footer>
        <el-button type="primary" size="small" @click="outbound">直接出库</el-button>
        <el-button type="primary" size="small" @click="lockStock">锁定库存</el-button>
        <el-button type="danger" size="small" @click="showDetialBox = false">关闭</el-button>
      </template>
    </vol-box>
  </div>
</template>
<script>
import VolBox from "@/components/basic/VolBox.vue";
export default {
  components: { VolBox },
  data() {
    return {
      row: null,
      showDetialBox: false,
      tableData: [],
      tableColumns: [
        {
          prop: "materielCode",
          title: "物料编号",
          type: "string",
          width: 150,
        },
        {
          prop: "materielName",
          title: "物料名称",
          type: "string",
          width: 150,
        },
        {
          prop: "palletCode",
          title: "托盘编号",
          type: "string",
          width: 150,
        },
        {
          prop: "locationCode",
          title: "货位编号",
          type: "string",
          width: 180,
        },
        {
          prop: "useableQuantity",
          title: "可用数量",
          type: "string",
        },
      ],
      selection: [],
      selectionSum: 0,
      selectionClass: "less-style",
      originalQuantity: 0,
    };
  },
  methods: {
    open(row) {
      this.row = row;
      this.showDetialBox = true;
      this.originalQuantity = this.row.lockQuantity;
      this.selectionSum = this.row.lockQuantity;
      this.getData();
      if (this.selectionSum == this.row.orderQuantity) {
        this.selectionClass = "equle-style";
      } else if (this.selectionSum < this.row.orderQuantity) {
        this.selectionClass = "less-style";
      } else {
        this.selectionClass = "more-style";
      }
    },
    lockStock() {
      this.http
        .post(
          "api/OutboundOrderDetail/LockOutboundStock?id=" + this.row.id,
          this.selection,
          "数据处理中"
        )
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.$message.success("操作成功");
          this.showDetialBox = false;
          this.$emit("parentCall", ($vue) => {
            $vue.getData();
          });
        });
    },
    outbound() {
      this.http
        .post(
          "api/Task/GenerateOutboundTask?id=" + this.row.id,
          this.selection,
          "数据处理中"
        )
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.$message.success("操作成功");
          this.showDetialBox = false;
          this.$emit("parentCall", ($vue) => {
            $vue.getData();
          });
        });
    },
    getData() {
      this.http
        .post(
          "api/StockInfo/GetStockSelectViews?materielCode=" +
          this.row.materielCode,
          null,
          "查询中"
        )
        .then((x) => {
          this.tableData = x;
        });
    },
    revokeAssign() {
      console.log(this.row);
      this.http
        .post(
          "api/OutboundOrderDetail/RevokeLockOutboundStock?id=" + this.row.id,
          null,
          "数据处理中"
        )
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.$message.success("操作成功");
          this.showDetialBox = false;
          this.$emit("parentCall", ($vue) => {
            $vue.getData();
          });
        });
    },
    handleSelectionChange(val) {
      this.selection = val;
      this.selectionSum =
        val.reduce(
          (accumulator, currentValue) =>
            accumulator + currentValue["useableQuantity"],
          0
        ) + this.originalQuantity;
      if (this.selectionSum == this.row.orderQuantity) {
        this.selectionClass = "equle-style";
      } else if (this.selectionSum < this.row.orderQuantity) {
        this.selectionClass = "less-style";
      } else {
        this.selectionClass = "more-style";
      }
    },
    toggleSelection(rows) {
      if (rows) {
        rows.forEach((row) => {
          this.$refs.singleTable.toggleRowSelection(row);
        });
      } else {
        this.$refs.singleTable.clearSelection();
      }
    },
    clearSelection() {
      this.$refs.singleTable.clearSelection();
    },
    handleRowClick(row) {
      this.$refs.singleTable.toggleRowSelection(row);
    },
  },
};
</script>
<style scoped>
.less-style {
  color: black;
}
.equle-style {
  color: green;
}
.more-style {
  color: red;
}
</style>
<style>
.text-button:hover {
  background-color: #f0f9eb !important;
}
.el-table .warning-row {
  background: oldlace;
}
.box-table .el-table tbody tr:hover>td {
  background-color: #d8e0d4 !important;
  /* color: #ffffff; */
}
.box-table .el-table tbody tr.current-row>td {
  background-color: #f0f9eb !important;
  /* color: #ffffff; */
}
.el-table .success-row {
  background: #f0f9eb;
}
.box-table .el-table {
  border: 1px solid #ebeef5;
}
.box-head .el-alert__content {
  width: 100%;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,371 @@
<template>
  <div>
    <vol-box v-model="showDetialBox" :lazy="true" width="75%" :padding="15" title="单据明细信息">
      <div class="box-head">
        <el-alert :closable="false" style="width: 100%">
          <el-row>
            <el-col :span="16">
              <span>已选中 {{ selection.length }} é¡¹</span>
            </el-col>
            <el-col :span="8">
              <el-link type="primary" size="small" style="float: right; height: 20px" @click="lockstocks">锁定库存</el-link>
              <el-link type="primary" size="small" style="float: right; height: 20px; margin-right: 10px"
                @click="outbound">直接出库</el-link>
              <el-link type="primary" size="small" style="float: right; height: 20px; margin-right: 10px"
                @click="getData">刷新</el-link></el-col>
          </el-row>
        </el-alert>
      </div>
      <div class="box-table" style="margin-top: 1%">
        <el-table ref="singleTable" :data="tableData" style="width: 100%; height: 100%" highlight-current-row
          @current-change="handleCurrentChange" height="500px" @row-click="handleRowClick"
          @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55"> </el-table-column>
          <el-table-column label="序号" type="index" fixed="left" width="55" align="center"></el-table-column>
          <el-table-column v-for="(item, index) in tableColumns.filter((x) => !x.hidden)" :key="index" :prop="item.prop"
            :label="item.title" :width="item.width" align="center">
            <template #default="scoped">
              <div v-if="item.type == 'icon'">
                <el-tooltip class="item" effect="dark" :content="item.title" placement="bottom"><el-link type="primary"
                    :disabled="getButtonEnable(item.prop, scoped.row)" @click="tableButtonClick(scoped.row, item)"><i
                      :class="item.icon" style="font-size: 22px"></i></el-link></el-tooltip>
              </div>
              <div v-else-if="item.type == 'tag'">
                <el-tag size="small">
                  {{ getDictionary(scoped.row, item) }}
                </el-tag>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </vol-box>
    <stock-select ref="child" @parentCall="parentCall"></stock-select>
    <selected-stock ref="selectedStock" @parentCall="parentCall"></selected-stock>
  </div>
</template>
<script>
import VolBox from "@/components/basic/VolBox.vue";
import VolForm from "@/components/basic/VolForm.vue";
import StockSelect from "./StockSelect.vue";
import SelectedStock from "./SelectedStock.vue";
export default {
  components: { VolBox, VolForm, StockSelect, SelectedStock },
  data() {
    return {
      row: null,
      showDetialBox: false,
      flag: false,
      currentRow: null,
      selection: [],
      tableData: [],
      tableColumns: [
        {
          prop: "id",
          title: "Id",
          type: "int",
          width: 90,
          hidden: true,
        },
        {
          prop: "orderId",
          title: "出库单主键",
          type: "string",
          width: 90,
          hidden: true,
        },
        {
          prop: "materielCode",
          title: "物料编号",
          type: "string",
          width: 150,
        },
        {
          prop: "materielName",
          title: "物料名称",
          type: "string",
          width: 150,
        },
        {
          prop: "batchNo",
          title: "批次号",
          type: "string",
          width: 90,
        },
        {
          prop: "orderQuantity",
          title: "单据数量",
          type: "string",
          width: 90,
        },
        {
          prop: "lockQuantity",
          title: "锁定数量",
          type: "int",
          width: 90,
        },
        {
          prop: "overOutQuantity",
          title: "已出数量",
          type: "string",
          width: 90,
        },
        {
          prop: "orderDetailStatus",
          title: "订单明细状态",
          type: "tag",
          width: 180,
          bindKey: "orderDetailStatusEnum"
        },
        {
          prop: "assignStock",
          title: "指定库存",
          type: "icon",
          width: 90,
          icon: "el-icon-s-grid",
        },
        {
          prop: "viewDetail",
          title: "出库详细",
          type: "icon",
          width: 90,
          icon: "el-icon-s-operation",
        },
        {
          prop: "creater",
          title: "创建人",
          type: "string",
          width: 90,
        },
        {
          prop: "createDate",
          title: "创建时间",
          type: "datetime",
          width: 160,
        },
        {
          prop: "modifier",
          title: "修改人",
          type: "string",
          width: 100,
        },
        {
          prop: "modifyDate",
          title: "修改时间",
          type: "datetime",
          width: 160,
        },
        {
          prop: "remark",
          title: "备注",
          type: "string",
        },
      ],
      paginations: {
        sort: "id",
        order: "desc",
        Foots: "",
        total: 0,
        // 2020.08.29增加自定义分页条大小
        sizes: [30, 60, 100, 120],
        size: 30, // é»˜è®¤åˆ†é¡µå¤§å°
        Wheres: [],
        page: 1,
        rows: 30,
      },
      searchFormOptions: [
        [
          {
            title: "单据编号",
            field: "allocation_code",
            type: "like",
          },
          {
            title: "单据类型",
            field: "allocation_type",
            type: "select",
            dataKey: "OrderType",
            data: [],
          },
          {
            title: "单据状态",
            field: "allocation_state",
            type: "select",
            dataKey: "OrderState",
            data: [],
          },
        ],
      ],
      searchFormFields: {
        allocation_code: "",
        allocation_type: "",
        allocation_state: "",
      },
      dictionaryList: null,
    };
  },
  methods: {
    open(row) {
      this.row = row;
      this.showDetialBox = true;
      this.getDictionaryData();
      this.getData();
    },
    getData() {
      var wheres = [{ name: "orderId", value: this.row.id }];
      var param = {
        page: this.paginations.page,
        rows: this.paginations.rows,
        sort: this.paginations.sort,
        order: this.paginations.order,
        wheres: JSON.stringify(wheres), // æŸ¥è¯¢æ¡ä»¶ï¼Œæ ¼å¼ä¸º[{ name: "字段", value: "xx" }]
      };
      this.http
        .post("api/OutboundOrderDetail/GetPageData", param, "查询中")
        .then((x) => {
          this.tableData = x.rows;
        });
    },
    tableButtonClick(row, column) {
      if (column.prop == "assignStock") {
        this.$refs.child.open(row);
      } else {
        this.$refs.selectedStock.open(row);
      }
    },
    lockstocks() {
      if (this.selection.length === 0) {
        return this.$message.error("请选择单据明细");
      }
      var keys = this.selection.map((item) => item.id); // èŽ·å–é€‰ä¸­è¡Œçš„id
      this.http
        .post("api/OutboundOrderDetail/LockOutboundStocks", keys, "数据处理中")
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.$message.success("操作成功");
          this.showDetialBox = false;
          this.$emit("parentCall", ($vue) => {
            $vue.getData();
          });
        });
    },
    outbound() {
      if (this.selection.length === 0) {
        return this.$message.error("请选择单据明细");
      }
      var keys = this.selection.map((item) => item.id); // èŽ·å–é€‰ä¸­è¡Œçš„id
      this.http
        .post("api/Task/GenerateOutboundTasks", keys, "数据处理中")
        .then((x) => {
          if (!x.status) return this.$message.error(x.message);
          this.$message.success("操作成功");
          this.showDetialBox = false;
          this.$emit("parentCall", ($vue) => {
            $vue.getData();
          });
        });
    },
    setCurrent(row) {
      this.$refs.singleTable.setCurrentRow(row);
    },
    handleCurrentChange(val) {
      this.currentRow = val;
    },
    getButtonEnable(propName, row) {
      if (propName == "assignStock") {
        if (
          row.orderDetailStatus !== 0 &&
          row.orderDetailStatus !== 60 &&
          row.orderDetailStatus !== 70
        ) {
          return true;
        } else {
          return false;
        }
      }
      return false;
    },
    parentCall(fun) {
      if (typeof fun != "function") {
        return console.log("扩展组件需要传入一个回调方法才能获取父级Vue对象");
      }
      fun(this);
    },
    handleRowClick(row) {
      this.$refs.singleTable.toggleRowSelection(row);
    },
    handleSelectionChange(val) {
      this.selection = val;
    },
    getDictionaryData() {
      if (this.dictionaryList) {
        return;
      }
      var param = [];
      this.tableColumns.forEach((x) => {
        if (x.type == "tag" && x.bindKey != "") {
          param.push(x.bindKey);
        }
      });
      this.http
        .post("api/Sys_Dictionary/GetVueDictionary", param, "查询中")
        .then((x) => {
          if (x.length > 0) {
            this.dictionaryList = x;
          }
        });
    },
    getDictionary(row, column) {
      if (this.dictionaryList) {
        var item = this.dictionaryList.find((x) => x.dicNo == column.bindKey);
        if (item) {
          var dicItem = item.data.find((x) => x.key == row[column.prop]);
          console.log(dicItem);
          if (dicItem) {
            return dicItem.value;
          } else {
            return row[column.prop];
          }
        } else {
          return row[column.prop];
        }
      }
    },
  },
};
</script>
<style scoped>
.text-button {
  border: 0px;
}
</style>
<style>
.text-button:hover {
  background-color: #f0f9eb !important;
}
.el-table .warning-row {
  background: oldlace;
}
.box-table .el-table tbody tr:hover>td {
  background-color: #d8e0d4 !important;
  /* color: #ffffff; */
}
.box-table .el-table tbody tr.current-row>td {
  background-color: #f0f9eb !important;
  /* color: #ffffff; */
}
.el-table .success-row {
  background: #f0f9eb;
}
.box-table .el-table {
  border: 1px solid #ebeef5;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
import gridBody from './extend/outOrderDetail.vue'
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: gridBody,
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
        //扩展页面初始化操作
        this.columns.push({
          field: '操作',
          title: '操作',
          width: 90,
          fixed: 'right',
          align: 'center',
          formatter: (row) => {
              return (
                  '<i style="cursor: pointer;color: #2d8cf0;"class="el-icon-view">查看明细</i>'
              );
          },
          click: (row) => {
              this.$refs.gridBody.open(row);
          }
      });
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/outbound/outboundOrderDetail.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/record/locationStatusChangeRecord.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
        this.boxOptions.labelWidth = 180;
        this.labelWidth=150;
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/record/stockQuantityChangeRecord.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/stock/stockInfo.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/stock/stockInfoDetail.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/stock/stockView.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Dictionary.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
import { h, resolveComponent } from 'vue';
let extension = {
    components: { //动态扩充组件或组件路径
        //表单header、content、footer对应位置扩充的组件
        //扩展组件引入方式
        gridHeader: '',
        gridBody: '',
        gridFooter: '',
        //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
        modelHeader: '',
        modelBody: '',
        modelFooter: ''
    },
    buttons: [], //扩展的按钮
    methods: { //事件扩展
        onInit() {
            //点击单元格编辑与结束编辑(默认是点击单元格编辑,鼠标离开结束编辑)
            this.detailOptions.clickEdit = true;
            this.editFormOptions.forEach(x => {
                x.forEach(item => {
                    if (item.field == 'ParentId') {
                        item.min = 0;
                    }
                    if (item.field == "DbSql") {
                        item.placeholder = "如果从数据库加载数据源,请按此格式配置sql语句:select orderType as key,orderName as value from order  å¦‚果需要根据用户信息加载数据源,请配置好此sql,再修改后台DictionaryHandler.GetCustomDBSql方法";
                    }
                })
            })
            this.detailOptions.columns.forEach(x => {
                if (x.field == 'OrderNo') {
                    x.summary = true;
                }
            })
            //保存后不关闭编辑框
            this.boxOptions.saveClose = false;
        },
        onInited() {
            this.boxOptions.height = document.body.clientHeight * 0.87
            this.height = this.height - 45;
        },
        addBefore(formData) {
            return this.saveBefore(formData);
        },
        updateBefore(formData) {
            return this.saveBefore(formData);
        },
        saveBefore(formData) {
            if (this.editFormFields.DbSql &&
                (this.editFormFields.DbSql.indexOf('value') == -1 ||
                    this.editFormFields.DbSql.indexOf('key') == -1)
            ) {
                this.$message.error("sql语句必须包括key/value字段,如:select orderType as key,orderName as value from order");
                return false;
            }
            return true;
        },
        searchBefore(param) {
            return true;
        },
        searchAfter(result) {
            return true;
        }
    }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/system/Sys_DictionaryList.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
let extension = {
    components: {//动态扩充组件或组件路径
        //表单header、content、footer对应位置扩充的组件
        gridHeader:'',
        gridbody:'',
        gridFooter: '',
        //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
        modelHeader: '',
        modelBody: '',
        modelFooter: ''
    },
    buttons: [],//扩展的按钮
    methods: {//事件扩展
        onInit() {
        },
        onInited() {
        }
    }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Log.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
import { h, resolveComponent } from 'vue';
let extension = {
  components: {
    //动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: "", //{ template: "<div>扩展组xxä»¶</div>" },
    gridBody: '',
    gridFooter: "",
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: "",
    modelBody: "",
    modelFooter: ""
  },
  buttons: [], //扩展的按钮
  methods: {
    //事件扩展
    onInit() {
      console.log("sys_log")
      this.setFiexdSearchForm(true);
    },
    onInited() {
      this.height = this.height - 170;
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Role.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
let extension = {
  components: {//动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: '',
    gridBody: '',
    gridFooter: '',
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  buttons: [],//扩展的按钮
  tableAction:"Sys_Role",
  methods: {//事件扩展
    onInited () {
      this.height = this.height - 80;
       this.editFormOptions.forEach(x => {
        x.forEach(item => {
          if (item.field == 'ParentId') {
            item.title = "上级角色";
            //设置任意节点都能选中(默认只能选中最后一个节点)
            item.changeOnSelect = true;
          }
        })
      })
    },
    onInit() {
      //设置treetable的唯一值字段(这个字段的值在表里面必须是唯一的)
      this.rowKey="Role_Id";
    },
    /***加载后台数据见Sys_RoleController.cs文件***/
    loadTreeChildren(tree, treeNode, resolve) { //加载子节点
      let url=`api/role/getTreeTableChildrenData?roleId=${tree.Role_Id}`;
      this.http.post(url,{}).then(result=>{
        resolve(result.rows)
      })
    },
      /***加载后台数据见Sys_RoleController.cs文件***/
    searchBefore(params){//判断加载根节点或子节点
      //没有查询条件,默认查询返回所有根节点数据
      if (!params.wheres.length) {
        params.value=1;
      }
      return true;
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Role1.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
import { h, resolveComponent } from 'vue';
let extension = {
  components: {//动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: '',
    gridBody: {
      render () {
          return [
              h(resolveComponent('el-alert'), {
                  style: { 'margin-bottom': '12px' },
                  'show-icon': true, type: 'error',
                  closable: false, title: '关于TreeTable使用'
              }, ' treetable同样全部代码自动生成,页面生成后设置this.rowKe="xxx" tree主键字段,即可完成树形table配置,具体说明见Sys_Role1.js'),
          ]
      }
  },
    gridFooter: '',
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  buttons: [],//扩展的按钮
  tableAction:"Sys_Role",
  methods: {//事件扩展
    onInited () {
      this.height = this.height - 80;
       this.editFormOptions.forEach(x => {
        x.forEach(item => {
          if (item.field == 'ParentId') {
            item.title = "上级角色";
            //设置任意节点都能选中(默认只能选中最后一个节点)
            item.changeOnSelect = true;
          }
        })
      })
    },
    onInit() {
      //设置treetable的唯一值字段(这个字段的值在表里面必须是唯一的)
      this.rowKey="Role_Id";
    },
    /***加载后台数据见Sys_RoleController.cs文件***/
    loadTreeChildren(tree, treeNode, resolve) { //加载子节点
      let url=`api/role/getTreeTableChildrenData?roleId=${tree.Role_Id}`;
      this.http.post(url,{}).then(result=>{
        resolve(result.rows)
      })
    },
      /***加载后台数据见Sys_RoleController.cs文件***/
    searchBefore(params){//判断加载根节点或子节点
      //没有查询条件,默认查询返回所有根节点数据
      if (!params.wheres.length) {
        params.value=1;
      }
      return true;
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/system/Sys_User.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,86 @@
import {  defineAsyncComponent } from "vue";
let extension = {
    components: { //动态扩充组件或组件路径
        //表单header、content、footer对应位置扩充的组件
        gridHeader: defineAsyncComponent(() =>
            import("./Sys_User/Sys_UserGridHeader.vue")),
        gridBody: '',
        gridFooter: '',
        //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
        modelHeader: '',
        modelBody: '',
        modelFooter: ''
    },
    text: "只能看到当前角色下的所有帐号",
    buttons: [], //扩展的按钮
    methods: { //事件扩展
        onInit() {
            this.boxOptions.height = 530;
            this.columns.push({
                title: '操作',
                hidden: false,
                align: "center",
                fixed: 'right',
                width: 120,
                render: (h, { row, column, index }) => {
                    return h(
                        "div", { style: { 'font-size': '13px', 'cursor': 'pointer', 'color': '#409eff' } }, [
                        h(
                            "a", {
                            style: { 'margin-right': '15px' },
                            onClick: (e) => {
                                e.stopPropagation()
                                this.$refs.gridHeader.open(row);
                            }
                        }, "修改密码"
                        ),
                        h(
                            "a", {
                            style: {},
                            onClick: (e) => {
                                e.stopPropagation()
                                this.edit(row);
                            }
                        },
                            "编辑"
                        ),
                    ])
                }
            })
        },
        onInited() { },
        addAfter(result) { //用户新建后,显示随机生成的密码
            if (!result.status) {
                return true;
            }
            //显示新建用户的密码
            //2020.08.28优化新建成后提示方式
            this.$confirm(result.message, '新建用户成功', {
                confirmButtonText: '确定',
                type: 'success',
                center: true
            }).then(() => { })
            this.boxModel = false;
            this.refresh();
            return false;
        },
        modelOpenAfter() {
            //点击弹出框后,如果是编辑状态,禁止编辑用户名,如果新建状态,将用户名字段设置为可编辑
            let isEDIT = this.currentAction == this.const.EDIT;
            this.editFormOptions.forEach(item => {
                item.forEach(x => {
                    if (x.field == "UserName") {
                        x.disabled=isEDIT;
                    }
                })
                //不是新建,性别默认值设置为男
                if (!isEDIT) {
                    this.editFormFields.Gender = "0";
                }
            })
        }
    }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/system/Sys_User/Sys_UserGridHeader.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
<template>
  <div>
    <vol-box
      v-model="model"
      :padding="30"
      title="修改密码"
      :width="500"
      :height="250"
    >
      <el-alert type="success">
        <h3>
          <span>帐号:{{ row.userName }}</span>
          <span>用户:{{ row.userTrueName }}</span>
        </h3>
      </el-alert>
      <div>
        <el-input
          placeholder="请输入密码"
          v-model="password"
          size="large"
          style="width: 100%; margin-top: 15px"
        />
      </div>
      <template #footer>
        <el-button
          type="primary"
          @click="savePwd()"
          >修改密码</el-button
        >
        <el-button
          @click="model = false"
          >关闭</el-button
        >
      </template>
    </vol-box>
  </div>
</template>
<script>
import { defineComponent, defineAsyncComponent } from "vue";
export default defineComponent({
  components: {
    VolBox: defineAsyncComponent(() => import("@/components/basic/VolBox.vue"))
  },
  data() {
    return {
      row: {},
      password: "",
      model: false,
    };
  },
  methods: {
    open(row) {
      this.password = "";
      this.row = row;
      this.model = true;
    },
    savePwd() {
      if (!this.password) return this.$Message.error("请输密码");
      if (this.password.length < 6)
        return this.$Message.error("密码长度至少6位");
      let url =
        "/api/user/modifyUserPwd?password=" +
        this.password +
        "&userName=" +
        this.row.UserName;
      this.http.post(url, {}, true).then((x) => {
        if (!x.status) {
          return this.$message.error(x.message);
        }
        this.model = false;
        this.$Message.success(x.message);
      });
    },
  },
  created() {},
})
</script>
<style lang="less" scoped>
h3 {
  font-weight: 500;
  > span:last-child {
    margin-left: 30px;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/system/system/Sys_Department.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,152 @@
/*****************************************************************************************
**  Author:jxx 2022
**  QQ:283591387
**完整文档见:http://v2.volcore.xyz/document/api ã€ä»£ç ç”Ÿæˆé¡µé¢ViewGrid】
**常用示例见:http://v2.volcore.xyz/document/vueDev
**后台操作见:http://v2.volcore.xyz/document/netCoreDev
*****************************************************************************************/
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridBody: '',
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {  //框架初始化配置前,
      this.rowKey = "DepartmentId";
    },
    loadTreeChildren(tree, treeNode, resolve) { //加载子节点
      let url = `api/Sys_Department/getTreeTableChildrenData?departmentId=${tree.DepartmentId}`;
      this.http.post(url, {}).then(result => {
        resolve(result.rows)
      })
    },
    /***加载后台数据见Sys_RoleController.cs文件***/
    searchBefore(params) {//判断加载根节点或子节点
      //没有查询条件,默认查询返回所有根节点数据
      if (!params.wheres.length) {
        params.value = 1;
      }
      return true;
    },
    onInited() {
      let hasUpdate, hasDel, hasAdd;
      this.buttons.forEach((x) => {
        if (x.value == 'Update') {
          x.hidden = true;
          hasUpdate = true;
        } else if (x.value == 'Delete') {
          hasDel = true;
          x.hidden = true;//隐藏按钮
        }
        else if (x.value == 'Add') {
          x.type="primary";
          hasAdd = true;
        }
      });
      if (!(hasUpdate || hasDel || hasAdd)) {
        return;
      }
      this.columns.push({
        title: '操作',
        field: '操作',
        width: 80,
        fixed: 'right',
        align: 'center',
        render: (h, { row, column, index }) => {
          return (
            <div>
              <el-button
                onClick={($e) => {
                  this.addBtnClick(row)
                }}
                type="primary"
                link
                v-show={hasAdd}
                icon="Plus"
              >
              </el-button>
              <el-button
                onClick={($e) => {
                  this.edit(row);
                }}
                type="success"
                link
                v-show={hasUpdate}
                icon="Edit"
              >
              </el-button>
              <el-tooltip
                class="box-item"
                effect="dark"
                content="删除"
                placement="top"
              >
                <el-button
                  link
                  onClick={($e) => {
                    this.del(row);
                  }}
                  v-show={hasDel}
                  type="danger"
                  icon="Delete"
                >
                </el-button>
              </el-tooltip>
            </div>
          );
        }
      });
    },
    addBtnClick(row) {
      //这里是动态addCurrnetRow属性记录当前点击的行数据,下面modelOpenAfter设置默认值
      this.addCurrnetRow = row;
      this.add();
    },
    addAfter() {//添加后刷新字典
      this.initDicKeys();
      return true;
    },
    updateAfter() {
      this.initDicKeys();
      return true;
    },
    delAfter(result) {//查询界面的表删除后
      this.initDicKeys();
      return true;
    },
    modelOpenAfter(row) {
      //点击行上的添加按钮事件
      if (this.addCurrnetRow) {
        //获取当前组织构架的所有父级id,用于设置新建时父级id的默认值
        //获取数据数据源
        let data = [];
        this.editFormOptions.forEach(options => {
          options.forEach(option => {
            if (option.field == 'ParentId') {
              data = option.orginData;
            }
          })
        })
        let parentIds = this.base.getTreeAllParent(this.addCurrnetRow.DepartmentId, data).map(x => { return x.id });
        //设置编辑表单上级组织的默认值
        this.editFormFields.ParentId = parentIds;
        this.addCurrnetRow = null;
      }
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/taskinfo/task.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,96 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
        let TaskHandCancelBtn = this.buttons.find(x => x.value == 'TaskHandCancel');
      if (TaskHandCancelBtn) {
        TaskHandCancelBtn.onClick = function () {
          let rows = this.$refs.table.getSelected();
          if (rows.length == 0) return this.$error("请选择数据!");
          if (rows.length > 1) return this.$error("请选择一条数据!");
          var param = rows[0].taskNum;
          this.http
            .post("api/Task/TaskCancel?taskNum="+param, "数据处理中...")
            .then((x) => {
              if (x.status) {
                this.$Message.success('任务取消成功.');
                this.refresh();
              } else {
                return this.$error(x.message);
              }
            });
        }
      }
      let TaskHandCompletedBtn = this.buttons.find(x => x.value == 'TaskHandCompleted');
      if (TaskHandCompletedBtn) {
        TaskHandCompletedBtn.onClick = function () {
          let rows = this.$refs.table.getSelected();
          if (rows.length == 0) return this.$error("请选择数据!");
          if (rows.length > 1) return this.$error("请选择一条数据!");
          var param = rows[0].taskNum;
          this.http
            .post("api/Task/TaskCompleted?taskNum="+param, "数据处理中...")
            .then((x) => {
              if (x.status) {
                this.$Message.success('任务手动完成');
                this.refresh();
              } else {
                return this.$error(x.message);
              }
            });
        }
      }
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/taskinfo/task_hty.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
      }
    }
  };
  export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/main.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus';
// import 'element-plus/lib/theme-chalk/index.css';
import 'element-plus/dist/index.css'
import './assets/element-icon/icon.css'
import base from './uitils/common'
import http from './api/http'
// import 'dayjs/locale/zh-cn'
// import locale from 'element-plus/lib/locale/lang/zh-cn'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import permission from './api/permission'
import viewgird from './components/basic/ViewGrid';
const app = createApp(App);
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component)
}
app.config.globalProperties.base = base;
app.config.globalProperties.http = http;
app.config.globalProperties.$tabs = {};
app.config.globalProperties.permission = permission;
app.config.globalProperties.$global = {
    signalR: false, //是否开启signalR
    table: {
        //vol-table带数据源的单元格是否启用tag标签(下拉框等单元格以tag标签显示)
        useTag: true
    },
    audit: { //审核选项
        data: [
            { text: '通过', value: 1 },
            { text: '拒绝', value: 3 },
            { text: '驳回', value: 4 }
        ],
        status:[0,2] //审核中的数据
        // å¾…审核 = 0,
        // å®¡æ ¸é€šè¿‡ = 1,
        // å®¡æ ¸ä¸­ = 2,
        // å®¡æ ¸æœªé€šè¿‡ = 3,
        // é©³å›ž = 4
    }
}
//2023.03.13,
//修改见:volupload.vue,后台AliOSSController.cs,阿里云OSS配置.doc
window.oss = {
    ali: { //阿里云
        use: false,//使用阿里云上传文件
        //阿里缩略图压缩大小
        //.aliyuncs.com
        small: "?x-oss-process=image/resize,m_lfit,w_200"
    }
}
app.use(store)
    .use(ElementPlus, { size: 'default' })
    .use(router)
    .use(viewgird)
    .mount('#app');
app.config.globalProperties.$Message = app.config.globalProperties.$message;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/router/charts.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
let charts=[
    {
        path: '/chart',
        name: 'chart',
        component: () => import('@/views/charts/chart.vue')
    },
    {
        path: '/formChart',
        name: 'formChart',
        component: () => import('@/views/charts/formChart.vue')
    },
    {
        path: '/flex',
        name: 'flex',
        component: () => import('@/views/charts/flex.vue')
    }]
export default charts
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/router/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,82 @@
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
import viewgird from './viewGird'
import store from '../store/index'
import redirect from './redirect'
import charts from './charts'
const routes = [
  {
    path: '/',
    name: 'Index',
    component: () => import('@/views/Index'),
    redirect: '/home',
    children: [
      ...viewgird,
      ...redirect,
      ...charts,
      {
        path: '/home',
        name: 'home',
        component: () => import('@/views/Home.vue')
      }, {
        path: '/UserInfo',
        name: 'UserInfo',
        component: () => import('@/views/system/UserInfo.vue')
      },
      {
        path: '/sysMenu',
        name: 'sysMenu',
        component: () => import('@/views/system/Sys_Menu.vue')
      }
    ]
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('@/views/Login.vue'),
    meta:{
        anonymous:true
      }
  },
  {
    path: '/bigdata',
    name: 'bigdata',
    component: () => import('@/views/charts/bigdata.vue'),
    meta: {
      keepAlive: false
    }
  }
]
const router = createRouter({
  history: createWebHashHistory(), //createWebHistory(process.env.BASE_URL),
  routes
})
router.beforeEach((to, from, next) => {
  if (to.matched.length == 0) return next({ path: '/404' });
  //2020.06.03增加路由切换时加载提示
  store.dispatch("onLoading", true);
  if ((to.hasOwnProperty('meta') && to.meta.anonymous) || store.getters.isLogin() || to.path == '/login') {
    return next();
  }
  next({ path: '/login', query: { redirect: Math.random() } });
})
router.afterEach((to, from) => {
  store.dispatch("onLoading", false);
})
router.onError((error) => {
  // const targetPath = router.currentRoute.value.matched;
  try {
    console.log(error.message);
    if (process.env.NODE_ENV == 'development') {
      alert(error.message)
    }
    localStorage.setItem("route_error", error.message)
  } catch (e) {
  }
  window.location.href = '/'
});
export default router
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/router/redirect.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
let redirect = [{
    path: '/404',
    name: '404',
    component: () => import('@/components/redirect/404'),
    meta:{
        anonymous:true
      }
}, {
    path: '/401',
    name: '401',
    component: () => import('@/components/redirect/401')
}, {
    path: '/coding',
    name: 'coding',
    component: () => import('@/components/redirect/coding')
}, {
    path: '/message',
    name: 'message',
    component: () => import('@/components/redirect/Message.vue')
}]
export default redirect;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/router/viewGird.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,122 @@
let viewgird = [
  {
    path: '/Sys_Log',
    name: 'sys_Log',
    component: () => import('@/views/system/Sys_Log.vue')
  },
  {
    path: '/Sys_User',
    name: 'Sys_User',
    component: () => import('@/views/system/Sys_User.vue')
  },
  {
    path: '/permission',
    name: 'permission',
    component: () => import('@/views/system/Permission.vue')
  },
  {
    path: '/permissionPDA',
    name: 'permissionPDA',
    component: () => import('@/views/system/PermissionPDA.vue')
  },
  {
    path: '/Sys_Dictionary',
    name: 'Sys_Dictionary',
    component: () => import('@/views/system/Sys_Dictionary.vue')
  },
  {
    path: '/Sys_Role',
    name: 'Sys_Role',
    component: () => import('@/views/system/Sys_Role.vue')
  }, {
    path: '/Sys_Role1',
    name: 'Sys_Role1',
    component: () => import('@/views/system/Sys_Role1.vue')
  }, {
    path: '/Sys_DictionaryList',
    name: 'Sys_DictionaryList',
    component: () => import('@/views/system/Sys_DictionaryList.vue')
  }, {
    path: '/areaInfo',
    name: 'areaInfo',
    component: () => import('@/views/basic/areaInfo.vue')
  },
  {
    path: '/areaRouter',
    name: 'areaRouter',
    component: () => import('@/views/basic/areaRouter.vue')
  }, {
    path: '/locationInfo',
    name: 'locationInfo',
    component: () => import('@/views/basic/locationInfo.vue')
  }, {
    path: '/materielInfo',
    name: 'materielInfo',
    component: () => import('@/views/basic/materielInfo.vue')
  },
  {
    path: '/cachePoint',
    name: 'cachePoint',
    component: () => import('@/views/basic/cachePoint.vue')
  },
  {
    path: '/roadwayInfo',
    name: 'roadwayInfo',
    component: () => import('@/views/basic/roadwayInfo.vue')
  }, {
    path: '/warehouse',
    name: 'warehouse',
    component: () => import('@/views/basic/warehouse.vue')
  }, {
    path: '/inboundOrder',
    name: 'inboundOrder',
    component: () => import('@/views/inbound/inboundOrder.vue')
  }, {
    path: '/inboundOrderDetail',
    name: 'inboundOrderDetail',
    component: () => import('@/views/inbound/inboundOrderDetail.vue')
  }, {
    path: '/outboundOrder',
    name: 'outboundOrder',
    component: () => import('@/views/outbound/outboundOrder.vue')
  }, {
    path: '/outboundOrderDetail',
    name: 'outboundOrderDetail',
    component: () => import('@/views/outbound/outboundOrderDetail.vue')
  }, {
    path: '/stockInfo',
    name: 'stockInfo',
    component: () => import('@/views/stock/stockInfo.vue')
  }, {
    path: '/stockInfoDetail',
    name: 'stockInfoDetail',
    component: () => import('@/views/stock/stockInfoDetail.vue')
  }, {
    path: '/task',
    name: 'task',
    component: () => import('@/views/taskinfo/task.vue')
  },
  {
    path: '/task_hty',
    name: 'task_hty',
    component: () => import('@/views/taskinfo/task_hty.vue')
  },{
    path: '/stockView',
    name: 'stockView',
    component: () => import('@/views/stock/stockView.vue')
  },{
    path: '/StockQuantityChangeRecord',
    name: 'StockQuantityChangeRecord',
    component: () => import('@/views/record/stockQuantityChangeRecord.vue')
  },{
    path: '/locationStatusChangeRecord',
    name: 'locationStatusChangeRecord',
    component: () => import('@/views/record/locationStatusChangeRecord.vue')
  },{
    path: '/receiveOrder',
    name: 'receiveOrder',
    component: () => import('@/views/inbound/receiveOrder.vue')
  }]
export default viewgird
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/store/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,94 @@
import { createStore } from 'vuex'
const keys = { USER: 'user' }
function getUserInfo(state) {
  if (state.userInfo) return state.userInfo;
  let userInfo = localStorage.getItem(keys.USER);
  if (userInfo) {
    state.userInfo = JSON.parse(userInfo);
  }
  return state.userInfo;
}
export default createStore({
  state: {
    data: {},
    permission: [],
    isLoading: false,//2020.06.03增加路由切换时加载提示
    userInfo: null,
    websocke: null,//websocket
    // wcsState: true//wcs服务状态
  },
  mutations: {
    setPermission(state, data) {  //调用方式 this.$store.commit('setPermission', data)
      if (!data || typeof data != 'object') return;
      if (data instanceof Array) {
        state.permission.push(...data);
      } else {
        state.permission = data;
      }
    }, setUserInfo(state, data) {
      state.userInfo = data;
      localStorage.setItem(keys.USER, JSON.stringify(data));
    },
    clearUserInfo(state) {
      state.permission = [];
      state.userInfo = null;
      localStorage.removeItem(keys.USER);
    },
    test(state) {
      return 113344;
    },
    updateLoadingState(state, flag) {
      state.isLoading = flag
    },
    setWebsocket(state, data) {
      state.websocke = data;
    }
  }, getters: {
    getPermission: (state) => (path) => {  //调用方式 store.getters.getPermission('sys_User')
      if (!path) return state.permission;
      return state.permission.find(x => x.path == path);
    },
    getUserInfo: (state) => () => {
      getUserInfo(state);
      return state.userInfo;
    }, getUserName: (state) => () => {
      getUserInfo(state);
      if (state.userInfo) {
        return state.userInfo.userName;
      }
      return '未获取到登陆信息';
    },
    getToken: (state) => () => {
      getUserInfo(state);
      if (state.userInfo) {
        return 'Bearer ' + state.userInfo.token;
      }
      return '';
    },
    isLogin: (state) => () => {
      if (getUserInfo(state)) {
        return true;
      }
      return false;
    },
    isLoading: (state) => () => {
      return state.isLoading;
    },
    data: (state) => () => {
      return state.data;
    },
    getData: (state) => () => {
      return state.data;
    },
  }, actions: {
    setPermission(context, data) {
      context.commit('setPermission', data); //调用方式 store.dispatch('push')
    },
    toDo(context) {
      return context.Store.m;
    },
    onLoading(context, flag) {
      context.commit("updateLoadingState", flag);
    }
  }
})
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/uitils/common.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,344 @@
let base = {
  addDays(date, days) {
    //给指定日期增加天数
    if (!days) {
      return date;
    }
    let dateArr = date.split(' ');
    date = new Date(new Date(date).setDate(new Date(date).getDate() + days));
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    if (month < 10) {
      month = '0' + month;
    }
    var day = date.getDate();
    if (day < 10) {
      day = '0' + day;
    }
    date = year + '-' + month + '-' + day;
    if (dateArr.length == 1) {
      return date;
    }
    return date + ' ' + dateArr[1];
  },
  //获取当前时间,time是否带时分秒
  getDate(time) {
    let date = new Date();
    let year = date.getFullYear();
    let month = date.getMonth() + 1;
    let day = date.getDate();
    let datetime =
      year +
      '-' +
      (month < 10 ? '0' + month : month) +
      '-' +
      (day < 10 ? '0' + day : day);
    if (!time) {
      return datetime;
    }
    let hour = date.getHours();
    let minutes = date.getMinutes();
    let second = date.getSeconds();
    return (
      datetime +
      '' +
      ' ' +
      (hour < 10 ? '0' + hour : hour) +
      ':' +
      (minutes < 10 ? '0' + minutes : minutes) +
      ':' +
      (second < 10 ? '0' + second : second)
    );
  },
  isPhone(val) {
    return /^[1][3,4,5,6,7,8,9][0-9]{9}$/.test(val);
  },
  isDecimal(val) {
    return /(^[\-0-9][0-9]*(.[0-9]+)?)$/.test(val);
  },
  isNumber(val) {
    return /(^[\-0-9][0-9]*([0-9]+)?)$/.test(val);
  },
  isMail(val) {
    return /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(val);
  },
  isUrl(url) {
    return this.checkUrl(url);
  },
  checkUrl(url) {
    // url= åè®®://(ftp的登录信息)[IP|域名](:端口号)(/或?请求参数)
    var strRegex =
      '^((https|http|ftp)://)?' + // (https或http或ftp):// å¯æœ‰å¯æ— 
      "(([\\w_!~*'()\\.&=+$%-]+: )?[\\w_!~*'()\\.&=+$%-]+@)?" + // ftp的user@  å¯æœ‰å¯æ— 
      '(([0-9]{1,3}\\.){3}[0-9]{1,3}' + // IP形式的URL- 3位数字.3位数字.3位数字.3位数字
      '|' + // å…è®¸IP和DOMAIN(域名)
      '(localhost)|' + // åŒ¹é…localhost
      "([\\w_!~*'()-]+\\.)*" + // åŸŸå- è‡³å°‘一个[英文或数字_!~*\'()-]加上.
      '\\w+\\.' + // ä¸€çº§åŸŸå -英文或数字  åŠ ä¸Š.
      '[a-zA-Z]{1,6})' + // é¡¶çº§åŸŸå- 1-6位英文
      '(:[0-9]{1,5})?' + // ç«¯å£- :80 ,1-5位数字
      '((/?)|' + // url无参数结尾 - æ–œæ†æˆ–这没有
      "(/[\\w_!~*'()\\.;?:@&=+$,%#-]+)+/?)$"; // è¯·æ±‚参数结尾- è‹±æ–‡æˆ–æ•°å­—å’Œ[]内的各种字符
    var re = new RegExp(strRegex, 'i'); // i不区分大小写
    // å°†url做uri转码后再匹配,解除请求参数中的中文和空字符影响
    if (re.test(encodeURI(url))) {
      return true;
    }
    return false;
  },
  matchUrlIp(url, ip) {
    // url使用是否使用的当前ip
    if (!url || !ip) {
      return false;
    }
    return url.indexOf(ip.replace('https://', '').replace('http://', '')) >= 0;
  },
  getImgSrc(src, httpUrl) {
    if (this.isUrl(src)) {
      return src;
    }
    if (httpUrl) {
      return httpUrl + src;
    }
    return src;
  },
  previewImg(src, httpUrl) {
    // å›¾ç‰‡é¢„览,目前只支持单图片预览
    if (src && !this.isUrl(src) && httpUrl) {
      if (
        src.substr(0, 1) == '/' &&
        httpUrl.substr(httpUrl.length - 1, 1) == '/'
      ) {
        src = src.substr(1);
      }
      src = httpUrl + src;
    }
    let id = 'vol-preview';
    let $div = document.getElementById(id);
    if (!$div) {
      $div = document.createElement('div');
      $div.setAttribute('id', 'vol-preview');
      let $mask = document.createElement('div');
      $mask.style.position = 'absolute';
      $mask.style.width = '100%';
      $mask.style.height = '100%';
      $mask.style.background = 'black';
      $mask.style.opacity = '0.6';
      $div.appendChild($mask);
      $div.style.position = 'fixed';
      $div.style.width = '100%';
      $div.style.height = '100%';
      // $div.style.overflow = "scroll";
      $div.style.top = 0;
      $div.style['z-index'] = 9999999;
      let $img = document.createElement('img');
      $img.setAttribute('class', 'vol-preview-img');
      $img.style.position = 'absolute';
      $img.style.top = '50%';
      $img.style.left = '50%';
      $img.style['max-width'] = '90%';
      $img.style['max-height'] = '90%';
      $img.style.transform = 'translate(-50%,-50%)';
      // $img.src = src;
      $img.setAttribute('src', src);
      $div.appendChild($img);
      $div.addEventListener('click', function() {
        this.style.display = 'none';
      });
      document.body.appendChild($div);
      return;
    }
    let $img1 = document.body
      .appendChild($div)
      .querySelector('.vol-preview-img');
    // img.src = src;
    $img1.setAttribute('src', src);
    $div.style.display = 'block';
  },
  // ä¸‹è½½æ–‡ä»¶ $element æ ‡ç­¾, url完整url, fileName æ–‡ä»¶å, header ä»¥key/value传值
  // backGroundUrl åŽå°url,如果后台url直接从后台下载,其他全部通过点击a标签下载
  dowloadFile(url, fileName, header, backGroundUrl) {
    if (!url) return alert('此文件没有url不能下载');
    if (!this.isUrl(url)) {
      url = backGroundUrl + url;
    }
    window.open(url);
  },
  downloadImg(data) {
    if (!data.url || !data.callback || typeof data.callback !== 'function') {
      return;
    }
    // url, backGroundUrl, header, callback
    if (
      this.isUrl(data.url) &&
      !this.matchUrlIp(data.url, data.backGroundUrl)
    ) {
      return data.url;
    }
    // é€šè¿‡åŽå°api服务器下载
    if (!this.isUrl(data.url)) {
      if (!this.isUrl(data.backGroundUrl + data.url)) {
        return;
      }
      data.url = data.backGroundUrl + data.url;
    }
    var xmlResquest = new XMLHttpRequest();
    xmlResquest.open('get', data.url, true);
    xmlResquest.responseType = 'blob';
    xmlResquest.setRequestHeader('Content-Type', 'application/json');
    if (data.header && typeof data.header === 'object') {
      for (const key in data.header) {
        xmlResquest.setRequestHeader(key, data.header[key]);
      }
    }
    xmlResquest.onload = function() {
      if (this.status == 200) {
        var blob = this.response;
        callback(window.URL.createObjectURL(blob));
      }
    };
    xmlResquest.send();
  },
  // 2020.06.01增加通用方法,将普通对象转换为tree结构
  // data数据格式[
  //     { name: 'tree1', id: 1, parentId: 0 },
  //     { name: 'tree2', id: 2, parentId: 0 }]
  // 1、id与parentId这两个字段必须有
  // 2、树形tree需要注意Id与parentId循环依赖的问题
  // 3、callback每次生成一新的节点的时回调的方法
  convertTree(data, callback) {
    var treeIds = [];
    var root_data = [];
    if (data.length>100) {
      data = JSON.parse(JSON.stringify(data));
    }
    data.forEach((x) => {
      // if (!x.children) {
      //   x.children = []
      // }
      if (
        !x.hidden &&
        x.id !== undefined &&
        x.id !== x.parentId &&
        !data.some((s) => {
          return x.parentId == s.id;
        })
      ) {
        x.isRoot = true;
        callback && callback(x, data, true, treeIds);
        root_data.push(x);
        getTree(x.id, x, data, callback, treeIds);
      } else {
        callback && callback(x, data, true, treeIds);
      }
    });
    var exceptionNodes = data.filter((f) => {
      return treeIds.indexOf(f.id) == -1 && !f.hidden;
    });
    root_data.push(...exceptionNodes);
    return root_data;
  },
  getTreeAllParent(id, data) {
    // èŽ·å–æŸä¸ªèŠ‚ç‚¹çš„æ‰€æœ‰çˆ¶èŠ‚ç‚¹ä¿¡æ¯2020.11.01
    var nodes = [];
    if (!(data instanceof Array)) {
      return nodes;
    }
    if (data.length>100) {
      data = JSON.parse(JSON.stringify(data));
    }
    data.forEach((x) => {
      if (x.id === x.parentId) {
        x.parentId = 0;
      } else if (data.some((c) => c.parentId === x.id && c.id === x.parentId)) {
        x.parentId = 0;
      }
    });
    var _child = data.find((x) => {
      return x.id === id;
    });
    if (!_child) {
      return [];
    }
    nodes.push(_child);
    var _parentIds = [_child.parentId];
    for (let index = 0; index < _parentIds.length; index++) {
      var _node = data.find((x) => {
        return x.id === _parentIds[index] && x.id !== x.parentId;
      });
      if (!_node) {
        return nodes;
      }
      _parentIds.push(_node.parentId);
      nodes.unshift(_node);
    }
    return nodes;
  },
  //获取所有节点的子节点
  // data数据格式[
  //     { name: 'tree1', id: 1, parentId: 0 },
  //     { name: 'tree2', id: 2, parentId: 0 }]
  getTreeAllChildren(id, data) {
    //递归获取某个节点的所有子节点信息
    var nodes = [];
    if (!(data instanceof Array)) {
      return nodes;
    }
    if (data.length>100) {
      data = JSON.parse(JSON.stringify(data));
    }
    var _child = data.find((x) => {
      return x.id === id;
    });
    if (!_child) {
      return [];
    }
    nodes.push(_child);
    var _parentIds = [_child.id];
    for (let index = 0; index < _parentIds.length; index++) {
      data.forEach((_node) => {
        if (
          _node.parentId === _parentIds[index] &&
          _node.parentId !== _node.id
        ) {
          _parentIds.push(_node.id);
          nodes.unshift(_node);
        }
      });
    }
    return nodes;
  },
  //获取所有子节点的id
  // data数据格式[
  //     { name: 'tree1', id: 1, parentId: 0 },
  //     { name: 'tree2', id: 2, parentId: 0 }]
  getTreeAllChildrenId(id, data) {
    return this.getTreeAllChildren(id, data).map((c) => {
      return c.id;
    });
  }
};
export default base;
// 2020.06.01增加通用方法,将普通对象转换为tree结构
function getTree(id, node, data, callback, treeIds) {
  if (treeIds.indexOf(id) == -1) {
    treeIds.push(id);
  }
  data.forEach((x) => {
    if (!x.hidden && x.parentId == id) {
      if (!node.children) node.children = [];
      callback && callback(x, node, false);
      node.children.push(x);
      getTree(x.id, x, data, callback, treeIds);
    }
  });
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/Home.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
<template>
  <div class="title"></div>
</template>
<script>
import { ref, reactive } from 'vue'
export default {
  setup() {
    return {
    }
  }
}
</script>
<style scoped>
.title {
  line-height: 70vh;
  text-align: center;
  font-size: 28px;
  color: orange;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/Index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,834 @@
<template>
  <div id="vol-container" :class="['vol-theme-' + theme]">
    <div class="vol-aside" :style="{ width: menuWidth + 'px' }">
      <div class="header" :style="{ width: menuWidth - 1 + 'px' }">
        <img v-show="!isCollapse" v-bind:src="logo" />
        <i
          @click="toggleLeft"
          class="collapse-menu"
          :class="isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'"
        />
      </div>
      <div class="vol-menu">
        <el-scrollbar style="height: 100%">
          <VolMenu
            :currentMenuId="currentMenuId"
            :on-select="onSelect"
            :enable="true"
            :open-select="false"
            :isCollapse="isCollapse"
            :list="menuOptions"
          ></VolMenu>
        </el-scrollbar>
      </div>
    </div>
    <div class="vol-container" :style="{ left: menuWidth - 1 + 'px' }">
      <div class="vol-header">
        <div class="project-name">WMS</div>
        <div class="header-text">
          <div class="h-link">
            <a
              href="javascript:void(0)"
              @click="to(item)"
              v-for="(item, index) in links.filter((c) => {
                return !c.icon;
              })"
              :key="index"
            >
              <span v-if="!item.icon"> {{ item.text }}</span>
              <i v-else :class="item.icon"></i>
            </a>
          </div>
        </div>
        <div class="header-info">
          <div class="h-link">
            <a
              href="javascript:void(0)"
              @click="to(item)"
              v-for="(item, index) in links.filter((c) => {
                return c.icon;
              })"
              :key="index"
            >
              <span v-if="!item.icon"> {{ item.text }}</span>
              <i v-else :class="item.icon"></i>
            </a>
          </div>
          <!--消息管理-->
          <div class="h-link" @click="messageModel = true">
            <a
              ><i class="el-icon-message-solid"
                ><el-badge
                  :value="messageList.length"
                  :type="messageList.length > 0 ? 'danger' : 'success'"
                  class="item"
                  style="width: 10px"
                ></el-badge></i
            ></a>
          </div>
          <div>
            <img class="user-header" :src="userImg" :onerror="errorImg" />
          </div>
          <div class="user">
            <span>{{ userName }}</span>
            <span id="index-date"></span>
          </div>
          <div class="settings">
            <i
              style="font-size: 20px"
              class="el-icon-s-tools"
              @click="drawer_model = true"
            />
          </div>
        </div>
      </div>
      <div class="vol-path">
        <el-tabs
          @tab-click="selectNav"
          @tab-remove="removeNav"
          @contextmenu.prevent="bindRightClickMenu(false)"
          type="border-card"
          class="header-navigation"
          v-model="selectId"
          :strtch="false"
        >
          <el-tab-pane
            v-for="(item, navIndex) in navigation"
            type="card"
            :name="navIndex + ''"
            :closable="navIndex > 0"
            :key="navIndex"
            :label="item.name"
          >
            <span style="display: none">{{ navIndex }}</span>
          </el-tab-pane>
        </el-tabs>
        <!-- å³é”®èœå• -->
        <div v-show="contextMenuVisible">
          <ul
            :style="{ left: menuLeft + 'px', top: menuTop + 'px' }"
            class="contextMenu"
          >
            <li v-show="visibleItem.all">
              <el-button link @click="closeTabs()">
                <i class="el-icon-close"></i>
                {{
                  navigation.length == 2 ? "关闭菜单" : "关闭所有"
                }}</el-button
              >
            </li>
            <li v-show="visibleItem.left">
              <el-button link @click="closeTabs('left')"
                ><i class="el-icon-back"></i>关闭左边</el-button
              >
            </li>
            <li v-show="visibleItem.right">
              <el-button link @click="closeTabs('right')">
                <i class="el-icon-right"></i>关闭右边</el-button
              >
            </li>
            <li v-show="visibleItem.other">
              <el-button link @click="closeTabs('other')"
                ><i class="el-icon-right"></i>关闭其他
              </el-button>
            </li>
          </ul>
        </div>
      </div>
      <div class="vol-main" id="vol-main">
        <el-scrollbar style="height: 100%" v-if="permissionInited">
          <loading v-show="$store.getters.isLoading()"></loading>
          <router-view v-slot="{ Component }">
            <keep-alive>
              <component
                :is="Component"
                :key="$route.name"
                v-if="
                  !$route.meta ||
                  ($route.meta && !$route.meta.hasOwnProperty('keepAlive'))
                "
              />
            </keep-alive>
            <component
              :is="Component"
              :key="$route.name"
              v-if="$route.meta && $route.meta.hasOwnProperty('keepAlive')"
            />
          </router-view>
        </el-scrollbar>
      </div>
    </div>
    <el-drawer
      title="选择主题"
      v-model="drawer_model"
      direction="rtl"
      destroy-on-close
    >
      <div class="theme-selector">
        <div
          @click="changeTheme(item.name)"
          class="item"
          v-for="(item, index) in theme_color"
          :key="index"
          :style="{ background: item.color }"
        >
          <div
            v-show="item.leftColor"
            :style="{ background: item.leftColor }"
            style="height: 100%; width: 20px"
            class="t-left"
          ></div>
          <div class="t-right"></div>
        </div>
      </div>
    </el-drawer>
    <el-drawer
      title="消息列表"
      v-model="messageModel"
      direction="rtl"
      destroy-on-close
      size="40%"
    >
      <Message :list="messageList"></Message>
    </el-drawer>
  </div>
</template>
<style lang="less" scoped>
@import "./index/index.less";
</style>
<script>
import loading from "@/components/basic/RouterLoading";
import VolMenu from "@/components/basic/VolElementMenu.vue";
import Message from "./index/Message.vue";
import MessageConfig from "./index/MessageConfig.js";
var imgUrl = require("@/assets/imgs/wms_x.png");
var $this;
var $interval;
var $indexDate;
import {
  defineComponent,
  reactive,
  ref,
  watch,
  onMounted,
  getCurrentInstance,
  h
} from "vue";
import { useRouter, useRoute } from "vue-router";
import store from "../store/index";
import http from "@/../src/api/http.js";
import { ElNotification } from "element-plus";
export default defineComponent({
  components: {
    VolMenu,
    loading,
    Message,
  },
  data() {
    return {
      allTabs: true,
      leftTabs: true,
      rightTabs: true,
      otherTabs: true,
      menuLeft: 0,
      menuTop: 0,
      client: null,
      //  contextMenuVisible: false, // å³é”®å…³é—­æ˜¾/隐
    };
  },
  setup(props, context) {
    let client = ref(null);
    // èŽ·å–å…¨å±€å±žæ€§å’Œæ–¹æ³•
    const { proxy } = getCurrentInstance();
    // èœå•导航默认宽度
    const menuWidth = ref(200);
    const contextMenuVisible = ref(false);
    const isCollapse = ref(false);
    const drawer_model = ref(false);
    const messageModel = ref(false);
    const theme_color = ref([
      { name: "blue", color: "rgb(45, 140, 240)" },
      { name: "blue2", color: "rgb(45, 140, 240)", leftColor: "#0068d6" },
      { name: "red", color: "rgb(237, 64, 20)" },
      { name: "red2", color: "rgb(237, 64, 20)", leftColor: "#a90000" },
      { name: "dark", color: "#272929" },
      { name: "orange", color: "#ff9900" },
      { name: "orange2", color: "#ff9900", leftColor: "rgb(232 141 5)" },
      { name: "green", color: "rgb(25, 190, 107)" },
      { name: "green2", color: "rgb(25, 190, 107)", leftColor: "#019e4f" },
      { name: "white", color: "#fff" },
    ]);
    const links = ref([
      { text: "个人中心", path: "/UserInfo", id: -1, icon: "el-icon-s-custom" },
      {
        text: "安全退出",
        path: "/login",
        id: -4,
        icon: "el-icon-switch-button",
      },
    ]);
    const errorImg = ref(
      'this.src="' + require("@/assets/imgs/error-img.png") + '"'
    );
    const selectId = ref("1");
    // ã€é¦–页】标签序号(当前右键选中的菜单)
    const selectMenuIndex = ref("0");
    //2022.05.29增加tab选项与菜单联动功能
    const currentMenuId = ref(0);
    const userName = ref("--");
    const userInfo = ref({});
    const visibleItem = reactive({
      left: false,
      right: false,
      all: false,
      other: false,
    });
    const userImg = ref("");
    const navigation = reactive([
      { orderNo: "0", id: "1", name: "首页", path: "/home" },
    ]);
    const logo = ref(imgUrl);
    const theme = ref("blue2");
    const menuOptions = ref([]);
    const permissionInited = ref(false);
    const messageList = reactive([]);
    let _config = getCurrentInstance().appContext.config.globalProperties;
    let router = useRouter();
    const toggleLeft = () => {
      isCollapse.value = !isCollapse.value;
      menuWidth.value = isCollapse.value ? 63 : 200;
    };
    //2021.08.28开放手动折叠菜单方法
    _config.menu = {
      show() {
        toggleLeft();
      },
      hide() {
        toggleLeft();
      },
    };
    const handleMessage = (e) => {
      let data = JSON.parse(e.data);
      messageList.push(data);
      ElNotification({
        title: data.title,
        message: h("i", { style: "color: teal" }, data.message),
      });
    };
    const createSocket = (url) => {
      // åˆ›å»ºWebSocket连接
      //"ws://127.0.0.1:9295/admin"
      client = new WebSocket(url);
      client.onopen = function () {
        client.onmessage = handleMessage;
        store.commit("setWebsocket", client);
        console.log("WebSocket è¿žæŽ¥æˆåŠŸ");
      };
      client.onclose = function () {
        console.log("WebSocket è¿žæŽ¥å…³é—­");
        setTimeout(createSocket, 10000);
      };
      client.onerror = function () {
      };
    };
    const changeTheme = (name) => {
      if (theme.value != name) {
        theme.value = name;
      }
      localStorage.setItem("vol3_theme", name);
    };
    const to = (item) => {
      /* 2020.07.31增加手动打开tabs*/
      if (item.path == "#") {
        window.open("https://github.com/cq-panda/Vue.NetCore");
        return;
      }
      if (item.path.indexOf("http") != -1) {
        window.open(item.path);
        return;
      }
      if (typeof item == "string" || item.path == "/login") {
        if (item == "/login" || item.path == "/login") {
          store.commit("clearUserInfo", "");
          window.location.href = "/";
          return;
        }
        router.push({ path: item });
        return;
      }
      if (item.path == "#") return;
      open(item);
    };
    const open = (item, useRoute) => {
      /* 2020.07.31增加手动打开tabs*/
      let _index = navigation.findIndex((x) => {
        return x.path == item.path;
      });
      if (_index == -1) {
        navigation.push({
          //  orderNo: String(navigation.length),// åºå·
          id: item.id + "",
          name: item.name || item.text || "无标题",
          path: item.path,
          query: item.query, //2021.03.20修复自定义二次打开$tabs时参数丢失的问题
        });
        //新打开的tab移至最后一个选项
        selectId.value = navigation.length - 1 + "";
      } else {
        selectId.value = _index + "";
      }
      if (useRoute === undefined) {
        //非标准菜单,记录最后一次跳转的页面,用于刷新
        setItem(item);
        router.push(item);
        // this.$router.push(item);
      }
      currentMenuId.value = item.id * 1;
      // tab菜单绑定右键事件
      proxy.$nextTick(function (e) {
        proxy.bindRightClickMenu(true);
      });
    };
    const close = (path) => {
      /* 2020.07.31增加手动打开tabs*/
      let index = navigation.findIndex((x) => {
        return x.path == path;
      });
      if (index == -1) {
        return _config.$Message.error("未找到菜单");
      }
      removeNav(index);
    };
    const setItem = (item) => {
      /* 2020.07.31增加手动打开tabs*/
      localStorage.setItem(
        window.location.origin + "_tabs",
        JSON.stringify(item)
      );
    };
    const getItem = () => {
      /* 2020.07.31增加手动打开tabs*/
      let nav = localStorage.getItem(window.location.origin + "_tabs");
      return nav ? JSON.parse(nav) : null;
    };
    const selectNav = (item) => {
      //升级element正式版修改
      selectId.value = item.props.name;
      let _path = navigation[item.index].path;
      currentMenuId.value = (
        menuOptions.value.find((c) => {
          return c.path == _path;
        }) || { id: 0 }
      ).id;
      router.push({
        path: navigation[item.index].path,
        query: navigation[item.index].query,
      });
    };
    const removeNav = (_index) => {
      return new Promise(() => {
        //关闭的当前项,跳转到前一个页面
        if (selectId.value == _index + "") {
          console.log(navigation[_index - 1]);
          setItem(navigation[_index - 1]);
          router.push({
            path: navigation[_index - 1].path,
            //2022.06.27修复tabs二次切换后参数丢失的问题
            query: navigation[_index - 1].query,
          });
          navigation.splice(_index, 1);
          selectId.value = selectId.value - 1 + "";
          return;
        }
        if (_index < selectId.value) {
          selectId.value = selectId.value - 1 + "";
        }
        navigation.splice(_index, 1);
        currentMenuId.value = (
          menuOptions.value.find((c) => {
            return c.path == navigation[selectId.value * 1].path;
          }) || { id: 0 }
        ).id;
      });
    };
    const getSelectMenuName = (id) => {
      return menuOptions.value.find(function (x) {
        return x.id == id;
      });
    };
    const onSelect = (treeId) => {
      /* 2020.07.31增加手动打开tabs*/
      var item = getSelectMenuName(treeId);
      open(item, false);
    };
    /**
     * æ˜¾ç¤ºå³é”®èœå•
     * @param {*} e äº‹ä»¶å¯¹è±¡
     */
    const openTabsMenu = function (e) {
      e.preventDefault(); // é˜²æ­¢é»˜è®¤èœå•弹出
      let tabId = e.target.id.split("-")[1] * 1;
      //记录当前选中的菜单index
      selectMenuIndex.value =
        document.getElementById("pane-" + tabId).children[0].textContent * 1;
      //只有首页时不显示
      if (navigation.length == 1) {
        return;
      }
      //首页设置显示关闭右边菜单
      if (!selectMenuIndex.value) {
        visibleItem.all = false;
        visibleItem.right = true;
        visibleItem.left = false;
        visibleItem.other = false;
      } else {
        visibleItem.all = true;
        //不是最后一个显示关闭右边菜单
        visibleItem.right = selectMenuIndex.value != navigation.length - 1;
        //只有两个菜单时不显示关闭左边
        visibleItem.left = navigation.length != 2;
        //只有两个菜单时不显示关闭其他
        visibleItem.other = navigation.length != 2;
      }
      contextMenuVisible.value = true;
      // è®¾ç½®å³é”®èœå•显示的位置
      proxy.menuLeft =
        e.target.getBoundingClientRect().left - (isCollapse.value ? 63 : 198); //-e.target.clientWidth
      proxy.menuTop = 36;
    };
    /**
     * å…³é—­å³é”®èœå•
     */
    const closeTabsMenu = () => {
      contextMenuVisible.value = false;
    };
    const toHome = () => {
      open({
        text: navigation[0].name,
        path: navigation[0].path,
      });
    };
    /**
     * å…³é—­å…¶å®ƒæ ‡ç­¾é¡µ
     * @param {*} par å…³é—­ç±»åž‹(left,right,other)
     */
    const closeTabs = (value) => {
      let _menuId = navigation[selectId.value * 1].id;
      let currnetIndex = selectId.value * 1; // navigation.findIndex(c => { return c.id == selectId.value });
      switch (value) {
        case "left": {
          // åˆ é™¤å·¦ä¾§tab标签
          navigation.splice(1, currnetIndex - 1); // åˆ é™¤å·¦ä¾§tab标签
          break;
        }
        case "right": {
          // åˆ é™¤å³ä¾§tab标签
          if (selectMenuIndex.value == 0) {
            navigation.splice(currnetIndex); // åˆ é™¤å³ä¾§tab标签
            toHome();
          } else {
            navigation.splice(currnetIndex + 1); // åˆ é™¤å³ä¾§tab标签
            if (selectMenuIndex.value < currnetIndex) {
              navigation.splice(
                selectMenuIndex.value,
                currnetIndex - selectMenuIndex.value
              );
            }
          }
          break;
        }
        case "other": {
          // åˆ é™¤å…¶ä»–所有tab标签
          navigation.splice(currnetIndex + 1); // åˆ é™¤å³ä¾§tab标签(这里必须按照右→左顺序删除)
          navigation.splice(1, currnetIndex - 1); // åˆ é™¤å·¦ä¾§tab标签
          break;
        }
        default: {
          //关闭所有
          navigation.splice(1, navigation.length);
          toHome();
          break;
        }
      }
      selectId.value =
        navigation.findIndex((c) => {
          return c.id == _menuId;
        }) + "";
      closeTabsMenu();
    };
    watch(
      () => contextMenuVisible.value,
      (newVal, oldVal) => {
        // ç›‘视
        if (newVal) {
          document.body.addEventListener("click", closeTabsMenu);
        } else {
          document.body.removeEventListener("click", closeTabsMenu);
        }
      }
    );
    /**
     * ç³»ç»Ÿåˆ›å»ºå¼€å§‹
     */
    const created = () => {
      let _theme = localStorage.getItem("vol3_theme");
      if (_theme) {
        theme.value = _theme;
      }
      let _userInfo = store.getters.getUserInfo();
      if (_userInfo) {
        userName.value = _userInfo.userName;
        if (_userInfo.img) {
          userImg.value = _config.base.getImgSrc(_userInfo.img, http.ipAddress);
        }
      }
      createSocket("ws://127.0.0.1:9295/" + _userInfo.userName);
      Object.assign(_config.$tabs, { open: open, close: close });
      http.get("api/Sys_Menu/getTreeMenu", {}, true).then((data) => {
        data.push({ id: "1", name: "首页", url: "/home" }); // ä¸ºäº†èŽ·å–é€‰ä¸­id使用
        data.forEach((d) => {
          d.path = (d.url || "").replace("/Manager", "");
          d.to = (d.url || "").replace("/Manager", "");
          if (!d.icon || d.icon.substring(0, 3) != "el-") {
            d.icon = "el-icon-menu";
          }
        });
        store.dispatch("setPermission", data);
        menuOptions.value = data;
        permissionInited.value = true;
        //开启消息推送(main.js中设置是否开启signalR)2022.05.05
        if (_config.$global.signalR) {
          MessageConfig(http, (result) => {
            messageList.unshift(result);
            //    console.log(result)
          });
        }
        //当前刷新是不是首页
        if (router.currentRoute.value.path != navigation[0].path) {
          //查找系统菜单
          let item = menuOptions.value.find((x) => {
            return x.path == router.currentRoute.value.path; //this.$route.path;
          });
          if (item) return onSelect(item.id);
          //查找顶部快捷连接
          item = links.value.find((x) => {
            return x.path == router.currentRoute.value.path; //this.$route.path;
          });
          //查找最后一次跳转的页面
          if (!item) {
            item = getItem();
          }
          if (item) {
            return open(item, false);
          }
        }
        selectId.value = "1";
      });
    };
    created();
    return {
      menuWidth,
      isCollapse,
      drawer_model,
      theme_color,
      errorImg,
      userInfo,
      userName,
      userImg,
      selectId,
      selectMenuIndex,
      navigation,
      links,
      onSelect,
      openTabsMenu,
      selectNav,
      getSelectMenuName,
      removeNav,
      logo,
      theme,
      menuOptions,
      permissionInited,
      changeTheme,
      to,
      toggleLeft,
      messageModel,
      messageList,
      contextMenuVisible,
      visibleItem,
      closeTabsMenu,
      closeTabs,
      currentMenuId,
    };
  },
  /**
   * æŒ‚载钩子函数
   */
  mounted() {
    let _date = showTime();
    $indexDate = document.getElementById("index-date");
    $indexDate.innerText = _date;
    $interval = setInterval(function () {
      $indexDate.innerText = showTime();
    }, 1000);
    this.bindRightClickMenu(true);
  },
  methods: {
    /**
     * ç»‘定右键事件
     * @param {*} enable æ˜¯å¦å¯ç”¨å³é”®äº‹ä»¶[true:启用;false:禁用;]
     * @param {*} $event äº‹ä»¶
     */
    bindRightClickMenu(enable) {
      if (!enable) return;
      let that = this;
      // ä½¿ç”¨åŽŸç”Ÿjs ä¸ºå•个dom绑定鼠标右击事件
      that.$nextTick(() => {
        let tab_top_dom = Object.assign(
          [],
          document.getElementsByClassName("el-tabs__item is-top")
        );
        tab_top_dom.forEach((item, index) => {
          item.oncontextmenu = that.openTabsMenu;
        });
      });
    },
  },
  /**
   * é”€æ¯é’©å­å‡½æ•°
   */
  destroyed() {
    $this = null;
    clearInterval($interval);
  },
});
const week = new Array(
  "星期一",
  "星期二",
  "星期三",
  "星期四",
  "星期五",
  "星期六",
  "星期日"
);
function showTime() {
  let date = new Date();
  let year = date.getFullYear();
  let month = date.getMonth() + 1;
  let day = date.getDate();
  let hour = date.getHours();
  let minutes = date.getMinutes();
  let second = date.getSeconds();
  return (
    year +
    "." +
    (month < 10 ? "0" + month : month) +
    "." +
    (day < 10 ? "0" + day : day) + //202.08.08修复日期天数小于10时添加0
    "" +
    " " +
    (hour < 10 ? "0" + hour : hour) +
    ":" +
    (minutes < 10 ? "0" + minutes : minutes) +
    ":" +
    (second < 10 ? "0" + second : second) +
    " " + //2020.08.30修复首页日期星期天不显示的问题
    (week[date.getDay() - 1] || week[6])
  );
}
</script>
<style lang="less" scoped>
.vol-container .vol-path ::v-deep(.el-tabs__content) {
  padding: 0;
}
.item {
  margin-top: -20px;
  margin-right: 40px;
}
.contextMenu {
  width: 120px;
  margin: 0;
  border: 1px solid #eaeaea;
  background: #fff;
  z-index: 30000;
  position: absolute;
  list-style-type: none;
  padding: 5px 0;
  border-radius: 4px;
  font-size: 14px;
  color: #333;
  box-shadow: 2px 2px 3px 0 rgb(182 182 182 / 20%);
  i,
  button {
    font-size: 14px !important;
  }
}
.contextMenu li {
  margin: 0;
  padding: 5px 17px;
}
.contextMenu li:hover {
  background: #fafafa;
  cursor: pointer;
}
.contextMenu li button {
  color: #626060;
  font-size: 14px;
  letter-spacing: 1px;
}
.el-tabs.el-tabs--top.el-tabs--border-card.header-navigation
  > .el-tabs__header
  .el-tabs__item:last-child,
.el-tabs--top.el-tabs--border-card.header-navigation
  > .el-tabs__header
  .el-tabs__item:nth-child(2) {
  padding: 0;
}
.header-navigation ::v-deep(.el-tabs__item.is-top) {
  padding: 0 15px;
}
</style>
<style>
.horizontal-collapse-transition {
  transition: 0s width ease-in-out, 0s padding-left ease-in-out,
    0s padding-right ease-in-out;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/Login.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,408 @@
<template>
  <div class="login-container">
    <div class="project-name">WIDESEA_WMS</div>
    <div class="login-form">
      <div class="form-user" @keypress="loginPress">
        <div class="login-text">
          <div>
            <div>欢迎登录...</div>
            <div class="login-line"></div>
          </div>
          <div style="flex: 1"></div>
        </div>
        <div class="login-text-small">WELCOME TO LOGIN</div>
        <div class="item">
          <div class="input-icon el-icon-user"></div>
          <input
            type="text"
            v-focus
            v-model="userInfo.userName"
            placeholder="请输入账号"
          />
        </div>
        <div class="item">
          <div class="input-icon el-icon-lock"></div>
          <input
            type="password"
            v-focus
            v-model="userInfo.password"
            placeholder="请输入密码"
          />
        </div>
        <div class="item">
          <div class="input-icon el-icon-mobile"></div>
          <input
            v-focus
            type="text"
            v-model="userInfo.verificationCode"
            placeholder="输入验证码"
          />
          <div class="code" @click="getVierificationCode">
            <img v-show="codeImgSrc != ''" :src="codeImgSrc" />
          </div>
        </div>
      </div>
      <div class="loging-btn">
        <el-button
          size="large"
          :loading="loading"
          color="#3a6cd1"
          :dark="true"
          @click="login"
          long
        >
          <span v-if="!loading">登录</span>
          <span v-else>正在登录...</span>
        </el-button>
      </div>
      <!-- è´¦å·ä¿¡æ¯ -->
      <!-- <div class="account-info">
        <p>演示账号:admin666 &nbsp; &nbsp;密码:123456</p>
        <p>本地账号:admin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;密码:123456</p>
        <p><a href="https://jq.qq.com/?_wv=1027&k=Sqstuy0M" style="text-decoration: none"
            target="_blank">QQ3群:743852316</a>
          &nbsp; &nbsp;&nbsp; &nbsp;
          <a href="http://v2.volcore.xyz/document/guide" style="text-decoration: none" target="_blank">框架文档</a>
        </p>
      </div> -->
      <!-- é“¾æŽ¥ä½ç½® -->
      <!-- <div class="app-link" >
        <a href="#" style="text-decoration: none">移动端扫码</a>
        <a>
          <i class="el-icon-chat-dot-round"></i> å°ç¨‹åº
          <img src="https://app-1256993465.cos.ap-nanjing.myqcloud.com/wechat.jpg" /></a>
        <a>
          <i class="el-icon-apple"></i>
          Android
          <img src="https://app-1256993465.cos.ap-nanjing.myqcloud.com/Android.png" /></a>
        <a>
          <i class="el-icon-document"></i>
          H5
          <img src="https://app-1256993465.cos.ap-nanjing.myqcloud.com/H5.png" /></a>
      </div> -->
    </div>
    <!-- é¡µé¢åº•部 -->
    <!-- <div class="login-footer">
      <a style="text-decoration: none" href="https://beian.miit.gov.cn/" target="_blank">京ICP备19056538号-1</a>
      <a href="https://dotnet9.com/" style="text-decoration: none" target="blank">Dotnet9</a>
      <a href="https://space.bilibili.com/525836469" style="text-decoration: none" target="blank">NET视频教程(微软MVP-ACE录制)</a>
      <a href="https://www.cctalk.com/m/group/90268531" style="text-decoration: none" target="blank">VOL框架视频</a>
      <a href="http://120.48.115.252:9990" style="text-decoration: none" target="blank">视频演示地址</a>
    </div> -->
    <img class="login-bg" src="/static/login_bg.png" />
  </div>
</template>
<script >
import {
  defineComponent,
  ref,
  reactive,
  toRefs,
  getCurrentInstance,
} from "vue";
import { useRouter, useRoute } from "vue-router";
import store from "../store/index";
import http from "@/../src/api/http.js";
export default defineComponent({
  setup(props, context) {
    store.commit("clearUserInfo", "");
    const loading = ref(false);
    const codeImgSrc = ref("");
    const userInfo = reactive({
      userName: "admin",
      password: "123456",
      verificationCode: "1234",
      UUID: undefined,
    });
    const getVierificationCode = () => {
      http.get("/api/User/getVierificationCode").then((x) => {
        codeImgSrc.value = "data:image/png;base64," + x.img;
        userInfo.UUID = x.uuid;
      });
    };
    getVierificationCode();
    let appContext = getCurrentInstance().appContext;
    let $message = appContext.config.globalProperties.$message;
    let router = useRouter();
    const login = () => {
      if (!userInfo.userName) return $message.error("请输入用户名");
      if (!userInfo.password) return $message.error("请输入密码");
      if (!userInfo.verificationCode) {
        return $message.error("请输入验证码");
      }
      loading.value = true;
      http.post("/api/User/login", userInfo, "正在登录....").then((result) => {
        if (!result.status) {
          loading.value = false;
          getVierificationCode();
          return $message.error(result.message);
        }
        $message.success("登录成功,正在跳转!");
        store.commit("setUserInfo", result.data);
        router.push({ path: "/" });
      });
    };
    const loginPress = (e) => {
      if (e.keyCode == 13) {
        login();
      }
    };
    const openUrl = (url) => {
      window.open(url, "_blank");
    };
    return {
      loading,
      codeImgSrc,
      getVierificationCode,
      login,
      userInfo,
      loginPress,
      openUrl,
    };
  },
  directives: {
    focus: {
      inserted: function (el) {
        el.focus();
      },
    },
  },
});
</script>
<style lang="less" scoped>
.login-container {
  display: flex;
  width: 100%;
  height: 100%;
  background: rgb(246, 247, 252);
  justify-content: flex-end;
  align-items: center;
}
.login-form {
  align-items: center;
  width: 50%;
  display: flex;
  flex-direction: column;
  // margin-right: 150px;
  z-index: 999;
  .form-user {
    // margin: 25px 0;
    .item {
      border-radius: 5px;
      border: 1px solid #ececec;
      display: flex;
      margin-bottom: 30px;
      background: #ffff;
      height: 45px;
      padding-left: 20px;
      display: flex;
      .code {
        position: relative;
        cursor: pointer;
        width: 74px;
        padding: 5px 10px 0 0;
      }
      .input-icon {
        line-height: 45px;
        color: #7a7a7a;
        padding-right: 20px;
      }
    }
  }
  input:-webkit-autofill {
    box-shadow: 0 0 0px 1000px white inset;
    -webkit-box-shadow: 0 0 0px 1000px white inset !important;
  }
  input {
    background: white;
    display: block;
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    margin: 0;
    padding: 0;
    color: #323233;
    line-height: inherit;
    text-align: left;
    border: 0;
    outline: none;
    font-size: 16px;
    line-height: 20px;
  }
}
.form-user,
.loging-btn {
  width: 400px;
}
.loging-btn {
  box-shadow: 2px 4px 11px #a4c2ff;
  margin-top: 10px;
  button {
    padding: 21px;
    font-size: 14px !important;
    width: 100%;
  }
}
.login-text {
  font-weight: bolder;
  font-size: 20px;
  letter-spacing: 2px;
  position: relative;
  display: flex;
  .login-line {
    z-index: -1;
    padding: 5px;
    position: relative;
    top: -8px;
    width: 100%;
    background-image: linear-gradient(to right, #6598ff, white);
  }
}
.login-text-small {
  margin-bottom: 20px;
  font-size: 13px;
  color: #7d7c7c;
}
.login-bg {
  left: 0;
  position: absolute;
  height: 100%;
  width: 50%;
  z-index: 0;
}
.project-name {
  position: absolute;
  top: 40px;
  left: 40px;
  z-index: 9999;
  font-weight: bolder;
  background-image: linear-gradient(to right, #1850c1, #9c009c);
  -webkit-background-clip: text;
  color: transparent;
  font-size: 25px;
}
</style>
<style lang="less" scoped>
.app-link {
  // font-weight: bolder;
  text-align: center;
  padding-top: 5px;
  font-size: 12px;
  width: 400px;
  padding-left: 40px;
  display: flex;
  a {
    flex: 1;
    position: relative;
    cursor: pointer;
    width: 70px;
    color: #666666;
    margin: 2px 10px 0 0;
  }
  img {
    display: none;
  }
  a:hover {
    color: #0545f6 !important;
    img {
      display: block;
      position: absolute;
      z-index: 999999999;
      top: -130px;
      width: 120px;
      left: -22px;
      border: 1px solid #b1b1b1;
    }
  }
}
.login-footer {
  position: absolute;
  width: 50%;
  bottom: 0.5rem;
  font-size: 12px;
  text-align: center;
  padding-bottom: 10px;
  color: #4f4f4f;
  a {
    margin-right: 10px;
    font-size: 12px;
    color: #4f4f4f;
  }
  div {
    margin-bottom: 5px;
  }
  a:hover {
    cursor: pointer;
    color: #0540e3 !important;
  }
}
.account-info {
  font-size: 12px;
  color: #636363;
  margin-top: 15px;
}
</style>
<style lang="less" scoped>
@media screen and (max-width: 700px) {
  .login-bg,
  .account-info,
  .app-link,
  .login-footer,
  .project-name {
    display: none;
  }
  .login-container {
    padding: 2rem;
    justify-content: center;
  }
  .login-form {
    width: 100%;
  }
  .form-user,
  .loging-btn {
    width: 100%;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/basic/areaInfo.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,215 @@
<template>
  <view-grid
    ref="grid"
    :columns="columns"
    :detail="detail"
    :editFormFields="editFormFields"
    :editFormOptions="editFormOptions"
    :searchFormFields="searchFormFields"
    :searchFormOptions="searchFormOptions"
    :table="table"
    :extend="extend"
  >
  </view-grid>
</template>
    <script>
import extend from "@/extension/basic/areaInfo.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup() {
    const table = ref({
      key: "id",
      footer: "Foots",
      cnName: "区域信息",
      name: "areaInfo",
      url: "/AreaInfo/",
      sortName: "id",
    });
    const editFormFields = ref({
      areaCode: "",
      areaName: "",
      warehouseId: "",
      areaDes: "",
    });
    const editFormOptions = ref([
      [
        {
          title: "区域编号",
          required: true,
          field: "areaCode",
          type: "string",
        },
        {
          title: "区域名称",
          required: true,
          field: "areaName",
          type: "string",
        },
        {
          title: "仓库主键",
          required: true,
          field: "warehouseId",
          type: "select",
          dataKey: "warehouse",
          data: [],
        },
      ],
      [
      {
          title: "区域类型",
          required: true,
          field: "areaType",
          type: "int",
        },
        {
          title: "区域描述",
          field: "areaDes",
          type: "textarea",
        },
        { title: "区域状态", field: "areaStatus" ,type: "select",dataKey: "enableEnum",data: [],},
      ],
    ]);
    const searchFormFields = ref({
      areaCode: "",
      areaName: "",
      warehouseId: "",
      areaDes: "",
    });
    const searchFormOptions = ref([
      [
        { title: "区域编号", field: "areaCode", type: "like" },
        { title: "区域名称", field: "areaName", type: "like" },
        {
          title: "区域状态",
          field: "areaStatus",
          type: "select",
          dataKey: "enableEnum",
          data: [],
        },
      ],
      [
        {
          title: "仓库主键",
          field: "warehouseId",
          type: "select",
          dataKey: "warehouse",
          data: [],
        },{ title: "区域类型", field: "areaType" },
      ],
    ]);
    const columns = ref([
      {
        field: "id",
        title: "Id",
        type: "int",
        width: 90,
        hidden: true,
        readonly: true,
        require: true,
        align: "left",
      },
      {
        field: "areaCode",
        title: "区域编号",
        type: "string",
        width: 80,
        align: "left",
      },
      {
        field: "warehouseId",
        title: "仓库主键",
        type: "string",
        width: 90,
        align: "left",
        bind:{ key: "warehouse", data: [] },
      },
      {
        field: "areaName",
        title: "区域名称",
        type: "string",
        width: 150,
        align: "left",
      },
      {
        field: "areaType",
        title: "区域类型",
        type: "decimal",
        width: 90,
        align: "left",
      },
      {
        field: "areaStatus",
        title: "区域状态",
        type: "string",
        width: 90,
        align: "left",
        bind: { key: "enableEnum", data: [] },
      },
      {
        field: "areaDes",
        title: "区域描述",
        type: "int",
        width: 120,
        align: "left",
      },
      {
        field: "creater",
        title: "创建人",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "createDate",
        title: "创建时间",
        type: "datetime",
        width: 160,
        align: "left",
        sort: true,
      },
      {
        field: "modifier",
        title: "修改人",
        type: "string",
        width: 100,
        align: "left",
      },
      {
        field: "modifyDate",
        title: "修改时间",
        type: "datetime",
        width: 160,
        align: "left",
        sort: true,
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 100,
        align: "left",
      },
    ]);
    const detail = ref({
      cnName: "#detailCnName",
      table: "",
      columns: [],
      sortName: "",
    });
    return {
      table,
      extend,
      editFormFields,
      editFormOptions,
      searchFormFields,
      searchFormOptions,
      columns,
      detail,
    };
  },
});
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/basic/areaRouter.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,171 @@
<template>
  <view-grid
    ref="grid"
    :columns="columns"
    :detail="detail"
    :editFormFields="editFormFields"
    :editFormOptions="editFormOptions"
    :searchFormFields="searchFormFields"
    :searchFormOptions="searchFormOptions"
    :table="table"
    :extend="extend"
  >
  </view-grid>
</template>
    <script>
import extend from "@/extension/basic/areaRouter.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup() {
    const table = ref({
      key: "id",
      footer: "Foots",
      cnName: "缓存点",
      name: "areaRouter",
      url: "/areaRouter/",
      sortName: "id",
    });
    const editFormFields = ref({
      areaId: "",
      startArea: "",
      nextArea: "",
      routerType: "",
      isEnd: "",
    });
    const editFormOptions = ref([
      [
        {title: "起点",required: true,field: "startArea",type: "string",},
        {title: "终点区域ID",required: true,field: "nextArea",type: "select",dataKey: "areainfo",data: [],},
      ],
      [
        {title: "路由类型",field: "routerType",type: "like"},
        {title: "是否为终点",field: "isEnd",type: "select",dataKey: "enable",data: [],}
      ],
    ]);
    const searchFormFields = ref({
      areaId: "",
      pointCode: "",
      pointStatus: "",
      enableStatus: "",
      pointType: "",
    });
    const searchFormOptions = ref([
      [
        {title: "起点",required: true,field: "startArea",type: "string",},
        {title: "终点区域ID",field: "nextArea",type: "select",dataKey: "areainfo",data: [],},
        // {title: "终点区域ID",required: true,field: "nextArea",type: "string",},
      ],
      [
        {title: "路由类型",field: "routerType",type: "like"},
        {title: "是否为终点",field: "isEnd",type: "select",dataKey: "enable",data: [],}
      ],
    ]);
    const columns = ref([
      {
        field: "id",
        title: "Id",
        type: "int",
        width: 90,
        hidden: true,
        readonly: true,
        require: true,
        align: "left",
      },
      {
        field: "startArea",
        title: "起点",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "nextArea",
        title: "终点区域ID",
        type: "string",
        width: 150,
        align: "left",
        bind:{ key: "areainfo", data: [] },
      },
      {
        field: "routerType",
        title: "路由类型",
        type: "string",
        width: 90,
        align: "left",
        // bind: { key: "locationStatusEnum", data: [] },
      },
      {
        field: "isEnd",
        title: "是否是终点",
        type: "byte",
        width: 90,
        align: "left",
        bind: { key: "enable", data: [] },
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "creater",
        title: "创建人",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "createDate",
        title: "创建时间",
        type: "datetime",
        width: 160,
        align: "left",
        sort: true,
      },
      {
        field: "modifier",
        title: "修改人",
        type: "string",
        width: 100,
        align: "left",
      },
      {
        field: "modifyDate",
        title: "修改时间",
        type: "datetime",
        width: 160,
        align: "left",
        sort: true,
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 100,
        align: "left",
      },
    ]);
    const detail = ref({
      cnName: "#detailCnName",
      table: "",
      columns: [],
      sortName: "",
    });
    return {
      table,
      extend,
      editFormFields,
      editFormOptions,
      searchFormFields,
      searchFormOptions,
      columns,
      detail,
    };
  },
});
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/basic/cachePoint.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,209 @@
<template>
  <view-grid
    ref="grid"
    :columns="columns"
    :detail="detail"
    :editFormFields="editFormFields"
    :editFormOptions="editFormOptions"
    :searchFormFields="searchFormFields"
    :searchFormOptions="searchFormOptions"
    :table="table"
    :extend="extend"
  >
  </view-grid>
</template>
    <script>
import extend from "@/extension/basic/CachePoint.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup() {
    const table = ref({
      key: "id",
      footer: "Foots",
      cnName: "缓存点",
      name: "CachePoint",
      url: "/CachePoint/",
      sortName: "id",
    });
    const editFormFields = ref({
      areaId: "",
      pointCode: "",
      pointStatus: "",
      enableStatus: "",
      pointType: "",
      row: "",
      column: "",
      depth: "",
    });
    const editFormOptions = ref([
      [
        {title: "缓存点编号",required: true,field: "pointCode",type: "string",},
        {title: "区域主键",required: true,field: "areaId",type: "select",dataKey: "areainfo", data: [] ,},
        {title: "缓存点状态",field: "pointStatus",type: "select",dataKey: "locationStatusEnum",data: [],},
        {title: "是否禁用",field: "enableStatus",type: "select",dataKey: "enableStatusEnum",data: [],},
      ],[
        { title: "行", field: "row", type: "string" },
        { title: "列", field: "column", type: "string" },
        { title: "深度", field: "depth", type: "string" },
        { title: "缓存点类型", field: "pointType", type: "string"},
      ],
    ]);
    const searchFormFields = ref({
      areaId: "",
      pointCode: "",
      pointStatus: "",
      enableStatus: "",
      pointType: "",
      row: "",
      column: "",
      depth: "",
    });
    const searchFormOptions = ref([
      [
        {title: "缓存点编号",field: "pointCode",type: "string",},
        {title: "区域主键",field: "areaId",type: "select",dataKey: "areainfo",data: [],},
        {title: "缓存点状态",field: "pointStatus",type: "select",dataKey: "locationStatusEnum",data: [],},
        {title: "是否禁用",field: "enableStatus",type: "select",dataKey: "enableStatusEnum",data: [],},
      ],[
        { title: "行", field: "row", type: "string" },
        { title: "列", field: "column", type: "string" },
        { title: "深度", field: "depth", type: "string" },
        { title: "缓存点类型", field: "pointType", type: "string"},
      ],
    ]);
    const columns = ref([
      {
        field: "id",
        title: "Id",
        type: "int",
        width: 90,
        hidden: true,
        readonly: true,
        require: true,
        align: "left",
      },
      {
        field: "areaId",
        title: "区域主键",
        type: "int",
        width: 120,
        align: "left",
        bind:{ key: "areainfo", data: [] },
      },
      {
        field: "pointCode",
        title: "缓存点编号",
        type: "string",
        width: 150,
        align: "left",
      },
      {
        field: "pointStatus",
        title: "缓存点状态",
        type: "string",
        width: 90,
        align: "left",
        bind: { key: "locationStatusEnum", data: [] },
      },
      {
        field: "enableStatus",
        title: "是否禁用",
        type: "decimal",
        width: 90,
        align: "left",
        bind: { key: "enableStatusEnum", data: [] },
      },
      {
        field: "row",
        title: "行",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "column",
        title: "列",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "depth",
        title: "深度",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "pointType",
        title: "缓存点类型",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "Remark",
        title: "备注",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "creater",
        title: "创建人",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "createDate",
        title: "创建时间",
        type: "datetime",
        width: 160,
        align: "left",
        sort: true,
      },
      {
        field: "modifier",
        title: "修改人",
        type: "string",
        width: 100,
        align: "left",
      },
      {
        field: "modifyDate",
        title: "修改时间",
        type: "datetime",
        width: 160,
        align: "left",
        sort: true,
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 100,
        align: "left",
      },
    ]);
    const detail = ref({
      cnName: "#detailCnName",
      table: "",
      columns: [],
      sortName: "",
    });
    return {
      table,
      extend,
      editFormFields,
      editFormOptions,
      searchFormFields,
      searchFormOptions,
      columns,
      detail,
    };
  },
});
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/basic/locationInfo.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,205 @@
<template>
  <view-grid
    ref="grid"
    :columns="columns"
    :detail="detail"
    :editFormFields="editFormFields"
    :editFormOptions="editFormOptions"
    :searchFormFields="searchFormFields"
    :searchFormOptions="searchFormOptions"
    :table="table"
    :extend="extend"
  >
  </view-grid>
</template>
    <script>
import extend from "@/extension/basic/locationInfo.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup() {
    const table = ref({
      key: "id",
      footer: "Foots",
      cnName: "货位信息",
      name: "locationInfo",
      url: "/LocationInfo/",
      sortName: "id",
    });
    const editFormFields = ref({
      locationStatus: "",
    });
    const editFormOptions = ref([
      [
        { title: "货位状态", field: "locationStatus" ,type: "select",dataKey: "locationStatusEnum",data: [],},
      ],
    ]);
    const searchFormFields = ref({
      locationCode: "",
      roadwayNo: "",
    });
    const searchFormOptions = ref([
      [
        { title: "货位编号", field: "locationCode", type: "like" },
        { title: "巷道编号", field: "roadwayNo" },
        { title: "货位类型", field: "locationType",type: "select",dataKey: "locationTypeEnum",data: [], },
        { title: "禁用状态", field: "enableStatus" ,type: "select",dataKey: "enableStatusEnum",data: [],},
      ],
      [
        { title: "货位状态", field: "locationStatus" ,type: "selectList",dataKey: "locationStatusEnum",data: [],},
      ],
    ]);
    const columns = ref([
      {
        field: "id",
        title: "Id",
        type: "int",
        width: 90,
        hidden: true,
        readonly: true,
        require: true,
        align: "left",
      },
      // {
      //   field: "areaId",
      //   title: "区域主键",
      //   type: "string",
      //   width: 90,
      //   align: "left",
      //   bind: {key: "areainfo",data: []}
      // },
      {
        field: "locationCode",
        title: "货位编号",
        type: "string",
        width: 180,
        align: "left",
      },
      {
        field: "locationName",
        title: "货位名称",
        type: "string",
        width: 220,
        align: "left",
      },
      {
        field: "roadwayNo",
        title: "巷道编号",
        type: "decimal",
        width: 90,
        align: "left",
      },
      {
        field: "row",
        title: "货位行",
        type: "string",
        width: 90,
        align: "left",
        hidden: true,
      },
      {
        field: "column",
        title: "货位列",
        type: "int",
        width: 120,
        align: "left",
        hidden: true,
      },
      {
        field: "layer",
        title: "货位层",
        type: "string",
        width: 200,
        align: "left",
        hidden: true,
      },
      {
        field: "depth",
        title: "货位深度",
        type: "string",
        width: 180,
        align: "left",
        hidden: true,
      },
      {
        field: "locationType",
        title: "货位类型",
        type: "string",
        width: 120,
        align: "left",
        bind:{key: "locationTypeEnum", data: []}
      },
      {
        field: "locationStatus",
        title: "货位状态",
        type: "string",
        width: 200,
        align: "left",
        bind: { key: "locationStatusEnum", data: [] },
      },
      {
        field: "enableStatus",
        title: "禁用状态",
        type: "string",
        width: 180,
        align: "left",
        bind: { key: "enableStatusEnum", data: [] },
      },
      {
        field: "creater",
        title: "创建人",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "createDate",
        title: "创建时间",
        type: "datetime",
        width: 160,
        align: "left",
        sort: true,
      },
      {
        field: "modifier",
        title: "修改人",
        type: "string",
        width: 100,
        align: "left",
      },
      {
        field: "modifyDate",
        title: "修改时间",
        type: "datetime",
        width: 160,
        align: "left",
        sort: true,
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 100,
        align: "left",
      },
    ]);
    const detail = ref({
      cnName: "#detailCnName",
      table: "",
      columns: [],
      sortName: "",
    });
    return {
      table,
      extend,
      editFormFields,
      editFormOptions,
      searchFormFields,
      searchFormOptions,
      columns,
      detail,
    };
  },
});
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/basic/materielInfo.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,221 @@
<template>
  <view-grid
    ref="grid"
    :columns="columns"
    :detail="detail"
    :editFormFields="editFormFields"
    :editFormOptions="editFormOptions"
    :searchFormFields="searchFormFields"
    :searchFormOptions="searchFormOptions"
    :table="table"
    :extend="extend"
  >
  </view-grid>
</template>
    <script>
import extend from "@/extension/basic/materielInfo.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup() {
    const table = ref({
      key: "id",
      footer: "Foots",
      cnName: "物料信息",
      name: "materielInfo",
      url: "/MaterielInfo/",
      sortName: "id",
    });
    const editFormFields = ref({
      areaId: "",
      materielCode: "",
      materielName: "",
      materielDes: "",
      isMixBatch: "",
      isMixMateriel: "",
    });
    const editFormOptions = ref([
      [
        {
          title: "区域",
          required: true,
          field: "areaId",
          type: "string",
        },
        {
          title: "物料编号",
          required: true,
          field: "materielCode",
          type: "string",
        },
        {
          title: "物料名称",
          required: true,
          field: "materielName",
          type: "string",
        },
        {
          title: "计量单位",
          required: true,
          field: "unit",
          type: "string",
        },
      ],
      [
        {
          title: "物料描述",
          field: "materielDes",
          type: "textarea",
        },
      ],
    ]);
    const searchFormFields = ref({
      materielCode: "",
      materielName: "",
      areaId: "",
    });
    const searchFormOptions = ref([
      [
        { title: "物料编号", field: "materielCode", type: "like" },
        { title: "物料名称", field: "materielName", type: "like" },
        { title: "设备状态", field: "deviceStatus" },
      ],
    ]);
    const columns = ref([
      {
        field: "id",
        title: "Id",
        type: "int",
        width: 90,
        hidden: true,
        readonly: true,
        require: true,
        align: "left",
      },
      {
        field: "areaId",
        title: "区域主键",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "materielCode",
        title: "物料编号",
        type: "string",
        width: 150,
        align: "left",
      },
      {
        field: "materielName",
        title: "物料名称",
        type: "string",
        width: 150,
        align: "left",
      },
      {
        field: "materielDes",
        title: "物料描述",
        type: "decimal",
        width: 90,
        align: "left",
      },
      {
        field: "cotainerType",
        title: "容器类型",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "packspes",
        title: "包装规格",
        type: "int",
        width: 120,
        align: "left",
      },
      {
        field: "attribute",
        title: "物料属性",
        type: "string",
        width: 200,
        align: "left",
      },
      {
        field: "unit",
        title: "计量单位",
        type: "string",
        width: 180,
        align: "left",
      },
      {
        field: "validity",
        title: "有效期",
        type: "string",
        width: 120,
        align: "left",
      },
      {
        field: "safetyStock",
        title: "安全库存",
        type: "string",
        width: 120,
        align: "left",
      },
      {
        field: "creater",
        title: "创建人",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "createDate",
        title: "创建时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
      {
        field: "modifier",
        title: "修改人",
        type: "string",
        width: 100,
        align: "left",
      },
      {
        field: "modifyDate",
        title: "修改时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 100,
        align: "left",
      },
    ]);
    const detail = ref({
      cnName: "#detailCnName",
      table: "",
      columns: [],
      sortName: "",
    });
    return {
      table,
      extend,
      editFormFields,
      editFormOptions,
      searchFormFields,
      searchFormOptions,
      columns,
      detail,
    };
  },
});
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/basic/roadwayInfo.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,236 @@
<template>
  <view-grid
    ref="grid"
    :columns="columns"
    :detail="detail"
    :editFormFields="editFormFields"
    :editFormOptions="editFormOptions"
    :searchFormFields="searchFormFields"
    :searchFormOptions="searchFormOptions"
    :table="table"
    :extend="extend"
  >
  </view-grid>
</template>
      <script>
import extend from "@/extension/basic/roadwayInfo.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup() {
    const table = ref({
      key: "id",
      footer: "Foots",
      cnName: "巷道信息",
      name: "roadwayInfo",
      url: "/roadwayInfo/",
      sortName: "id",
    });
    const editFormFields = ref({
      roadwayNo: "",
      areaId: "",
      enalbeStatus: "",
      deviceNo: "",
      inStationCode: "",
      inSCStationCode: "",
      outStationCode: "",
      outSCStationCode: "",
    });
    const editFormOptions = ref([
      [
      {title: "区域主键",field: "areaId",type: "select",dataKey: "areainfo",data: [],},
        {
          title: "巷道编号",
          required: true,
          field: "roadwayNo",
          type: "string",
        },
        {
          title: "设备编号",
          required: true,
          field: "deviceNo",
          type: "string",
        },
        {
          title: "禁用状态",
          required: true,
          field: "enalbeStatus",
          type: "select",
          dataKey: "enableStatusEnum",
          data: [],
       },
      ],
      [
        {
          title: "入库站台编号",
          field: "inStationCode",
          type: "string",
        },
        {
          title: "堆垛机入库站台编号",
          field: "inSCStationCode",
          type: "string",
        },
        {
          title: "出库站台编号",
          field: "outStationCode",
          type: "string",
        },
        {
          title: "堆垛机出库站台编号",
          field: "outSCStationCode",
          type: "string",
        },
      ],
    ]);
    const searchFormFields = ref({
      roadwayNo: "",
      areaId: "",
      enableStatus: "",
      deviceNo: "",
      inStationCode: "",
      inSCStationCode: "",
      outStationCode: "",
      outSCStationCode: "",
    });
    const searchFormOptions = ref([
      [
        { title: "巷道编号", field: "roadwayNo", type: "like" },
        {title: "区域主键",field: "areaId",type: "select",dataKey: "areainfo",data: [],},
        { title: "禁用状态", field: "enableStatus",type: "select",dataKey: "enableStatusEnum",data: [],},
      ],
      [
        { title: "入库站台编号", field: "inStationCode", type: "like" },
        { title: "堆垛机入库站台编号", field: "inSCStationCode", type: "like" },
        { title: "设备编号", field: "deviceNo", type: "like" },
      ],
      [
        { title: "出库站台编号", field: "outStationCode", type: "like" },
        { title: "堆垛机出库站台编号",field: "outSCStationCode",type: "like",},
      ]
    ]);
    const columns = ref([
      {
        field: "id",
        title: "Id",
        type: "int",
        width: 90,
        hidden: true,
        readonly: true,
        require: true,
        align: "left",
      },
      {
        field: "roadwayNo",
        title: "巷道编号",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "areaId",
        title: "区域主键",
        type: "int",
        width: 150,
        align: "left",
        bind:{ key: "areainfo", data: [] },
      },
      {
        field: "enableStatus",
        title: "禁用状态",
        type: "select",
        width: 150,
        align: "left",
        bind: { key: "enableStatusEnum", data: [] },
      },
      {
        field: "deviceNo",
        title: "设备编号",
        type: "decimal",
        width: 90,
        align: "left",
      },
      {
        field: "inStationCode",
        title: "入库站台编号",
        type: "string",
        width: 120,
        align: "left",
      },
      {
        field: "inSCStationCode",
        title: "堆垛机入库站台编号",
        type: "string",
        width: 150,
        align: "left",
      },
      {
        field: "outStationCode",
        title: "出库站台编号",
        type: "decimal",
        width: 120,
        align: "left",
      },
      {
        field: "outSCStationCode",
        title: "堆垛机出库站台编号",
        type: "string",
        width: 150,
        align: "left",
      },
      {
        field: "creater",
        title: "创建人",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "createDate",
        title: "创建时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
      {
        field: "modifier",
        title: "修改人",
        type: "string",
        width: 100,
        align: "left",
      },
      {
        field: "modifyDate",
        title: "修改时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 100,
        align: "left",
      },
    ]);
    const detail = ref({
      cnName: "#detailCnName",
      table: "",
      columns: [],
      sortName: "",
    });
    return {
      table,
      extend,
      editFormFields,
      editFormOptions,
      searchFormFields,
      searchFormOptions,
      columns,
      detail,
    };
  },
});
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/basic/warehouse.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,179 @@
<template>
  <view-grid
    ref="grid"
    :columns="columns"
    :detail="detail"
    :editFormFields="editFormFields"
    :editFormOptions="editFormOptions"
    :searchFormFields="searchFormFields"
    :searchFormOptions="searchFormOptions"
    :table="table"
    :extend="extend"
  >
  </view-grid>
</template>
    <script>
import extend from "@/extension/basic/warehouse.js";
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup() {
    const table = ref({
      key: "id",
      footer: "Foots",
      cnName: "仓库信息",
      name: "warehouse",
      url: "/Warehouse/",
      sortName: "id",
    });
    const editFormFields = ref({
      warehouseCode: "",
      warehouseName: "",
      warehouseType: "",
      warehouseStatus: "",
      warehouseDes: "",
    });
    const editFormOptions = ref([
      [
        {
          title: "仓库编号",
          required: true,
          field: "warehouseCode",
          type: "string",
        },
        {
          title: "仓库名称",
          required: true,
          field: "warehouseName",
          type: "string",
        },
        {
          title: "仓库描述",
          field: "warehouseDes",
          type: "textarea",
        },
      ],
    ]);
    const searchFormFields = ref({
      warehouseCode: "",
      warehouseName: "",
      warehouseType: "",
      warehouseStatus: "",
    });
    const searchFormOptions = ref([
      [
        { title: "仓库编号", field: "warehouseCode", type: "like" },
        { title: "仓库名称", field: "warehouseName", type: "like" },
        { title: "仓库类型", field: "warehouseType", type: "like" },
        {
          title: "仓库状态",
          field: "warehouseStatus",
          type: "select",
          dataKey: "enableEnum",
          data: [],
        },
      ],
    ]);
    const columns = ref([
      {
        field: "id",
        title: "Id",
        type: "int",
        width: 90,
        hidden: true,
        readonly: true,
        require: true,
        align: "left",
      },
      {
        field: "warehouseCode",
        title: "仓库编号",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "warehouseName",
        title: "仓库名称",
        type: "string",
        width: 150,
        align: "left",
      },
      {
        field: "warehouseType",
        title: "仓库类型",
        type: "string",
        width: 150,
        align: "left",
      },
      {
        field: "warehouseStatus",
        title: "仓库状态",
        type: "decimal",
        width: 90,
        align: "left",
        bind: { key: "enableEnum", data: [] },
      },
      {
        field: "warehouseDes",
        title: "仓库描述",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "creater",
        title: "创建人",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "createDate",
        title: "创建时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
      {
        field: "modifier",
        title: "修改人",
        type: "string",
        width: 100,
        align: "left",
      },
      {
        field: "modifyDate",
        title: "修改时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
      {
        field: "remark",
        title: "备注",
        type: "string",
        width: 100,
        align: "left",
      },
    ]);
    const detail = ref({
      cnName: "#detailCnName",
      table: "",
      columns: [],
      sortName: "",
    });
    return {
      table,
      extend,
      editFormFields,
      editFormOptions,
      searchFormFields,
      searchFormOptions,
      columns,
      detail,
    };
  },
});
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/charts/bigdata.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,258 @@
<template>
  <div id="big-data-container" class="big-data-container">
    <div class="head">
      <h1>大屏数据统计分析显示</h1>
    </div>
    <div class="data-container">
      <div class="data-left">
        <div class="data-left-item">
          <div class="title">商品销量分类</div>
          <div id="chart-vleft-1" style="height: calc(100% - 30px)"></div>
          <div class="data-foot-line"></div>
        </div>
        <div class="data-left-item">
          <div class="title">本月商品销量</div>
          <div id="chart-vleft-3" style="height: calc(100% - 30px)"></div>
          <div class="data-foot-line"></div>
        </div>
        <div class="data-left-item">
          <div class="title">7日订单销量</div>
          <div id="chart-vleft-2" style="height: calc(100% - 30px)"></div>
          <div class="data-foot-line"></div>
        </div>
      </div>
      <div class="data-center">
        <!-- <div class="title">中间位置</div> -->
        <div class="center-top-num">
          <div class="item">
            <div class="text">累计销量</div>
            <div class="num">220,000</div>
          </div>
          <div class="item">
            <div class="text">累计销售金额</div>
            <div class="num">58,000,000</div>
          </div>
          <div class="item">
            <div class="text">购买用户人数</div>
            <div class="num">15,000</div>
          </div>
          <div class="data-foot-line"></div>
        </div>
        <div
          class="center-top"
          style="height: 260px; padding-top: 25px; overflow: hidden"
        >
          <!-- <div class="title">用户活跃信息-1</div> -->
          <div id="chart-vgauge-1" style="height: 400px"></div>
          <!-- <iview-circle :size="200" style="padding: 8px 0;"></iview-circle> -->
          <div class="data-foot-line"></div>
        </div>
        <div class="title">订单销售统计</div>
        <div id="chart-vcenter" style="height:400px;" class="chart-vcenter"></div>
      </div>
      <div class="data-right">
        <div class="data-right-item">
          <div class="title">销售情况走势</div>
          <div id="chart-vright-1" style="height: calc(100% - 30px)"></div>
          <div class="data-foot-line"></div>
        </div>
        <div class="data-right-item" style="height: 220px; padding-top: 25px">
          <!-- <div class="title">用户活跃信息</div> -->
          <!-- <iview-circle></iview-circle> -->
          <div id="chart-vgauge-2" style="height: 300px"></div>
          <div class="data-foot-line"></div>
        </div>
        <div class="data-right-item right-3">
          <div class="title">商品销售排行</div>
          <div id="chart-vright-3" class="right-item">
            <div class="item">
              <div class="top">排名</div>
              <div class="pro-name">商品名称</div>
              <div class="num">销量</div>
              <div class="num">销售金额</div>
            </div>
            <div class="item">
              <div class="top top-1">
                <span>1</span>
              </div>
              <div class="pro-name">卡帝乐鳄鱼</div>
              <div class="num">2,200</div>
              <div class="num">360,00</div>
            </div>
            <div class="item">
              <div class="top top-2">
                <span>2</span>
              </div>
              <div class="pro-name">春夏男T恤</div>
              <div class="num">1,700</div>
              <div class="num">24,500</div>
            </div>
            <div class="item">
              <div class="top top-3">
                <span>3</span>
              </div>
              <div class="pro-name">男女同款休闲鞋</div>
              <div class="num">1,120</div>
              <div class="num">12,700</div>
            </div>
          </div>
          <div class="boxfoot"></div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
var echarts = require("echarts");
let $chartLeft1,
  $chartLeft2,
  $chartLeft3,
  $chartCenter,
  $chartRight1,
  $chartGauge1,
  $chartGauge2;
import {
  chartLeft1,
  chartLeft2,
  chartLeft3,
  chartRight1,
  gauge,
} from "./bigdata/chart-options";
// import IviewCircle from "./bigdata/IviewCircle";
import "./bigdata/layout.less";
export default {
  components: {
    // "iview-circle": IviewCircle
  },
  data() {
    return {};
  },
  created() {
    console.log("chart");
  },
  mounted() {
    if ($chartLeft1) {
      $chartLeft1.dispose();
      $chartLeft2.dispose();
      $chartLeft3.dispose();
      $chartCenter.dispose();
      $chartRight1.dispose();
      $chartGauge1.dispose();
      $chartGauge2.dispose();
    }
    $chartLeft1 = echarts.init(document.getElementById("chart-vleft-1"));
    $chartLeft1.setOption(chartLeft1, true);
    $chartLeft2 = echarts.init(document.getElementById("chart-vleft-2"));
    $chartLeft2.setOption(chartLeft2, true);
    $chartLeft3 = echarts.init(document.getElementById("chart-vleft-3"));
    $chartLeft3.setOption(chartLeft3, true);
    $chartCenter = echarts.init(document.getElementById("chart-vcenter"));
    $chartCenter.setOption(chartRight1, true);
    $chartRight1 = echarts.init(document.getElementById("chart-vright-1"));
    $chartRight1.setOption(chartRight1, true);
    $chartGauge1 = echarts.init(document.getElementById("chart-vgauge-1"));
    $chartGauge1.setOption(gauge, true);
    $chartGauge2 = echarts.init(document.getElementById("chart-vgauge-2"));
    $chartGauge2.setOption(gauge);
  },
  destroyed() {
    $chartLeft1 = null;
    $chartLeft2 = null;
    $chartLeft3 = null;
    $chartCenter = null;
    $chartRight1 = null;
    $chartGauge1 = null;
    $chartGauge2 = null;
  },
};
</script>
<style scoped>
/* .chart-center {
  display: flex;
  border: 1px solid #0000ff;
  height: 200px;
  flex-direction: column;
  margin-top: 20px;
}
.chart-center .item {
  text-align: center;
  border: 1px solid #00c1b3;
  flex: 1;
} */
.right-3 {
  display: flex;
  flex-direction: column;
  /* margin-top: 20px; */
}
.right-3 .right-item {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.right-3 .item {
  text-align: left;
  border-bottom: 1px solid #549069;
  flex: 1;
  display: flex;
  padding: 5px 10px;
  margin: 0 10px;
  font-size: 14px;
  line-height: 30px;
}
.right-3 .item:last-child {
  border-bottom: 0;
}
.right-3 .item > div {
  color: white;
}
.right-3 .top {
  width: 60px;
  position: relative;
}
.right-3 .top span {
  position: absolute;
  width: 20px;
  line-height: 20px;
  top: 5px;
  text-align: center;
  border-radius: 5px;
}
.right-3 .top-1 span {
  background: #e80d0d;
}
.right-3 .top-2 span {
  background: #00c935;
}
.right-3 .top-3 span {
  background: #0083f4;
}
.right-3 .num {
  width: 88px;
}
.right-3 .pro-name {
  flex: 1;
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/charts/bigdata/IviewCircle.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
<template>
  <div class="demo-Circle">
    <div style>
      <i-circle
        :size="size"
        :trail-width="4"
        :stroke-width="5"
        :percent="75"
        stroke-linecap="square"
        stroke-color="#43a3fb"
      >
        <div class="demo-Circle-custom">
          <h1>1500</h1>
          <p>昨日活跃用户数量</p>
          <span>
            å æ¯”
            <i>{{1500/20000}}%</i>
          </span>
        </div>
      </i-circle>
    </div>
    <div style>
      <i-circle
        :size="size"
        :trail-width="4"
        :stroke-width="5"
        :percent="75"
        stroke-linecap="square"
        stroke-color="#43a3fb"
      >
        <div class="demo-Circle-custom">
          <h1>12000</h1>
          <p>上月活跃用户数量</p>
          <span>
            å æ¯”
            <i>{{12000/150000}}%</i>
          </span>
        </div>
      </i-circle>
    </div>
  </div>
</template>
<script>
export default {
  props:{
    size:{
      type:Number,
      default:150
    }
  }
}
</script>
<style scoped>
.demo-Circle {
  display: flex;
}
.demo-Circle > div {
  flex: 1;
  text-align: center;
}
.demo-Circle > div:first-child{
  padding-left:10%;
}
.demo-Circle > div:last-child{
  padding-right:10%;
}
</style>
<style lang="less" scoped>
.demo-Circle-custom {
  & h1 {
    color:#ffffff;
    font-size: 28px;
    font-weight: normal;
  }
  & p {
    color: #ece8e8;
    font-size: 14px;
    margin: 10px 0 15px;
  }
  & span {
    display: block;
    padding-top: 15px;
    color: wheat;
    font-size: 14px;
    &:before {
      content: "";
      display: block;
      width: 50px;
      height: 1px;
      margin: 0 auto;
      background: #e0e3e6;
      position: relative;
      top: -15px;
    }
  }
  & span i {
    font-style: normal;
    color: white;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/charts/bigdata/chart-options.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,551 @@
var echarts = require("echarts");
let chartLeft1 = {
  tooltip: {
    trigger: "axis",
    axisPointer: {
      type: "shadow"
    }
  },
  grid: {
    left: "0%",
    top: "10px",
    right: "0%",
    bottom: "4%",
    containLabel: true
  },
  xAxis: [
    {
      type: "category",
      data: [
        "商超门店",
        "教育培训",
        "房地产",
        "生活服务",
        "汽车销售",
        "旅游酒店",
        "五金建材"
      ],
      axisLine: {
        show: true,
        lineStyle: {
          color: "rgba(255,255,255,.1)",
          width: 1,
          type: "solid"
        }
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        interval: 0,
        show: true,
        splitNumber: 15,
        textStyle: {
          color: "rgba(255,255,255,.6)",
          fontSize: "12"
        }
      }
    }
  ],
  yAxis: [
    {
      type: "value",
      axisLabel: {
        show: true,
        textStyle: {
          color: "rgba(255,255,255,.6)",
          fontSize: "12"
        }
      },
      axisTick: {
        show: false
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: "rgba(255,255,255,.1    )",
          width: 1,
          type: "solid"
        }
      },
      splitLine: {
        lineStyle: {
          color: "rgba(255,255,255,.1)"
        }
      }
    }
  ],
  series: [
    {
      type: "bar",
      data: [200, 600, 300, 900, 1500, 1200, 600],
      barWidth: "35%",
      itemStyle: {
        normal: {
          color: "#2f89cf",
          opacity: 1,
          barBorderRadius: 5
        }
      }
    }
  ]
};
let chartLeft2 = {
  tooltip: {
    trigger: "axis",
    axisPointer: {
      type: "shadow"
    }
  },
  grid: {
    left: "0%",
    top: "10px",
    right: "0%",
    bottom: "4%",
    containLabel: true
  },
  xAxis: [
    {
      type: "category",
      data: [
        "07.01",
        "07.02",
        "07.03",
        "07.04",
        "07.05",
        "07.06",
      ],
      axisLine: {
        show: true,
        lineStyle: {
          color: "rgba(255,255,255,.1)",
          width: 1,
          type: "solid"
        }
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        interval: 0,
        // rotate:50,
        show: true,
        splitNumber: 15,
        textStyle: {
          color: "rgba(255,255,255,.6)",
          fontSize: "12"
        }
      }
    }
  ],
  yAxis: [
    {
      type: "value",
      axisLabel: {
        show: true,
        textStyle: {
          color: "rgba(255,255,255,.6)",
          fontSize: "12"
        }
      },
      axisTick: {
        show: false
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: "rgba(255,255,255,.1    )",
          width: 1,
          type: "solid"
        }
      },
      splitLine: {
        lineStyle: {
          color: "rgba(255,255,255,.1)"
        }
      }
    },
    {
      type: "value",
      axisLabel: {
        show: true,
        textStyle: {
          color: "rgba(255,255,255,.6)",
          fontSize: "12"
        }
      },
      axisTick: {
        show: false
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: "rgba(255,255,255,.1    )",
          width: 1,
          type: "solid"
        }
      },
      splitLine: {
        lineStyle: {
          color: "rgba(255,255,255,.1)"
        }
      }
    }
  ], series: [
    {
      type: "bar",
      name: "销量",
      data: [1200, 800, 300, 500, 560, 220],
      barWidth: "25%",
      itemStyle: {
        normal: {
          color: "#2f89cf",
          opacity: 1,
          barBorderRadius: 5
        }
      }
    }, {
      type: "bar",
      name: "订单",
      data: [1000, 750, 380, 450, 450, 120],
      barWidth: "25%",
      itemStyle: {
        normal: {
          color: "#46d000",
          opacity: 1,
          barBorderRadius: 5
        }
      }
    }
  ]
};
let chartLeft3 = {
  tooltip: {
    trigger: 'axis',
    axisPointer: {            // åæ ‡è½´æŒ‡ç¤ºå™¨ï¼Œåæ ‡è½´è§¦å‘有效
      type: 'shadow'        // é»˜è®¤ä¸ºç›´çº¿ï¼Œå¯é€‰ä¸ºï¼š'line' | 'shadow'
    }
  },
  grid: {
    left: "0%",
    top: "-5px",
    right: "3%",
    bottom: "4%",
    containLabel: true
  },
  xAxis: {
    type: 'value',
    axisLabel: {
      show: true,
      textStyle: {
        color: "rgba(255,255,255,.6)",
        fontSize: "12"
      }
    },
    axisTick: {
      show: false
    },
    axisLine: {
      show: true,
      lineStyle: {
        color: "rgba(255,255,255,.1    )",
        width: 1,
        type: "solid"
      }
    },
    splitLine: {
      lineStyle: {
        color: "rgba(255,255,255,.1)"
      }
    }
  },
  yAxis: {
    type: 'category',
    axisLabel: {
      show: true,
      textStyle: {
        color: "rgba(255,255,255,.6)",
        fontSize: "12"
      }
    },
    axisTick: {
      show: false
    },
    axisLine: {
      show: true,
      lineStyle: {
        color: "rgba(255,255,255,.1    )",
        width: 1,
        type: "solid"
      }
    },
    splitLine: {
      lineStyle: {
        color: "rgba(255,255,255,.1)"
      }
    },
    data: ['周一', '周二', '周三', '周四', '周五']
  },
  series: [
    {
      name: '直接访问',
      type: 'bar',
      stack: '总量',
      label: {
        show: true,
        position: 'insideRight'
      },
      barWidth: "55%",
      itemStyle: {
        normal: {
          color: "#2f89cf",
          opacity: 1,
          barBorderRadius: 5
        }
      },
      data: [120, 302, 400, 200, 700]
    }
  ]
};
let chartRight1 = {
  title: {},
  tooltip: {
    trigger: "axis",
    axisPointer: {
      type: "cross",
      label: {
        backgroundColor: "#6a7985"
      }
    }
  },
  color: ["#ffab6f", "#09b916", "#83cddc"], //图例颜色
  legend: {
    top: "0%",
    icon: "roundRect",
    data: ["销售订单", "退货订单", "折扣订单"],
    textStyle: {
      color: "rgba(255,255,255,.5)",
      fontSize: "12"
    }
  },
  toolbox: {
    feature: {}
  },
  grid: {
    left: "10",
    top: "20",
    right: "10",
    bottom: "10",
    containLabel: true
  },
  xAxis: [
    {
      type: "category",
      boundaryGap: false,
      axisLabel: {
        textStyle: {
          color: "rgba(255,255,255,.6)",
          fontSize: 12
        }
      },
      axisLine: {
        lineStyle: {
          color: "rgba(255,255,255,.2)"
        }
      },
      data: [
        "2020.06.15",
        "2020.06.16",
        "2020.06.17",
        "2020.06.18",
        "2020.06.19",
        "2020.06.20",
        "2020.06.21",
        "2020.06.22"
      ]
    }
  ],
  yAxis: [
    {
      type: "value",
      axisTick: { show: false },
      minInterval: 60,
      axisLine: {
        lineStyle: {
          color: "rgba(255,255,255,.1)"
        }
      },
      axisLabel: {
        textStyle: {
          color: "rgba(255,255,255,.6)",
          fontSize: 12
        }
      },
      splitLine: {
        lineStyle: {
          color: "rgba(255,255,255,.1)"
        }
      }
    }
  ],
  series: [
    {
      name: "销售订单",
      type: "line",
      smooth: true,
      lineStyle: {
        color: "#45d4ba",
        width: 1
      }, //线条的样式
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 0,
            color: "#83cddc"
          },
          {
            offset: 1,
            color: "#bfdffbb5"
          }
        ])
      },
      data: [5, 22, 150, 54, 1, 230, 4, 1]
    },
    {
      name: "退货订单",
      type: "line",
      smooth: true,
      lineStyle: {
        color: "#04a710",
        width: 1
      }, //
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 0,
            color: "#0cbf22"
          },
          {
            offset: 1,
            color: "#b8f7d1b5"
          }
        ])
      },
      data: [10, 150, 1, 250, 20, 100, 10, 150]
    },
    {
      name: "折扣订单",
      type: "line",
      lineStyle: {
        color: "#0864c3",
        width: 1
      }, //线条的样式
      smooth: true,
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 0,
            color: "#29d7ff"
          },
          {
            offset: 1,
            color: "#34ccef85"
          }
        ])
      },
      data: [100, 2, 260, 1, 200, 30, 101, 40]
    }
  ]
};
var gauge = {
  series: [{
    radius: '90%',
    type: 'gauge',
    startAngle: 180,
    endAngle: 0,
    min: 0,
    max: 1,
    splitNumber: 8,
    axisLine: {
      lineStyle: {
        width: 3,
        color: [
          [0.25, '#FF6E76'],
          [0.5, '#FDDD60'],
          [0.75, '#58D9F9'],
          [1, '#7CFFB2']
        ]
      }
    },
    pointer: {
      icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
      length: '12%',
      width: 20,
      offsetCenter: [0, '-60%'],
      itemStyle: {
        color: 'auto'
      }
    },
    axisTick: {
      length: 12,
      lineStyle: {
        color: 'auto',
        width: 2
      }
    },
    splitLine: {
      length: 20,
      lineStyle: {
        color: 'auto',
        width: 5
      }
    },
    axisLabel: {
      color: '#464646',
      fontSize: 20,
      distance: -60,
      formatter: function (value) {
        if (value === 0.875) {
          return '优';
        }
        else if (value === 0.625) {
          return '中';
        }
        else if (value === 0.375) {
          return '良';
        }
        else if (value === 0.125) {
          return 'å·®';
        }
      }
    },
    title: {
      offsetCenter: [0, '-20%'],
      fontSize: 20
    },
    detail: {
      fontSize: 30,
      offsetCenter: [0, '0%'],
      valueAnimation: true,
      formatter: function (value) {
        return Math.round(value * 100) + '分';
      },
      color: 'auto'
    },
    data: [{
      value: 0.70,
      name: '成绩评定'
    }]
  }]
}
export { chartLeft1, chartLeft2, chartLeft3, chartRight1, gauge }
在上述文件截断后对比
代码管理/WMS/WIDESEA_WMSClient/src/views/charts/bigdata/head_bg.png 代码管理/WMS/WIDESEA_WMSClient/src/views/charts/bigdata/layout.less 代码管理/WMS/WIDESEA_WMSClient/src/views/charts/chart.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/charts/chartOptions.js 代码管理/WMS/WIDESEA_WMSClient/src/views/charts/flex.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/charts/formChart.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/charts/formOptions.js 代码管理/WMS/WIDESEA_WMSClient/src/views/home/home-chart-options.js 代码管理/WMS/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/inbound/inboundOrderDetail.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/inbound/receiveOrder.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/index/Message.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/index/MessageConfig.js 代码管理/WMS/WIDESEA_WMSClient/src/views/index/index.less 代码管理/WMS/WIDESEA_WMSClient/src/views/outbound/outboundOrder.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/outbound/outboundOrderDetail.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/record/locationStatusChangeRecord.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/stock/stockInfoDetail.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/Permission.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/Permission/RoleTree.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/PermissionPDA.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_Dictionary.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_DictionaryList.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_Log.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_Menu.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_Role.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_Role1.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/Sys_User.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/UserInfo.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/system/Sys_Department.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/system/test.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/taskinfo/task.vue 代码管理/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_hty.vue 代码管理/WMS/WIDESEA_WMSClient/tests/unit/example.spec.js 代码管理/WMS/WIDESEA_WMSClient/vue.config.js 代码管理/WMS/WIDESEA_WMSClient/yarn.lock 代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/5719e6ae-bc65-4344-93bf-c0d23dd5d595.vsidx (已删除) 代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/6c6ca66c-f03a-48f7-9fb7-7620f4736346.vsidx (已删除) 代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/789398d4-ad10-4b21-9f9c-c017ed2e4aa0.vsidx 代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/7dfb58b4-b4db-4726-99ab-289029af1540.vsidx (已删除) 代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/914d9c3f-57db-4637-bc40-52081424fde2.vsidx 代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/e2441919-0f15-4240-aa6e-d0b378dfd0ba.vsidx (已删除) 代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/eef0aa91-791e-44dd-b321-3146cf9e9a18.vsidx 代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/f3502ed8-fc43-47df-b9a2-74d7c2feb215.vsidx 代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/f91e73eb-1823-4174-b99b-0eb163ec64f8.vsidx 代码管理/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/FileContentIndex/fed10872-4afc-4516-bd7e-bb67d0b38147.vsidx (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalRepository/ApprovalFlowRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalRepository/ApprovalNodeRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalRepository/ApprovalTaskRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalRepository/NodeTransitionRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalRepository/WIDESEA_ApprovalRepository.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalService/ApprovalFlowService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalService/ApprovalNodeService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalService/ApprovalTaskService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ApprovalService/WIDESEA_ApprovalService.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_BasicRepository/LocationInfoRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_BasicRepository/WarehouseRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/Base/LocationInfoService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/Base/WarehouseService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/Service/LocationInfoService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckRepository/CheckOrderRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckRepository/CheckOrderResultRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckRepository/WIDESEA_CheckRepository.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckService/CheckOrderResultService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckService/CheckOrderService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_CheckService/WIDESEA_CheckService.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/CommonEnum/AuditStatusEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/CommonEnum/UploadStatusEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/LocationEnum/LocationChangeType.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/CheckOrderEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InOrderStatusEnum.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InOrderTypeEnum.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InboundOrderMenu.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutOrderStatusEnum.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutOrderTypeEnum.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutboundOrderEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/PurchaseOrderEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/ReceiveOrderEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/SynchronizationFlagEmun.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockChangeTypeEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/AOP/SqlSugarAop.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/App.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Attributes/SequenceAttirbute.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/BaseController/ApiBaseController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/BaseModels/PageDataOptions.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/BaseRepository/IRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/BaseRepository/RepositoryBase.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/BaseServices/ServiceBase.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/CodeConfigEnum/AnalysisCodeEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/CodeConfigEnum/AnalysisFormatTypeEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/CodeConfigEnum/RuleCodeEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/DB/MainDb.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/DB/Models/BaseWarehouseEntity.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Enums/AuthorityScopeEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Enums/OperateTypeEnum.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Extensions/AutofacModuleRegister.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Extensions/SqlsugarSetup.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Extensions/WebSocketSetup.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Helper/CodeAnalysisHelper.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Helper/ObjectExtension.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/HostedService/PermissionDataHostService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/HostedService/SeedDataHostedService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/HttpContextUser/AspNetUser.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/LogHelper/Logger.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Utilities/EntityProperties.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Utilities/ModelValidate.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Utilities/ParamsValidator.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/WIDESEA_Core.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Basic/MatSerNumAnalysisModel.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/ERP/PurchaseOrderModel.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/ERP/ReceiveOrderModel.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Inbound/InboundOrderAddDTO.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Inbound/InboundOrderDetailAddDTO.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MatSerialNumberDTO.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Stock/StockViewDTO.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/System/VueDictionaryDTO.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_External/ERPService/ERPInvokeService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_External/IERPService/IERPInvokeService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_External/Model/PurchaseOrderModel.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_External/WIDESEA_External.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalRepository/IApprovalFlowRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalRepository/IApprovalNodeRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalRepository/IApprovalTaskRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalRepository/INodeTransitionRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalRepository/WIDESEA_IApprovalRepository.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalService/IApprovalFlowService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalService/IApprovalTaskService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IApprovalService/WIDESEA_IApprovalService.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IBasicRepository/ILocationInfoRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/ILocationInfoService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckRepository/ICheckOrderRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckRepository/ICheckOrderResultRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckRepository/WIDESEA_ICheckRepository.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckService/ICheckOrderResultService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckService/ICheckOrderService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ICheckService/WIDESEA_ICheckService.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundRepository/IInboundRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundRepository/IPurchaseOrderDetailRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundRepository/IPurchaseOrderRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundRepository/IReceiveOrderDetailRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundRepository/IReceiveOrderRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IInboundOrderDetailService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IInboundOrderService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IInboundService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IPurchaseOrderService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IReceiveOrderDetailService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IInboundService/IReceiveOrderService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutStockLockInfoService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundOrderService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IRecordService/ILocationStatusChangeRecordSetvice.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IRecordService/IStockQuantityChangeRecordService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ISystemRepository/ISys_RoleDataPermissionRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ISystemService/ISys_RoleService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITask_HtyService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundRepository/InboundRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundRepository/PurchaseOrderDetailRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundRepository/PurchaseOrderRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundRepository/ReceiveOrderDetailRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundRepository/ReceiveOrderRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Base/InboundOrderDetailService.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Base/InboundOrderDetail_HtyService.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Base/InboundOrderService.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Base/InboundOrder_HtyService.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderDetailService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderDetail_HtyService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrder_HtyService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/InboundService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/PurchaseOrderService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/ReceiveOrderDetailService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/ReceiveOrderService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Service/InboundOrderDetailService.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/Service/InboundOrderService.cs (已删除) 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_InboundService/WIDESEA_InboundService.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/ApprovalFlow/Dt_ApprovalFlow.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/ApprovalFlow/Dt_ApprovalNode.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/ApprovalFlow/Dt_ApprovalTask.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/ApprovalFlow/Dt_NodeTransition.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Basic/Dt_LocationInfo.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Basic/Dt_MaterielInfo.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Basic/Dt_SupplierInfo.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Basic/Dt_Warehouse.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Check/Dt_CheckOrder.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Check/Dt_CheckOrderResult.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_InboundOrder.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_InboundOrderDetail.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_PurchaseOrder.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_PurchaseOrderDetail.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_ReceiveOrder.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_ReceiveOrderDetail.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Record/Dt_StockQuantityChangeRecord.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Stock/Dt_StockInfo.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Stock/Dt_StockInfoDetail.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_Log.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_Role.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_RoleDataPermission.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/System/Sys_User.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/TaskInfo/Dt_Task.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/TaskInfo/Dt_Task_Hty.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/Base/OutStockLockInfoService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/Base/OutboundOrderDetailService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/Base/OutboundOrderDetail_HtyService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/Base/OutboundOrderService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/Base/OutboundOrder_HtyService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_RecordService/Service/LocationStatusChangeRecordSetvice.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_RecordService/Service/StockQuantityChangeRecordService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockRepository/StockInfoRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/Base/StockInfoService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/Base/StockInfo_HtyService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/Base/StockViewService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/Service/StockInfoService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemRepository/Sys_DictionaryRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemRepository/Sys_RoleDataPermissionRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemRepository/Sys_UserRepository.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_DictionaryService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_RoleService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_UserService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemService/WIDESEA_SystemService.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/Task_HtyService.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer.sln 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Approval/ApprovalFlowController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Approval/ApprovalTaskController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Basic/LocationInfoController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Check/CheckOrderController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Check/CheckOrderResultController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/ERP/ErpController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/ReceiveOrderController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/ReceiveOrderDetailController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutStockLockInfoController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundOrderController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Filter/CustomProfile.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/wwwroot/WIDESEA_DB.DBSeed.Json/Sys_Dictionary.tsv 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/wwwroot/WIDESEA_DB.DBSeed.Json/Sys_User.tsv