分支自 SuZhouGuanHong/TaiYuanTaiZhong

WMS
dengjunjie
2023-12-13 d772a6cddc8ed656a2cb5604fc02f6e891db546e
WMS
已添加708个文件
168897 ■■■■■ 文件已修改
代码管理/WMS/WMS_Client/.eslintrc.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/.gitignore 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/README.md 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/babel.config.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/config/buttons.js 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/package-lock.json 33431 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/package.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/public/index.html 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/public/static/login_bg.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/public/wms_d.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/App.vue 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/api/http.js 323 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/api/permission.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/api/useTest.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/css/common.less 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/element-icon/fonts/element-icons.ttf 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/element-icon/fonts/element-icons.woff 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/element-icon/icon.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/error-img.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/error.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/h5/01.jpg 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/h5/02.jpg 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/h5/03.jpg 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/h5/04.jpg 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/h5/05.jpg 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/h5/06.jpg 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/h5/07.jpg 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/log.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/wcs_logo.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/wms_d.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/imgs/wms_x.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/script/common.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/script/extend.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/assets/script/testFormExtend.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/AsyncLoading.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/Audit.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/Empty.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ErrorMsg.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/Icons.vue 345 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/QuickSearch.vue 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/RouterLoading.vue 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/UploadExcel.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/AuditHis.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/ViewGrid.less 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/ViewGrid.vue 806 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/ViewGridAudit.vue 427 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/ViewGridCustomColumn.js 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/ViewGridCustomColumn.vue 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/detailMethods.js 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/index.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/methods.js 1682 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/props.js 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/ViewGrid/serviceFilter.js 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolBox.vue 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolElementMenu.vue 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolElementMenuChild.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolForm.vue 1487 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolForm/VolFormRender.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolFormDraggable/DownloadForm.js 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolFormDraggable/VolFormDraggable.vue 1157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolFormDraggable/VolFormPreview.vue 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolFormDraggable/formTemplate.js 664 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolFormDraggable/index.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolFormDraggable/options.js 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolFormDraggable/templateCode.js 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolHeader.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolTable.vue 1832 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolTable/VolTableRender.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/basic/VolUpload.vue 880 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/editor/KindEditor.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/editor/VolWangEditor.vue 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/redirect/401.vue 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/redirect/404.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/redirect/Message.vue 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/redirect/RedirectError.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/redirect/coding.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/data_A.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/force-directed.js 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/index.css 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/jsplumb.js 15711 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/mixins.js 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/node.vue 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/node_filter.vue 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/node_form.vue 350 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/node_menu.vue 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/panel.vue 612 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/components/workflow/utils.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_Expert.js 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_Expert/App_ExpertGridHeader.vue 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_Expert/App_ExpertModelBody.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_Expert2.js 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_News.js 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_News/App_NewGirdHeader.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_NewsEditor.js 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_ReportPrice.js 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_ReportPrice/App_ReportPriceModelBody.vue 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_Transaction.js 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_Transaction2.js 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/App_TransactionAvgPrice.js 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/news_article.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/appmanager/vProvinceCity.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/App_Appointment.js 329 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/App_Appointment/App_AppointmentGridFooter.vue 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/App_Appointment2.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrder.js 383 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrder2.js 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrder2/SellOrder2GridFooter.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrder2/SellOrder2ModelBody.vue 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrder3.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrder3/SellOrder3GridFooter.vue 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrderComponents/GridBody.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrderComponents/GridFooter.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrderComponents/GridHeader.vue 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrderComponents/ModelBody.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/SellOrderComponents/ModelFooter.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/vSellOrderImg.js 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/order/vSellOrderImg/vSellOrderImgModelBody.vue 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/Sys_Dictionary.js 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/Sys_DictionaryList.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/Sys_Log.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/Sys_Role.js 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/Sys_Role1.js 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/Sys_User.js 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/Sys_User/Sys_UserGridHeader.vue 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/flow/Sys_WorkFlow.js 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/flow/Sys_WorkFlow/WorkFlowGridHeader.vue 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/flow/Sys_WorkFlowTable.js 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/form/FormCollectionObject.js 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/form/FormCollectionOptionsGridHeader.vue 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/form/FormDesignOptions.js 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/quartz/Sys_QuartzLog.js 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/quartz/Sys_QuartzOptions.js 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/quartz/Sys_QuartzOptionsGridBody.vue 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/system/system/Sys_Department.js 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/widesea_system/system/dt_log.js 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/widesea_wms/system/base_routing_table.js 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/extension/widesea_wms/system/dt_stationinfo.js 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/main.js 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/router/charts.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/router/form.js 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/router/formsMulti.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/router/index.js 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/router/redirect.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/router/tables.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/router/viewGird.js 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/store/index.js 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/uitils/common.js 344 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/Home.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/Index.vue 716 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/Login.vue 386 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/Task/widesea_wms/taskinfo/dt_agvtask.vue 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/Task/widesea_wms/taskinfo/dt_agvtask_hty.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/appmanager/App_Expert.vue 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/appmanager/App_Expert2.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/appmanager/App_News.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/appmanager/App_NewsEditor.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/appmanager/App_ReportPrice.vue 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/appmanager/App_Transaction.vue 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/appmanager/App_Transaction2.vue 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/appmanager/App_TransactionAvgPrice.vue 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/builder/builderData.js 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/builder/coder.vue 658 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/charts/bigdata.vue 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/charts/bigdata/IviewCircle.vue 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/charts/bigdata/chart-options.js 551 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/charts/bigdata/head_bg.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/charts/bigdata/layout.less 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/charts/chart.vue 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/charts/chartOptions.js 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/charts/flex.vue 386 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/charts/formChart.vue 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/charts/formOptions.js 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/extension/widesea_wms/taskinfo/dt_agvtask.js 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/extension/widesea_wms/taskinfo/dt_agvtask_hty.js 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formDraggable/FormCollectionResultTree.vue 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formDraggable/FormSubmit.vue 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formDraggable/formDraggable.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/editTable.vue 272 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/form.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/form1.vue 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/form2.vue 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/form3.vue 355 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/form4.vue 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/form5.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/form6.vue 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/form7.vue 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/objectValidator.vue 265 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/forms/table.vue 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formsMulti/multi1.vue 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formsMulti/multi2.vue 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formsMulti/multi3.vue 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formsMulti/multil1Extension/multi1.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formsMulti/multil1Extension/table1.vue 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formsMulti/multil2Extension/mtable.vue 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formsMulti/multil2Extension/multi2.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formsMulti/multil3Extension/comMulti.vue 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/formsMulti/multil3Extension/multi3.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/h5/Guide.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/home/home-chart-options.js 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/html/Editor.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/html/List.vue 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/index/Message.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/index/MessageConfig.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/index/index.less 644 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/order/App_Appointment.vue 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/order/App_Appointment2.vue 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/order/SellOrder.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/order/SellOrder2.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/order/SellOrder3.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/order/vSellOrderImg.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/router/viewGird.js 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/signalR/Index.vue 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/Permission.vue 358 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/Permission/RoleTree.vue 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/Sys_Dictionary.vue 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/Sys_DictionaryList.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/Sys_Log.vue 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/Sys_Menu.vue 617 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/Sys_Role.vue 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/Sys_Role1.vue 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/Sys_User.vue 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/UserInfo.vue 317 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/flow/FlowDemo.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/flow/Sys_WorkFlow.vue 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/flow/Sys_WorkFlowTable.vue 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/form/FormCollectionObject.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/form/FormDesignOptions.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/quartz/Sys_QuartzLog.vue 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/quartz/Sys_QuartzOptions.vue 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/system/Sys_Department.vue 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/system/test.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/tables/table2.vue 243 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/tables/table3.vue 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/tables/tableForms.js 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/tables/tableForms.vue 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/tables/tableFormsViewGrid.js 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/tables/tabsTable.vue 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/treeTable/TreeTable1.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/treeTable/TreeTable2.vue 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/treeTable/TreeTable3.vue 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/treeTable/demo1/Table.vue 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/treeTable/demo1/Tree.vue 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/treeTable/demo1/table.js 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/treeTable/demo2/Table2.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/treeTable/demo2/Tree2.vue 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/treeTable/demo2/tree_options.js 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/upload/formUpload.vue 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/upload/volUploadExample.vue 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/widesea_system/dialog/logDetial.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/widesea_system/system/dt_log.vue 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/widesea_wms/system/base_routing_table.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/src/views/widesea_wms/system/dt_stationinfo.vue 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/tests/unit/example.spec.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/vue.config.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Client/yarn.lock 10203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/.dockerignore 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/.gitattributes 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/.gitignore 364 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/Dockerfile 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Builder/IRepositories/Core/ISys_TableInfoRepository.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Builder/IServices/Core/ISys_TableInfoService.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Builder/IServices/Core/Partial/ISys_TableInfoService.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Builder/Properties/launchSettings.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Builder/Repositories/Core/Sys_TableInfoRepository.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Builder/Services/Core/Partial/Sys_TableInfoService.cs 1956 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Builder/Services/Core/Sys_TableInfoService.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Builder/Utility/ProjectPath.cs 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Builder/WIDESEA_Builder.csproj 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Comm/DataHandle/DataParse.cs 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Comm/DataHandle/OperateDB.cs 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Comm/Http/HttpHelper.cs 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Comm/LogInfo/WriteDBLog.cs 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Comm/LogInfo/WriteLog.cs 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Comm/WIDESEA_Comm.csproj 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/BaseInterface/IServices.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/DictionaryComponent/DictionaryViewComponent.cs 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/IRepository.cs 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/IService.cs 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/RepositoryBase.cs 661 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/ServerMapPath/PathProvider.cs 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/ServiceBase.cs 1429 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/CacheManager/IService/ICacheService.cs 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/CacheManager/Service/MemoryCacheService .cs 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/CacheManager/Service/RedisCacheService.cs 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Configuration/AppSetting.cs 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Const/ApplicationContentType.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Const/DataBaseType.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Const/HtmlElementType.cs 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Const/Secret.cs 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Const/SqlDbTypeName.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Controllers/Basic/ApiBaseController.cs 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Controllers/Basic/BaseController.cs 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Controllers/Basic/WebBaseController.cs 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/DBManager/DBConnectionAttribute.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/DBManager/DBServerProvider.cs 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/DBManager/DbName.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/DBManager/Partial/DBServerProvider.cs 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Dapper/DapperParseGuidTypeHandler.cs 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Dapper/ISqlDapper.cs 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Dapper/SqlDapper.cs 953 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/EFDbContext/EFLoggerProvider.cs 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/EFDbContext/VOLContext.cs 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/ActionPermissionOptions.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/ApiMessage.cs 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/ApiStatutsCode.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/CPrefix.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/DbCurrentType.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/LinqExpressionType.cs 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/LoggerType.cs 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/QueryOrderBy.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/ResponseType.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/UserAgent.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/AuthorizationResponse.cs 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/AutofacManager/AutofacContainerModule.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/AutofacManager/AutofacContainerModuleExtension.cs 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/AutofacManager/IDependency.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/CacheKeyExtensions.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/ConvertJsonExtension.cs 360 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/EntityProperties.cs 1454 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/GenericExtension.cs 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/HtmlHelperViewExtensions.cs 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/LambdaExtensions.cs 522 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/ObjectExtension.cs 1181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/RequestExtension.cs 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/Response/ResponseMsg.cs 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/SecurityEncDecryptExtension.cs 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/ServerExtension.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/ServiceProviderManagerExtension.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/StaticFileExtensions.cs 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/StaticHttpContextExtensions.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/StringExtension.cs 577 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ActionExecuteFilter.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ActionPermissionAttribute.cs 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ActionPermissionFilter.cs 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ActionPermissionRequirement.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ApiActionPermissionAttribute.cs 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ApiAuthorizeFilter.cs 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/FixedTokenAttribute.cs 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/JWTAuthorize.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ServiceFunFilter.cs 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/FreeDB/FreeDB.cs 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Infrastructure/DictionaryHandler.cs 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Infrastructure/DictionaryManager.cs 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Middleware/ExceptionHandlerMiddleWare.cs 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Middleware/HttpRequestMiddleware.cs 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/ModelBinder/BaseBinderProvider.cs 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/ModelBinder/BaseModelBinder.cs 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/ModelBinder/BinderObject.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/ExpressValidator/GeneralOptions.cs 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/ExpressValidator/MethodsValidator.cs 366 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/ExpressValidator/ObjectModelValidatorState.cs 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/Filters/ObjectGeneralValidatorFilter.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/Filters/ObjectModelValidatorFilter.cs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/NullObjectModelValidator.cs 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/ValidationContainer.cs 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Properties/launchSettings.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Services/ActionExecutingLogger.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Services/Logger.cs 305 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Tenancy/TenancyManager.cs 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/UserManager/DepartmentContext.cs 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/UserManager/RoleContext.cs 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/UserManager/UserContext.cs 398 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/ApiAuthorizeRequire.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/DateTimeExtension.cs 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/DateTimeHelper.cs 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/DynamicPropertyBag .cs 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/EPPlusHelper.cs 665 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/FileHelper.cs 339 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/HttpContext.cs 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/HttpManager.cs 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/JwtHelper.cs 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/MailHelper.cs 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/NPOIHelper.cs 550 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/PDFHelper/IPDFService.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/PDFHelper/PDFService.cs 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/Response/FilterResponse.cs 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/Response/WebResponseContent.cs 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/SecurityEncDecrypt.cs 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/VierificationCode.cs 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/VierificationCodeHelpers.cs 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/VierificationCodeServices.cs 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/XmlHelper.cs 717 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/WIDESEA_Core.csproj 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/AuditBack.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/AuditRefuse.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/AuditStatus.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/FieldFilter.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/StepType.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/WorkFlowContainer.cs 337 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/WorkFlowFilter.cs 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/WorkFlowManager.cs 730 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/WorkFlowTableOptions.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/AttributeManager/EntityAttribute.cs 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/AttributeManager/PermissionTableAttribute.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/BaseCore/MappingManager.cs 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/ApiEntity/Input/ApiSys_UserInput.cs 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/ApiEntity/OutPut/ApiSys_UserOutput.cs 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Core/LoadSingleDataModel.cs 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Core/PageGridData.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Core/SaveDataModel.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Core/Sys_TableColumn.cs 245 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Core/Sys_TableInfo.cs 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/LoginInfo.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Permissions.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/RoleAuthor.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_Department.cs 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_Dictionary.cs 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_DictionaryList.cs 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_Log.cs 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_Menu.cs 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_Role.cs 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_RoleAuth.cs 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_User.cs 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_UserDepartment.cs 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/TableColumnInfo.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/UserInfo.cs 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/base_routing_table.cs 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/dt_log.cs 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/dt_stationinfo.cs 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/Sys_Department.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/Sys_User.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/Sys_UserDepartment.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/base_routing_table.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/dt_log.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/dt_stationinfo.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/vSys_Dictionary.cs 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Taskinfo/dt_agvtask.cs 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Taskinfo/dt_agvtask_hty.cs 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Taskinfo/partial/dt_agvtask.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Taskinfo/partial/dt_agvtask_hty.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/Sys_WorkFlow.cs 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/Sys_WorkFlowStep.cs 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/Sys_WorkFlowTable.cs 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/Sys_WorkFlowTableAuditLog.cs 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/Sys_WorkFlowTableStep.cs 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/partial/Sys_WorkFlow.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/partial/Sys_WorkFlowStep.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/partial/Sys_WorkFlowTable.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/partial/Sys_WorkFlowTableAuditLog.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/partial/Sys_WorkFlowTableStep.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/MappingManager.cs 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_DepartmentMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_DictionaryListMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_DictionaryMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_LogMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_MenuMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_RoleMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_UserDepartmentMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_UserMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/base_routing_tableMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/dt_logMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/dt_stationinfoMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/vSys_DictionaryMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/Taskinfo/dt_agvtaskMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/Taskinfo/dt_agvtask_htyMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/flow/Sys_WorkFlowMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/flow/Sys_WorkFlowStepMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/flow/Sys_WorkFlowTableAuditLogMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/flow/Sys_WorkFlowTableMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/flow/Sys_WorkFlowTableStepMapConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/SystemModels/BaseEntity.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/SystemModels/Sys_MenuRole.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_Entity/WIDESEA_Entity.csproj 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_DepartmentRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_DictionaryListRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_DictionaryRepository.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_LogRepository.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_MenuRepository.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_RoleRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_UserRepository.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/Idt_logRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/IvSys_DictionaryRepository.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/flow/ISys_WorkFlowRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/flow/ISys_WorkFlowStepRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/flow/ISys_WorkFlowTableAuditLogRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/flow/ISys_WorkFlowTableRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/flow/ISys_WorkFlowTableStepRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_DepartmentService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_DictionaryListService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_DictionaryService.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_LogService.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_MenuService.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_RoleService.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_UserService.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Idt_logService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/IvSys_DictionaryService.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_DepartmentService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_DictionaryListService.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_DictionaryService.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_MenuService.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_RoleService.cs 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_UserService.cs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/Idt_logService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/ISys_WorkFlowService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/ISys_WorkFlowStepService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/ISys_WorkFlowTableAuditLogService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/ISys_WorkFlowTableService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/ISys_WorkFlowTableStepService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/Partial/ISys_WorkFlowService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/Partial/ISys_WorkFlowStepService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/Partial/ISys_WorkFlowTableAuditLogService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/Partial/ISys_WorkFlowTableService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/Partial/ISys_WorkFlowTableStepService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Properties/launchSettings.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Partial/Sys_MenuRepository.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_DepartmentRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_DictionaryListRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_DictionaryRepository.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_LogRepository.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_MenuRepository.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_RoleRepository.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_UserRepository.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/dt_logRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/vSys_DictionaryRepository.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/flow/Sys_WorkFlowRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/flow/Sys_WorkFlowStepRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/flow/Sys_WorkFlowTableAuditLogRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/flow/Sys_WorkFlowTableRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/flow/Sys_WorkFlowTableStepRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_DepartmentService.cs 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_DictionaryListService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_DictionaryService.cs 284 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_MenuService.cs 303 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_RoleService.cs 372 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_UserService.cs 503 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/dt_logService.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_DepartmentService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_DictionaryListService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_DictionaryService.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_LogService.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_MenuService.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_RoleService.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_UserService.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/dt_logService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/vSys_DictionaryService.cs 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Partial/Sys_WorkFlowService.cs 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Partial/Sys_WorkFlowStepService.cs 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Partial/Sys_WorkFlowTableAuditLogService.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Partial/Sys_WorkFlowTableService.cs 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Partial/Sys_WorkFlowTableStepService.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Sys_WorkFlowService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Sys_WorkFlowStepService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Sys_WorkFlowTableAuditLogService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Sys_WorkFlowTableService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Sys_WorkFlowTableStepService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_System/WIDESEA_System.csproj 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IRepositories/Taskinfo/Idt_agvtaskRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IRepositories/Taskinfo/Idt_agvtask_htyRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IRepositories/system/Ibase_routing_tableRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IRepositories/system/Idt_stationinfoRepository.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/Taskinfo/Idt_agvtaskService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/Taskinfo/Idt_agvtask_htyService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/Taskinfo/Partial/Idt_agvtaskService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/Taskinfo/Partial/Idt_agvtask_htyService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/system/Ibase_routing_tableService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/system/Idt_stationinfoService.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/system/Partial/Ibase_routing_tableService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/system/Partial/Idt_stationinfoService.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Repositories/Taskinfo/dt_agvtaskRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Repositories/Taskinfo/dt_agvtask_htyRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Repositories/system/base_routing_tableRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Repositories/system/dt_stationinfoRepository.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/Taskinfo/Partial/dt_agvtaskService.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/Taskinfo/Partial/dt_agvtask_htyService.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/Taskinfo/dt_agvtaskService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/Taskinfo/dt_agvtask_htyService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/system/Partial/base_routing_tableService.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/system/Partial/dt_stationinfoService.cs 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/system/base_routing_tableService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/system/dt_stationinfoService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMS/WIDESEA_WMS.csproj 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WMSServe.sln 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/.config/dotnet-tools.json 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/ApiHomeController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/Builder/BuilderController.cs 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_DepartmentController.cs 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_DictionaryController.cs 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_DictionaryListController.cs 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_MenuController.cs 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_RoleController.cs 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_UserController.cs 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_WorkFlowController.cs 255 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_WorkFlowStepController.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_WorkFlowTableAuditLogController.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_WorkFlowTableController.cs 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_WorkFlowTableStepController.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_DepartmentController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_DictionaryController.cs 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_DictionaryListController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_LogController.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_MenuController.cs 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_RoleController.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_UserController.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_WorkFlowController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_WorkFlowStepController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_WorkFlowTableAuditLogController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_WorkFlowTableController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_WorkFlowTableStepController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_System/Partial/dt_logController.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_System/dt_logController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/Partial/base_routing_tableController.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/Partial/dt_agvtaskController.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/Partial/dt_agvtask_htyController.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/Partial/dt_stationinfoController.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/base_routing_tableController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/dt_agvtaskController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/dt_agvtask_htyController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/dt_stationinfoController.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Dockerfile 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/20231208/Template/AGV任务20231208134657.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/20231208/Template/AGV任务20231208170607.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/20231208/Template/AGV任务20231208171603.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/20231208/Template/AGV任务20231208173403.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/20231208/Template/AGV任务20231208175204.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV任务20231208150437.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV任务20231208152432.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV任务20231208172503.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV任务20231208173004.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208154331.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208161840.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208162251.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208163634.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208163750.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208165240.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Program.cs 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Properties/launchSettings.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Startup.cs 277 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/AppHtml/news.html 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/AppHtml/productDesc.html 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Controller/Controller.html 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Controller/ControllerApi.html 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Controller/ControllerApiPartial.html 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Controller/ControllerPartial.html 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/DomianModel/ApiInputDomainModel.html 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/DomianModel/ApiOutputDomainModel.html 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/DomianModel/DomainModel.html 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/DomianModel/MappingConfiguration.html 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/IRepositorys/BaseIRepositorie.html 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/IServices/IServiceBase.html 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/IServices/IServiceBasePartial.html 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/SearchPage.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/Vue3SearchPage.html 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/VueExtension.html 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/VueSearchPage.html 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/app/extension.html 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/app/options.html 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/app/page.html 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/gridParameters.html 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/router.html 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Repositorys/BaseRepository.html 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Repositorys/BaseRepositoryPartial.html 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Services/ServiceBase.html 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Services/ServiceBasePartial.html 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Upload/20231208/dt_agvtask/0a1819d1-6d55-44ba-b7c0-0a3e677cf62d_21KH231 苏州冠鸿 荆门亿纬H5项目软件系统任务-2022.11.10.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Upload/20231208/dt_agvtask/147d9561-ba54-43dc-928a-2e5de0a05679_2014Z211-XM0603-1-BOM表-签字版.xls 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Upload/20231208/dt_agvtask/7449d43d-6d90-4e81-b6ef-81237b91e2e4_TSW449_3_103_PAR.SPF 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Upload/20231208/dt_agvtask/bae36617-a982-4c7b-a4db-2cfd08143f08_TSW449_3_C2_S2.SPF 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/Upload/20231208/dt_agvtask/ce28a3b3-1880-4c25-9bc6-46081bb66514_TSW449_3_103_PAR.SPF 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/WIDESEA_WebApi.csproj 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/appsettings.Development.json 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/appsettings.json 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/App_News/202204200018378581/img02.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/App_Transaction/202204172225478035/img03.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/App_Transaction/202204172225587342/img01.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/App_Transaction/202204172226012098/img04.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/Sys_User/202204130014502760/2.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/Sys_User/202307110945105304/Default.jpg.jpeg 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/css/site.css 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/js/site.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/LICENSE 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css 3719 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css 331 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap.css 10038 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js 7013 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.js 4435 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js 432 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation/LICENSE.md 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation/dist/additional-methods.js 1158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation/dist/additional-methods.min.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation/dist/jquery.validate.js 1601 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery/LICENSE.txt 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery/dist/jquery.js 10364 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery/dist/jquery.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery/dist/jquery.min.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/test.txt 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/新建文本文档.txt 补丁 | 查看 | 原始文档 | blame | 历史
´úÂë¹ÜÀí/WMS/WMS_Client/.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/WMS_Client/.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/WMS_Client/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/WMS_Client/babel.config.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}
´úÂë¹ÜÀí/WMS/WMS_Client/config/buttons.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
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-bottom',
    class: '',
    type: 'success',
    plain: true,
    value: 'Import',
    onClick: function () {
        this.import();
    }
},
{
    name: "导 å‡º",
    icon: 'el-icon-top',
    type: 'success',
    plain: true,
    value: 'Export',
    onClick: function () {
        this.export();
    }
},
{
    name: "上传",
    icon: 'el-icon-top',
    type: 'success',
    plain: true,
    value: 'Upload',
    onClick: function () {
        this.Upload();
    }
}
    // , {
    //     name: "数据结构",
    //     icon: 'ios-cog',
    //     class: '',
    //     value: '',
    //     onClick: function () {
    //         this.openViewColumns();
    //     }
    // }
]
export default buttons
´úÂë¹ÜÀí/WMS/WMS_Client/package-lock.json
¶Ô±ÈÐÂÎļþ
ÎļþÌ«´ó
´úÂë¹ÜÀí/WMS/WMS_Client/package.json
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
{
  "name": "WIDESEA.vue3",
  "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",
    "wangeditor": "^4.7.6"
  },
  "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",
    "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/WMS_Client/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/WMS_Client/public/static/login_bg.png
´úÂë¹ÜÀí/WMS/WMS_Client/public/wms_d.png
´úÂë¹ÜÀí/WMS/WMS_Client/src/App.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
<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,
    };
  },
};
</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/WMS_Client/src/api/http.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,323 @@
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:8098/';
}
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://127.0.0.1:8098/';
}
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("vol_exp") == "1") {
            replaceToken();
        }
    }
    else if (res.headers.vol_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 => {
                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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/src/assets/element-icon/fonts/element-icons.ttf
Binary files differ
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/element-icon/fonts/element-icons.woff
Binary files differ
´úÂë¹ÜÀí/WMS/WMS_Client/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/WMS_Client/src/assets/imgs/error-img.png
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/error.png
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/favicon.ico
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/h5/01.jpg
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/h5/02.jpg
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/h5/03.jpg
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/h5/04.jpg
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/h5/05.jpg
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/h5/06.jpg
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/h5/07.jpg
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/log.png
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/logo.png
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/wcs_logo.png
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/wms_d.png
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/imgs/wms_x.png
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/logo.png
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/script/common.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2 @@
var test1 = function () { alert(11) }
export { test1 }
´úÂë¹ÜÀí/WMS/WMS_Client/src/assets/script/extend.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
//对vue参数进行扩展
var extend = function (param) {
    console.log(param)
 }
export { extend }
´úÂë¹ÜÀí/WMS/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/src/components/basic/Empty.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
<template>
  <div></div>
</template>
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/basic/ErrorMsg.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
<template>
    <div id="test"></div>
</template>
´úÂë¹ÜÀí/WMS/WMS_Client/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-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-menu",
        "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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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: false, //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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/src/components/basic/ViewGrid/methods.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1682 @@
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(x.message);
        //删除后
        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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/src/components/basic/VolFormDraggable/VolFormDraggable.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1157 @@
<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;
      }
      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) {
      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/WMS_Client/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/WMS_Client/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/WMS_Client/src/components/basic/VolFormDraggable/index.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,3 @@
import VolFormDraggable from './VolFormDraggable'
 export default VolFormDraggable;
´úÂë¹ÜÀí/WMS/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/src/components/basic/VolTable.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1832 @@
<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="columnIndex"
        type="index"
        :fixed="fixed"
        width="55"
      ></el-table-column>
      <el-table-column
        v-if="ck"
        type="selection"
        :fixed="fixed"
        :selectable="selectable"
        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="column.showOverflowTooltip"
      >
        <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-if="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-else
                    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' ? false : true"
                    :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/WMS_Client/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/WMS_Client/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/WMS_Client/src/components/editor/KindEditor.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
<template>
</template>
<script>
export default {
}
</script>
<style>
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/editor/VolWangEditor.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,154 @@
<template>
  <div class="hello" ref="volWangEditor"></div>
</template>
<script>
import E from "wangeditor";
export default {
  props: {
    url: {
      //上传图片的url
      type: String,
      default: "",
    },
    upload: {
      //上传方法
      type: Function,
      // (file, insertImgFn) => {}
      default: null,
    },
    uploadCount: {
      //最多可以上传(图片)的数量
      type: Number,
      default: 3,
    },
    modelValue: "",
    width: {
      type: String,
      default: "100%",
    },
    height: {
      type: Number,
      default: 250,
    },
    minWidth: {
      type: Number,
      default: 650,
    },
    minHeight: {
      type: Number,
      default: 100,
    },
  },
  name: "wang-editor",
  data() {
    return {
      lastHtml: "",
      change: false,
      editor: null,
      init: false,
    };
  },
  watch: {
    modelValue(newVal, val) {
      if (
        (newVal !== val &&
          this.lastHtml !== "" &&
          val === this.lastHtml &&
          this.editor.txt.html() === this.lastHtml) ||
        this.editor.txt.html() === ""
      ) {
        this.editor.txt.html(newVal);
      }
      this.lastHtml = newVal;
    },
  },
  destroyed() {
    this.editor = null;
  },
  mounted() {
    this.editor = null;
    let editor = new E(this.$refs.volWangEditor);
    this.editor = editor;
    let $this = this;
    editor.config.zIndex = 500;
    editor.config.height = this.height;
    editor.config.onchange = (html) => {
      if (!this.init && this.lastHtml === "") {
        this.lastHtml = html;
        this.init = true;
      }
      this.$emit("update:modelValue", html);
    };
    // editor.config.uploadFileName = "fileInput";
    // //设置header
    // editor.config.uploadImgHeaders = {
    //   Accept: "application/json",
    //   Authorization: this.$store.getters.getToken(),
    // };
    //上传地址
    editor.config.uploadImgServer = this.http.ipAddress + this.url;
    // console.log(editor.config.uploadImgServer);
    editor.config.customUploadImg = function (resultFiles, insertImgFn) {
      // è‡ªå®šä¹‰ä¸Šä¼ 
      if ($this.upload) {
        console.log("调用自定义的上传方法");
        console.log(resultFiles);
        // resultFiles æ˜¯ input ä¸­é€‰ä¸­çš„æ–‡ä»¶åˆ—表
        // insertImgFn æ˜¯èŽ·å–å›¾ç‰‡ url åŽï¼Œæ’入到编辑器的方法
        //有可能会上传多张图片,上传多张图片就需要进行遍历
        resultFiles.map((item) => {
          // _this.getUploadImg(item, insertImgFn);
          $this.upload(item, insertImgFn);
        });
      } else {
        let formData = new FormData();
        let nameArr = [];
        resultFiles.forEach(function (file) {
          formData.append("fileInput", file, file.name);
          nameArr.push(file.name);
        });
        if (!$this.url) {
          $this.$message.error("未配置url");
          return;
        }
        $this.http.post($this.url, formData, true).then((x) => {
          if (!x.status) {
            return $this.$message.error(x.message);
          }
          nameArr.forEach(m=>{
            insertImgFn($this.http.ipAddress + x.data + m);
          })
          // let imgs = nameArr
          //   .map((m) => {
          //     return $this.http.ipAddress + x.data + m;
          //   })
          //   .join(",");
          // insertImgFn(imgs);
        });
      }
    };
    editor.create();
    editor.txt.html(this.modelValue);
  },
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1,
h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/src/components/workflow/data_A.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
let dataA = {
    "name": "流程A",
    "nodeList": [
        {
            "id": "0",
            "name": "流程开始",
            "type": "start",
            "left": "346px",
            "top": "22px",
            "ico": "el-icon-user-solid"
        },
        {
            "id": "nodeA",
            "name": "流程A-节点A",
            "type": "node",
            "left": "346px",
            "top": "132px",
            "ico": "el-icon-user-solid"
        },
    //     {
    //         "id": "nodeB",
    //         "name": "流程A-节点B",
    //         "type": "node",
    //         "left": "347px",
    //         "top": "235px",
    //         "ico": "el-icon-goods"
    //     },
    //     {
    //         "id": "nodeC",
    //         "name": "流程A-节点C",
    //         "type": "node",
    //         "left": "323px",
    //         "top": "399px",
    //         "ico": "el-icon-present"
    //     }
    ],
    "lineList": [
        {
            "from": "0",
            "to": "nodeA"
        },
        // {
        //     "from": "nodeA",
        //     "to": "nodeB"
        // },
        // {
        //     "from": "nodeB",
        //     "to": "nodeC"
        // }
    ]
}
export function getDataA () {
    return dataA
}
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/workflow/force-directed.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,182 @@
/**
 * æ„Ÿè°¢ https://github.com/chaangliu/ForceDirectedLayout/blob/master/javascript/force-directed.js
 * A force directed graph layout implementation by liuchang on 2018/05/10.
 */
const CANVAS_WIDTH = 1000
const CANVAS_HEIGHT = 1000
let k
let mNodeList = []
let mEdgeList = []
let mDxMap = {}
let mDyMap = {}
let mNodeMap = {}
export function ForceDirected(data = {}) {
    // generate nodes and edges
    // for (let i = 0; i < 20; i++) {
    //     mNodeList.push(new Node(i))
    // }
    k = 0
    mNodeList = []
    mEdgeList = []
    mDxMap = {}
    mDyMap = {}
    mNodeMap = {}
    let nodeList = data.nodeList
    for (let i = 0; i < nodeList.length; i++) {
        let node = nodeList[i]
        mNodeList.push(node)
    }
    // for (let i = 0; i < 20; i++) {
    //     let edgeCount = Math.random() * 8 + 1
    //     for (let j = 0; j < edgeCount; j++) {
    //         let targetId = Math.floor(Math.random() * 20)
    //         let edge = new Edge(i, targetId)
    //         mEdgeList.push(edge)
    //     }
    // }
    // line è½¬ edge
    let lineList = data.lineList
    for (let i = 0; i < lineList.length; i++) {
        let line = lineList[i]
        let edge = new Edge(line.from, line.to)
        mEdgeList.push(edge)
    }
    if (mNodeList && mEdgeList) {
        k = Math.sqrt(CANVAS_WIDTH * CANVAS_HEIGHT / mNodeList.length)
    }
    for (let i = 0; i < mNodeList.length; i++) {
        let node = mNodeList[i]
        if (node) {
            mNodeMap[node.id] = node
        }
    }
    // éšæœºç”Ÿæˆåæ ‡. Generate coordinates randomly.
    let initialX, initialY, initialSize = 40.0
    for (let i in mNodeList) {
        initialX = CANVAS_WIDTH * 0.5
        initialY = CANVAS_HEIGHT * 0.5
        mNodeList[i].x = initialX + initialSize * (Math.random() - 0.5)
        mNodeList[i].y = initialY + initialSize * (Math.random() - 0.5)
    }
    // è¿­ä»£200次. Iterate 200 times.
    for (let i = 0; i < 200; i++) {
        calculateRepulsive()
        calculateTraction()
        updateCoordinates()
    }
    // console.log(JSON.stringify(new Result(mNodeList, mEdgeList)))
    // åæ ‡æ·»åŠ px
    for (let i = 0; i < mNodeList.length; i++) {
        let node = mNodeList[i]
        node.left = node.x + 'px'
        node.top = node.y + 'px'
        node.x = undefined
        node.y = undefined
    }
    data.nodeList = mNodeList
    // console.log(data)
    return data
}
function Node(id = null) {
    this.id = id
    this.x = 22
    this.y = null
}
function Edge(source = null, target = null) {
    this.source = source
    this.target = target
}
/**
 * è®¡ç®—两个Node的斥力产生的单位位移。
 * Calculate the displacement generated by the repulsive force between two nodes.*
 */
function calculateRepulsive() {
    let ejectFactor = 6
    let distX, distY, dist
    for (let i = 0; i < mNodeList.length; i++) {
        mDxMap[mNodeList[i].id] = 0.0
        mDyMap[mNodeList[i].id] = 0.0
        for (let j = 0; j < mNodeList.length; j++) {
            if (i !== j) {
                distX = mNodeList[i].x - mNodeList[j].x
                distY = mNodeList[i].y - mNodeList[j].y
                dist = Math.sqrt(distX * distX + distY * distY)
            }
            if (dist < 30) {
                ejectFactor = 5
            }
            if (dist > 0 && dist < 250) {
                let id = mNodeList[i].id
                mDxMap[id] = mDxMap[id] + distX / dist * k * k / dist * ejectFactor
                mDyMap[id] = mDyMap[id] + distY / dist * k * k / dist * ejectFactor
            }
        }
    }
}
/**
 * è®¡ç®—Edge的引力对两端Node产生的引力。
 * Calculate the traction force generated by the edge acted on the two nodes of its two ends.
 */
function calculateTraction() {
    let condenseFactor = 3
    let startNode, endNode
    for (let e = 0; e < mEdgeList.length; e++) {
        let eStartID = mEdgeList[e].source
        let eEndID = mEdgeList[e].target
        startNode = mNodeMap[eStartID]
        endNode = mNodeMap[eEndID]
        if (!startNode) {
            console.log('Cannot find start node id: ' + eStartID + ', please check it out.')
            return
        }
        if (!endNode) {
            console.log('Cannot find end node id: ' + eEndID + ', please check it out.')
            return
        }
        let distX, distY, dist
        distX = startNode.x - endNode.x
        distY = startNode.y - endNode.y
        dist = Math.sqrt(distX * distX + distY * distY)
        mDxMap[eStartID] = mDxMap[eStartID] - distX * dist / k * condenseFactor
        mDyMap[eStartID] = mDyMap[eStartID] - distY * dist / k * condenseFactor
        mDxMap[eEndID] = mDxMap[eEndID] + distX * dist / k * condenseFactor
        mDyMap[eEndID] = mDyMap[eEndID] + distY * dist / k * condenseFactor
    }
}
/**
 * æ›´æ–°åæ ‡ã€‚
 * update the coordinates.
 */
function updateCoordinates() {
    let maxt = 4, maxty = 3 // Additional coefficients.
    for (let v = 0; v < mNodeList.length; v++) {
        let node = mNodeList[v]
        let dx = Math.floor(mDxMap[node.id])
        let dy = Math.floor(mDyMap[node.id])
        if (dx < -maxt) dx = -maxt
        if (dx > maxt) dx = maxt
        if (dy < -maxty) dy = -maxty
        if (dy > maxty) dy = maxty
        node.x = node.x + dx >= CANVAS_WIDTH || node.x + dx <= 0 ? node.x - dx : node.x + dx
        node.y = node.y + dy >= CANVAS_HEIGHT || node.y + dy <= 0 ? node.y - dy : node.y + dy
    }
}
function Result(nodes = null, links = null) {
    this.nodes = nodes
    this.links = links
}
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/workflow/index.css
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,258 @@
/*画布容器*/
.efContainer {
  position: relative;
  overflow: scroll;
  flex: 1;
}
.tools {
    position: absolute;
    left: 220px;
    /* background: #fff; */
    /* border: 1px solid #d8d7d7; */
    /* border-radius: 5px; */
    padding: 5px 5px;
    display: flex;
    z-index: 99;
    background: #fcfcfc;
}
/*顶部工具栏*/
.ef-tooltar {
  padding-left: 10px;
  box-sizing: border-box;
  height: 42px;
  line-height: 42px;
  z-index: 3;
  border-bottom: 1px solid #dadce0;
}
.jtk-overlay {
  cursor: pointer;
  color: #4a4a4a;
}
.ef-node-pmenu-item {
  padding: 10px;
  background: #f8f8f8;
  font-size: 13px;
  font-weight: bold;
  letter-spacing: 1px;
  border-top: 1px solid #eee;
  border-bottom: 1px solid #eee;
  border-right: 1px solid #eee;
}
/*节点菜单*/
.ef-node-pmenu {
  cursor: pointer;
  height: 32px;
  line-height: 32px;
  width: 225px;
  display: block;
  font-weight: bold;
  color: #4a4a4a;
  padding-left: 5px;
}
.ef-node-pmenu:hover {
  background-color: #e0e0e0;
}
.ef-node-menu-item {
  padding: 10px;
}
.ef-node-menu-li {
  cursor: move;
  border: 1px solid #eee;
  padding: 2px 13px;
  text-align: left;
  line-height: 28px;
  margin: 4px;
  border-radius: 3px;
  background: #f0f9eb;
  font-size: 12px;
  float: left;
  width: 98px;
}
.ef-node-menu-li  > div:first-child{
  display: inline-block;
  padding: 4px;
}
.ef-node-menu-li:hover {
  /* è®¾ç½®ç§»åŠ¨æ ·å¼*/
  cursor: move;
  border: 1px dashed #787be8;
  color: #787be8;
  /* background-color: #F0F7FF;
    border: 1px dashed #1879FF;
    border-left: 4px solid #1879FF;
    padding-left: 5px; */
}
.ef-node-menu-ul {
  list-style: none;
  padding-left: 0;
  margin: 0;
}
/*节点的最外层容器*/
.ef-node-container {
  position: absolute;
  display: flex;
  width: 170px;
  height: 32px;
  border: 1px solid #e0e3e7;
  border-radius: 5px;
  background-color: #fff;
}
.ef-node-container:hover {
  /* è®¾ç½®ç§»åŠ¨æ ·å¼*/
  cursor: move;
  background-color: #f0f7ff;
  /*box-shadow: #1879FF 0px 0px 12px 0px;*/
  background-color: #f0f7ff;
  border: 1px dashed #1879ff;
}
/*节点激活样式*/
.ef-node-active {
  background-color: #f0f7ff;
  /*box-shadow: #1879FF 0px 0px 12px 0px;*/
  background-color: #f0f7ff;
  border: 1px solid #1879ff;
}
/*节点左侧的竖线*/
.ef-node-left {
  width: 4px;
  background-color: #1879ff;
  border-radius: 4px 0 0 4px;
}
/*节点左侧的图标*/
.ef-node-left-ico {
  line-height: 32px;
  margin-left: 8px;
}
.ef-node-left-ico:hover {
  /* è®¾ç½®æ‹–拽的样式 */
  cursor: crosshair;
}
/*节点显示的文字*/
.ef-node-text {
  color: #565758;
  font-size: 12px;
  line-height: 32px;
  margin-left: 8px;
  width: 100px;
  /* è®¾ç½®è¶…出宽度文本显示方式*/
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
}
/*节点右侧的图标*/
.ef-node-right-ico {
  line-height: 32px;
  position: absolute;
  right: 5px;
  color: #84cf65;
  cursor: default;
}
/*节点的几种状态样式*/
.el-node-state-success {
  line-height: 32px;
  position: absolute;
  right: 5px;
  color: #84cf65;
  cursor: default;
}
.el-node-state-error {
  line-height: 32px;
  position: absolute;
  right: 5px;
  color: #f56c6c;
  cursor: default;
}
.el-node-state-warning {
  line-height: 32px;
  position: absolute;
  right: 5px;
  color: #e6a23c;
  cursor: default;
}
.el-node-state-running {
  line-height: 32px;
  position: absolute;
  right: 5px;
  color: #84cf65;
  cursor: default;
}
/*node-form*/
.ef-node-form-header {
  height: 32px;
  border-top: 1px solid #dce3e8;
  border-bottom: 1px solid #dce3e8;
  background: #f1f3f4;
  color: #000;
  line-height: 32px;
  padding-left: 12px;
  font-size: 14px;
}
.ef-node-form-body {
  margin-top: 10px;
  padding-right: 10px;
  padding-bottom: 20px;
}
/* è¿žçº¿ä¸­çš„label æ ·å¼*/
.jtk-overlay.flowLabel:not(.aLabel) {
  /* padding: 4px 10px; */
  padding: 1px 8px 2px 8px;
  background-color: white;
  color: #a9aaaa !important;
  border: 1px solid #e0e3e7;
  border-radius: 3px;
}
/* label ä¸ºç©ºçš„æ ·å¼ */
.emptyFlowLabel {
}
.ef-dot {
  background-color: #1879ff;
  border-radius: 10px;
}
.ef-dot-hover {
  background-color: red;
}
.ef-rectangle {
  background-color: #1879ff;
}
.ef-rectangle-hover {
  background-color: red;
}
.ef-img {
}
.ef-img-hover {
}
.ef-drop-hover {
  border: 1px dashed #1879ff;
}
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/workflow/jsplumb.js
¶Ô±ÈÐÂÎļþ
ÎļþÌ«´ó
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/workflow/mixins.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,157 @@
export const easyFlowMixin = {
    data() {
        return {
            jsplumbSetting: {
                // åŠ¨æ€é”šç‚¹ã€ä½ç½®è‡ªé€‚åº”
                Anchors: ['Top', 'TopCenter', 'TopRight', 'TopLeft', 'Right', 'RightMiddle', 'Bottom', 'BottomCenter', 'BottomRight', 'BottomLeft', 'Left', 'LeftMiddle'],
                // å®¹å™¨ID
                Container: 'efContainer',
                // è¿žçº¿çš„æ ·å¼ï¼Œç›´çº¿æˆ–者曲线等,可选值:  StateMachine、Flowchart,Bezier、Straight
                Connector: ['Bezier', {curviness: 100}],
                // Connector: ['Straight', {stub: 20, gap: 1}],
                // Connector: ['Flowchart', {stub: 30, gap: 1, alwaysRespectStubs: false, midpoint: 0.5, cornerRadius: 10}],
                // Connector: ['StateMachine', {margin: 5, curviness: 10, proximityLimit: 80}],
                // é¼ æ ‡ä¸èƒ½æ‹–动删除线
                ConnectionsDetachable: false,
                // åˆ é™¤çº¿çš„æ—¶å€™èŠ‚ç‚¹ä¸åˆ é™¤
                DeleteEndpointsOnDetach: false,
                /**
                 * è¿žçº¿çš„两端端点类型:圆形
                 * radius: åœ†çš„半径,越大圆越大
                 */
                // Endpoint: ['Dot', {radius: 5, cssClass: 'ef-dot', hoverClass: 'ef-dot-hover'}],
                /**
                 * è¿žçº¿çš„两端端点类型:矩形
                 * height: çŸ©å½¢çš„高
                 * width: çŸ©å½¢çš„宽
                 */
                // Endpoint: ['Rectangle', {height: 20, width: 20, cssClass: 'ef-rectangle', hoverClass: 'ef-rectangle-hover'}],
                /**
                 * å›¾åƒç«¯ç‚¹
                 */
                // Endpoint: ['Image', {src: 'https://www.easyicon.net/api/resizeApi.php?id=1181776&size=32', cssClass: 'ef-img', hoverClass: 'ef-img-hover'}],
                /**
                 * ç©ºç™½ç«¯ç‚¹
                 */
                Endpoint: ['Blank', {Overlays: ''}],
                // Endpoints: [['Dot', {radius: 5, cssClass: 'ef-dot', hoverClass: 'ef-dot-hover'}], ['Rectangle', {height: 20, width: 20, cssClass: 'ef-rectangle', hoverClass: 'ef-rectangle-hover'}]],
                /**
                 * è¿žçº¿çš„两端端点样式
                 * fill: é¢œè‰²å€¼ï¼Œå¦‚:#12aabb,为空不显示
                 * outlineWidth: å¤–边线宽度
                 */
                EndpointStyle: {fill: '#1879ffa1', outlineWidth: 1},
                // æ˜¯å¦æ‰“å¼€jsPlumb的内部日志记录
                LogEnabled: true,
                /**
                 * è¿žçº¿çš„æ ·å¼
                 */
                PaintStyle: {
                    // çº¿çš„颜色
                    stroke: '#E0E3E7',
                    // çº¿çš„粗细,值越大线越粗
                    strokeWidth: 1,
                    // è®¾ç½®å¤–边线的颜色,默认设置透明,这样别人就看不见了,点击线的时候可以不用精确点击,参考 https://blog.csdn.net/roymno2/article/details/72717101
                    outlineStroke: 'transparent',
                    // çº¿å¤–边的宽,值越大,线的点击范围越大
                    outlineWidth: 10
                },
                DragOptions: {cursor: 'pointer', zIndex: 2000},
                /**
                 *  å åŠ  å‚考: https://www.jianshu.com/p/d9e9918fd928
                 */
                Overlays: [
                    // ç®­å¤´å åŠ 
                    ['Arrow', {
                        width: 10, // ç®­å¤´å°¾éƒ¨çš„宽度
                        length: 8, // ä»Žç®­å¤´çš„尾部到头部的距离
                        location: 1, // ä½ç½®ï¼Œå»ºè®®ä½¿ç”¨0~1之间
                        direction: 1, // æ–¹å‘,默认值为1(表示向前),可选-1(表示向后)
                        foldback: 0.623 // æŠ˜å›žï¼Œä¹Ÿå°±æ˜¯å°¾ç¿¼çš„角度,默认0.623,当为1时,为正三角
                    }],
                    // ['Diamond', {
                    //     events: {
                    //         dblclick: function (diamondOverlay, originalEvent) {
                    //             console.log('double click on diamond overlay for : ' + diamondOverlay.component)
                    //         }
                    //     }
                    // }],
                    ['Label', {
                        label: '',
                        location: 0.1,
                        cssClass: 'aLabel'
                    }]
                ],
                // ç»˜åˆ¶å›¾çš„æ¨¡å¼ svg、canvas
                RenderMode: 'svg',
                // é¼ æ ‡æ»‘过线的样式
                HoverPaintStyle: {stroke: '#b0b2b5', strokeWidth: 1},
                // æ»‘过锚点效果
                // EndpointHoverStyle: {fill: 'red'}
                Scope: 'jsPlumb_DefaultScope' // èŒƒå›´ï¼Œå…·æœ‰ç›¸åŒscope的点才可连接
            },
            /**
             * è¿žçº¿å‚æ•°
             */
            jsplumbConnectOptions: {
                isSource: true,
                isTarget: true,
                // åŠ¨æ€é”šç‚¹ã€æä¾›äº†4个方向 Continuous、AutoDefault
                anchor: 'Continuous',
                // è®¾ç½®è¿žçº¿ä¸Šé¢çš„label样式
                labelStyle: {
                    cssClass: 'flowLabel'
                },
                // ä¿®æ”¹äº†jsplumb æºç ï¼Œæ”¯æŒlabel ä¸ºç©ºä¼ å…¥è‡ªå®šä¹‰style
                emptyLabelStyle: {
                    cssClass: 'emptyFlowLabel'
                }
            },
            /**
             * æºç‚¹é…ç½®å‚æ•°
             */
            jsplumbSourceOptions: {
                // è®¾ç½®å¯ä»¥æ‹–拽的类名,只要鼠标移动到该类名上的DOM,就可以拖拽连线
                filter: '.flow-node-drag',
                filterExclude: false,
                anchor: 'Continuous',
                // æ˜¯å¦å…è®¸è‡ªå·±è¿žæŽ¥è‡ªå·±
                allowLoopback: true,
                maxConnections: -1,
                onMaxConnections: function (info, e) {
                    console.log(`超过了最大值连线: ${info.maxConnections}`)
                }
            },
            // å‚考 https://www.cnblogs.com/mq0036/p/7942139.html
            jsplumbSourceOptions2: {
                // è®¾ç½®å¯ä»¥æ‹–拽的类名,只要鼠标移动到该类名上的DOM,就可以拖拽连线
                filter: '.flow-node-drag',
                filterExclude: false,
                // anchor: 'Continuous',
                // æ˜¯å¦å…è®¸è‡ªå·±è¿žæŽ¥è‡ªå·±
                allowLoopback: true,
                connector: ['Flowchart', {curviness: 50}],
                connectorStyle: {
                    // çº¿çš„颜色
                    stroke: 'red',
                    // çº¿çš„粗细,值越大线越粗
                    strokeWidth: 1,
                    // è®¾ç½®å¤–边线的颜色,默认设置透明,这样别人就看不见了,点击线的时候可以不用精确点击,参考 https://blog.csdn.net/roymno2/article/details/72717101
                    outlineStroke: 'transparent',
                    // çº¿å¤–边的宽,值越大,线的点击范围越大
                    outlineWidth: 10
                },
                connectorHoverStyle: {stroke: 'red', strokeWidth: 2}
            },
            jsplumbTargetOptions: {
                // è®¾ç½®å¯ä»¥æ‹–拽的类名,只要鼠标移动到该类名上的DOM,就可以拖拽连线
                filter: '.flow-node-drag',
                filterExclude: false,
                // æ˜¯å¦å…è®¸è‡ªå·±è¿žæŽ¥è‡ªå·±
                anchor: 'Continuous',
                allowLoopback: true,
                dropOptions: {hoverClass: 'ef-drop-hover'}
            }
        }
    }
}
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/workflow/node.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,99 @@
<template>
    <div ref="node" class="node-item" :style="nodeContainerStyle" @click="clickNode" @mouseup="changeNodeSite"
        :class="nodeContainerClass">
        <!-- æœ€å·¦ä¾§çš„那条竖线 -->
        <div class="ef-node-left"></div>
        <!-- èŠ‚ç‚¹ç±»åž‹çš„å›¾æ ‡ -->
        <div class="ef-node-left-ico flow-node-drag">
            <i :class="nodeIcoClass"></i>
        </div>
        <!-- èŠ‚ç‚¹åç§° -->
        <div class="ef-node-text" :show-overflow-tooltip="true">
            {{ node.name }}
        </div>
        <i @click.stop="delNode" v-if="node.type == 'node' && !disabled" style="display: none" class="el-icon-delete"></i>
        <!-- èŠ‚ç‚¹çŠ¶æ€å›¾æ ‡ -->
        <div class="ef-node-right-ico">
            <i class="el-icon-circle-check el-node-state-success" v-show="node.state === 'success'"></i>
            <i class="el-icon-circle-close el-node-state-error" v-show="node.state === 'error'"></i>
            <i class="el-icon-warning-outline el-node-state-warning" v-show="node.state === 'warning'"></i>
            <i class="el-icon-loading el-node-state-running" v-show="node.state === 'running'"></i>
        </div>
    </div>
</template>
<script>
export default {
    props: {
        node: Object,
        activeElement: Object,
        disabled: {
            typeof: Boolean,
            default: false
        }
    },
    data() {
        return {}
    },
    computed: {
        nodeContainerClass() {
            return {
                'ef-node-container': true,
                'ef-node-active': this.activeElement.type == 'node' ? this.activeElement.nodeId === this.node.id : false
            }
        },
        // èŠ‚ç‚¹å®¹å™¨æ ·å¼
        nodeContainerStyle() {
            return {
                top: this.node.top,
                left: this.node.left
            }
        },
        nodeIcoClass() {
            var nodeIcoClass = {}
            nodeIcoClass[this.node.ico] = true
            // æ·»åŠ è¯¥class可以推拽连线出来,viewOnly å¯ä»¥æŽ§åˆ¶èŠ‚ç‚¹æ˜¯å¦è¿è¡Œç¼–è¾‘
            nodeIcoClass['flow-node-drag'] = this.node.viewOnly ? false : true
            return nodeIcoClass
        }
    },
    methods: {
        // ç‚¹å‡»èŠ‚ç‚¹
        clickNode() {
            this.$emit('clickNode', this.node.id)
        },
        // é¼ æ ‡ç§»åŠ¨åŽæŠ¬èµ·
        changeNodeSite() {
            // é¿å…æŠ–动
            if (this.node.left == this.$refs.node.style.left && this.node.top == this.$refs.node.style.top) {
                return;
            }
            this.$emit('changeNodeSite', {
                nodeId: this.node.id,
                left: this.$refs.node.style.left,
                top: this.$refs.node.style.top,
            })
        }, delNode() {
            this.$emit("delNode");
        },
    }
}
</script>
<style  scoped>
/* .node-item{
    position: relative;
} */
.node-item:hover .el-icon-delete {
    display: inline-block !important;
}
.el-icon-delete {
    cursor: pointer;
    position: relative;
    top: -18px;
    padding-left: 5px;
    right: -16px;
    color: #f61313;
    height: 20px;
}
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/workflow/node_filter.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,201 @@
<template>
    <div class="node-filter-container">
        <!-- <div class="add-btn">
          <span class="name">条件设置</span>  <el-button @click="addItem" link><i>+</i>添加字段</el-button>
        </div> -->
        <!-- {{ $store.getters.data().flowTable.WorkTable }} -->
        <div class="ef-node-pmenu-item" style="display: flex;">
            <div style="flex:1;">
                <span class="name"><i class="el-icon-news"></i>条件设置</span>
            </div>
            <div><el-button link size="small" @click="addItem" type="primary" v-if="!disabled">
                    + æ·»åŠ å­—æ®µ</el-button></div>
        </div>
        <div>
            <table>
                <tr>
                    <td>字段</td>
                    <td style="width:90px">条件</td>
                    <td class="value">值</td>
                    <td style="width: 40px;" v-if="!disabled">操作</td>
                </tr>
                <tr v-for="(item, index) in filters" :key="index">
                    <td><el-select @change="(field) => { fieldChange(field, index) }" size="small" v-model="item.field"
                            placeholder="请选择" :disabled="disabled">
                            <el-option v-for="data in fieldsOptions" :key="data.field" :label="data.name"
                                :value="data.field" />
                        </el-select></td>
                    <td><el-select size="small" v-model="item.filterType" placeholder="请选择" :disabled="disabled">
                            <el-option v-for="data in filterType" :key="data.value" :label="data.name"
                                :value="data.value" />
                        </el-select></td>
                    <td>
                        <template v-if="item.data">
                            <el-select v-if="item.data.length >= 300" multiple size="small" v-model="item.value"
                                placeholder="请选择">
                                <el-option v-for="data in item.data" :key="data.key" :label="data.value"
                                    :value="data.key" :disabled="disabled" />
                            </el-select>
                            <el-select-v2 style="width: 100%;" v-else multiple size="small" :options="item.data"
                                v-model="item.value" placeholder="请选择" :disabled="disabled">
                            </el-select-v2>
                        </template>
                        <el-input v-else v-model="item.value" size="small" :disabled="disabled"></el-input>
                    </td>
                    <td @click="delItem(index)" class="item-del" v-if="!disabled"><i class="el-icon-delete"></i></td>
                </tr>
            </table>
        </div>
        <!-- <div>
            <label>自定义sql</label>
            <div><el-input type="textarea" v-model="customSql"></el-input></div>
        </div> -->
    </div>
</template>
<script>
let _this = this;
export default {
    props: {
        tableName: {
            type: String,
            default: ""
        },
        filters: {
            type: Array,
            default: () => {
                return []
            }
        },
        disabled:{
            typeof:Boolean,
            default:false
        }
    },
    data() {
        return {
            filter: this.$store.getters.data().flowTable,
            customSql: "",
            value: "",
            //{ field: "名称", value: "", filterType: "=" },
            //  filters: [],
            fieldsOptions: [
            ],
            t: [],
            filterType: [{ name: "等于(=)", value: "=" },
            { name: "不等于(!=)", value: "!=" },
            { name: "大于(>)", value: ">" },
            { name: "大于等于(>=)", value: ">=" },
            { name: "小于(<)", value: "<" },
            { name: "小于等于(<=)", value: "<=" },
            { name: "包括(in)", value: "in" },
            // { name: "不包括(not in)", value: "notin" },
            { name: "模糊匹配(like)", value: "like" },
            { name: "或者(or)", value: "or" }
            ]
        }
    },
    methods: {
        delItem(index) {
            this.$confirm('确认要删除字配置条件配置吗?', '警告', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning',
                center: true
            }).then(() => {
                this.filters.splice(index, 1);
            });
        },
        addItem() {
            this.filters.push({ field: "", value: "", filterType: "", data: null })
        },
        fieldChange(field, index) {
            let option = this.fieldsOptions.find(x => { return x.field == field });
            this.filters[index].field = option.field;
            this.filters[index].value = option.data ? [] : null;
            this.filters[index].data = option.data;;
        },
        convertOptions(result) {
        },
        getOptions(tableName) {
            const url = 'api/Sys_WorkFlow/getFields?table=' + tableName;
            this.http.post(url, {}, false).then(result => {
                result.forEach(c => {
                    if (c.data && c.data.length < 300) {
                        c.data = c.data.map(x => {
                            return {
                                value: x.key,
                                label: x.value,
                                key: x.key
                            }
                        })
                    }
                })
                _this.fieldsOptions = result;
            })
        }
    },
    watch: {
        'filter.WorkTable': {
            handler(newvalue, oldvalue) {
                if (newvalue) {
                    this.getOptions(newvalue);
                } else {
                    //  this.fieldsOptions.splice(0)
                }
            }
        }
        // deep:true,
        // filter(newVal,oldVal){
        //    alert(1)
        // }
    },
    created() {
        _this = this;
    },
}
</script>
<style lang="less" scoped>
.node-filter-container {
    margin-top: 15px;
    table {
        width: 100%;
        padding-left: 6px;
        td {
            font-size: 13px;
            padding: 5px;
        }
        tr:first-child {
            font-size: 12px;
            font-weight: bolder;
        }
        .item-del {
            text-align: center;
            color: rgb(226, 4, 4);
            cursor: pointer;
        }
        .value {
            width: 150px;
        }
    }
    .add-btn {
        text-align: right;
        padding-right: 10px;
        border-bottom: 1px solid #e8e8e8;
        padding-bottom: 5px;
    }
    .node-filter-item {}
}</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/workflow/node_form.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,350 @@
<template>
    <div>
        <div class="ef-node-form">
            <div class="ef-node-pmenu-item">
                <div style="flex:1;">
                    <span class="name"><i class="el-icon-news"></i>节点属性</span>
                    <!-- <span @click="nameClick(1)" :class="{ active: index === 1 }" class="name">审批条件</span> -->
                </div>
                <!-- <div><el-button link size="small" type="primary" @click="save"><i class="el-icon-check"></i>
                        ä¿å­˜é…ç½®</el-button></div> -->
            </div>
            <div class="ef-node-form-body">
                <div class="form-info">
                    <VolForm ref="form" style="padding:0 10px;" :label-width="130" :loadKey="false" :formFields="node"
                        :formRules="formRules" :disabled="disabled">
                    </VolForm>
                </div>
                <div>
                    <node-filter :filters="node.filters" :disabled="disabled" :tableName="tableName" ref="filter">
                    </node-filter>
                </div>
            </div>
            <!--            <div class="el-node-form-tag"></div>-->
        </div>
    </div>
</template>
<script>
// import { cloneDeep } from 'lodash'
import VolForm from '@/components/basic/VolForm.vue';
import nodeFilter from './node_filter.vue';
export default {
    components: {
        VolForm,
        'node-filter': nodeFilter
    },
    props: {
        disabled:{
            typeof:Boolean,
            default:false
        }
        // node: {
        //     type: Object,
        //     default: () => {
        //         return {
        //             name: '',
        //             auditType: 1,//审核类型
        //             userId: null,
        //             roleId: null,
        //             deptId: null,
        //             auditRefuse: null,//审核未通过
        //             auditBack: null, //驳回
        //             auditMethod: 0,//审批方式(会签)
        //             stepValue: null,
        //             sendMail: 0,
        //             filters: [] //字段过滤条件
        //         }
        //     }
        // }
    },
    created() {
        this.http.get('api/Sys_WorkFlow/getNodeDic').then((result) => {
            this.formRules.forEach((options) => {
                options.forEach((option) => {
                    if (option.dataKey && !option.data.length) {
                        option.data = result[option.dataKey] || [];
                    }
                });
            });
        });
    },
    data() {
        return {
            tableName: "",
            index: 1,
            visible: true,
            // node æˆ– line
            type: 'node',
            node: {},
            line: {},
            data: {},
            node: {
                name: '',
                auditType: 1,//审核类型
                userId: null,
                roleId: null,
                deptId: null,
                auditRefuse: null,//审核未通过
                auditBack: null, //驳回
                auditMethod: 0,//审批方式(会签)
                //  nodeValue: null,
                sendMail: 0,
                filters: []
            },
            formRules: [
                [
                    {
                        title: '节点名称',
                        field: 'name',
                        required: true,
                        colSize: 12
                    }],
                [
                    {
                        dataKey: '',
                        title: '审批类型',
                        required: true,
                        hidden: false,
                        field: 'auditType',
                        data: [
                            { key: 1, value: '按用户审批' },
                            { key: 2, value: '按角色审批' },
                            { key: 3, value: '按部门审批' }
                        ],
                        type: 'select',
                        onChange: this.nodeTypeChange,
                        colSize: 12
                    }
                ],
                [
                    {
                        dataKey: 'users',
                        hidden: false,
                        title: '审批用户',
                        required: true,
                        field: 'userId',
                        data: [],
                        type: 'selectList',
                        colSize: 12
                    }
                    ,
                    {
                        dataKey: 'roles',
                        hidden: true,
                        title: '角色信息',
                        required: true,
                        field: 'roleId',
                        data: [],
                        type: 'select',
                        colSize: 12
                    }
                    ,
                    {
                        dataKey: 'dept',
                        hidden: true,
                        title: '部门信息',
                        required: true,
                        field: 'deptId',
                        data: [],
                        type: 'select',
                        colSize: 12
                    }
                ], [
                    {
                        dataKey: '',
                        title: '审批未通过',
                        required: false,
                        field: 'auditRefuse',
                        hidden: false,
                        data: [
                            { key: 1, value: '返回上一节点' },
                            { key: 2, value: '流程重新开始' },
                            { key: 0, value: '流程结束' },
                        ],
                        type: 'select',
                        colSize: 6
                    }
                    ,
                    {
                        dataKey: '',
                        title: '审批驳回',
                        required: false,
                        hidden: false,
                        field: 'auditBack',
                        data: [
                            { key: 1, value: '返回上一节点' },
                            { key: 2, value: '流程重新开始' },
                            { key: 0, value: '流程结束' },
                        ],
                        type: 'select',
                        colSize: 6
                    }
                ],
                [
                    {
                        dataKey: '',
                        title: '审核后发送邮件通知',
                        required: false,
                        hidden: false,
                        field: 'sendMail',
                        data: [
                            { key: 1, value: '是' },
                            { key: 0, value: '否' },
                        ],
                        type: 'switch'
                    },
                    {
                        dataKey: '',
                        title: '启用会签',
                        required: false,
                        hidden: false,
                        field: 'auditMethod',//审批方式
                        data: [
                            { key: 1, value: '是' },
                            { key: 0, value: '否' }
                        ],
                        type: 'switch'
                    }
                ],
            ],
        }
    },
    methods: {
        nameClick(index) {
            this.index = index;
        },
        /**
         * è¡¨å•修改,这里可以根据传入的ID进行业务信息获取
         * @param data
         * @param id
         */
        nodeInit(data, id, tableName) {
            this.tableName = tableName;
            this.type = 'node'
            this.data = data;
            // this.tableName=data.
            data.nodeList.filter((node) => {
                if (node.id === id) {
                    this.formRules.forEach(options => {
                        options.forEach(c => {
                            if (c.field != 'name') {
                                c.hidden = node.type == 'start' || node.type == 'end';
                            }
                        })
                    })
                    if (!node.filters) {
                        node.filters = [];
                    }
                    this.node = node;// cloneDeep(node)
                    if (node.type != 'start' && node.type != 'end') {
                        this.nodeTypeChange(node.auditType);
                    }
                }
            })
            // data.nodeList.filter((node) => {
            //     if (node.id === id) {
            //         let _node = cloneDeep(node);
            //         _node.roleId = _node.roleId || null;
            //         _node.userId = _node.userId || null;
            //         _node.nodeType = (_node.nodeType || 1) * 1;
            //         if (!node.filters) {
            //             node.filters = [];
            //         }
            //         _node.filters = node.filters;
            //         this.nodeTypeChange(_node.nodeType);
            //         Object.assign(this.node, _node);
            //     }
            // });
        },
        nodeTypeChange(value) {
            // { key: 1, value: '按用户审批' },
            //   { key: 2, value: '按角色审批' },
            //   { key: 3, value: '按部门审批' }
            this.formRules.forEach((options) => {
                options.forEach((option) => {
                    if (option.field == 'userId') {
                        option.hidden = value != 1;
                    } else if (option.field == 'roleId') {
                        option.hidden = value != 2;
                    } else if (option.field == 'deptId') {
                        option.hidden = value != 3;
                    }
                });
            });
        },
        lineInit(line) {
            this.type = 'line'
            this.line = line
        },
        // ä¿®æ”¹è¿žçº¿
        saveLine() {
            this.$emit('setLineLabel', this.line.from, this.line.to, this.line.label)
        },
        save() {
            this.data.nodeList.filter((node) => {
                if (node.id === this.node.id) {
                    node.name = this.node.name;
                    node.left = this.node.left;
                    node.top = this.node.top;
                    node.ico = this.node.ico;
                    node.state = this.node.state;
                    node.stepValue = this.node.stepValue;
                    this.$emit('repaintEverything', this.node);
                }
            });
            this.$message.success('保存成功')
        }
    }
}
</script>
<style lang="less" scoped>
.el-node-form-tag {
    position: absolute;
    top: 50%;
    margin-left: -15px;
    height: 40px;
    width: 15px;
    background-color: #fbfbfb;
    border: 1px solid rgb(220, 227, 232);
    border-right: none;
    z-index: 0;
}
.btns {
    text-align: center;
    padding: 10px;
    buttton {
        flex: 1;
    }
}
.ef-node-pmenu-item {
    display: flex;
    .name {
        cursor: pointer;
        margin-right: 15px;
    }
    .active {
        color: #0659e8;
    }
}
.form-info ::v-deep(.vol-form-item) {
    display: flex;
    .el-form-item:nth-child(2),
    .el-form-item:nth-child(3),
    .el-form-item:nth-child(4) {
        margin-left: 12px;
    }
}
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/workflow/node_menu.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
<template>
    <div class="flow-menu" ref="tool">
        <div v-for="menu  in  menuList" :key="menu.id">
            <div class="ef-node-pmenu-item"><i class="el-icon-notebook-2"></i>节点配置</div>
            <ul v-show="menu.open" class="ef-node-menu-ul">
                <draggable @end="end" @start="move" v-model="menu.children" :options="draggableOptions">
                    <li v-for="subMenu in menu.children" class="ef-node-menu-li" :key="subMenu.id" :type="subMenu.type">
                        <i :class="subMenu.ico"></i> {{ subMenu.name }}
                    </li>
                </draggable>
            </ul>
        </div>
    </div>
</template>
<script>
import { VueDraggableNext as draggable } from "vue-draggable-next";
var mousePosition = {
    left: -1,
    top: -1
}
export default {
    data() {
        return {
            activeNames: '1',
            // draggable配置参数参考 https://www.cnblogs.com/weixin186/p/10108679.html
            draggableOptions: {
                preventOnFilter: false,
                sort: false,
                disabled: false,
                ghostClass: 'tt',
                // ä¸ä½¿ç”¨H5原生的配置
                forceFallback: true,
                // æ‹–拽的时候样式
                // fallbackClass: 'flow-node-draggable'
            },
            // é»˜è®¤æ‰“开的左侧菜单的id
            defaultOpeneds: ['1', '2'],
            menuList: [
                {
                    id: '1',
                    type: 'group',
                    name: '开始节点',
                    ico: 'el-icon-video-play',
                    open: true,
                    children: [
                        {
                            id: '0',
                            type: 'start',
                            name: '流程开始',
                            ico: 'el-icon-time',
                            // è‡ªå®šä¹‰è¦†ç›–样式
                            style: {}
                        },
                        {
                            id: '1',
                            type: 'end',
                            name: '流程结束',
                            ico: 'el-icon-switch-button',
                            // è‡ªå®šä¹‰è¦†ç›–样式
                            style: {}
                        },   {
                            id: '2',
                            type: 'node',
                            name: '流程节点',
                            ico: 'el-icon-news',
                            // è‡ªå®šä¹‰è¦†ç›–样式
                            style: {}
                        }
                    ]
                }],
            nodeMenu: {}
        }
    },
    components: {
        draggable
    },
    created() {
        /**
         * ä»¥ä¸‹æ˜¯ä¸ºäº†è§£å†³åœ¨ç«ç‹æµè§ˆå™¨ä¸ŠæŽ¨æ‹½æ—¶å¼¹å‡ºtab页到搜索问题
         * @param event
         */
        if (this.isFirefox()) {
            document.body.ondrop = function (event) {
                // è§£å†³ç«ç‹æµè§ˆå™¨æ— æ³•获取鼠标拖拽结束的坐标问题
                mousePosition.left = event.layerX
                mousePosition.top = event.clientY - 50
                event.preventDefault();
                event.stopPropagation();
            }
        }
    },
    methods: {
        // æ ¹æ®ç±»åž‹èŽ·å–å·¦ä¾§èœå•å¯¹è±¡
        getMenuByType(type) {
            for (let i = 0; i < this.menuList.length; i++) {
                let children = this.menuList[i].children;
                for (let j = 0; j < children.length; j++) {
                    if (children[j].type === type) {
                        return children[j]
                    }
                }
            }
        },
        // æ‹–拽开始时触发
        move(evt, a, b, c) {
            var type = evt.item.attributes.type.nodeValue
            this.nodeMenu = this.getMenuByType(type)
        },
        // æ‹–拽结束时触发
        end(evt, e) {
            this.$emit('addNode', evt, this.nodeMenu, mousePosition)
        },
        // æ˜¯å¦æ˜¯ç«ç‹æµè§ˆå™¨
        isFirefox() {
            var userAgent = navigator.userAgent
            if (userAgent.indexOf("Firefox") > -1) {
                return true
            }
            return false
        }
    }
}
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/workflow/panel.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,612 @@
<!-- å®¡æ ¸æµç¨‹æ’件基于https://gitee.com/xiaoka2017/easy-flow修改-->
<!--感谢萌级小菜鸟 / easy-flow -->
<template>
    <div v-if="easyFlowVisible" class="flow-panel">
        <div style="display: flex;height: 100%;position: relative;">
            <el-scrollbar style="height: 100%;border-right: 1px solid rgb(220, 227, 232);">
                <div style="width: 220px;">
                    <div class="ef-node-pmenu-item"><i class="el-icon-warning-outline"></i>基础信息</div>
                    <VolForm ref="form" style="padding: 10px;" :label-width="180" :loadKey="true" :formFields="formFields"
                        :disabled="disabled" :formRules="formRules"></VolForm>
                    <node-menu @addNode="addNode" ref="nodeMenu" v-if="!disabled"></node-menu>
                </div>
            </el-scrollbar>
            <div class="tools">
                <el-button circle @click="zoomAdd"><i class="el-icon-zoom-in"></i></el-button>
                <el-button circle @click="zoomSub"><i class="el-icon-zoom-out"></i></el-button>
            </div>
            <div style="flex: 1;" id="efContainer" ref="efContainer" class="container efContainer" v-flowDrag>
                <template :key="node.id" v-for="node in data.nodeList">
                    <flow-node :id="node.id" @delNode="deleteNode(node.id)" :node="node" :activeElement="activeElement"
                        :disabled="disabled" @changeNodeSite="changeNodeSite" @nodeRightMenu="nodeRightMenu"
                        @clickNode="clickNode">
                    </flow-node>
                </template>
                <!-- ç»™ç”»å¸ƒä¸€ä¸ªé»˜è®¤çš„宽度和高度 -->
                <div style="position:absolute;top: 3000px;left: 4000px;">&nbsp;</div>
            </div>
            <!-- å³ä¾§è¡¨å• -->
            <div style="width: 400px;border-left: 1px solid #dce3e8;background-color: #FBFBFB">
                <el-scrollbar style="height: 100%;padding-bottom: 10px;">
                    <flow-node-form @delNode="deleteNode" ref="nodeForm" @setLineLabel="setLineLabel" :disabled="disabled"
                        @repaintEverything="repaintEverything"></flow-node-form>
                </el-scrollbar>
            </div>
        </div>
    </div>
</template>
<script>
import { VueDraggableNext as draggable } from "vue-draggable-next";
// import { jsPlumb } from 'jsplumb'
// ä½¿ç”¨ä¿®æ”¹åŽçš„jsplumb
import './jsplumb'
import { easyFlowMixin } from './mixins'
import flowNode from './node'
import nodeMenu from './node_menu'
import FlowNodeForm from './node_form'
import lodash from 'lodash'
// import { getDataA } from './data_A'
import VolForm from '@/components/basic/VolForm.vue';
export default {
    props: {
        disabled: {
            typeof: Boolean,
            default: false
        }
    },
    data() {
        return {
            formFields: {
                WorkName: '',
                WorkTable: '',
                WorkTableName: '',
                Weight: 1,
                AuditingEdit: 0,
                Remark: ''
            },
            formRules: [
                [
                    {
                        dataKey: '流程名称',
                        title: '流程名称',
                        field: 'WorkName',
                        required: true
                    }],
                [{
                    dataKey: '',
                    title: '流程实例',
                    required: true,
                    field: 'WorkTable',
                    data: [],
                    readonly: false,
                    type: 'select',
                    onChange: (value, item) => {
                        this.formRules.forEach((options) => {
                            options.forEach((option) => {
                                if (option.field == 'WorkTable') {
                                    this.formFields.WorkTableName = option.data.find((x) => {
                                        return x.key == value;
                                    }).value;
                                }
                            });
                        });
                    }
                }],
                [{
                    title: '权重(相同条件权重大优先)',
                    field: 'Weight',
                    type: "number",
                }
                ],
                [{
                    title: '审核中数据是否可以编辑',
                    field: 'AuditingEdit',
                    type: "switch",
                    data: [{ key: 0, value: "否" }, { key: 1, value: "是" }]
                }
                ],
                [{
                    title: '备注',
                    field: 'Remark'
                }
                ]
            ],
            // jsPlumb å®žä¾‹
            jsPlumb: null,
            // æŽ§åˆ¶ç”»å¸ƒé”€æ¯
            easyFlowVisible: true,
            // æ˜¯å¦åŠ è½½å®Œæ¯•æ ‡å¿—ä½
            loadEasyFlowFinish: false,
            // æ•°æ®
            data: {},
            // æ¿€æ´»çš„元素、可能是节点、可能是连线
            activeElement: {
                // å¯é€‰å€¼ node ã€line
                type: undefined,
                // èŠ‚ç‚¹ID
                nodeId: undefined,
                // è¿žçº¿ID
                sourceId: undefined,
                targetId: undefined
            },
            zoom: 1
        }
    },
    // ä¸€äº›åŸºç¡€é…ç½®ç§»åŠ¨è¯¥æ–‡ä»¶ä¸­
    mixins: [easyFlowMixin],
    components: {
        draggable, flowNode, nodeMenu, FlowNodeForm, VolForm
    },
    directives: {
        'flowDrag': {
            mounted(el, binding, vnode, oldNode) {
                if (!binding) {
                    return
                }
                el.onmousedown = (e) => {
                    if (e.button == 2) {
                        // å³é”®ä¸ç®¡
                        return
                    }
                    //  é¼ æ ‡æŒ‰ä¸‹ï¼Œè®¡ç®—当前原始距离可视区的高度
                    let disX = e.clientX
                    let disY = e.clientY
                    el.style.cursor = 'move'
                    document.onmousemove = function (e) {
                        // ç§»åŠ¨æ—¶ç¦æ­¢é»˜è®¤äº‹ä»¶
                        e.preventDefault()
                        const left = e.clientX - disX
                        disX = e.clientX
                        el.scrollLeft += -left
                        const top = e.clientY - disY
                        disY = e.clientY
                        el.scrollTop += -top
                    }
                    document.onmouseup = function (e) {
                        el.style.cursor = 'auto'
                        document.onmousemove = null
                        document.onmouseup = null
                    }
                }
            }
        }
    },
    mounted() {
        this.jsPlumb = jsPlumb.getInstance()
        // this.$nextTick(() => {
        //     // é»˜è®¤åŠ è½½æµç¨‹A的数据、在这里可以根据具体的业务返回符合流程数据格式的数据即可
        //     this.dataReload(getDataA())
        // })
    },
    created() {
        this.http.get('api/Sys_WorkFlow/getTableInfo').then((result) => {
            this.formRules.forEach((options) => {
                options.forEach((option) => {
                    if (option.field == 'WorkTable') {
                        option.data = result;
                    }
                });
            });
        });
        this.$store.getters.data().flowTable = this.formFields;
    },
    methods: {
        // è¿”回唯一标识
        getUUID() {
            return Math.random().toString(36).substr(3, 10)
        },
        jsPlumbInit() {
            this.jsPlumb.ready(() => {
                // å¯¼å…¥é»˜è®¤é…ç½®
                this.jsPlumb.importDefaults(this.jsplumbSetting)
                // ä¼šä½¿æ•´ä¸ªjsPlumb立即重绘。
                this.jsPlumb.setSuspendDrawing(false, true);
                // åˆå§‹åŒ–节点
                this.loadEasyFlow()
                // å•点击了连接线, https://www.cnblogs.com/ysx215/p/7615677.html
                this.jsPlumb.bind('click', (conn, originalEvent) => {
                    this.activeElement.type = 'line'
                    this.activeElement.sourceId = conn.sourceId
                    this.activeElement.targetId = conn.targetId
                    this.$refs.nodeForm.lineInit({
                        from: conn.sourceId,
                        to: conn.targetId,
                        label: conn.getLabel()
                    })
                    this.deleteElement();
                })
                // è¿žçº¿
                this.jsPlumb.bind("connection", (evt) => {
                    let from = evt.source.id
                    let to = evt.target.id
                    if (this.loadEasyFlowFinish) {
                        this.data.lineList.push({ from: from, to: to })
                    }
                })
                // åˆ é™¤è¿žçº¿å›žè°ƒ
                this.jsPlumb.bind("connectionDetached", (evt) => {
                    this.deleteLine(evt.sourceId, evt.targetId)
                })
                // æ”¹å˜çº¿çš„连接节点
                this.jsPlumb.bind("connectionMoved", (evt) => {
                    this.changeLine(evt.originalSourceId, evt.originalTargetId)
                })
                // è¿žçº¿å³å‡»
                this.jsPlumb.bind("contextmenu", (evt) => {
                    console.log('contextmenu', evt)
                })
                // è¿žçº¿
                this.jsPlumb.bind("beforeDrop", (evt) => {
                    let from = evt.sourceId
                    let to = evt.targetId
                    if (from === to) {
                        this.$message.error('节点不支持连接自己')
                        return false
                    }
                    if (this.hasLine(from, to)) {
                        this.$message.error('该关系已存在,不允许重复创建')
                        return false
                    }
                    if (this.hashOppositeLine(from, to)) {
                        this.$message.error('不支持两个节点之间连线回环');
                        return false
                    }
                    this.$message.success('连接成功')
                    setTimeout(() => { this.setLineLabel(from, to, 'x') }, 50)
                    return true
                })
                // beforeDetach
                this.jsPlumb.bind("beforeDetach", (evt) => {
                    console.log('beforeDetach', evt)
                })
                this.jsPlumb.setContainer(this.$refs.efContainer)
            })
        },
        // åŠ è½½æµç¨‹å›¾
        loadEasyFlow() {
            // åˆå§‹åŒ–节点
            for (var i = 0; i < this.data.nodeList.length; i++) {
                let node = this.data.nodeList[i]
                if (node.userId && node.userId != '') {
                    // userId为数值类型
                    if (typeof node.userId == 'number'){
                        node.userId = [node.userId]
                    } else {
                        node.userId = node.userId.split(',').map(Number);
                    }
                } else {
                    node.userId = []
                }
                // è®¾ç½®æºç‚¹ï¼Œå¯ä»¥æ‹–出线连接其他节点
                this.jsPlumb.makeSource(node.id, lodash.merge(this.jsplumbSourceOptions, {}))
                // // è®¾ç½®ç›®æ ‡ç‚¹ï¼Œå…¶ä»–源点拖出的线可以连接该节点
                this.jsPlumb.makeTarget(node.id, this.jsplumbTargetOptions)
                if (!node.viewOnly && !this.disabled) {
                    this.jsPlumb.draggable(node.id, {
                        containment: 'parent',
                        stop: function (el) {
                            // æ‹–拽节点结束后的对调
                            console.log('拖拽结束: ', el)
                        }
                    })
                }
            }
            // åˆå§‹åŒ–连线
            for (var i = 0; i < this.data.lineList.length; i++) {
                let line = this.data.lineList[i]
                var connParam = {
                    source: line.from,
                    target: line.to,
                    label: this.disabled ? null : (line.label ? line.label : 'x'),
                    connector: line.connector ? line.connector : '',
                    anchors: line.anchors ? line.anchors : undefined,
                    paintStyle: line.paintStyle ? line.paintStyle : undefined,
                }
                this.jsPlumb.connect(connParam, this.jsplumbConnectOptions)
            }
            this.$nextTick(function () {
                this.loadEasyFlowFinish = true
            })
        },
        // è®¾ç½®è¿žçº¿æ¡ä»¶
        setLineLabel(from, to, label) {
            var conn = this.jsPlumb.getConnections({
                source: from,
                target: to
            })[0]
            if (!label || label === '') {
                conn.removeClass('flowLabel ')
                conn.addClass('emptyFlowLabel')
            } else {
                conn.addClass('flowLabel')
            }
            conn.setLabel({
                label: 'x' //label,
            })
            this.data.lineList.forEach(function (line) {
                if (line.from == from && line.to == to) {
                    line.label = 'x'// label
                }
            })
        },
        // åˆ é™¤æ¿€æ´»çš„元素
        deleteElement() {
            if (this.disabled)
                return
            if (this.activeElement.type === 'node') {
                this.deleteNode(this.activeElement.nodeId)
            } else if (this.activeElement.type === 'line') {
                this.$confirm('确定删除所点击的线吗?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    var conn = this.jsPlumb.getConnections({
                        source: this.activeElement.sourceId,
                        target: this.activeElement.targetId
                    })[0]
                    this.jsPlumb.deleteConnection(conn)
                }).catch(() => {
                })
            }
        },
        // åˆ é™¤çº¿
        deleteLine(from, to) {
            this.data.lineList = this.data.lineList.filter(function (line) {
                if (line.from == from && line.to == to) {
                    return false
                }
                return true
            })
        },
        // æ”¹å˜è¿žçº¿
        changeLine(oldFrom, oldTo) {
            this.deleteLine(oldFrom, oldTo)
        },
        // æ”¹å˜èŠ‚ç‚¹çš„ä½ç½®
        changeNodeSite(data) {
            for (var i = 0; i < this.data.nodeList.length; i++) {
                let node = this.data.nodeList[i]
                if (node.id === data.nodeId) {
                    node.left = data.left
                    node.top = data.top
                }
            }
        },
        /**
         * æ‹–拽结束后添加新的节点
         * @param evt
         * @param nodeMenu è¢«æ·»åŠ çš„èŠ‚ç‚¹å¯¹è±¡
         * @param mousePosition é¼ æ ‡æ‹–拽结束的坐标
         */
        addNode(evt, nodeMenu, mousePosition) {
            if (nodeMenu.type == 'start' && this.data.nodeList.some(x => { return x.type == 'start' })) {
                this.$message.error('【流程结束】节点已存在,只有选择一个流程开始节点');
                return
            }
            if (nodeMenu.type == 'end' && this.data.nodeList.some(x => { return x.type == 'end' })) {
                this.$message.error('【流程结束】节点已存在,只有选择一个流程开始节点');
                return
            }
            var screenX = evt.originalEvent.clientX, screenY = evt.originalEvent.clientY
            let efContainer = this.$refs.efContainer
            var containerRect = efContainer.getBoundingClientRect()
            var left = screenX, top = screenY
            // è®¡ç®—是否拖入到容器中
            if (left < containerRect.x || left > containerRect.width + containerRect.x || top < containerRect.y || containerRect.y > containerRect.y + containerRect.height) {
                this.$message.error("请把节点拖入到画布中")
                return
            }
            left = left - containerRect.x + efContainer.scrollLeft
            top = top - containerRect.y + efContainer.scrollTop
            // å±…中
            left -= 85
            top -= 16
            var nodeId = this.getUUID()
            // åŠ¨æ€ç”Ÿæˆåå­—
            var origName = nodeMenu.name
            var nodeName = origName
            var index = 1
            while (index < 10000) {
                var repeat = false
                for (var i = 0; i < this.data.nodeList.length; i++) {
                    let node = this.data.nodeList[i]
                    if (node.name === nodeName) {
                        nodeName = origName + index
                        repeat = true
                    }
                }
                if (repeat) {
                    index++
                    continue
                }
                break
            }
            var node = {
                id: nodeId,
                name: nodeName,
                type: nodeMenu.type,
                left: left + 'px',
                top: top + 'px',
                ico: nodeMenu.ico,
                state: 'success'
            }
            /**
             * è¿™é‡Œå¯ä»¥è¿›è¡Œä¸šåŠ¡åˆ¤æ–­ã€æ˜¯å¦èƒ½å¤Ÿæ·»åŠ è¯¥èŠ‚ç‚¹
             */
            this.data.nodeList.push(node)
            this.$nextTick(function () {
                this.jsPlumb.makeSource(nodeId, this.jsplumbSourceOptions)
                this.jsPlumb.makeTarget(nodeId, this.jsplumbTargetOptions)
                this.jsPlumb.draggable(nodeId, {
                    containment: 'parent',
                    stop: function (el) {
                        // æ‹–拽节点结束后的对调
                        console.log('拖拽结束: ', el)
                    }
                })
            })
        },
        /**
         * åˆ é™¤èŠ‚ç‚¹
         * @param nodeId è¢«åˆ é™¤èŠ‚ç‚¹çš„ID
         */
        deleteNode(nodeId) {
            this.$confirm('确定要删除节点' + nodeId + '?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning',
                closeOnClickModal: false
            }).then(() => {
                /**
                 * è¿™é‡Œéœ€è¦è¿›è¡Œä¸šåŠ¡åˆ¤æ–­ï¼Œæ˜¯å¦å¯ä»¥åˆ é™¤
                 */
                this.data.nodeList = this.data.nodeList.filter(function (node) {
                    if (node.id === nodeId) {
                        // ä¼ªåˆ é™¤ï¼Œå°†èŠ‚ç‚¹éšè—ï¼Œå¦åˆ™ä¼šå¯¼è‡´ä½ç½®é”™ä½
                        // node.show = false
                        return false
                    }
                    return true
                })
                this.$nextTick(function () {
                    this.jsPlumb.removeAllEndpoints(nodeId);
                })
            }).catch(() => {
            })
            return true
        },
        clickNode(nodeId) {
            this.activeElement.type = 'node'
            this.activeElement.nodeId = nodeId
            this.$refs.nodeForm.nodeInit(this.data, nodeId, this.formFields.WorkTable)
        },
        // æ˜¯å¦å…·æœ‰è¯¥çº¿
        hasLine(from, to) {
            for (var i = 0; i < this.data.lineList.length; i++) {
                var line = this.data.lineList[i]
                if (line.from === from && line.to === to) {
                    return true
                }
            }
            return false
        },
        // æ˜¯å¦å«æœ‰ç›¸åçš„线
        hashOppositeLine(from, to) {
            return this.hasLine(to, from)
        },
        nodeRightMenu(nodeId, evt) {
            this.menu.show = true
            this.menu.curNodeId = nodeId
            this.menu.left = evt.x + 'px'
            this.menu.top = evt.y + 'px'
        },
        repaintEverything(node) {
            let _node = this.data.nodeList.find((x) => {
                return x.id == node.id;
            });
            Object.assign(_node, node);
            console.log(_node);
            this.jsPlumb.repaint();
        },
        // åŠ è½½æµç¨‹å›¾
        dataReload(data, isAdd) {
            this.easyFlowVisible = false
            this.data.nodeList = []
            this.data.lineList = []
            this.$nextTick(() => {
                data = lodash.cloneDeep(data)
                this.easyFlowVisible = true
                this.data = data
                this.$nextTick(() => {
                    this.jsPlumb = jsPlumb.getInstance()
                    this.$nextTick(() => {
                        this.jsPlumbInit()
                    })
                })
            })
            this.formRules.forEach(options => {
                options.forEach(option => {
                    if (option.field == "WorkTable") {
                        option.readonly = !isAdd;
                    }
                })
            })
        },
        zoomAdd() {
            if (this.zoom >= 1) {
                return
            }
            this.zoom = this.zoom + 0.1
            this.$refs.efContainer.style.zoom = this.zoom;
            // this.jsPlumb.setZoom(this.zoom)
        },
        zoomSub() {
            if (this.zoom <= 0) {
                return
            }
            this.zoom = this.zoom - 0.1;
            if (this.zoom < 0.3) {
                this.zoom = 0.3;
            }
            this.$refs.efContainer.style.zoom = this.zoom;
            // this.jsPlumb.setZoom(this.zoom)
        }
    }
}
</script>
<style scoped lang="less">
@import './index.css';
.flow-panel {
    position: absolute;
    height: 100%;
    width: 100%;
}
.flow-panel ::v-deep(.el-form-item__label) {
    margin-bottom: -2px !important;
    text-align: left;
    padding: 0 !important;
    justify-content: flex-start;
}
.flow-panel ::v-deep(.el-form-item) {
    display: flex;
    flex-direction: column;
    margin-bottom: 7px !important;
}
.ef-node-menu-form {
    padding: 0px;
}
::-webkit-scrollbar {
    width: 0px;
    height: 0px;
}
::-webkit-scrollbar-thumb {
    border-radius: 0px;
    background: #e0e3e7;
    height: 20px;
}
::-webkit-scrollbar-track {
    background-color: transparent;
}
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/components/workflow/utils.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
// æ˜¯å¦å…·æœ‰è¯¥çº¿
export function hasLine(data, from, to) {
    for (let i = 0; i < data.lineList.length; i++) {
        let line = data.lineList[i]
        if (line.from === from && line.to === to) {
            return true
        }
    }
    return false
}
// æ˜¯å¦å«æœ‰ç›¸åçš„线
export function hashOppositeLine(data, from, to) {
    return hasLine(data, to, from)
}
// èŽ·å–è¿žçº¿
export function getConnector(jsp, from, to) {
    let connection = jsp.getConnections({
        source: from,
        target: to
    })[0]
    return connection
}
// èŽ·å–å”¯ä¸€æ ‡è¯†
export function uuid() {
    return Math.random().toString(36).substr(3, 10)
}
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_Expert.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,182 @@
import gridHeader from './App_Expert/App_ExpertGridHeader'
//自定义选择数据源页面
import App_ExpertModelBody from './App_Expert/App_ExpertModelBody'
import { h, resolveComponent } from 'vue';
//声明vue对象
let $this;
let extension = {
  components: {
    gridHeader: gridHeader,
    gridBody: {
      render() {
        return h(resolveComponent('ElAlert'), {
          style: { 'margin-bottom': '12px' },
          'show-icon': true,
          closable: false,
        }, [h('p', {}, '1、多个弹出框:手动创建一个页面,接着在表对应的js文件中引入页面放到gridHeader中'),
        h('p', {}, ' 2、在手动创建的页面中,可以写任意代码,在js中通过this.$refs.gridHeader.xx即可访问页面的内容,具体见:App_Expert.js、App_ExpertGridHeader.vue')]);
      }
    },
    gridFooter: '',
    modelHeader: '',
    modelBody: App_ExpertModelBody,  //将选择数据源页面App_ExpertModelBody注册到弹出框中
    modelFooter: ''
  }, //动态扩充组件或组件路径
  buttons: {
    view: [{
      name: "弹出框1",
      icon: 'md-add',
      index: 1,//添加到第一个按钮后面
      type: 'primary',
      onClick: function () {
        $this.$refs.gridHeader.open1()
      }
    }]
  },
  methods: { //事件扩展
    click1(){
      this.$message.success('点击了提示')
    },
    onInited() {
      $this = this;
      //手动调度弹出框的高度
      this.boxOptions.height = this.boxOptions.height + 90;
      //手动设置表高度自动适应
      this.height = this.height - 100;
    },
    onInit() {
      this.editFormOptions.forEach(x => {
        x.forEach(item => {
          if (item.field == 'HeadImageUrl') {
            //选择文件时
            item.onChange=(files)=>{
               console.log('选择文件事件')
               //此处不返回true,会中断代码执行
               return true;
            }
            //上传前
            item.uploadBefore=(files)=>{
              console.log('上传前')
              return true;
            }
             //上传后
             item.uploadAfter=(files)=>{
              console.log('上传后')
              return true;
            }
          }
        })
      })
      //选择数据源功能
      this.editFormOptions.forEach(x => {
        x.forEach(item => {
          if (item.field == 'ReallyName') {
            //给编辑表单设置[选择数据]操作,extra具体配置见volform组件api
            item.extra = {
              icon: "el-icon-zoom-out",
              text: "选择数据",
              style: "color:#2196F3;font-size: 12px;cursor: pointer;",
              click: item => {
                this.$refs.modelBody.openDemo();
              }
            }
          }
        })
      })
      //设置保存后继续添加 ï¼Œä¸å…³é—­å½“前窗口
      //2021.04.11需要更新methods.js,ViewGrid.vue
      this.continueAdd = true;
      this.continueAddName = "连续添加";
      //将编辑表单第一行第一列【名称】字段添加一个额外提示属性
      this.editFormOptions[0][0].extra =
      {
        render: (h) => {
          return <el-popover
            placement="top-start"
            title="Title"
            width="200"
            trigger="hover"
            content="this is content, this is content, this is content"
          >
            {/* è¿™é‡Œå¯¹åº”下面的#reference数据槽 */}
            {{ reference: ()=>{return <i onClick={()=>{this.click1()}} class='el-icon-warning-outline'></i>} }}
          </el-popover>
        }
      }
      //设置界面上最多可显示的按钮数量
      this.maxBtnLength = 6;
      // ç¬¬2个弹出框操作
      this.buttons.splice(2, 0, ...[{
        name: "弹出框2",
        icon: 'md-add',
        type: 'success',
        onClick: function () {
          $this.$refs.gridHeader.open2()
        }
      },
      {
        name: "获取子组件对象",
        icon: 'md-add',
        type: 'warning',
        onClick: function () {
          this.$Message.info(this.$refs.gridHeader.getTestData())
        }
      }])
      // ç¬¬3个弹出框操作
      this.columns.forEach(x => {
        if (x.field == "Resume") {
          x.formatter = (row, column, event) => {
            return '<a style="color:#2a92ff;cursor: pointer;">(弹出框3)' + row.Resume + '</a>'
          };
          //绑定点击事件
          x.click = (row, column, event) => {
            $this.$refs.gridHeader.open3(row)
          };
        }
      })
      //启用多图上传,其他上传参数,参照volupload组件api
      this.editFormOptions.forEach(x => {
        x.forEach(item => {
          if (item.field == 'HeadImageUrl') {
            //item.type = 'file';
            //设置成100%宽度
            item.colSize = 12;
            item.multiple = true;
            //最多可以上传3张照片
            item.maxFile = 3;
            //限制图片大小,默认3M
            item.maxSize = 3;
            // item.append = true;
          }
        })
      })
      // //动态添加一行表单配置
      // this.editFormOptions[2].splice(0, 1, ...[
      //   {
      //     colSize: 12,
      //     render: (h) => {
      //       return <el-alert title="这里是自定的提示信息" style={{ padding:0 }} type="success" >
      //       </el-alert>
      //     }
      //   }
      // ])
    },
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_Expert/App_ExpertGridHeader.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,106 @@
<template>
  <div>
    <vol-box :lazy="true"
             v-model="model.box1"
             title="弹出框1"
             :height="400"
             :width="700"
             :padding="15">
      <div>弹出框1
        <el-button type="primary"
        size="mini"
                @click="getParent">获取父组件对象</el-button>
        <p>通过 this.$emit("parentCall", $vue => {})可以访问父组件ViewGird中的任何属性、对象、方法</p>
        <p>{{model.box1Text}}</p>
      </div>
    </vol-box>
    <!-- å¼¹å‡ºæ¡†2 -->
    <vol-box :lazy="true"
             v-model="model.box2"
             title="弹出框2"
             :height="420"
             :width="900"
             :padding="10">
      <div>
        <el-tabs type="border-card"
                 style="height: 358px;">
          <el-tab-pane>
            <template #label>  <span ><i class="el-icon-date"></i> æˆ‘的行程</span></template>
            æˆ‘的行程
          </el-tab-pane>
          <el-tab-pane :lazy="true"
                       label="消息中心">消息中心</el-tab-pane>
          <el-tab-pane :lazy="true"
                       label="角色管理">角色管理</el-tab-pane>
          <el-tab-pane :lazy="true"
                       label="定时任务补偿">定时任务补偿</el-tab-pane>
        </el-tabs>
      </div>
    </vol-box>
    <!-- å¼¹å‡ºæ¡†3 -->
    <vol-box :lazy="true"
             v-model="model.box3"
             title="弹出框3"
             :height="400"
             :width="700"
             :padding="15">
  <div>当前操作的行数据{{JSON.stringify(model.box3Row)}}</div>
        <template #footer>
      <div >
        <el-button type="primary"
        size="mini"
                @click="$Message.error('点击确认')">确认</el-button>
        <el-button type="default"
           size="mini"
                @click="model.box3=false">点击关闭弹出框</el-button>
      </div></template>
    </vol-box>
  </div>
</template>
<script>
import VolBox from "@/components/basic/VolBox.vue";
export default {
  components: { "vol-box": VolBox },
  methods: {},
  data() {
    return {
      model: {
        box1Text: "",
        box1: false,
        box1Text: "",
        box2: false,
        box3: false,
        box3Row: {},
      },
    };
  },
  methods: {
    getParent() {
      this.$emit("parentCall", ($vue) => {
        this.model.box1Text = JSON.stringify($vue.buttons);
      });
    },
    getTestData() {
      return "这里是获取到的子组件对象" + JSON.stringify(this.model);
    },
    //弹出框1
    open1() {
      this.model.box1 = true;
    },
    //弹出框2
    open2() {
      this.model.box2 = true;
    },
    //弹出框3
    open3(row) {
      this.model.box3Row = row;
      this.model.box3 = true;
    },
  },
};
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_Expert/App_ExpertModelBody.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
<template>
  <VolBox v-model="model" :lazy="true" title="选择数据" :height="450" :width="800" :padding="15">
    <!-- è®¾ç½®æŸ¥è¯¢æ¡ä»¶ -->
    <div style="padding-bottom: 10px">
      <span style="margin-right: 20px">请选择数据</span>
      <el-input placeholder="名称" style="width: 200px" v-model="expertName" />
      <el-button type="primary" style="margin-left:10px" size="small" icon="Search" @click="search">搜索</el-button>
    </div>
    <!-- vol-table配置的这些属性见VolTable组件api文件 -->
    <vol-table ref="mytable" :loadKey="true" :columns="columns" :pagination="pagination" :pagination-hide="false"
      :max-height="380" :url="url" :index="true" :single="true" :defaultLoadPage="defaultLoadPage"
      @loadBefore="loadTableBefore" @loadAfter="loadTableAfter"></vol-table>
    <!-- è®¾ç½®å¼¹å‡ºæ¡†çš„æ“ä½œæŒ‰é’® -->
    <template #footer>
      <div>
        <el-button size="small" type="primary" icon="el-icon-plus" @click="addRow()">添加选择的数据</el-button>
        <el-button size="mini" icon="Close" @click="model = false">关闭</el-button>
      </div>
    </template>
  </VolBox>
</template>
<script>
import VolBox from "@/components/basic/VolBox.vue";
import VolTable from "@/components/basic/VolTable.vue";
export default {
  components: {
    VolBox: VolBox,
    VolTable: VolTable,
  },
  data() {
    return {
      model: false,
      defaultLoadPage: false, //第一次打开时不加载table数据,openDemo手动调用查询table数据
      expertName: "", //查询条件字段
      url: "api/App_Expert/getSelectorDemo",//加载数据的接口
      columns: [
        { field: "expertId", title: "主键id", width: 90, hidden: true },
        { field: "expertName", title: "名称", width: 120 },
        { field: "headImageUrl", type: "img", title: "头像", width: 120 },
        { field: "resume", title: "简介", width: 90 },
        {
          field: "enable",
          title: "是否启用",
          bind: { key: "enable", data: [] },
          width: 110,
        },
      ],
      pagination: {}, //分页配置,见voltable组件api
    };
  },
  methods: {
    openDemo(row) {
      this.model = true;
      //打开弹出框时,加载table数据
      this.$refs.mytable && this.$refs.mytable.load();
    },
    search() {
      //点击搜索
      this.$refs.mytable.load();
    },
    addRow() {
      var rows = this.$refs.mytable.getSelected();
      if (!rows || rows.length == 0) {
        return this.$message.error("请选择行数据");
      }
      //回写数据到表单
      this.$emit("parentCall", ($parent) => {
        //将选择的数据合并到表单中(注意框架生成的代码都是大写,后台自己写的接口是小写的)
        $parent.editFormFields.ExpertId = rows[0].expertId;
        $parent.editFormFields.ExpertName = rows[0].expertName;
        $parent.editFormFields.HeadImageUrl = rows[0].headImageUrl;
        $parent.editFormFields.Resume = rows[0].resume;
        $parent.editFormFields.Enable = rows[0].enable + ""; //enable是数字类型,框架绑定下拉框的时候要转换成字符串
      });
      //关闭当前窗口
      this.model = false;
    },
    //这里是从api查询后返回数据的方法
    loadTableAfter(row) { },
    loadTableBefore(params) {
      //查询前,设置查询条件
      if (this.expertName) {
        params.wheres = [{ name: "expertName", value: this.expertName }];
      }
      return true;
    },
  },
};
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_Expert2.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,148 @@
import { h, resolveComponent } from 'vue';
let extension = {
  components: {
    gridHeader: ``,
    gridBody: {
      render() {
        return [
          h(resolveComponent('el-alert'), {
            style: { 'margin-bottom': '12px' },
            'show-icon': true, type: 'warning',
            closable: false, title: '复杂table内容,适用于table列较多的情况可以将列合并在一起显示(代码生成后,在对应js文件中设置合并显示信息),只需几行代码即可实现,见:App_Expert2.js'
          }, ''),
        ]
      }
    },
    gridFooter: '',
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  }, //动态扩充组件或组件路径
  buttons: {
    view: []
  },
  methods: { //事件扩展
    onInit() {
      this.buttons.push({
        name: '查看代码',
        onClick: () => {
          window.open('http://api.volcore.xyz/vol.doc/appexpert2.html', 'blank');
        }
      });
      //设置单单元格合并
      this.initFirstColumn();
      //动态添加【状态】列
      this.initColor();
      //在表最后添加操作列
      this.initColumnButton();
    },
    onInited() {
      //手动调整界面表高度
      this.height = this.height - 50;
      this.boxOptions.height = this.boxOptions.height + 40;
    },
    initColor() {
      var _index = this.columns.findIndex(x => { return x.field == "Enable" });
      if (_index == -1) {
        return;
      }
      //动态添加一列【状态】
      this.columns.splice(_index, 1, {
        title: "状态",
        field: "状态",
        with: 60,
        formatter: (row) => {
          var _color = row.Enable == 1 ? '#ff1212' : '#04c966';
          return "<span style='background:" + _color + ";width: 8px;  height: 8px; position: absolute; border-radius: 50%; margin-left: 7px;'>&nbsp;</span>"
        }
      })
    },
    initFirstColumn() {
      //在第一行后面动态添加一行
      this.columns.splice(1, 0, {
        title: "用户信息",
        field: "用户信息",
        width: 220,
        render: (h, { row, column, index }) => {
          //下面所有需要显示的信息都从row里面取出来
          return h(
            "div",
            {
              style: { display: "flex", cursor: 'pointer', },
            },
            [
              h(
                "img",
                {
                  src: this.http.ipAddress + row.HeadImageUrl,
                  style: { "width": "70px", height: "90px", "object-fit": "cover" },
                },
              ),
              h(
                "div",
                {
                  props: {},
                  style: { "margin-left": "15px" },
                },
                [
                  h("div", { style: { "font-size": "12px", "color": "#459fff", "margin-bottom": "8px", "font-weight": "bold" } },
                    [h("span", {}, row.ReallyName),
                    h("span", { style: { "margin-left": "20px" } }, row.Enable == "1" ? '在线' : "离线")]
                  ),
                  h("div", { style: { "font-size": "12px", "color": "#459fff", 'line-height': '20px' } }, row.IDNumber || '无身份证信息'),
                  h("div", { style: { "font-size": "12px", "color": "#459fff", 'line-height': '20px' } }, "电话:" + row.PhoneNo),
                  h("div", { style: { "font-size": "12px", "color": "#459fff", 'line-height': '20px' } }, "城市:" + row.City),
                ]
              )])
        }
      })
    },
    initColumnButton() {
      //在表最后添加操作列
      this.columns.push({
        title: '操作',
        fixed: 'right',
        align: "center",
        width: 130,
        render: (h, { row, column, index }) => {
          return h(
            "div", { style: { cursor: 'pointer' } }, [
            h(
              resolveComponent("el-button"), {
              style: { padding: '0 7px' },
              type: "danger",
              plain: true,
              size: 'mini',
              onClick: (e) => {
                e.stopPropagation()
                this.del([row]);
              },
            },
              [h('i', { class: 'el-icon-delete' }, '删除')]
            ),
            h(
              resolveComponent("el-button"), {
              style: { padding: '0 7px' },
              type: "primary",
              plain: true,
              size: 'mini',
              onClick: (e) => {
                e.stopPropagation()
                this.linkData(row);
              },
            },
              [h('i', { class: 'el-icon-edit' }, '修改')]
            ),
          ])
        }
      })
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_News.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,144 @@
import gridHeader from './App_News/App_NewGirdHeader'
import { h, resolveComponent } from 'vue';
let extension = {
    components: {//动态扩充组件或组件路径
        gridHeader: gridHeader,
        gridBody: {
            render() {
                return [
                    h(resolveComponent('el-alert'), {
                        style: { 'margin-bottom': '12px' },
                        'show-icon': true, type: 'warning',
                        closable: false, title: '发布静态页面、页面预览见:App_News.js'
                    }, ''),
                ]
            }
        },
        gridFooter: '',
        modelHeader: '',
        modelFooter: ''
    },
    text: "静态文件没有提交到github,本地重新生成下静态页面与设置封面即可预览",
    buttons: {
        view: [//ViewGrid查询界面扩展的按钮
        ]
    },
    methods: {
        initButton() {
            //当前用户是否有编辑或新建权限
            if (this.currentReadonly) { return; }
            this.buttons.splice(2, 0, {
                name: "设置封面", icon: 'el-icon-picture', value: 'Edit', type: 'primary',
                onClick: function () { this.setCover(); }
            })
            //添加弹出框生成静态页面的按钮
            this.boxButtons.splice(0, 0, ...[{
                name: "生成静态页面", icon: 'el-icon-tickets', type: 'primary',
                onClick: function () { this.publish(); }
            },
            {
                name: "预览页面", icon: 'el-icon-view', type: 'primary',
                onClick: function () {
                    if (!this.currentRow
                        || !this.currentRow.Content
                        || !this.currentRow.DetailUrl) {
                        return this.$Message.error("请先【保存】,再点击【生成静态页面】")
                    }
                    this.preview(this.currentRow);
                }
            }])
        },
        onInit() { //初始化预览与弹出框大小
            //设置表格内容超出换行
            this.textInline=false;
            //根据用户权限初始化按钮
            this.initButton();
            //设置保存成功后,不关闭弹出框
            this.boxOptions.saveClose = false;
            //设置查询表格只能单选
            this.single = true;
            //设置table表格DetailUrl字段点击预览静态页面
            this.editFormOptions.forEach(x => {
                x.forEach(item => {
                    this.columns.forEach(item => {
                        //设置url点击事件
                        if (item.field == 'DetailUrl') {
                            item.title = "页面预览";
                            item.formatter = (row) => { return '<a>预览</a>' }
                            item.click = (row, column, event) => {
                                this.preview(row);
                            }
                        }
                    })
                })
            })
        },
        onInited(){
            this.height = this.height - 50;
        },
        addBefore(formData) {//新建前验证
            return this.validContent(formData);
        },
        updateBefore(formData) { //修改前验证
            return this.validContent(formData);
        },
        validContent(formData) {
            if (!this.editFormFields.Content) {
                this.$Message.error("请编辑要发布的内容");
                return false;
            }
            return true;
        },
        preview(row) { //预览html页面
            if (!row.DetailUrl || row.DetailUrl.indexOf('.html') == -1 || !this.base.isUrl(this.http.ipAddress + row.DetailUrl)) {
                return this.$Message.error("请先发布静态页面")
            }
            window.open(this.http.ipAddress + row.DetailUrl + '?r=' + Math.random());
        },
        publish() { //生成静态页面
            if (!this.currentRow || !this.currentRow[this.table.key]) {
                return this.$Message.error("请先保存数据")
            }
            if (!this.currentRow.Content) {
                return this.$Message.error("请编辑要发布的内容")
            }
            this.http.post("api/news/createPage", this.currentRow).then(x => {
                if (x.status) {
                    // this.editFormFields.DetailUrl = x.data.url;
                    this.currentRow.DetailUrl = x.data.url;
                }
                this.refresh();
                return this.$Message.info(x.message)
            })
        },
        setCover() {  //设置封面图片
            let rows = this.getSelectRows();
            if (rows.length == 0) {
                return this.$Message.error("请选中要设置封面的行")
            }
            //设置封面图片,先获取当前已经图片fileInfo格式见volupdate组件参数说明
            let fileInfo = this.getFilePath(rows[0].ImageUrl) || [];
            this.$refs.gridHeader.open(fileInfo)
        },
        getFilePath(pathSring) {//拆分url并初始化图片到上传组件中
            //获取表的图片与文件显示
            if (!pathSring) return "";
            let fileInfo = [], filePath = pathSring.replace(/\\/g, "/").split(",");
            for (let index = 0; index < filePath.length; index++) {
                let file = filePath[index];
                if (file.indexOf(".") == -1) { continue; }
                let splitFile = file.split("/");
                if (splitFile.length == 0) { continue; }
                fileInfo.push({
                    name: splitFile[splitFile.length - 1],
                    path: this.base.isUrl(file) ? file : this.http.ipAddress + file
                });
            }
            return fileInfo;
        }
    }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_News/App_NewGirdHeader.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
<template>
  <VolBox
    v-model="model"
    title="封面图片设置"
    :height="230"
    :width="520"
    :lazy="true"
    :padding="15"
  >
    <VolUpload
        style="text-align: center; border: 1px dotted #FF9800;padding: 20px;"
        :autoUpload="false"
        :multiple="true"
        :url="url"
        :max-file="3"
        :img="true"
        :fileInfo="fileInfo"
        :upload-after="uploadAfter"
      >
        <div>可选择1-3张图片设置为封面图</div>
      </VolUpload>
  </VolBox>
</template>
<script>
import VolBox from "@/components/basic/VolBox.vue";
import {defineComponent,defineAsyncComponent,ref} from "vue"
export default defineComponent({
  data() {
    return {
      url: "api/app_news/upload",
      fileInfo: [],
      model: false,
    };
  },
  components: {
    VolBox: VolBox,
    VolUpload:defineAsyncComponent( () => import("@/components/basic/VolUpload.vue"))
  },
  methods: {
    open(fileInfo) {
      this.model = true;
      this.fileInfo = fileInfo;
    },
    //封面图片上传完成后,将图片的路径更新到表中
    uploadAfter(result, files) {
      if (!result.status) {
        return true;
      }
      //上传完成后,保存每个图片所存储的文件路径
      let fileUrls = files.map((x) => {
           //2021.09.25修复示例上传路径逻辑错误的问题
        if (x.path) {
          return x.path;
        }
        return result.data + x.name;
      });
      let data = { imageUrl: fileUrls.join(",") };
      //父组件vue对象(查询界面)
      let $parentVue;
      //获取父组件当前选中行的id用于后台更新
      this.$emit("parentCall", ($vue) => {
        $parentVue = $vue;
        data.Id = $vue.getSelectRows()[0].Id;
      });
      this.http
        .post("api/news/setCover", data, "正在设置图片封面")
        .then((x) => {
          //刷新查询界面table
          $parentVue.refresh();
          this.model = false;
        });
      return true;
    },
  }
});
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_NewsEditor.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
import { h, resolveComponent } from 'vue';
let extension = {
  components: {//动态扩充组件或组件路径
    gridHeader: '',
    gridBody: {
      render() {
        return [
          h(resolveComponent('el-alert'), {
            style: { 'margin-bottom': '12px' },
            'show-icon': true, type: 'warning',
            closable: false, title: '设置属性后textInline,表格超出换行onInit(){ this.textInline = false};代码生成器编辑类型选择editor即可默认生成编辑器:App_NewsEditor.js或App_News.js'
          }, ''),
        ]
      }
    },
    gridFooter: '',
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  }, //动态扩充组件或组件路径
  buttons: {
    view: []
  },
  tableAction: "App_News",
  methods: { //事件扩展
    onInit() {
      //设置表的最大高度
      // this.tableMaxHeight = 400;
      //table内容超出后自动换行
      this.textInline = false;
      //添加预览操作
      this.columns.forEach(item => {
        //设置url点击事件
        if (item.field == 'DetailUrl') {
          item.title = "页面预览";
          item.formatter = (row) => { return '<a>预览</a>' }
          item.click = (row, column, event) => {
            if (!row.DetailUrl || row.DetailUrl.indexOf('.html') == -1 || !this.base.isUrl(this.http.ipAddress + row.DetailUrl)) {
              return this.$Message.error("请先发布静态页面")
            }
            window.open(this.http.ipAddress + row.DetailUrl);
          }
        }
      })
    },
    onInited(){
      this.tableMaxHeight=this.height-50;
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_ReportPrice.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
import { h, resolveComponent, defineAsyncComponent } from 'vue';
import modelBody from "./App_ReportPrice/App_ReportPriceModelBody.vue"
let extension = {
  components: {//动态扩充组件或组件路径
    gridHeader: "",
    gridBody: {
      render() {
        return h(resolveComponent('ElAlert'), {
          style: { 'margin-bottom': '12px' },
          'show-icon': true,
          closable: false,
        }, [h('p', {}, '1、此界面与上面的区别是:多个明细表在弹出框进行的扩展,见App_ReportPrice.js(点击新建或编辑即可查看效果)'),
        h('p', {}, ' 2、手动创建一个页面(可以写任意代码),引入到App_ReportPrice.js的modelBody位置')]);
      }
    },
    gridFooter: '',
    modelHeader: '',
    //通过defineAsyncComponent异步引用
    modelBody: modelBody,
    // defineAsyncComponent(() => (import("./App_ReportPrice/App_ReportPriceModelBody.vue"))),
    modelFooter: ''
  },
  buttons: [],//扩展的按钮
  text: "弹出框一对多明细",
  methods: {//事件扩展
    onInit() {
    },
    onInited() {
      //初始化后将table高度减少85,因为gridHeader加了提示会导致页面有滚动条
      this.height = this.height - 100;
      //自定义弹出框的高与宽
      this.boxOptions.height = document.body.clientHeight * 0.9;
      this.boxOptions.width = document.body.clientWidth * 0.8;
    },
    modelOpenAfter() {//打开弹出框时
      //是否子组件渲染完成
      //新建功时,清空 æ¸…空,从表1,从表2的数据
      this.$nextTick(() => {
        //这里没有给弹出框中的表格传参,如果需要参数可以通过 this.$emit("parentCall", èŽ·å–é¡µé¢çš„å‚æ•°
        //具体见自定义页面App_ReportPriceModelBody.vue中的modelOpen方法的使用 this.$emit("parentCall", ($this) => {
        this.$refs.modelBody.modelOpen();
      })
    },
    addBefore(formData) { //弹出框新建或编辑功能点保存时可以将从表1,从表2的数据提到后台
      this.setFormData(formData);
      return true;
    },
    updateBefore(formData) { //编辑时功能点保存时可以将从表1,从表2的数据提到后台
      this.setFormData(formData);
      return true;
    },
    setFormData(formData) { //新建或编辑时,将从表1、2的数据提交到后台,见后台App_ReportPriceService的新建方法
      //后台从对象里直接取extra的值
      let extra = {
        table1List: this.$refs.modelBody.$refs.table1.rowData,//获取从表1的行数据
        table2List: this.$refs.modelBody.$refs.table2.rowData//获取从表2的行数据
      }
      formData.extra = JSON.stringify(extra);
    },
    resetUpdateFormAfter() { //编辑弹出框时,点重置时,可自定义重置
      console.log('resetUpdateFormAfter')
      return true;
    },
    resetAddFormAfter() { //新建弹出框时,点重置时,可自定义重置
      console.log('resetAddFormAfter')
      return true;
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_ReportPrice/App_ReportPriceModelBody.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,278 @@
<template>
  <div class="vol-tabs" style="height:390px ;">
    <el-tabs
      type="border-card"
      style="
        min-height: 370px;
        box-shadow: none;
        border-bottom: 0;
        border-top: 1px solid #eee;
      "
    >
      <el-tab-pane>
        <template #label>
          <span><i class="el-icon-date"></i> ä»Žè¡¨1</span>
        </template>
        <!-- æ˜¾ç¤ºæ“ä½œæŒ‰é’® -->
        <div>
          <el-button
            type="primary"
            icon="Close"
            link
            @click="del"
            >删除行</el-button
          >
          <el-button
            type="success"
            icon="Plus"
            link
            @click="add"
            >添加行</el-button
          >
          <el-button
            type="warning"
            icon="Check"
            link
            @click="getRows"
            >获取选中的行</el-button
          >
          <el-button
            type="info"
            icon="Refresh"
            link
            @click="$refs.table1.load()"
            >刷新</el-button
          >
        </div>
        <el-alert
          title="双击行可以编辑,或者可以根据菜单: table使用->table编辑(二)在行上配置操作,完整文档见:组件api->voltable"
          type="warning"
          style="margin: 10px 0"
          show-icon
        >
        </el-alert>
        <!-- :defaultLoadPage="false"打开窗口禁用默认加载数据 -->
        <vol-table
          ref="table1"
          :clickEdit="true"
          :loadKey="true"
          :columns="tableColumns1"
          :pagination-hide="false"
          :height="205"
          :url="table1Url"
          :index="true"
          :defaultLoadPage="false"
          @loadBefore="loadTableBefore1"
          @loadAfter="loadTableAfter1"
        ></vol-table>
      </el-tab-pane>
      <!-- ä»Žè¡¨2 -->
      <el-tab-pane :lazy="false" label="从表2">
        <template #label>
          <span><i class="el-icon-date"></i> ä»Žè¡¨2</span>
        </template>
        <!-- ä»Žè¡¨2配置 ,双击可以开启编辑-->
        <div style="padding-bottom: 10px">
          <el-button
            type="primary"
             link
            icon="Plus"
            @click="$refs.table2.addRow({})"
            >添加行</el-button
          >
          <el-button
            icon="Close"
            link
            type="success"
            ghost
            @click="$refs.table2.load()"
            >刷新</el-button
          >
        </div>
        <vol-table
          ref="table2"
          :loadKey="true"
          :clickEdit="true"
          :columns="tableColumns2"
          :pagination-hide="false"
          :height="275"
          :url="table2Ur"
          :defaultLoadPage="false"
          @loadBefore="loadTableBefore2"
          :index="true"
        ></vol-table>
      </el-tab-pane>
      <el-tab-pane :lazy="false" label="从表3">从表3</el-tab-pane>
    </el-tabs>
  </div>
</template>
<script>
//开发一对多从表需要参照voltable与viewgrid组件api
import VolTable from "@/components/basic/VolTable.vue";
export default {
  components: { VolTable },
  data() {
    return {
      //从表1
      table1Url: "api/App_ReportPrice/getTable1Data", //table1获取数据的接口
      //表配置的字段注意要与后台返回的查询字段大小写一致
      tableColumns1: [
        { field: "id", title: "主键ID", type: "int", width: 80, hidden: true },
        {
          field: "title",
          title: "标题",
          type: "string",
          width: 400,
          require: true,
          sortable: true,
          edit: { type: "text" }, //keep:true始终开启编辑,false双击才能编辑
        },
        { field: "imageUrl", title: "封面图片", type: "file", width: 170 },
        {
          field: "dailyRecommend",
          title: "内容推荐",
          type: "sbyte",
          bind: { key: "dr", data: [] },
          edit: { type: "switch" },
          width: 120,
          require: true,
          onChange: (column, row, tableData, value) => {
            this.$Message.info(value + "");
          },
        },
        {
          field: "enable",
          title: "是否启用",
          type: "int",
          width: 90,
          bind: { key: "enable", data: [] }, //自动绑定数据源
          //配置为select编辑类型,keep=true始终处于编辑状态(如果想要双击编辑,去掉keep属性,具体配置可见voltable组件api)
          edit: { type: "select" },
          onChange: (column, row, tableData) => {
            this.$Message.info(row.enable + "");
          },
        },
        {
          field: "createDate",
          title: "发布时间",
          type: "datetime",
          width: 150,
          readonly: true,
          sortable: true,
          edit: { type: "datetime" },
        },
      ],
      //从表2
      table2Ur: "api/App_ReportPrice/getTable2Data", //table1获取数据的接口
      //表配置的字段注意要与后台返回的查询字段大小写一致
      tableColumns2: [
        { field: "id", title: "主键ID", type: "int", width: 80, hidden: true },
        {
          field: "name",
          title: "姓名",
          edit: { type: "text" },
          type: "text",
          width: 120,
        },
        {
          field: "phoneNo",
          title: "电话",
          type: "text",
          edit: { type: "text" },
          width: 150,
        },
        {
          field: "createDate",
          title: "创建时间",
          type: "text",
          edit: { type: "datetime" },
          width: 150,
        },
        {
          field: "describe",
          title: "描述",
          type: "text",
          edit: { type: "text" },
          width: 500,
        },
      ],
    };
  },
  methods: {
    //如果要获取页面的参数请使用 this.$emit("parentCall",见下面的使用方法
    modelOpen() {
      let $parent;
      //获取生成页面viewgrid的对象
      this.$emit("parentCall", ($this) => {
        $parent = $this;
      });
      //当前如果是新建重置两个表格数据
      if ($parent.currentAction == "Add") {
        this.$refs.table1.reset();
        this.$refs.table2.reset();
      } else {
        //如果是编辑,添加两个表格的数据
        this.$refs.table1.load();
        this.$refs.table2.load();
      }
    },
    loadTableBefore1(param, callBack) {
      let $parent = null;
      //当前是子页面,获取查询viewgrid页面的对象()
      this.$emit("parentCall", ($this) => {
        $parent = $this;
      });
      //如果是新建功能,禁止刷新操作
      if ($parent.currentAction == "Add") {
        return callBack(false);
      }
      //获取当前编辑主键id值
      let id = $parent.currentRow.Id;
      //添加从表的查询参数(条件)
      //将当前选中的行主键传到后台用于查询(后台在GetTable2Data(PageDataOptions loadData)会接收到此参数)
      param.wheres.push({ name: "Id", value: id });
      callBack(true);
    },
    //从表2加载数据数前(操作与上面一样的,增加查询条件)
    loadTableBefore2(param, callBack) {
      callBack(true);
    },
    //从后台加载从表1数据后
    loadTableAfter1(data, callBack) {
      return true;
    },
    del() {
      let rows = this.$refs.table1.getSelected();
      if (rows.length == 0) {
        return this.$Message.error("请先选中行");
      }
      this.$refs.table1.delRow();
      //可以this.http.post调用后台实际执行查询
    },
    clear() {
      this.$refs.table1.reset();
    },
    add() {
    //  this.$refs.table1.addRow({});
    this.$refs.table1.rowData.unshift({title:"测试....."});
    },
    getRows() {
      //获取选中的行
      let rows = this.$refs.table1.getSelected();
      if (rows.length == 0) {
        return this.$Message.error("请先选中行");
      }
      this.$Message.error(JSON.stringify(rows));
    },
  },
};
</script>
<style lang="less" scoped>
.vol-tabs {
  background: white;
}
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_Transaction.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
import { h, resolveComponent } from 'vue';
let extension = {
  components: {
    //动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: '', //{ template: "<div>扩展组xxä»¶</div>" },
    // gridBody: {
    //   template: '<Alert  type="success" show-icon>\
    //     æŸ¥è¯¢é»˜è®¤/显示所有查询条件<template slot="desc"><p>1、 onInit(){ this.setFiexdSearchForm(true);  //设置固定显示所有查询条件}</p>\
    //     2、 è®¾ç½®é»˜è®¤æŸ¥è¯¢å€¼(下拉框、默认日期)、查询界面表高度等,具体见App_Transaction.js配置与说明</template>\
    //    </Alert>' },
    gridBody: {
      render() {
        return h(
          resolveComponent('ElAlert'),
          {
            style: { 'margin-bottom': '12px' },
            'show-icon': true,
            type: 'success',
            closable: false
          },
          [
            h(
              'p',
              {},
              '1、默认界面上显示的列都可以导入,也可以在后台指定导入与导出的列,见后台开发文档->后台基础代码扩展实现导入方法说明'
            ),
            h(
              'p',
              {},
              ' 2、添加switch、checkbox组件,设置默认查询值(下拉框、默认日期)、查询界面表高度等,App_Transaction.js配置与说明'
            )
          ]
        );
      }
    },
    gridFooter: '',
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: 'App_Appointment', //指定菜单权限,其他任何页面引用时都会走对应权限
  text:
    '目前导入导出的字段为代码生成器中配置[是否显示与编辑列],可自行添加配置字段处理',
  buttons: [], //扩展的按钮
  methods: {
    //事件扩展
    //事件扩展
    onInit() {
      this.buttons.push({
        name: '查看代码',
        onClick: () => {
          window.open('http://api.volcore.xyz/vol.doc/apptransaction.html', 'blank');
        }
      });
      //设置查询条件
      // this.searchFormFields.Name = "林";
      //设置下拉框的字段(是否买入)的默认值(注意下拉框key如要是数字同样也要设置为字符类型数字,如果是自定sql数据源的key则需要设置成数字类型)
      //  this.searchFormFields.TransactionType = '1';
      //注意日期设置默认值的时候 ï¼Œå¦‚果查询类型选择的是datetime后面一定要写上,00:00:00
      //如果查询类型是date直接写年月日即可
      this.searchFormFields.CreateDate = [
        '2015-01-01 00:00:00',
        '2030-12-31 00:00:00'
      ];
      //设置页面上显示的按钮个数(不是必须的)
      this.maxBtnLength = 6;
      //设置显示所有查询条件
      this.setFiexdSearchForm(true);
      this.columns.forEach(col=>{
          if (col.field=='Describe') {
            col.hidden=true;
          }
      })
      this.columns.push({
        title: 'switch',
        field: 'switch',
        width: 80,
        fixed: 'right',
        align: 'center',
        render: (h, { row, column, index }) => {
          //这里必须将要操作的字段变更为bool类型
          row.Enable=row.Enable||false;
          return (
            <div>
              <el-switch
                v-model={row.Enable}
                onChange={(val) => {
                  this.switchChange(row);
                }}
              ></el-switch>
            </div>
          );
        }
      });
      this.columns.push({
        title: 'checkbox',
        field: 'checkbox',
        width: 80,
        fixed: 'right',
        align: 'center',
        render: (h, { row, column, index }) => {
          //这里必须将要操作的字段变更为bool类型
          row.Enable=row.Enable||false;
          return (
            <div>
              <el-checkbox
                v-model={row.Enable}
                onChange={(val) => {
                  this.switchChange(row);
                }}
              ></el-checkbox>
            </div>
          );
        }
      });
    },
    switchChange(row) {
      this.$message.success(row.Enable + '');
    },
    onInited() {
      //设置查询界面表高度
      this.height = this.height-215;
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_Transaction2.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
let extension = {
  components: {
    //动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: '', //{ template: "<div>扩展组xxä»¶</div>" },
    gridBody: '',
    gridFooter: '',
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  text: '点击行或者点击表格的编辑即可开启编辑功能',
  tableAction: 'App_Transaction',
  buttons: [], //扩展的按钮
  methods: {
    //事件扩展
    onInit() {
      //手动设置弹出框的高度与宽度
      //判断有没有App_Transaction表修改的权限 ï¼Œæ— æƒé™ä¸å¼€å¯ç¼–辑功能
      if (!this.filterPermission('App_Transaction', 'Update')) {
        return;
      }
      //开启编辑功能
      this.doubleEdit = true;
      //开启指定列可以编辑
      //**注意,开启字段的编辑信息,如果调用框架的保存方法,代码生成器中必须设置了编辑行并生成了model否则验证通不过
      this.columns.forEach((column) => {
        if (column.field == 'Describe' || column.field == 'Name') {
          column.edit = { type: 'text' };
        }
        if (column.field == 'TransactionType') {
          column.edit = { type: 'switch' };
        }
        if (column.field == 'CowType') {
          column.edit = { type: 'select' };
        }
      });
      //动态添加操作列
      this.columns.push({
        field: '操作',
        title: '操作',
        align: 'center',
        width: 120,
        render: this.getRender()
      });
    },
    beginEdit(row, column, index) {
      console.log('编辑行:'+index)
      //点击行编辑  return false阻止编辑(可以根据row不同的值判断当前是否可以编辑);
      return true;
    },
    endEditBefore(row, column, index) {
      //可以自动结束编辑时,自动执行保存,下面getRender的保存按钮去掉
      // this.editSave();
      return true;
    },
    editSave(row) {
      //调用框架的默认保存方法
      this.http
        .post('/api/App_Transaction/update', { mainData: row }, true)
        .then((x) => {
          this.$Message.info('保存成功');
          console.log('保存结果:' + JSON.stringify(x));
        });
    },
    getRender() {
      //生成最后一列操作列
      return (h, { row, column, index }) => {
        return h(
          'div',
          {
            style: { color: '#0c83ff', 'font-size': '13px', cursor: 'pointer' }
          },
          [
            h(
              'a',
              {
                props: {},
                style: { 'border-bottom': '1px solid' },
                onClick: (e) => {
                  e.stopPropagation();
                  //取消其他行选中
                  this.$refs.table.$refs.table.clearSelection();
                  //设置当前后选中
                  this.$refs.table.$refs.table.toggleRowSelection(row);
                  this.del([row]);
                }
              },
              '删除'
            ),
            h(
              'a',
              {
                props: {},
                style: { 'margin-left': '9px', 'border-bottom': '1px solid' },
                onClick: (e) => {
                  e.stopPropagation();
                  //将当前行设置为编辑行
                  this.$refs.table.edit.rowIndex = index;
                }
              },
              '编辑'
            ),
            h(
              'a',
              {
                props: {},
                style: { 'margin-left': '9px', 'border-bottom': '1px solid' },
                onClick: (e) => {
                  e.stopPropagation();
                  //强制结束编辑
                  this.$refs.table.edit.rowIndex = -1;
                  //执行保存方法
                  this.editSave(row);
                }
              },
              '保存'
            )
          ]
        );
      };
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/App_TransactionAvgPrice.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
import { h, resolveComponent } from 'vue';
let extension = {
  components: {
    //动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: '', //{ template: "<div>扩展组xxä»¶</div>" },
    gridBody: {
      render() {
        return [
          h(resolveComponent('el-alert'), {
            style: { 'margin-bottom': '12px' },
            'show-icon': true, type: 'warning',
            closable: false, title: 'onInit中设置this.maxBtnLength = 7;指定按钮显示的个数。见代码:App_TransactionAvgPrice.js'
          }, ''),
        ]
      }
    },
    gridFooter: "",
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: "",
    modelBody: "",
    modelFooter: ""
  },
  text:
    "还没想好",
  buttons: [], //扩展的按钮
  methods: {
    //事件扩展
    onInit() {
      //设置页面上显示的按钮个数(不是必须的)
      this.maxBtnLength = 7;
      //this.boxButtons弹出框的按钮,this.detailOptions.buttons,同样适用上面上方法
      //2021.07.17更新volform.vue组件后才能使用
      this.editFormOptions.forEach(x => {
        x.forEach(option => {
          if (option.field == "Date") {
            option.min = "2021-07-01 00:00";
            option.max = Date.now();//日期最大值"2021-07-20 00:00"
          }
        })
      })
      this.columns.forEach(option => {
        if (option.field == 'AgeRange') {
          option.normal = true;
        }
      })
      //如果要设置查询的日期范围选择同上
      //this.searchFormOptions.forEach
      //设置显示所有查询条件
      // this.setFiexdSearchForm(true);
    },
    onInited() {
      //设置表高度
      this.height = this.height - 50;
    },
    rowClick({ row, column, event }) { //查询界面table点击行时选中当前行
      this.$refs.table.$refs.table.toggleRowSelection(row);
    },
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/news_article.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
let extension = {
    components: {//动态扩充组件或组件路径
        //表单header、content、footer对应位置扩充的组件
        gridHeader:'',//{ template: "<div>扩展组xxä»¶</div>" },
        gridBody: '',
        gridFooter: '',
        //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
        modelHeader: '',
        modelBody: '',
        modelFooter: ''
    },
    buttons: [],//扩展的按钮
    methods: {//事件扩展
    }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/appmanager/vProvinceCity.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
let extension = {
    components: {//动态扩充组件或组件路径
        //表单header、content、footer对应位置扩充的组件
        gridHeader:'',//{ template: "<div>扩展组xxä»¶</div>" },
        gridBody: '',
        gridFooter: '',
        //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
        modelHeader: '',
        modelBody: '',
        modelFooter: ''
    },
    buttons: [],//扩展的按钮
    methods: {//事件扩展
    }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/App_Appointment.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,329 @@
import { h, resolveComponent } from 'vue';
let extension = {
  components: {
    //动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: '',
    gridBody: {
      render(h) {
        return (
          <el-alert
            style={{ 'margin-bottom': '10px' }}
            type="success"
            show-icon
          >
            <p v-html="1、 onInit(){ this.setFiexdSearchForm(true){设置固定显示所有查询条件}">
              {' '}
            </p>
            <p v-html="2、自定义表格按钮、弹出框提示、弹出框分组信息,见示例:App_Appointment.js文件">
              {' '}
            </p>
          </el-alert>
        );
      }
    },
    gridFooter: '',
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  buttons: [], //扩展的按钮
  tableAction: 'App_Appointment', //指定菜单权限,其他任何页面引用时都会走对应权限
  text:
    '代码生成器中设置[是否只读]或如果没有编辑或新建权限弹出框都是只读的(点击用户姓名列可查看表单分组)',
  methods: {
    btn1Click(row, $e) {
      $e.stopPropagation();
      this.edit(row);
    },
    btn2Click(row, $e) {
      $e.stopPropagation();
      this.$message.success('点击了按钮');
    },
    dropdownClick(value, row, column) {
      console.log(row);
      this.$message.success(value);
    },
    //事件扩展
    onInit() {
      this.buttons.push({
        name: '查看代码',
        onClick: () => {
          window.open('http://api.volcore.xyz/vol.doc/appointment.html', 'blank');
        }
      });
      //设置显示所有查询条件
      this.setFiexdSearchForm(true);
      //表格上添加自定义按钮
      this.columns.push({
        title: '操作',
        field: '操作',
        width: 150,
        align: 'center',
        render: (h, { row, column, index }) => {
          return (
            <div>
              <el-button
                onClick={($e) => {
                  this.btn1Click(row, $e);
                }}
                type="primary"
                plain
                size="small"
                style="height:26px; padding: 10px !important;"
              >
                æŸ¥çœ‹
              </el-button>
              <el-button
                onClick={($e) => {
                  this.btn2Click(row, $e);
                }}
                type="success"
                plain
                size="small"
                style="height:26px;padding: 10px !important;"
              >
                æŒ‰é’®
              </el-button>
              <el-dropdown
                onClick={(value) => {
                  this.dropdownClick(value);
                }}
                trigger="click"
                v-slots={{
                  dropdown: () => (
                    <el-dropdown-menu>
                      <el-dropdown-item>
                        <div
                          onClick={() => {
                            this.dropdownClick('京酱肉丝', row, column);
                          }}
                        >
                          äº¬é…±è‚‰ä¸
                        </div>
                      </el-dropdown-item>
                      <el-dropdown-item>
                        <div
                          onClick={() => {
                            this.dropdownClick('驴肉火烧', row, column);
                          }}
                        >
                          é©´è‚‰ç«çƒ§
                        </div>
                      </el-dropdown-item>
                      <el-dropdown-item>
                        <div
                          onClick={() => {
                            this.dropdownClick('吊炉烤鸭', row, column);
                          }}
                        >
                          åŠç‚‰çƒ¤é¸­
                        </div>
                      </el-dropdown-item>
                    </el-dropdown-menu>
                  )
                }}
              >
                <span
                  style="font-size: 13px;color: #409eff;margin: 5px 0 0 10px;"
                  class="el-dropdown-link"
                >
                  æ›´å¤š<i class="el-icon-arrow-right"></i>
                </span>
              </el-dropdown>
            </div>
          );
        }
      });
      //表格显示Tooltip提示
      this.columns.forEach((col) => {
        if (col.field == 'Describe') {
          col.title = '单元格Tooltip(鼠标放上来看效果)';
          col.render = (h, { row, column, index }) => {
            return (
              <el-popover
                placement="top-start"
                title="提示信息"
                width={350}
                trigger="hover"
                content={
                  row.Describe +
                  ',这里是用render渲染的表格提示,示例见:App_Appointment.js'
                }
              >
                {{ reference: <span>{row.Describe}</span> }}
              </el-popover>
            );
          };
        }
      });
      //增加弹出框提示信息
      //https://cn.vuejs.org/guide/extras/render-function.html#passing-slots
      //自定义提示
      this.editFormOptions[0][0].extra = {
        render: (h) => {
          return (
            <el-popover
              placement="top-start"
              title="Title"
              width="200"
              trigger="hover"
              content="this is content, this is content, this is content"
            >
              {/* è¿™é‡Œå¯¹åº”下面的#reference数据槽 */}
              {{ reference: <i class="el-icon-warning-outline"></i> }}
            </el-popover>
          );
        }
      };
      //   <el-popover
      //   placement="top-start"
      //   title="Title"
      //   :width="200"
      //   trigger="hover"
      //   content="this is content, this is content, this is content"
      // >
      //   <template #reference>
      //     <el-button>Hover to activate</el-button>
      //   </template>
      // </el-popover>
      //格式化单格颜色
      this.columns.forEach((x) => {
        if (x.field == 'PhoneNo') {
          x.cellStyle = (row, rowIndex, columnIndex) => {
            if (row.PhoneNo == '138888887698' && rowIndex == 0) {
              return { background: '#ddecfd' };
            }
          };
        }
        if (x.field == 'Creator') {
          x.cellStyle = (row, rowIndex, columnIndex) => {
            if (row.Creator == '超级管理员') {
              return { background: 'rgb(45 140 240)', color: '#ffff' };
            }
          };
        }
        if (x.field == 'Name') {
          x.title = '点击查看表单';
        }
      });
      //设置表单分组
      this.editFormOptions.splice(0, 0, [
        {
          colSize: 12,
          render: (h) => {
            return (
              <div
                style={{
                  display: 'flex',
                  'margin-bottom': '-4px',
                  'line-height': '20px',
                  'margin-top': '5px',
                  'padding-bottom': '5px',
                  'border-bottom': '1px solid rgb(238, 238, 238)'
                }}
              >
                <div style="height: 19px; background: rgb(45, 206, 217); width: 9px; border-radius: 10px;"></div>
                <div style="padding-left: 6px; font-weight: bold; font-size: 13px;">
                  åŸºæœ¬ä¿¡æ¯
                </div>
              </div>
            );
          }
        }
      ]);
      //设置表单分组
      this.editFormOptions.splice(2, 0, [
        {
          colSize: 12,
          render: (h) => {
            return (
              <div
                style={{
                  display: 'flex',
                  'margin-bottom': '-4px',
                  'line-height': '20px',
                  'margin-top': '5px',
                  'padding-bottom': '5px',
                  'border-bottom': '1px solid rgb(238, 238, 238)'
                }}
              >
                <div style="height: 19px; background: rgb(45, 206, 217); width: 9px; border-radius: 10px;"></div>
                <div style="padding-left: 6px; font-weight: bold; font-size: 13px;">
                  åŸºæœ¬ä¿¡æ¯
                </div>
              </div>
            );
          }
        }
      ]);
      //弹出框增加分段alert提示
      this.editFormOptions.splice(3, 0, [
        {
          colSize: 12,
          render: (h) => {
            return (
              <el-alert
                title="这里是自定的提示信息"
                style={{ padding: 0 }}
                type="success"
              ></el-alert>
            );
          }
        }
      ]);
      //查询界面按钮组
      //按钮图标这里找https://element.eleme.cn/#/zh-CN/component/icon
      //第二个按钮后面添加按钮组
      this.buttons.splice(2, 1, {
        name: '按钮组',
        type: 'primary',
        plain: true,
        color: '#009688',
        data: [
          {
            name: '按钮一',
            icon: 'el-icon-plus',
            onClick: () => {
              this.$message.info('按钮一');
            }
          },
          {
            name: '按钮二',
            icon: 'el-icon-zoom-out',
            onClick: () => {
              this.$message.info('按钮二');
            }
          }
        ]
      });
    },
    onInited() {
      //多页签菜单打开时,重新设置表格的最大高度
      if (this.$route.path == '/tabsTable') {
        this.tableMaxHeight = document.body.clientHeight - 415;
      } else {
        //设置表的最大高度
        this.tableMaxHeight = this.height - 125; //400
      }
      //移除快捷查询
      this.singleSearch = null;
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/App_Appointment/App_AppointmentGridFooter.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,205 @@
<template>
  <div class="m-detail">
    <div class="m-title">
      <h2>订单详情</h2>
    </div>
    <div class="m-tabs">
      <Tabs>
        <TabPane label="配置要求" icon="md-apps">
          <div style="margin-bottom:10px;text-align: right;">
            <Button type="info" ghost @click="clear">清空表</Button>
            <Button type="info" ghost @click="del">删除行</Button>
            <Button type="info" ghost @click="add">添加行</Button>
            <Button type="info" ghost @click="getRows">获取选中的行</Button>
          </div>
          <vol-table
            ref="table"
            :linkView="_linkView"
            :columns="columns"
            :height="400"
            :index="true"
            url="/api/App_Appointment/getPageData"
            @loadBefore="loadBefore"
            :defaultLoadPage="false"
            :pagination-hide="false"
          ></vol-table>
        </TabPane>
        <TabPane label="订单明细" icon="md-apps">
          <VolForm ref="myform" :loadKey="loadKey" :formFileds="formFileds" :formRules="formRules"></VolForm>
          <div class="m-btn">
            <Button type="info" @click="()=>{}">保存</Button>
          </div>
        </TabPane>
        <TabPane label="回款计划" icon="md-apps">2</TabPane>
        <TabPane label="回款情况" icon="md-apps">2</TabPane>
      </Tabs>
    </div>
    <br />
    <br />
    <br />
  </div>
</template>
<script>
import VolForm from "@/components/basic/VolForm.vue";
import VolTable from "@/components/basic/VolTable.vue";
import VolBox from "@/components/basic/VolBox.vue";
export default {
  components: {
    VolForm,
    VolTable,
    VolBox
  },
  data() {
    return {
      row: {},
      loadKey: true, //如果有下拉框的表单,这里设置为true,自动绑定下拉框数据
      formFileds: {
        Variety: "",
        AgeRange: "",
        DateRange: [],
        City: "",
        AvgPrice: 8.88,
        Date: ""
      },
      formRules: [
        [
          {
            dataKey: "age", //后台下拉框对应的数据字典编号
            data: [], //loadKey设置为true,会根据dataKey从后台的下拉框数据源中自动加载数据
            title: "月龄",
            filter: true,
            required: true, //设置为必选项
            field: "AgeRange",
            type: "select"
          },
          {
            title: "品种",
            dataKey: "pz",
            //如果这里绑定了data数据,后台不会加载此数据源
            data: [
              { key: "1", value: "1" },
              { key: "2", value: "2" }
            ],
            required: false,
            field: "Variety",
            type: "select"
          },
          {
            dataKey: "city",
            title: "城市",
            required: true,
            data: [],
            field: "City",
            type: "select"
          }
        ],
        [
          {
            type: "decimal",
            title: "成交均价",
            required: true,
            field: "AvgPrice"
          },
          {
            title: "日期",
            required: true,
            field: "Date",
            placeholder: "你可以设置colSize属性决定标签的长度,可选值12/8/6/4",
            colSize: 8, //设置宽度为2/3
            type: "date"
          }
        ]
      ],
      columns: [
        {
          field: "Name",
          title: "姓名",
          type: "string",
          width: 100,
          sortable: true,
          edit:{type:"text"}
        },
        { field: "Describe", title: "描述", type: "string", width: 180, edit:{type:"text"} },
        { field: "PhoneNo", title: "电话", type: "string", width: 130 , edit:{type:"text"}},
        {
          field: "CreateID",
          title: "CreateID",
          type: "int",
          width: 80,
          hidden: true
        },
        { field: "Creator", title: "创建人", type: "string", width: 130 }
      ]
    };
  },
  methods: {
    rowChangeLoadData(row) {
      //选中行后触发扩展tabs的方法,可以在此处加载tabs里的数据
      // this.http.post("/xxx",{},'正在加载数据').then(x=>{
      // })
      if (this.$refs.table) {
        this.row = row; //保存当前触发的行数据,下面查询时用
        //触发table查询
        this.$refs.table.load(null, true);
      }
      console.log("选中行触发tabs方法:" + JSON.stringify(row));
    },
    loadBefore(param, callBack) {
      //单选时触发查询前方法
      //查询前设置查询条件及分页信息
      //根据当前字段查询
      param.wheres = [{ name: "Name", value: this.row.Name }];
      callBack(true);
    },
    _linkView(row, column) {
      this.text =
        "点击单元格的弹出框,当前点击的行数据:" + JSON.stringify(row);
      this.viewModel = true;
      //  this.$message.error(JSON.stringify(row));
    },
    del() {
      let rows = this.$refs.table.getSelected();
      if (rows.length == 0) {
        return this.$message.error("请先选中行");
      }
      this.$refs.table.delRow();
    },
    clear() {
      this.tableData.splice(0);
    },
    add() {
      this.$refs.table.addRow({});
      //  this.tableData.push({});
    },
    getRows() {
      let rows = this.$refs.table.getSelected();
      if (rows.length == 0) {
        return this.$message.error("请先选中行1");
      }
      this.text = "当前选中的行数据:" + JSON.stringify(rows);
      this.viewModel = true;
    }
  }
};
</script>
<style lang="less" scoped>
.m-detail {
  min-height: 400px;
  margin-top: 20px;
  .m-tabs {
    background: white;
    padding: 0 15px;
  }
  .m-title {
    padding: 0 15px;
    h2 {
      font-weight: 500;
    }
  }
  .m-btn {
    text-align: right;
    padding: 10px 0;
  }
}
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/App_Appointment2.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
import { h, resolveComponent } from 'vue';
let extension = {
  components: {//动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: '',
    gridBody: {
      render() {
        return h(resolveComponent('ElAlert'), {
          style: { 'margin-bottom': '12px' },
          'show-icon': true,
          type: 'success',
          closable: false,
        }, [h('p', {}, '1、 onInited中重新定义表头数据,2021.01.08更新voltable.vue后才能使用'),
        h('p', {}, ' 2、具体见:App_Appointment2.js中配置(现在只支持到二级表头、不支持编辑与复杂操作)')]);
      }
    },
    gridFooter: '',
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction:"App_Appointment",
  text: "页面全部由代码生成器生成,只需要在onInited中重新配置表头数据",
  methods: {//事件扩展
    onInit() {
      //设置表的最大高度
      this.tableMaxHeight = 300;
    },
    onInited() {
      this.columns.splice(0);
      this.columns.push(...[
        {
          field: 'Name', title: '基础信息', type: 'string', align: 'center',
          children: [
            { field: 'Name', title: '用户姓名', type: 'string', link: true, width: 100, sortable: true },
            { field: 'PhoneNo', title: '电话', type: 'string', width: 130 },
            { field: 'Describe', title: '描述信息', type: 'string', width: 180 },
          ]
        },
        {
          field: 'Name', title: '创建人信息', type: 'string', align: 'center',
          children: [
            { field: 'Id', title: '主键ID', type: 'string', width: 90, hidden: true },
            { field: 'CreateDate', title: '创建时间', type: 'datetime', width: 120, sortable: true },
            { field: 'Creator', title: '创建人', type: 'string', width: 130, align: 'left' }]
        },
        {
          field: 'Name', title: '修改人信息', type: 'string', align: 'center',
          children: [
            { field: 'Modifier', title: 'ä¿® æ”¹ äºº', type: 'string', width: 130, align: 'left' },
            { field: 'ModifyDate', title: '修改时间', type: 'datetime', width: 150, sortable: true }]
        }
      ]
      )
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrder.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,383 @@
//1、此文件中的代码都是对基础业务进行扩展,也只能在此处编写代码,其他地方编写的代码会被代码生成器生成的代码覆盖
//2、此文件中的方法会与serviceFilter.js进行合并,终终执行的就是此文件中的方法
//3、components为扩展组件,可自定义页面的头部、body及尾部的额外显示的内容,分别对应的组件为:
//gridHeader、gridBody、gridFooter、modelHeader、modelBody、modelFooter共6个组件位置,如果不需要扩展组件,请忽略此处
//4、text为界面显示额外描述信息
//5、buttons->view/box/detail分别为查询界面、弹出框、弹出框明细表额外扩展的按钮
//6、methods为整个页面所有方法的业务代码扩展,如果需要在界面上的操作前、后编写业务,请覆盖此方法
//7、methods方法中可获取任意vue对象、方法、属性,可查看ViewGridConfig路径下的js文件及ViewGrid.vue的data属性
//如手动刷新表数据:this.search();
//获取表的列配置信息:this.columns  æ˜Žç»†è¡¨è¡¨çš„配置信息this.detail.columns
//8、获取子组件gridHeader、gridBody、gridFooter、modelHeader、modelBody、modelFooter则使用
//this.$refs.gridHeader获取gridHeader为自己扩展的对象
//9、在子组件gridHeader、gridBody、gridFooter、modelHeader、modelBody、modelFooter的方法中调用并获得父组件
// this.$emit("parentCall", $vue => {}) //$vue为父组件对象,具体使用参考order->GridHeader.vue文件
//10、子父件传参除8、9方式,另可使用已封装的vuex,使用方式:this.$store.getters.data().xxx = this;使用实例:App_News.js
//此处的下面的属性与方法都是对基础业务代码的扩展,如果不需要扩展则忽略对应的方法也不要写在下面
//serviceFilter.js
//所的文件都最终会合并到ViewGrid.vue文件中
import { h, resolveComponent } from 'vue';
import gridHeader from "./SellOrderComponents/GridHeader.vue"
import gridFooter from "./SellOrderComponents/GridFooter.vue"
import modelFooter from "./SellOrderComponents/ModelFooter.vue"
import modelBody from "./SellOrderComponents/ModelBody.vue"
let extension = {
  components: {//动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: gridHeader,
    gridBody: {
      render() {
        return [
          h(resolveComponent('el-alert'), {
            style: { 'margin-bottom': '12px' },
            'show-icon': true, type: 'warning',
            closable: false, title: '一对一全部由代码生成不需要写任何代码,点击新建或编辑查看明细表,可根据需要实现扩展gridHeader、gridBody、gridFooter、modelHeader、modelBody、modelFooter任意位置'
          }, ''),
        ]
      }
    },
    gridFooter: gridFooter,
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: "",
    modelBody: modelBody,
    modelFooter: modelFooter,
  },
  text: "示例覆盖全部可扩展方法,前台扩展文件SellOrder.js,后台Partial->SellOrdeService.cs",
  //this.filterPermission('表名','权限值,如:Add')来判断页面上是否有某个按钮的权限
  buttons: { //根据需要自行实现扩展按钮
    //注:没有编辑或新建权限的情况下,是不会显示此处添加的扩展按钮,如果仍需要显示此处的按钮,可以把按钮在methods的onInited方法中添加,如:this.boxButtons.push(...)
    view: [//ViewGrid查询界面按钮
    ],
    box: //新建、编辑弹出框按钮
      [//ViewGrid查询界面按钮
        {
          name: "点我1",
          icon: 'el-icon-delete',
          value: 'Edit',
          class: '',
          type: 'success',
          index: 1,//显示的位置
          onClick: function () {
            this.$message.error("扩展的明细Box按钮,可设置index值指定显示位置,可使用this.$refs拿到包括自定义扩展的所有组件");
          }
        }],
    detail: //新建、编辑弹出框明细表table表按钮
      [//ViewGrid查询界面按钮
        {
          name: "点我2",
          icon: 'el-icon-delete',
          value: 'Edit',
          class: '',
          type: 'success',
          index: 1,//显示的位置
          onClick: function () {
            this.$message.error("扩展的明细table按钮,可设置index值指定显示位置");
          }
        }]
  },//扩展的按钮
  methods: {
    //扩展方法使用示例,根据需要实行下面的方法
    getServiceDate() {
      this.http.post("/api/SellOrder/getServiceDate", {}, '正在调用后台数据').then(date => {
        this.$message.error("从后台获取的服务器时间是:" + date);
      })
    },
    mounted() {
      //this.$message.success('mounted方法执行时,你可以此处编写业务逻辑');
    },
    //方式1,通过select选择触发显示与隐藏
    onInit() {
     this.buttons.splice(1,0,...[
      {
        name: "点我弹出框",
        icon: 'md-create',
        value: 'Edit',
        class: '',
        type: 'primary',
        index: 1,//显示的位置
        onClick: function () { //扩展按钮执行事件
          //this可以获取所有属性,包括this.$refs.gridHeader/gridBody等获取扩展组件对象
          // this.$message("测试扩展按钮");
          this.$refs.gridHeader.open1();
        }
      }, {
        name: "调用后台",
        icon: 'md-create',
        value: 'Edit',
        class: '',
        type: 'primary',
        index: 1,//显示的位置
        onClick: function () { //扩展按钮执行事件
          this.getServiceDate();
        }
      }
     ])
      //获取订单类型select配置,当前订单类型select改变值时,动态设置Remark,SellNo两个字段是否显示
      var orderTypeOption = this.getFormOption("OrderType");
      orderTypeOption.onChange = (val) => {
        //当订单类型select改变值时,如果选中的是发货(对应字典编号为2),emark,SellNo隐藏,否则显示出来
        this.getFormOption("Remark").hidden = val == "2"
       // var sellNoOption = this.getFormOption("SellNo").hidden = val == "2"
      }
      //点击单元格编辑与结束编辑(默认是点击单元格编辑,鼠标离开结束编辑)
      this.detailOptions.clickEdit = true;
      //设置主表合计
      this.summary = true;
      //设置明细表合计
      this.detailOptions.summary = true;
      //表格设置为单选
      // this.single=true;
      // this.detailOptions.single=true;
      //设置编辑表单数量字段的最小与最大值
      this.editFormOptions.forEach(x => {
        x.forEach(item => {
          //设置输入的数量的最小值与最大值(默认是1)
          if (item.field == "Qty") {
            item.min = 10;
            item.max =100000;
          }
        });
      })
      //动态修改table并给列添加事件
      this.columns.forEach(x => {
        if (x.field == "Qty") {
          x.formatter = (row) => {
            return '<a style="color:#2196F3;">' + row.Qty + "(弹出框)" + '</a>'
          }
          x.click = (row, column, event) => {
            this.$refs.gridHeader.open2(row)
          }
        }
      })
      //动态设置查询界面table高度
      this.tableHeight = 300;
    },
    onInited() {
      this.detailOptions.columnIndex=false;
      this.detailOptions.ck=true;
      //设置主表求字段,后台需要实现SummaryExpress方法
      this.columns.forEach(x => {
        if (x.field == 'Qty'||x.field=='Weight') {
          x.summary = true;
        }
      })
      //设置明细表高度
      this.detailOptions.height = 220;
      this.boxOptions.height = document.body.clientHeight * 0.90;
      //设置明细表求字和段,后台需要实现GetDetailSummary方法
      this.detailOptions.columns.forEach(x => {
        if (x.field == 'Weight' || x.field == 'Qty') {
          x.summary = true;
        }
      })
      //   this.$message.success('create方法执行后', desc: '你可以SellOrder.js中编写业务逻辑,其他方法同样适用' });
    },
    searchBefore(param) { //查询ViewGird表数据前,param查询参数
      //你可以指定param查询的参数,处如果返回false,则不会执行查询
      // this.$message.success(this.table.cnName + ',查询前' });
      // console.log("扩展的"this.detailOptions.cnName + '触发loadDetailTableBefore');
      return true;
    },
    searchAfter(result) { //查询ViewGird表数据后param查询参数,result回返查询的结果
      // this.$notify({
      //   title: '查询结果',
      //   message: '返回的对象:' + JSON.stringify(result),
      //   type: 'success'
      // });
      return true;
    },
    searchDetailBefore(param) {//查询从表表数据前,param查询参数
      //  this.$message.success(this.detailOptions.cnName + '查询前' });
      return true;
    },
    searchDetailAfter(data) {//查询从表后param查询参数,result回返查询的结果
      // this.$notify({
      //   title: '明细查询结果',
      //   message: '返回的对象:' + JSON.stringify(data),
      //   type: 'success'
      // });
      return true;
    },
    delBefore(ids, rows) { //查询界面的表删除前 ids为删除的id数组,rows删除的行
      let auditStatus = rows.some(x => { return x.AuditStatus > 0 });
      // if (auditStatus) {
      //   this.$message.error('只能删除未审核的数据')
      //   return false;
      // }
      this.$message.success('删除前,选择的Id:' + ids.join(','));
      return true;
    },
    delAfter(result) {//查询界面的表删除后
      return true;
    },
    delDetailRow(rows) { //弹出框删除明细表的行数据(只是对table操作,并没有操作后台)
      console.log(rows)
      return true;
    },
    addBefore(formData) { //新建保存前formData为对象,包括明细表
      //formData格式:
      // {
      //     mainData: { ä¸»è¡¨å­—段1: 'x1', ä¸»è¡¨å­—段2: 'x2' },
      //     detailData: [{ æ˜Žç»†è¡¨å­—段1: d1 }],
      //     delKeys: null //删除明细表行数据的id
      // }
      //formData.mainData.xxx="xxxx";//还可以继续手动添加值
      //如果需要同时提交其他数据到后台,请设置formData.extra=xxxx
      //后台在表xxxxService.cs中重写Add方法即可从saveDataModel参数中拿到extra提交的对象
      console.log(this.detailOptions.cnName + '新建前,提交的数据:' + JSON.stringify(formData));
      return true;
    },
    async addBeforeAsync(formData) {
      //2020.12.06增加新建前异步方法同步处理
      //功能同上,区别在于此处可以做一些异步请求处理,全:
      // var _result = await this.http.post("/api/SellOrder/getPageData", {}, true).then(result => {
      //   console.log("1、异步请求前")
      //   return result;
      // })
      // console.log("2、异步请求,同步处理结果:" + JSON.stringify(_result))
      return true;
    },
    addAfter(result) {//新建保存后result返回的状态及表单对象
      console.log(this.detailOptions.cnName + '新建完成后,返回的数据' + JSON.stringify(result));
      return true;
    },
    updateBefore(formData) { //编辑保存前formData为对象,包括明细表、删除行的Id
      //formData格式:(自己调试出输看)
      // {
      //     mainData: { ä¸»è¡¨å­—段1: 'x1', ä¸»è¡¨å­—段2: 'x2' },
      //     detailData: [{ æ˜Žç»†è¡¨å­—段1: d1 }],
      //     delKeys: null //删除明细表行数据的id
      // }
      //formData.mainData.xxx="xxxx";//还可以继续手动添加值
      //如果需要同时提交其他数据到后台,请设置formData.extra=xxxx
      //后台在表xxxxService.cs中重写Update方法即可从saveDataModel参数中拿到extra提交的对象
      console.log(this.detailOptions.cnName + '编辑前,提交的数据:' + JSON.stringify(formData));
      //获取扩展的modelFooter属性text
      //  console.log(this.$refs.modelFooter.text)
      return true;
    },
    async updateBeforeAsync(formData) {
      //2020.12.06增加修改前异步方法同步处理
      //功能同上,区别在于此处可以做一些异步请求处理,全:
      var _result = await this.http.post("/api/SellOrder/getPageData", {}, true).then(result => {
        console.log("1、异步请求前")
        return result;
      })
      console.log("2、异步请求,同步处理结果:" + JSON.stringify(_result))
      return true;
    },
    updateAfter(result) {//编辑保存后result返回的状态及表单对象
      //  this.$message.success(this.detailOptions.cnName + '编辑完成后,返回的数据' + JSON.stringify(result));
      return true;
    },
    auditBefore(ids, rows) {//审核前
      if (rows.length > 2) {//每次最多只能审核2条数据
        this.$message.error('最多只能选择两条数据');
        return false;
      }
      return true;
    },
    auditAfter(result, rows) {// å®¡æ ¸åŽ
      if (result.status) {
        result.message = "审核成功。。。。。" + result.message;
      }
      return true;
    },
    resetAddFormBefore() { //重置新建表单前的内容
      return true;
    },
    resetAddFormAfter() { //重置新建表单后的内容
      //如果某些字段不需要重置,则可以重新赋值
      this.editFormFields.Remark = '新建重置默认值66666';
      //给明细表添加默认一行
      this.$refs.detail.rowData.push({ Remark: "新建666666" });
      return true;
    },
    resetUpdateFormBefore() { //重置编辑表单前的内容
      //this.editFormFields当前值
      console.log(this.editFormFields)
      //当前明细表的行
      console.log(this.$refs.detail.rowData)
      return true;
    },
    resetUpdateFormAfter() { //重置编辑表单后的内容
      //如果某些字段不需要重置,则可以重新赋值
      this.editFormFields.Remark = '编辑重置默认值66666';
      //给明细表添加默认一行
      this.$refs.detail.rowData.push({ Remark: "编辑666666" });
      return true;
    },
    importAfter(data) { //导入excel后刷新table表格数据
      this.search(); //刷新table
    },
    modelOpenBefore(row) { //点击编辑/新建按钮弹出框前,可以在此处写逻辑,如,从后台获取数据
    },
    async modelOpenBeforeAsync(row) { //点击编辑/新建按钮弹出框前,可以在此处写逻辑,如,从后台获取数据
      //2021.01.10
      if (row) {
        console.log("编辑操作")
      } else {
        console.log("新建操作")
      }
      //打开弹出框前,http请求同步执行
      // var _result = await this.http.post("url", {}, true).then(result => {
      //   _result = result;
      // })
      // console.log(result);
      //返回false不会弹出框
      //this.$message.error("不能打开弹出框 ");
      return true;
    },
    getFormOption(field) {
      let option;
      this.editFormOptions.forEach(x => {
        x.forEach(item => {
          if (item.field == field) {
            option = item;
          }
        })
      })
      return option;
    },
    //方式2,通过打开弹出框时触发显示与隐藏
    modelOpenAfter(row) {  //编辑或新建时,根据不同的情况控制字段是否显示
      //   this.editFormOptions.forEach(x => {
      //     x.forEach(item => {
      //       if (item.field == "Remark" || item.field == "SellNo") {
      //         //如果不是新建,则隐藏Remark,SellNo两个字段是否显示
      //          //也可以根据row当前编辑行的值来处理
      //         this.$set(item, "hidden", this.currentAction != "Add")
      //       }
      //     })
      //   })
    },
    rowClick({ row, column, event }) { //查询界面table点击行选中当前行
      this.$refs.table.$refs.table.toggleRowSelection(row);
    },
    // detailRowClick ({ row, column, event }) {
    //   //编辑弹出框从表table点击行选中当前行,没有从表的不用管
    //   this.$refs.detail.$refs.table.toggleRowSelection(row);
    // }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrder2.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,104 @@
import gridFooter from "./SellOrder2/SellOrder2GridFooter.vue"
//自定义从表选择数据源页面
import modelBody from "./SellOrder2/SellOrder2ModelBody.vue"
import { h, resolveComponent } from 'vue';
let extension = {
  components: {//动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: '',//{ template: "<div>扩展组xxä»¶</div>" },
    gridBody: {
      render() {
        return [
          h(resolveComponent('el-alert'), {
            style: { 'margin-bottom': '12px' },
            'show-icon': true, type: 'success',
            closable: false, title: '界面由代码生成器生成,只需几行代码即可实现点击主表行显示明细表数据(直接扩展gridFooter位置的代码,具体代码见此示例:SellOrder2.js)'
          }, ''),
        ]
      }
    },
    gridFooter: gridFooter,
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: "",
    modelBody: modelBody,//自定义从表选择数据源页面
    modelFooter: "",
  },
  text: "点击主表行加载明细表数据,如果本地看不到此菜单,可以按照演示环境配置下此页面菜单",
  buttons: { //根据需要自行实现扩展按钮
  },//扩展的按钮
  methods: {
    mounted() {
    },
    //方式1,通过select选择触发显示与隐藏
    onInit() {
      //点击单元格编辑与结束编辑(默认是点击单元格编辑,鼠标离开结束编辑)
      this.detailOptions.clickEdit = true;
      //设置主表合计
      this.summary = true;
    },
    onInited() {
      //调整界面table高度
      this.height = this.height - 310;
      //明细表选择数据源操作
      //获取明细表备注列,给备注列添加选择数据操作
      this.detailOptions.buttons.unshift({
        'name': '选择数据',
        icon: "el-icon-plus",
        onClick: () => {
          this.$refs.modelBody.open();
        }
      })
      // let _column = this.detailOptions.columns.find(x => { return x.field == "Remark" });
      // _column.title="(备注)点击选择数据"
      // //移除编辑操作
      // _column.edit = null;
      // //给备注列添加选择数据操作
      // _column.render = (h, { row, column, index }) => {
      //   return h("div", { style: {} },
      //     [
      //       h("i", {
      //         class: ["el-icon-zoom-out"],
      //         style: {
      //           cursor: "pointer",
      //           "margin-right": "8px",
      //           color: "#409eff",
      //         },
      //         onClick: (e) => {
      //           e.stopPropagation();
      //           //弹出选择数据源
      //           this.$refs.modelBody.open(row);
      //         },
      //       }),
      //     ], row.Remark)
      // };
    },
    // rowDbClick({ row, column, event }){//双击事件
    // },
    rowClick({ row, column, event }) { //查询界面table点击行选中当前行
      //取消其他行选中
      this.$refs.table.$refs.table.clearSelection();
      //设置选中当前行
      this.$refs.table.$refs.table.toggleRowSelection(row);
      if (this.$refs.gridFooter && this.$refs.gridFooter.$refs.tableList) {
        //load方法可参照voltable组件api文档
        this.$refs.gridFooter.$refs.tableList.load({ value: row.Order_Id, sort: "CreateDate" })
      }
    },
    searchAfter(rows) {
      //页面加载或者刷新数据后直接显示第一行的明细
      if (rows.length) {
        // this.$nextTick(() => {
        this.$refs.gridFooter.$refs.tableList.load({ value: rows[0].Order_Id, sort: "CreateDate" })
        // })
      } else {
        //没有数据时,清空明细数据
        this.$refs.gridFooter.$refs.tableList.rowData.splice(0)
      }
      return true;
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrder2/SellOrder2GridFooter.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
<template>
  <div style="padding: 0 4px;border-top: 10px solid #eee;">
    <h3 >
      <i class="ivu-icon ivu-icon-ios-information-circle-outline"></i>订单明细
    </h3>
    <div style="padding:10px;background: white;padding-top: 0;">
      <vol-table ref="tableList"
                 :loadKey="true"
                 :columns="columns"
                 :pagination-hide="true"
                 :height="210"
                 :defaultLoadPage="false"
                 @loadBefore="loadBefore"
                 url="/api/SellOrder/getDetailPage"
                 :row-index="true"
                 :index="false"></vol-table>
    </div>
  </div>
</template>
<script>
import VolTable from "@/components/basic/VolTable.vue";
export default {
  components: {
    VolTable
  },
  methods: {
    loadBefore (params, callback) {
      return callback(true);
    }
  },
  data () {
    return {
      tableData: [],
      //从生成的代码sellorder2.vue里面把明细配置复制过来就能用
      columns:  [{field:'OrderList_Id',title:'OrderList_Id',type:'string',width:90,hidden:true,require:true,align:'left'},
                {field:'Order_Id',title:'订单Id',type:'string',width:90,hidden:true,readonly:true,require:true,align:'left'},
                {field:'ProductName',title:'商品名称',type:'string',width:150,require:true,align:'left',sortable:true},
                {field:'MO',title:'批次',type:'string',width:100,require:true,align:'left'},
                {field:'Qty',title:'数量',type:'int',width:90,require:true,align:'left'},
                {field:'Weight',title:'重量',type:'decimal',width:90,align:'left'},
                {field:'Remark',title:'备注',type:'string',width:120,align:'left'},
                {field:'Creator',title:'创建人',type:'string',width:130,align:'left'},
                {field:'CreateDate',title:'创建时间',type:'datetime',width:90,align:'left'},
                {field:'Modifier',title:'修改人',type:'string',width:100,align:'left'},
                {field:'ModifyDate',title:'修改时间',type:'datetime',width:90,align:'left'}]
    }
  }
}
</script>
<style scoped>
 h3{
     font-weight: 500;
    padding-left: 10px;
    background: white;
    margin-top: 8px;
    padding-bottom: 5px;
 }
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrder2/SellOrder2ModelBody.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
<template>
  <VolBox v-model="model" title="选择数据" :lazy="true" :height="530" :width="1100" :padding="10">
    <!-- è®¾ç½®æŸ¥è¯¢æ¡ä»¶ -->
    <div style="padding-bottom: 10px">
      <span style="margin-right: 20px">请选择数据</span>
      <el-input placeholder="商品名称" style="width: 200px" v-model="ProductName" />
      <el-button type="primary" plain style="margin-left: 10px" icon="Search" @click="search">搜索</el-button>
    </div>
    <!-- vol-table配置的这些属性见VolTable组件api文件 -->
    <vol-table ref="mytable" :loadKey="true" :columns="columns" :pagination="pagination" :pagination-hide="false"
      :max-height="380" :url="url" :index="true" :single="false" :defaultLoadPage="false"
      @loadBefore="loadTableBefore"></vol-table>
    <template #footer>
      <div>
        <el-button plain type="primary" @click="addRow">选择数据</el-button>
        <el-button @click="model = false">关闭</el-button>
      </div>
    </template>
  </VolBox>
</template>
<script>
import VolBox from "@/components/basic/VolBox.vue";
import VolTable from "@/components/basic/VolTable.vue";
export default {
  components: {
    VolBox: VolBox,
    VolTable: VolTable,
  },
  data() {
    return {
      model: false,
      ProductName: "",
      //从后台接口加载数据,这里的接口用的框架自带的查询,也可以自定义接口,见App_ExpertModelBody.vue中调用的后台getSelectorDemo方法
      url: "api/sellorderlist/getPageData",
      columns: [
        {
          field: "ProductName",
          title: "商品名称",
          type: "string",
          bind: { key: "pn", data: [] },
          width: 150,
          sort: true,
        },
        { field: "MO", title: "批次", width: 100, sort: true },
        { field: "Qty", title: "数量", width: 90, sort: true },
        { field: "Weight", title: "重量", twidth: 90, sort: true },
        { field: "Remark", title: "备注", width: 120, sort: true },
        { field: "Creator", title: "创建人", width: 130, sort: true },
        {
          field: "CreateDate",
          title: "创建时间",
          type: "datetime",
          width: 145,
          sort: true,
        },
      ],
      pagination: {},
      row: {}, //明细表选择的行
    };
  },
  methods: {
    open(row) {
      //   this.row = row;
      this.model = true;
      //打开弹出框时,加载table数据
      this.$nextTick(() => {
        this.$refs.mytable.load();
      });
    },
    search() {
      this.$refs.mytable.load();
    },
    addRow() {
      var rows = this.$refs.mytable.getSelected();
      if (!rows || rows.length == 0) {
        return this.$Message.error("请选择行数据");
      }
      //回写明细表行数据,见文档子父组件调用与获取明细表行数据:http://v2.volcore.xyz/document/api
      this.$emit('parentCall', $parent => {
        //这里可以写个判断是否已经存在明细表,找到不存在的数据
        // rows = rows.filter(c => {
        //    return !$parent.$refs.detail.rowData.some(r => { return r.xx == c.xx })
        //  });
        //生成新的对象
        rows = rows.map(c => {
          return {
            ProductName: c.ProductName,
            MO: c.MO,
            Weight: c.Weight,
            Remark: c.Remark
          }
        })
        //可以清空明细表数据
        //$parent.$refs.detail.rowData.splice(0);
        //回写到明细表格
        $parent.$refs.detail.rowData.unshift(...rows);
      })
      this.model = false;
    },
    loadTableBefore(params) {
      //查询前,设置查询条件
      params.wheres = [
        { name: "ProductName", value: this.ProductName, displayType: "like" },
      ];
      return true;
    },
  },
};
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrder3.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
import SellOrder3GridFooter from "./SellOrder3/SellOrder3GridFooter.vue"
let extension = {
  components: {//动态扩充组件或组件路径
    //表单header、content、footer对应位置扩充的组件
    gridHeader: '',//{ template: "<div>扩展组xxä»¶</div>" },
    gridBody:'',
    gridFooter: SellOrder3GridFooter, //() => import("./SellOrder3/SellOrder3GridFooter.vue"),
    //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
    modelHeader: "",
    modelBody: '',
    modelFooter: "", //() => import("./SellOrderComponents/ModelFooter.vue"),
  },
  text: "用法与【主从一对一(2)】一致(见SellOrder3.js)",
  buttons: { //根据需要自行实现扩展按钮
  },//扩展的按钮
  methods: {
    mounted() {
    },
    //方式1,通过select选择触发显示与隐藏
    onInit() {
      //设置为单选,用于明细表加载数据时获取主表选行的id
      this.single = true;
    },
    onInited() {
      this.height = this.height - 350;
    },
    rowClick({ row, column, event }) { //查询界面table点击行选中当前行
      this.$refs.table.$refs.table.toggleRowSelection(row);
      if (this.$refs.gridFooter && this.$refs.gridFooter.$refs.tableList) {
        //添加明细表的数据(触发明细表加载数据,见SellOrder3GridFooter方法loadBefore)
        //load方法可参照voltable组件api文档
        this.$refs.gridFooter.$refs.tableList.load()
      }
    },
    searchAfter(rows) {
      //页面加载或者刷新数据后直接显示第一行的明细
      if (rows.length) {
        // this.$nextTick(() => {
        this.$refs.gridFooter.$refs.tableList.load({ value: rows[0].Order_Id, sort: "CreateDate" })
        // })
      } else {
        //没有数据时,清空明细数据
        this.$refs.gridFooter.$refs.tableList.rowData.splice(0)
      }
      return true;
    },
    modelOpenAfter() {
      //新建弹出框时,设置设置默认订单类型
      if (this.currentAction == "Add") {
        this.editFormOptions.forEach(item => {
          item.forEach(x => {
            //如果是编辑帐号设置为只读
            if (x.field == "OrderType") {
              //新建时默认选择中第一个下拉框的值,如果要选中其他的值,请遍历x.data获取key
              /*注意:如果下拉框的数据源是自定义sql,并且key是数字,请将(x.data[0].key*1)转换成数字*/
              this.editFormFields.OrderType = x.data[0].key;
              //可以指定其他input标签的默认值
              this.editFormFields.TranNo="8888"
            }
          })
        })
      }
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrder3/SellOrder3GridFooter.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,235 @@
<template>
  <div style="margin-top: 15px; padding: 0 16px">
    <el-tabs type="border-card" style="min-height: 320px; box-shadow: none">
      <el-tab-pane>
        <template #label>
          <span><i class="el-icon-date"></i> è®¢å•明细</span>
        </template>
        <vol-table
          ref="tableList"
          :loadKey="true"
          :columns="columns"
          :pagination-hide="false"
          :height="230"
          :defaultLoadPage="false"
          @loadBefore="loadBefore"
          :endEditAfter="endEditAfter"
          url="/api/SellOrder/getDetailPage"
          :row-index="true"
          :columnIndex="true"
          :index="true"
          :click-edit="true"
        ></vol-table>
      </el-tab-pane>
      <el-tab-pane :lazy="true" label="消息中心">消息中心</el-tab-pane>
      <el-tab-pane :lazy="true" label="角色管理">角色管理</el-tab-pane>
      <el-tab-pane :lazy="true" label="定时任务补偿">定时任务补偿</el-tab-pane>
    </el-tabs>
  </div>
</template>
<script>
import VolTable from "@/components/basic/VolTable.vue";
export default {
  components: {
    VolTable,
  },
  methods: {
    loadBefore(params, callback) {
      //设置查询 æ¡ä»¶
      var _row;
      //获取主表选中的行
      this.$emit("parentCall", ($vue) => {
        var rows = $vue.getSelectRows();
        if (rows.length) {
          _row = rows[0];
        }
      });
      if (!_row) {
        //取消选中,清空明细
        return (this.$refs.tableList.rowData.length = 0);
        //  return this.$Message.error("请选中主表行数据");
      }
      //设置查询条件,用主表id加载明细表数据(如果是自己定义的接口,这里条件自己处理)
      params.value = _row.Order_Id;
      //设置排序字段(如果是自己定义的接口,排序字段不一定填写)
      if (!params.sort) {
        params.sort = "CreateDate";
      }
      return callback(true);
    },
    endEditAfter(row) {
      //结束编辑时,可以直接调用后台的代码进行保存
      console.log(row);
      return true;
    },
    save(row) {
      //保存
      this.$Message.info("保存");
    },
    del(row) {
      this.$confirm(
        "确认要删除此行数据【" + row.ProductName + "】??",
        "确认信息",
        {
          distinguishCancelAndClose: true,
          confirmButtonText: "确认删除",
          cancelButtonText: "取消",
            center: true
        }
      )
        .then(() => {
          this.$message({
            type: "info",
            message: "提交删除请求",
          });
        })
    },
    getRender() {
      //生成表格编辑配置
      return (h, { row, column, index }) => {
        return h(
          "div",
          {
            style: {
              cursor: "pointer",
              color: " #409eff",
              "font-size": "13px",
            },
          },
          [
            h(
              "a",
              {
                props: {},
                style: { "border-bottom": "1px solid" },
                onClick: (e) => {
                  e.stopPropagation();
                  this.del(row);
                },
              },
              "删除"
            ),
            h(
              "a",
              {
                props: {},
                style: { "margin-left": "9px", "border-bottom": "1px solid" },
                onClick: (e) => {
                  e.stopPropagation();
                  this.$refs.tableList.edit.rowIndex = index;
                },
              },
              "编辑"
            ),
            h(
              "a",
              {
                props: {},
                style: { "margin-left": "9px", "border-bottom": "1px solid" },
                onClick: (e) => {
                  e.stopPropagation();
                  //强制结束编辑
                  this.$refs.tableList.edit.rowIndex = -1;
                  this.save();
                },
              },
              "保存"
            ),
          ]
        );
      };
    },
  },
  data() {
    return {
      tableData: [],
      //从生成的代码sellorder2.vue里面把明细配置复制过来就能用
      columns: [
        {
          field: "OrderList_Id",
          title: "OrderList_Id",
          type: "string",
          width: 90,
          hidden: true,
          require: true,
        },
        {
          field: "Order_Id",
          title: "订单Id",
          type: "string",
          width: 90,
          hidden: true,
          readonly: true,
        },
        {
          field: "ProductName",
          title: "商品名称",
          type: "string",
          bind: { key: "pn", data: [] },
          width: 150,
          edit: { type: "select" },
          require: true,
        },
        {
          field: "MO",
          title: "批次",
          type: "string",
          width: 100,
          edit: { type: "" },
          require: true,
          sort: true,
        },
        {
          field: "Qty",
          title: "数量",
          type: "int",
          width: 90,
          edit: { type: "drop" },
          summary: true, //设置求和
          require: true,
        },
        {
          field: "Weight",
          title: "重量",
          type: "decimal",
          summary: true, //设置求和
          width: 90,
          edit: { type: "" },
        },
        {
          field: "Creator",
          title: "创建人",
          type: "string",
          width: 100,
        },
        {
          field: "CreateDate",
          title: "创建时间",
          type: "datetime",
          width: 140,
          sort: true,
        },
        {
          title: "操作",
          width: 110,
          align: "center",
          render: this.getRender(),
        },
      ],
    };
  },
};
</script>
<style scoped>
h3 {
  font-weight: 500;
  padding-left: 10px;
  background: white;
  margin-top: 10px;
  padding-top: 6px;
  padding-bottom: 5px;
}
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrderComponents/GridBody.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
<template>
  <div>
    <el-alert type="info">
      <h5>SellOrder.js文件中的扩展SellOrder表显示body信息,你可以在此处定义需要显示的信息</h5>
    </el-alert>
  </div>
</template>
<script>
export default {
  components: {
    VolBox: () => import("@/components/basic/VolBox.vue")
  },
  data() {
    return {
      model: false
    };
  },
  methods: {
    test() {
      this.$emit("parentCall", $vue => {
        let rows = $vue.$refs.table.rowData;
        //此于拿到的$vue你可以操作其中的任何对象,如:
        //props.js中的属性,this.columns/this.editFormFields
        //或者操作其他动态扩展的组件如:$vue.$refs.gridBody/$vue.$refs.gridFooter
        //$vue.$refs.table获取表格信息
        //$vue.refresh()刷新表格等操作
        //能操作的所有对象可参照props.js与ViewGird.uve的属性
        //能操作的方法methods.js/detailMethods.js
      });
    }
  }
};
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrderComponents/GridFooter.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
<template>
  <div style="margin-top: 10px;">
    <el-alert type="info" title="gridFooter扩展位置" show-icon>
      <div>
        æ­¤ä»£ç ä½ç½®gridFooter.vue扩展组件被SellOrder.js的属性gridFooter引用,你可以在此弹出框定义其他业务。
        <a style="color: #409eff; cursor: pointer"
          >使用方式与上面gridHeader一致</a
        >
      </div>
    </el-alert>
  </div>
</template>
<script>
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup(props, context) {
    return {}
  },
});
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrderComponents/GridHeader.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
<template>
  <div style="border-bottom: 10px solid rgb(228 228 228)">
    <el-alert type="success" title="gridHeader扩展位置" show-icon>
      <div>
        1、此代码位置GridHeaderExtend.vue扩展组件被SellOrder.js的属性gridHeader引用,你可以在此弹出框定义其他业务。
        <a style="color: #409eff; cursor: pointer" @click="search"
          >点击调用父组件查询方法</a
        >
        <a
          style="color: #409eff; cursor: pointer; margin-left: 20px"
          @click="add"
          >点击调用父组件新建方法</a
        >
      </div>
      <div>
        2、使用 this.$emit('parentCall', ($vue) =>
        {})可以访问整个界面上的所有属性(页面具体对象与属性,见
        <a target="_blank" href="http://www.volcore.xyz/document/api"
          >viewgrid文档</a
        >)
      </div>
    </el-alert>
  </div>
  <vol-box
    :lazy="true"
    v-model="model1"
    title="弹出框2"
    :width="500"
    :padding="5"
    :onModelClose="onModelClose"
  >
    <div style="height: 150px;">按钮点击的弹出框</div>
  </vol-box>
  <vol-box
    :lazy="true"
    v-model="model2"
    title="弹出框2"
    :width="700"
    :padding="5"
    :onModelClose="onModelClose"
  >
    <div style="height: 400px;">表格当前行数据:{{ JSON.stringify(row2) }}</div>
    <template #footer>
      <el-button type="primary" size="small" @click="model2 = false"
        >确认</el-button
      >
      <el-button type="default" size="small" @click="model2 = false"
        >关闭弹</el-button
      >
    </template>
  </vol-box>
</template>
<script>
import VolBox from '@/components/basic/VolBox.vue';
import { ref, defineComponent } from 'vue';
export default defineComponent({
  components: {
    VolBox
  },
  setup(props, context) {
    const search = () => {
      context.emit('parentCall', ($parent) => {
        $parent.search();
      });
    };
    const add = () => {
      context.emit('parentCall', ($parent) => {
        $parent.add();
      });
    };
    const model1 = ref(false);
    const model2 = ref(false);
    const open1 = () => {
      model1.value = true;
    };
    const row2 = ref(null);
    const open2 = (row) => {
      model2.value = true;
      row2.value = row;
    };
    return { search, add, open1, open2, model1, model2, row2 };
  }
});
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrderComponents/ModelBody.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
<template>
  <div class="m-body">
    <a @click="close">
      è¿™é‡Œæ˜¯è‡ªå®šä¹‰æ‰©å±•的代码,可以访问整个界面上的所有属性
      this.$emit('parentCall', ($vue) => {});点击测试关闭弹出框</a
    >
    <el-steps :active="1" simple>
      <el-step title="步骤 1" icon="el-icon-edit"></el-step>
      <el-step title="步骤 2" icon="el-icon-upload"></el-step>
      <el-step title="步骤 3" icon="el-icon-picture"></el-step>
    </el-steps>
  </div>
</template>
<script>
import { ref, defineComponent } from "vue";
export default defineComponent({
  setup(props, context) {
    const close = () => {
      context.emit("parentCall", ($parent) => {
        $parent.boxModel = false;
      });
    };
    return { close };
  },
});
</script>
<style scoped>
.m-body {
  border-top: 1px solid #eee;
  margin-top: -14px;
  text-align: center;
  padding-top: 5px;
}
a {
  color: #2d94ff;
  cursor: pointer;
  display: inline-block;
  margin-bottom: 5px;
}
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/SellOrderComponents/ModelFooter.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
<template>
   <div style="padding:0 12px;">
      <el-alert type="success" title="自定义ModelBody位置的代码" show-icon>
    å¦‚果需要获整个ViewGrid的Vue对象,请在方法中使用 this.$emit("parentCall", $vue
    => {})
  </el-alert>
   </div>
</template>
<script>
export default {
};
</script>
<style scoped>
</style>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/vSellOrderImg.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
import { h, resolveComponent } from 'vue';
import modelBody from "./vSellOrderImg/vSellOrderImgModelBody.vue"
let extension = {
  components: {//动态扩充组件或组件路径
    gridHeader: '',
    gridBody: {
      render() {
        return h(resolveComponent('el-alert'), {
          type: "success",
          style: { 'margin-bottom': '12px' },
          'show-icon': false,
          closable: false,
        }, '点击新建、编辑弹出框,可以对明细表进行上传文件或者图片操作,见vSellOrderImg.js')
      }
    },
    gridFooter: '',
    modelHeader: "",
    //点击上传图片的弹出框
    modelBody: modelBody,
    modelFooter: "",
  },
  text: "一对一从表编辑上传图片",
  methods: {
    onInit() {
    },
    onInited() {
      this.height = this.height - 56;
      //获取图片位置,在图片后面加一个上传按钮,这里只是演示随便找的一个字段存图片
      let _index = this.detailOptions.columns.findIndex(x => { return x.field == 'Remark' });
      //这里只是演示,实际操作在代码生成器table显示类型设置为图片后这里就不用操作了
      //代码生成器中编辑行号设置为0,不要设置为大于0的数据
      this.detailOptions.columns[_index].edit = null;
      this.detailOptions.columns[_index].type = 'img';
      this.detailOptions.columns[_index].title = '图片';
      //从表动态添加一列(上传图片列),生成上传图片、与删除图片操作
      this.detailOptions.columns.splice(_index, 0, {
        field: "随便写",
        title: "上传图片",
        width: 150,
        align: "center",
        render: (h, { row, column, index }) => {
          //下面所有需要显示的信息都从row里面取出来
          return h(
            "div", { style: { color: '#0c83ff', 'font-size': '13px', cursor: 'pointer' } },
            [
              h(
                "i", {
                style: { 'margin-right': '10px' },
                class:['el-icon-upload'],
                onClick: (e) => {
                  e.stopPropagation();
                  //记住当前操作的明细表行数据
                  //如果原来有图片,上传图片界面把原来的图片也显示出来
                  let fileInfo = (row.Remark || '').split(",").filter(x => { return x }).map(img => {
                    //(生成文件格式) fileInfo格式参数,见volupload组件
                    return { path: img, name: "" };
                  })
                  this.$refs.modelBody.open(fileInfo, row)
                }
              }, [], '上传图片'
              ),
              h('i', {
                class: ['el-icon-delete'], onClick: (e) => {
                  e.stopPropagation(); row.Remark = ''
                }
              }, '删除图片')
            ])
        },
      })
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/order/vSellOrderImg/vSellOrderImgModelBody.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
<template>
  <VolBox
    v-model="model"
    title="选择图片"
    :height="228"
    :width="500"
    :padding="15"
  >
    <!-- ä¸Šä¼ å›¾ç‰‡ã€excel或其他文件、文件数量、大小限制都可以,参照volupload组件api -->
    <div style="height: 150px;">
      <VolUpload
      style="text-align: center; border: 1px dotted #ff9800; padding: 20px"
      :autoUpload="false"
      :multiple="true"
      :url="url"
      :max-file="2"
      :img="true"
      :fileInfo="fileInfo"
      :upload-after="uploadAfter"
    >
      <div>选择图片,只能上传3M以内的照片</div>
    </VolUpload>
    </div>
  </VolBox>
</template>
<script>
import { h, resolveComponent, defineAsyncComponent } from "vue";
export default {
  components: {
    VolUpload: defineAsyncComponent(() =>
      import("@/components/basic/VolUpload.vue")
    ),
    VolBox: defineAsyncComponent(() => import("@/components/basic/VolBox.vue")),
  },
  data() {
    return {
      //设置保存图片的路径,此处选择的是框架自带每个表的上传的路径
      //也可以自定义设置上传文件的接口,如果需要上传到第三方请实现uploadBefore方法
      url: "api/Sys_Dictionary/upload",
      fileInfo: [], //初始化一个空对象,用来存储编辑上传图片时的原始图片
      model: false,
      row: {}, //当前操作的明细表行
    };
  },
  methods: {
    open(fileInfo, row) {
      this.row=row;
      this.fileInfo = fileInfo;
      this.model = true;
    },
    //上传完成,将图片写入明细表数据
    uploadAfter(result, files) {
      if (!result.status) return true;
      //生成图片保存后返回的路径
      let imgs = files.map((x) => {
        //2021.09.25修复示例上传路径逻辑错误的问题
        if (x.path) {
          return x.path;
        }
        return result.data + x.name;
      });
      // //获取vue父组件(查询界面)
      // this.$emit('parentCall',($parent)=>{
      // })
      //将图片通过逗号隔开,重新写入明细表的行数据中
      this.row.Remark = imgs.join(",");
      this.model = false;
      return true;
    },
  },
};
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/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/WMS_Client/src/extension/system/flow/Sys_WorkFlow.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
/*****************************************************************************************
 **  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文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
import gridHader from './Sys_WorkFlow/WorkFlowGridHeader.vue';
import { h, resolveComponent } from 'vue';
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: gridHader,
    gridBody: {
      render() {
        return [
          h(
            resolveComponent('el-alert'),
            {
              style: { 'margin-bottom': '12px' },
              'show-icon': true,
              type: 'success',
              closable: false,
              title: '流程设计器根据easy-flow修改,表必须包括审批字段AuditStatus,具体见示例表SellOrder;后台startup需要注入审批流程'
            },
            ''
          )
        ];
      }
    },
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      //框架初始化配置前,
      //示例:在按钮的最前面添加一个按钮
      //   this.buttons.unshift({  //也可以用push或者splice方法来修改buttons数组
      //     name: '按钮', //按钮名称
      //     icon: 'el-icon-document', //按钮图标vue2版本见iview文档icon,vue3版本见element ui文档icon(注意不是element puls文档)
      //     type: 'primary', //按钮样式vue2版本见iview文档button,vue3版本见element ui文档button
      //     onClick: function () {
      //       this.$Message.success('点击了按钮');
      //     }
      //   });
      //示例:设置修改新建、编辑弹出框字段标签的长度
      // this.boxOptions.labelWidth = 150;
    },
    onInited() {
      this.height = this.height - 50;
      //框架初始化配置后
      //如果要配置明细表,在此方法操作
      //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); //单击行时选中当前行;
    },
    async modelOpenBeforeAsync(row) {
      //点击编辑/新建按钮弹出框前,可以在此处写逻辑,如,从后台获取数据
      this.$refs.gridHeader.open(row);
      return false;
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/system/flow/Sys_WorkFlow/WorkFlowGridHeader.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,254 @@
<template>
  <vol-box :lazy="false" v-model="model" :title="isAdd ? '新建流程' : '编辑流程'" :width="width" :padding="0">
    <div :style="{ height: height + 'px' }">
      <flow-panel ref="flow"></flow-panel>
    </div>
    <template #footer>
      <div style="text-align: center;">
        <el-button type="default" size="mini" @click="model = false">取消</el-button>
        <el-button type="primary" size="mini" @click="save">保存</el-button>
      </div>
    </template>
  </vol-box>
</template>
<script>
import FlowPanel from '@/components/workflow/panel'
import VolBox from '@/components/basic/VolBox.vue';
export default {
  name: 'App',
  components: {
    FlowPanel,
    VolBox
  },
  data() {
    return {
      nodeList: [],
      lineList: [],
      model: false,
      height: 500,
      width: 1200,
      row: null,
      isAdd: false
    };
  },
  created() {
    this.height = document.body.clientHeight - 140;
    let width = document.body.clientWidth * 0.9;
    this.width = width > 1800 ? 1800 : width;
  },
  methods: {
    open(row) {
      this.row = row;
      this.model = true;
      this.isAdd = Object.keys(this.row).length == 0;
      if (row.NodeConfig) {
        this.nodeList = JSON.parse(row.NodeConfig);
      } else {
        this.nodeList = [
          // {
          //   id: '1659276275052',
          //   name: '流程C-节点A',
          //   type: 'task',
          //   left: '230px',
          //   top: '15px',
          //   ico: 'el-icon-user-solid'
          // },
          // {
          //   id: '1659276282115',
          //   name: '流程C-节点B',
          //   type: 'task',
          //   left: '225px',
          //   top: '165px',
          //   ico: 'el-icon-goods'
          // }
        ];
      }
      if (row.LineConfig) {
        this.lineList = JSON.parse(row.LineConfig);
      } else {
        this.lineList = [
          // {
          //   from: '1659276275052',
          //   to: '1659276282115'
          // }
        ];
      }
      this.$nextTick(() => {
        this.$refs.flow.dataReload({
          lineList: this.lineList,
          nodeList: this.nodeList
        }, this.isAdd);
        Object.assign(this.$refs.flow.formFields, row);
        if (this.isAdd) {
          this.$refs.flow.formFields.WorkName="";
          this.$refs.flow.formFields.WorkTable="";
          this.$refs.flow.formFields.WorkTableName="";
          this.$refs.flow.formFields.Remark="";
          this.$refs.flow.formFields.Weight=1;
        }
        if (this.$refs.flow) {
          this.$refs.flow.$refs.nodeForm.$refs.filter.getOptions(row.WorkTable);
        } else {
          this.$refs.flow.$refs.form.reset(
            Object.keys(row).length
              ? row
              : { WorkName: '', WorkTable: '', WorkTableName: '', Remark: '',Weight:1 }
          );
        }
      });
    },
    save() {
      let mainData = JSON.parse(JSON.stringify(this.$refs.flow.formFields));
      if (!mainData.WorkName) {
        this.$message.error('请填写左侧表单【流程名称】')
        return;
      }
      if (!mainData.WorkTable) {
        this.$message.error('请选择左侧表单【流程实例】')
        return;
      }
      let nodeList = this.$refs.flow.data.nodeList;
      let nodeListOptions = JSON.parse(JSON.stringify(nodeList));
      nodeListOptions.forEach(item => {
        if (item.filters && item.filters.data) {
          item.filters.data = undefined;
        }
        if (item.userId && item.userId.length) {
          item.userId = item.userId.join(',');
        }
      })
      mainData.NodeConfig = JSON.stringify(nodeListOptions)
      let lineList = this.$refs.flow.data.lineList;
      lineList = JSON.parse(JSON.stringify(lineList));
      lineList.forEach(item => {
        if (item.filters) {
          item.filters.forEach(x => {
            if (x.data) {
              x.data = [];
            }
          })
        }
      })
      mainData.LineConfig = JSON.stringify(lineList);
      let rootNode = nodeList.filter(c => { return c.type == 'start' }).
        map(c => {
          return {
            StepId: c.id,
            StepName: c.name,
            StepAttrType: c.type,
            StepAuditType: null,
            ParentId: [''],
            Filters: c.filters
          }
        });
      if (!rootNode.length) {
        return this.$message.error('请添加流程开始节点');
      }
      if (rootNode.length > 1) {
        return this.$message.error('只能选择一个流程开始节点');
      }
      let endNodeCount = nodeList.filter(c => { return c.type == 'end' }).length;
      if (!endNodeCount) {
        return this.$message.error('请选择左侧【流程结束】节点');
      }
      if (endNodeCount > 1) {
        return this.$message.error('只能选择一个【流程结束】节点');
      }
      if (lineList.some(c => { return c.to == rootNode[0].id })) {
        return this.$message.error('不开始结点回连');
      }
      for (let index = 0; index < rootNode.length; index++) {
        const node = rootNode[index];
        node.OrderId = index;
        //这里有一节点有多个上级节点的时候数据重复了,比如线束节点
        lineList.filter(c => { return c.from == node.StepId }).forEach(c => {
          let item = nodeList.find(x => { return x.id == c.to });
          let _obj = rootNode.find(x => { return x.StepId === item.id });
          if (_obj) {
            _obj.ParentId.push(node.StepId);
          } else {
            rootNode.push({
              ParentId: [node.StepId], //父级id
              StepId: item.id,
              StepName: item.name,
              StepAttrType: item.type, //节点类型.start开始,end结束
              StepType: item.auditType,//审核类型,角色,用户,部门(这里后面考虑同时支持多个角色、用户、部门)
              //审核选择的值角色,用户,部门(这里后面考虑同时支持多个角色、用户、部门)
              StepValue: item.auditType == 1 ? item.userId.join(',') : (item.auditType == 2 ? item.roleId : item.deptId),
              AuditRefuse: item.auditRefuse,//审核未通过(返回上一节点,流程重新开始,流程结束)
              AuditBack: item.auditBack, //驳回(返回上一节点,流程重新开始,流程结束)
              AuditMethod: item.auditMethod,//审批方式(启用会签)
              SendMail: 0, //审核后发送邮件通知:
              Filters: item.filters
            })
          }
        });
        // rootNode.push(...data);
      }
      rootNode.forEach(item => {
        item.ParentId = item.ParentId.filter(x => { return x }).join(',');
        if (item.Filters && item.Filters.length) {
          item.Filters = item.Filters.map(m => {
            return {
              "field": m.field,
              filterType: m.filterType,
              value: Array.isArray(m.value) ? m.value.join(',') : m.value
            }
          });
          item.Filters =JSON.stringify(item.Filters)
        } else {
          item.Filters = null;
        }
      })
      for (let index = 0; index < rootNode.length; index++) {
        const step = rootNode[index];
        if (!step.StepName) {
          return this.$message.error(`请输入节点名称`);
        }
        if (step.StepAttrType == 'node' && !step.StepValue) {
          return this.$message.error(
            `请选择【${step.StepName}】的审批类型`
          );
        }
      }
      let params = {
        mainData: mainData,
        detailData: rootNode,
        delKeys: []
      };
      let url = 'api/Sys_WorkFlow/' + (!this.isAdd ? 'update' : 'add');
      this.http.post(url, params, true).then((result) => {
        if (!result.status) {
          return this.$message.error(result.message);
        }
        this.$message.success('保存成功');
        this.model = false;
        this.$emit('parentCall', ($parent) => {
          $parent.search();
        });
      });
    }
  },
}
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/system/flow/Sys_WorkFlowTable.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,103 @@
/*****************************************************************************************
 **  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文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
import gridHeader from '@/components/basic/ViewGrid/ViewGridAudit.vue'
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: gridHeader,
    gridBody: '',
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      //表格上添加自定义按钮
      this.columns.push({
        title: '操作',
        field: '操作',
        width: 120,
        align: 'center',
        render: (h, { row, column, index }) => {
          return (
            <div>
              <el-button
                onClick={($e) => {
                      this.$refs.gridHeader.open([row],true);
                }}
                type="primary"
                plain
                size="small"
                style="height:26px; padding: 10px !important;"
              >
                å®¡æ ¸
              </el-button>
              <el-button
                onClick={($e) => {
                  this.$tabs.open({
                    text: row.WorkTableName || row.WorkName,
                    path: '/' + row.WorkTable,
                    query: { id: row.WorkTableKey, viewflow: 1 }
                  });
                }}
                type="default"
                plain
                size="small"
                style="height:26px; padding: 10px !important;"
              >
                æŸ¥çœ‹
              </el-button>
            </div>
          )
        }
      });
    },
    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/WMS_Client/src/extension/system/form/FormCollectionObject.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
//author:jxx
//此处是对表单的方法,组件,权限操作按钮等进行任意扩展(方法扩展可参照SellOrder.js)
let extension = {
    components: {//动态扩充组件或组件路径
        //表单header、content、footer对应位置扩充的组件
        gridHeader: '',//{ template: "<div>扩展组xxä»¶</div>" },
        gridBody: '',
        gridFooter: '',
        //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
        modelHeader: '',
        modelBody: '',
        modelFooter: ''
    },
    text: "点击左侧表单名名字即可加载收集的数据",
    tableAction: "formCollectionResultTree",
    buttons: { view: [], box: [], detail: [] },//扩展的按钮
    methods: {//事件扩展
        onInit() {
            this.textInline = false;
            // this.ck = false;
            this.load = false;
            this.setFiexdSearchForm(true);
        },
        onInited() {
            this.height = this.height - 74;
        },
        loadById(item) {
            let columns = [
                {
                    title: "提交人",
                    field: "Creator"
                },
                {
                    title: "提交时间",
                    field: "CreateDate"
                }];
            JSON.parse(item.formOptions).formOptions.forEach(x => {
                columns.push(...x.map(m => {
                    return {
                        title: m.title,
                        field: m.field,
                        type: m.type
                    }
                }))
            })
            this.formId = item.formId;
            this.columns.splice(0);
            this.columns.push(...columns);
            this.search();
        },
        exportBefore(formData) {
            formData.Value = this.formId;
            return true;
        },
        searchBefore(formData) {
          //  formData.Value = this.formId;
            formData.wheres.push({name:'FormId',value:this.formId})
            return true;
        },
        searchAfter(rows) {
            rows.forEach(row => {
                if (row.FormData) {
                    let data = JSON.parse(row.FormData);
                    for (const key in data) {
                        row[key] = Array.isArray(data[key]) ? data[key].filter(x => { return x != null && x != undefined }).join(',') : data[key];
                    }
                }
            })
            return true;
        }
    }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/system/form/FormCollectionOptionsGridHeader.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
<template>
  <div>
    <VolBox
      :on-model-close="onModelClose"
      :lazy="true"
      v-model="model"
      title="表单设计"
      :height="height"
      :width="width"
      :padding="0"
    >
     <div :style="{height: height+'px'}">
      <VolFormDraggable
        ref="form"
        :showTips="false"
        style="height:500px"
        @save="save"
        :userComponents="userComponents"
      ></VolFormDraggable>
     </div>
      <template #footer>
        <el-button type="default" size="small" @click="model = false"
          >关闭</el-button
        >
      </template>
    </VolBox>
  </div>
</template>
    <script>
import VolFormDraggable from "@/components/basic/VolFormDraggable/index.js";
import VolBox from "@/components/basic/VolBox.vue";
export default {
  components: {
    VolBox,
    VolFormDraggable,
  },
  data() {
    return {
      height: 0,
      width: 0,
      model: false,
      userComponents: [],
      row: {},
    };
  },
  created() {
    this.width = document.body.clientWidth * 0.96;
    this.height = document.body.clientHeight * 0.9;
  },
  methods: {
    open(row) {
      if (row.DaraggeOptions && row.DaraggeOptions != "[]") {
        this.userComponents = JSON.parse(row.DaraggeOptions);
      } else {
        this.userComponents = [];
      }
      this.row = row;
      this.model = true;
    },
    onModelClose() {},
    save(options) {
      if (!options) {
        options = this.$refs.form.save();
      }
      this.row.DaraggeOptions = JSON.stringify(options.daraggeOptions);
      this.row.FormOptions = JSON.stringify(options.formOptions);
      let formConfig = [];
      options.formOptions.formOptions.forEach((item) => {
        formConfig.push(...item);
      });
      this.row.FormConfig = JSON.stringify(formConfig);
      this.row.TableConfig=JSON.stringify(options.formOptions.tables);
      this.http
        .post("api/FormDesignOptions/update", { mainData: this.row }, true)
        .then((x) => {
          if (!x.status) {
            this.$Message.error(x.message);
            return;
          }
          this.model = false;
        });
    },
  },
};
</script>
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/system/form/FormDesignOptions.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
//author:jxx
//此处是对表单的方法,组件,权限操作按钮等进行任意扩展(方法扩展可参照SellOrder.js)
import  gridHeader from './FormCollectionOptionsGridHeader.vue'
import { h, resolveComponent } from 'vue';
let extension = {
    components: {//动态扩充组件或组件路径
        //表单header、content、footer对应位置扩充的组件
        gridHeader:gridHeader,//{ template: "<div>扩展组xxä»¶</div>" },
        gridBody: {
            render() {
              return [
                h(resolveComponent('el-alert'), {
                  style: { 'margin-bottom': '12px' },
                  'show-icon': true, type: 'success',
                  closable: false, title: '1、点击新建随便输入,2、点击表格[表单设计]然后保存,3、点击预览(页面打开后提交数据),4、数据采集页面看查结果'
                }, ''),
              ]
            }
          },
        gridFooter: '',
        //弹出框(修改、编辑、查看)header、content、footer对应位置扩充的组件
        modelHeader: '',
        modelBody: '',
        modelFooter: ''
    },
    buttons: {view: [], box:[],  detail:[]},//扩展的按钮
    methods: {//事件扩展
        onInit() {
            this.boxOptions.height=200;
            this.initFormButton();
        },
        onInited(){
            this.height=  this.height-40;
        },
        initFormButton() {
            this.columns.splice(this.columns.findIndex(x => { return x.field == 'FormFields' }), 1, ...[{
                title: "操作",
                field: "表单设计",
                with: 80,
                sort: false,
                formatter: () => {
                    return '<a style="color: #3a8ee6;">表单设计</a>'
                },
                click: (row) => {
                    this.$refs.gridHeader.open(row);
                }
            },
             {
                title: "预览",
                field: "预览",
                with: 85,
                sort: false,
                formatter: () => {
                    return '<a style="color: #3a8ee6;">预览</a>'
                },
                click: (row) => {
                    this.$tabs.open({
                        path: "/formSubmit", text: row.Title, query: {
                            id: row.FormId
                        }
                    })
                    //  this.$refs.gridHeader.open(row);
                }
            }])
        }
    }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/system/quartz/Sys_QuartzLog.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
/*****************************************************************************************
 **  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: 'Sys_QuartzLog', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      //框架初始化配置前,
      //示例:在按钮的最前面添加一个按钮
      //   this.buttons.unshift({  //也可以用push或者splice方法来修改buttons数组
      //     name: '按钮', //按钮名称
      //     icon: 'el-icon-document', //按钮图标vue2版本见iview文档icon,vue3版本见element ui文档icon(注意不是element puls文档)
      //     type: 'primary', //按钮样式vue2版本见iview文档button,vue3版本见element ui文档button
      //     onClick: function () {
      //       this.$Message.success('点击了按钮');
      //     }
      //   });
      if (this.$route.path != '/Sys_QuartzLog') {
        this.tableHeight = 345;
      }
      //示例:设置修改新建、编辑弹出框字段标签的长度
      // this.boxOptions.labelWidth = 150;
    },
    onInited() {
      //框架初始化配置后
      //如果要配置明细表,在此方法操作
      //this.detailOptions.columns.forEach(column=>{ });
    },
    searchBefore(param) {
      //界面查询前,可以给param.wheres添加查询参数
      //返回false,则不会执行查询
      if (this.$route.path != '/Sys_QuartzLog') {
        param.wheres.push({
          name: 'Id',
          value: this.$store.getters.data().quartzId
        });
      }
      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/WMS_Client/src/extension/system/quartz/Sys_QuartzOptions.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,156 @@
/*****************************************************************************************
 **  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文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
import gridBody from './Sys_QuartzOptionsGridBody';
let extension = {
  components: {
    //查询界面扩展组件
    gridHeader: '',
    gridBody: gridBody,
    gridFooter: '',
    //新建、编辑弹出框扩展组件
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
  buttons: { view: [], box: [], detail: [] }, //扩展的按钮
  methods: {
    //下面这些方法可以保留也可以删除
    onInit() {
      this.textInline = false;
      this.columns.push({
        field: '操作',
        title: '操作',
        width: 150,
        fixed: 'right',
        align: 'center',
        render: (h, { row, column, index }) => {
          return h('div', { style: { color: '#0e84ff' } }, [
            h(
              'span',
              {
                style: {
                  cursor: 'pointer',
                  'margin-right': '8px',
                  'border-bottom': '1px solid'
                },
                onClick: (e) => {
                  this.request('start', row);
                }
              },
              '执行'
            ),
            h(
              'span',
              {
                style: {
                  cursor: 'pointer',
                  'margin-right': '8px',
                  'border-bottom': '1px solid'
                },
                onClick: (e) => {
                  this.request('pause', row);
                }
              },
              '暂停'
            ),
            h(
              'span',
              {
                style: {
                  cursor: 'pointer',
                  'border-bottom': '1px solid'
                },
                onClick: (e) => {
                  this.$store.getters.data().quartzId = row.Id;
                  this.$refs.gridBody.open();
                }
              },
              '日志'
            )
          ]);
        }
      });
      //示例:设置修改新建、编辑弹出框字段标签的长度
      // this.boxOptions.labelWidth = 150;
    },
    request(action, row) {
      let url = `api/Sys_QuartzOptions/${action}`;
      this.http.post(url, row, true).then((result) => {
        this.$message.success('执行成功');
        this.search();
      });
    },
    onInited() {
      this.height= this.height-50;
      this.columns.forEach((col) => {
        if (col.field == 'Status') {
          col.align = 'center';
          col.formatter = (row) => {
            //  return row.Status;
            if (row.Status == 1) {
              return '<a style="color:red;"><span style="display: inline-block;padding: 4px;background: red; border-radius: 50%; margin-right: 5px;"></span>暂停</a>';
            }
            return '<a style="color:#04b348;"><span style="display: inline-block;padding: 4px;background: #20c423; border-radius: 50%; margin-right: 5px;"></span>正常</a>';
          };
        }
      });
      //框架初始化配置后
      //如果要配置明细表,在此方法操作
      //this.detailOptions.columns.forEach(column=>{ });
      this.editFormOptions.forEach((options) => {
        options.forEach((option) => {
          if (option.field == 'CronExpression') {
            option.extra = {
              style: 'color: #0e84ff;cursor: pointer;',
              text: '查看',
              click: () => {
                window.open('https://cron.qqe2.com/', '_blank');
              }
            };
          }
        });
      });
    },
    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) {
      if (this.currentAction == 'Add' || !this.editFormFields.TimeOut) {
        this.editFormFields.TimeOut = 180;
      }
      this.editFormOptions.forEach((options) => {
        options.forEach((option) => {
          if (option.field == 'GroupName') {
            option.readonly = this.currentAction != 'Add';
          }
        });
      });
    }
  }
};
export default extension;
´úÂë¹ÜÀí/WMS/WMS_Client/src/extension/system/quartz/Sys_QuartzOptionsGridBody.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
<template>
  <vol-box
    :lazy="true"
    v-model="model"
    title="执行日志"
    :height="500"
    :width="1200"
    :padding="0"
  >
    <QuartzLog ref="log"></QuartzLog>
    <template #footer>
      <div>
        <el-button type="default" size="mini" @click="model = false"
          >关闭</el-button
        >
      </div></template
    >
  </vol-box>
  <el-alert style="margin-bottom:10px;" :show-icon="false" type="success">
    å®šæ—¶ä»»åŠ¡åªæœ‰å‘å¸ƒåŽæ‰ä¼šè¿è¡Œ(本地不会执行),<a
      style="color:#2d8cf0;margin-left:20px;"
      target="blank"
      href="http://v2.volcore.xyz/document/netCoreDev"
      >查看配置文档</a
    >
    <a
      style="color:#2d8cf0;margin-left:20px;"
      target="blank"
      href="http://v2.volcore.xyz/document/log"
      >查看更新方式</a
    >
  </el-alert>
</template>
<script>
import VolBox from '@/components/basic/VolBox.vue';
import QuartzLog from '@/views/system/quartz/Sys_QuartzLog';
//这里使用的vue2语法,也可以写成vue3语法
export default {
  components: { 'vol-box': VolBox, QuartzLog },
  methods: {},
  data() {
    return {
      model: false
    };
  },
  methods: {
    open() {
      this.model = true;
      this.$nextTick(() => {
        this.$refs.log.$refs.grid.search();
      });
    }
  }
};
</script>
在上述文件截断后对比
代码管理/WMS/WMS_Client/src/extension/system/system/Sys_Department.js 代码管理/WMS/WMS_Client/src/extension/widesea_system/system/dt_log.js 代码管理/WMS/WMS_Client/src/extension/widesea_wms/system/base_routing_table.js 代码管理/WMS/WMS_Client/src/extension/widesea_wms/system/dt_stationinfo.js 代码管理/WMS/WMS_Client/src/main.js 代码管理/WMS/WMS_Client/src/router/charts.js 代码管理/WMS/WMS_Client/src/router/form.js 代码管理/WMS/WMS_Client/src/router/formsMulti.js 代码管理/WMS/WMS_Client/src/router/index.js 代码管理/WMS/WMS_Client/src/router/redirect.js 代码管理/WMS/WMS_Client/src/router/tables.js 代码管理/WMS/WMS_Client/src/router/viewGird.js 代码管理/WMS/WMS_Client/src/store/index.js 代码管理/WMS/WMS_Client/src/uitils/common.js 代码管理/WMS/WMS_Client/src/views/Home.vue 代码管理/WMS/WMS_Client/src/views/Index.vue 代码管理/WMS/WMS_Client/src/views/Login.vue 代码管理/WMS/WMS_Client/src/views/Task/widesea_wms/taskinfo/dt_agvtask.vue 代码管理/WMS/WMS_Client/src/views/Task/widesea_wms/taskinfo/dt_agvtask_hty.vue 代码管理/WMS/WMS_Client/src/views/appmanager/App_Expert.vue 代码管理/WMS/WMS_Client/src/views/appmanager/App_Expert2.vue 代码管理/WMS/WMS_Client/src/views/appmanager/App_News.vue 代码管理/WMS/WMS_Client/src/views/appmanager/App_NewsEditor.vue 代码管理/WMS/WMS_Client/src/views/appmanager/App_ReportPrice.vue 代码管理/WMS/WMS_Client/src/views/appmanager/App_Transaction.vue 代码管理/WMS/WMS_Client/src/views/appmanager/App_Transaction2.vue 代码管理/WMS/WMS_Client/src/views/appmanager/App_TransactionAvgPrice.vue 代码管理/WMS/WMS_Client/src/views/builder/builderData.js 代码管理/WMS/WMS_Client/src/views/builder/coder.vue 代码管理/WMS/WMS_Client/src/views/charts/bigdata.vue 代码管理/WMS/WMS_Client/src/views/charts/bigdata/IviewCircle.vue 代码管理/WMS/WMS_Client/src/views/charts/bigdata/chart-options.js 代码管理/WMS/WMS_Client/src/views/charts/bigdata/head_bg.png 代码管理/WMS/WMS_Client/src/views/charts/bigdata/layout.less 代码管理/WMS/WMS_Client/src/views/charts/chart.vue 代码管理/WMS/WMS_Client/src/views/charts/chartOptions.js 代码管理/WMS/WMS_Client/src/views/charts/flex.vue 代码管理/WMS/WMS_Client/src/views/charts/formChart.vue 代码管理/WMS/WMS_Client/src/views/charts/formOptions.js 代码管理/WMS/WMS_Client/src/views/extension/widesea_wms/taskinfo/dt_agvtask.js 代码管理/WMS/WMS_Client/src/views/extension/widesea_wms/taskinfo/dt_agvtask_hty.js 代码管理/WMS/WMS_Client/src/views/formDraggable/FormCollectionResultTree.vue 代码管理/WMS/WMS_Client/src/views/formDraggable/FormSubmit.vue 代码管理/WMS/WMS_Client/src/views/formDraggable/formDraggable.vue 代码管理/WMS/WMS_Client/src/views/forms/editTable.vue 代码管理/WMS/WMS_Client/src/views/forms/form.vue 代码管理/WMS/WMS_Client/src/views/forms/form1.vue 代码管理/WMS/WMS_Client/src/views/forms/form2.vue 代码管理/WMS/WMS_Client/src/views/forms/form3.vue 代码管理/WMS/WMS_Client/src/views/forms/form4.vue 代码管理/WMS/WMS_Client/src/views/forms/form5.vue 代码管理/WMS/WMS_Client/src/views/forms/form6.vue 代码管理/WMS/WMS_Client/src/views/forms/form7.vue 代码管理/WMS/WMS_Client/src/views/forms/objectValidator.vue 代码管理/WMS/WMS_Client/src/views/forms/table.vue 代码管理/WMS/WMS_Client/src/views/formsMulti/multi1.vue 代码管理/WMS/WMS_Client/src/views/formsMulti/multi2.vue 代码管理/WMS/WMS_Client/src/views/formsMulti/multi3.vue 代码管理/WMS/WMS_Client/src/views/formsMulti/multil1Extension/multi1.js 代码管理/WMS/WMS_Client/src/views/formsMulti/multil1Extension/table1.vue 代码管理/WMS/WMS_Client/src/views/formsMulti/multil2Extension/mtable.vue 代码管理/WMS/WMS_Client/src/views/formsMulti/multil2Extension/multi2.js 代码管理/WMS/WMS_Client/src/views/formsMulti/multil3Extension/comMulti.vue 代码管理/WMS/WMS_Client/src/views/formsMulti/multil3Extension/multi3.js 代码管理/WMS/WMS_Client/src/views/h5/Guide.vue 代码管理/WMS/WMS_Client/src/views/home/home-chart-options.js 代码管理/WMS/WMS_Client/src/views/html/Editor.vue 代码管理/WMS/WMS_Client/src/views/html/List.vue 代码管理/WMS/WMS_Client/src/views/index/Message.vue 代码管理/WMS/WMS_Client/src/views/index/MessageConfig.js 代码管理/WMS/WMS_Client/src/views/index/index.less 代码管理/WMS/WMS_Client/src/views/order/App_Appointment.vue 代码管理/WMS/WMS_Client/src/views/order/App_Appointment2.vue 代码管理/WMS/WMS_Client/src/views/order/SellOrder.vue 代码管理/WMS/WMS_Client/src/views/order/SellOrder2.vue 代码管理/WMS/WMS_Client/src/views/order/SellOrder3.vue 代码管理/WMS/WMS_Client/src/views/order/vSellOrderImg.vue 代码管理/WMS/WMS_Client/src/views/router/viewGird.js 代码管理/WMS/WMS_Client/src/views/signalR/Index.vue 代码管理/WMS/WMS_Client/src/views/system/Permission.vue 代码管理/WMS/WMS_Client/src/views/system/Permission/RoleTree.vue 代码管理/WMS/WMS_Client/src/views/system/Sys_Dictionary.vue 代码管理/WMS/WMS_Client/src/views/system/Sys_DictionaryList.vue 代码管理/WMS/WMS_Client/src/views/system/Sys_Log.vue 代码管理/WMS/WMS_Client/src/views/system/Sys_Menu.vue 代码管理/WMS/WMS_Client/src/views/system/Sys_Role.vue 代码管理/WMS/WMS_Client/src/views/system/Sys_Role1.vue 代码管理/WMS/WMS_Client/src/views/system/Sys_User.vue 代码管理/WMS/WMS_Client/src/views/system/UserInfo.vue 代码管理/WMS/WMS_Client/src/views/system/flow/FlowDemo.vue 代码管理/WMS/WMS_Client/src/views/system/flow/Sys_WorkFlow.vue 代码管理/WMS/WMS_Client/src/views/system/flow/Sys_WorkFlowTable.vue 代码管理/WMS/WMS_Client/src/views/system/form/FormCollectionObject.vue 代码管理/WMS/WMS_Client/src/views/system/form/FormDesignOptions.vue 代码管理/WMS/WMS_Client/src/views/system/quartz/Sys_QuartzLog.vue 代码管理/WMS/WMS_Client/src/views/system/quartz/Sys_QuartzOptions.vue 代码管理/WMS/WMS_Client/src/views/system/system/Sys_Department.vue 代码管理/WMS/WMS_Client/src/views/system/test.vue 代码管理/WMS/WMS_Client/src/views/tables/table2.vue 代码管理/WMS/WMS_Client/src/views/tables/table3.vue 代码管理/WMS/WMS_Client/src/views/tables/tableForms.js 代码管理/WMS/WMS_Client/src/views/tables/tableForms.vue 代码管理/WMS/WMS_Client/src/views/tables/tableFormsViewGrid.js 代码管理/WMS/WMS_Client/src/views/tables/tabsTable.vue 代码管理/WMS/WMS_Client/src/views/treeTable/TreeTable1.vue 代码管理/WMS/WMS_Client/src/views/treeTable/TreeTable2.vue 代码管理/WMS/WMS_Client/src/views/treeTable/TreeTable3.vue 代码管理/WMS/WMS_Client/src/views/treeTable/demo1/Table.vue 代码管理/WMS/WMS_Client/src/views/treeTable/demo1/Tree.vue 代码管理/WMS/WMS_Client/src/views/treeTable/demo1/table.js 代码管理/WMS/WMS_Client/src/views/treeTable/demo2/Table2.vue 代码管理/WMS/WMS_Client/src/views/treeTable/demo2/Tree2.vue 代码管理/WMS/WMS_Client/src/views/treeTable/demo2/tree_options.js 代码管理/WMS/WMS_Client/src/views/upload/formUpload.vue 代码管理/WMS/WMS_Client/src/views/upload/volUploadExample.vue 代码管理/WMS/WMS_Client/src/views/widesea_system/dialog/logDetial.vue 代码管理/WMS/WMS_Client/src/views/widesea_system/system/dt_log.vue 代码管理/WMS/WMS_Client/src/views/widesea_wms/system/base_routing_table.vue 代码管理/WMS/WMS_Client/src/views/widesea_wms/system/dt_stationinfo.vue 代码管理/WMS/WMS_Client/tests/unit/example.spec.js 代码管理/WMS/WMS_Client/vue.config.js 代码管理/WMS/WMS_Client/yarn.lock 代码管理/WMS/WMS_Server/.dockerignore 代码管理/WMS/WMS_Server/.gitattributes 代码管理/WMS/WMS_Server/.gitignore 代码管理/WMS/WMS_Server/Dockerfile 代码管理/WMS/WMS_Server/WIDESEA_Builder/IRepositories/Core/ISys_TableInfoRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_Builder/IServices/Core/ISys_TableInfoService.cs 代码管理/WMS/WMS_Server/WIDESEA_Builder/IServices/Core/Partial/ISys_TableInfoService.cs 代码管理/WMS/WMS_Server/WIDESEA_Builder/Properties/launchSettings.json 代码管理/WMS/WMS_Server/WIDESEA_Builder/Repositories/Core/Sys_TableInfoRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_Builder/Services/Core/Partial/Sys_TableInfoService.cs 代码管理/WMS/WMS_Server/WIDESEA_Builder/Services/Core/Sys_TableInfoService.cs 代码管理/WMS/WMS_Server/WIDESEA_Builder/Utility/ProjectPath.cs 代码管理/WMS/WMS_Server/WIDESEA_Builder/WIDESEA_Builder.csproj 代码管理/WMS/WMS_Server/WIDESEA_Comm/DataHandle/DataParse.cs 代码管理/WMS/WMS_Server/WIDESEA_Comm/DataHandle/OperateDB.cs 代码管理/WMS/WMS_Server/WIDESEA_Comm/Http/HttpHelper.cs 代码管理/WMS/WMS_Server/WIDESEA_Comm/LogInfo/WriteDBLog.cs 代码管理/WMS/WMS_Server/WIDESEA_Comm/LogInfo/WriteLog.cs 代码管理/WMS/WMS_Server/WIDESEA_Comm/WIDESEA_Comm.csproj 代码管理/WMS/WMS_Server/WIDESEA_Core/BaseInterface/IServices.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/DictionaryComponent/DictionaryViewComponent.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/IRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/IService.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/RepositoryBase.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/ServerMapPath/PathProvider.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/BaseProvider/ServiceBase.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/CacheManager/IService/ICacheService.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/CacheManager/Service/MemoryCacheService .cs 代码管理/WMS/WMS_Server/WIDESEA_Core/CacheManager/Service/RedisCacheService.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Configuration/AppSetting.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Const/ApplicationContentType.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Const/DataBaseType.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Const/HtmlElementType.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Const/Secret.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Const/SqlDbTypeName.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Controllers/Basic/ApiBaseController.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Controllers/Basic/BaseController.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Controllers/Basic/WebBaseController.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/DBManager/DBConnectionAttribute.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/DBManager/DBServerProvider.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/DBManager/DbName.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/DBManager/Partial/DBServerProvider.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Dapper/DapperParseGuidTypeHandler.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Dapper/ISqlDapper.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Dapper/SqlDapper.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/EFDbContext/EFLoggerProvider.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/EFDbContext/VOLContext.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/ActionPermissionOptions.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/ApiMessage.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/ApiStatutsCode.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/CPrefix.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/DbCurrentType.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/LinqExpressionType.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/LoggerType.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/QueryOrderBy.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/ResponseType.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Enums/UserAgent.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/AuthorizationResponse.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/AutofacManager/AutofacContainerModule.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/AutofacManager/AutofacContainerModuleExtension.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/AutofacManager/IDependency.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/CacheKeyExtensions.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/ConvertJsonExtension.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/EntityProperties.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/GenericExtension.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/HtmlHelperViewExtensions.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/LambdaExtensions.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/ObjectExtension.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/RequestExtension.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/Response/ResponseMsg.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/SecurityEncDecryptExtension.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/ServerExtension.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/ServiceProviderManagerExtension.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/StaticFileExtensions.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/StaticHttpContextExtensions.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Extensions/StringExtension.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ActionExecuteFilter.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ActionPermissionAttribute.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ActionPermissionFilter.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ActionPermissionRequirement.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ApiActionPermissionAttribute.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ApiAuthorizeFilter.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/FixedTokenAttribute.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/JWTAuthorize.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Filters/ServiceFunFilter.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/FreeDB/FreeDB.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Infrastructure/DictionaryHandler.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Infrastructure/DictionaryManager.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Middleware/ExceptionHandlerMiddleWare.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Middleware/HttpRequestMiddleware.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/ModelBinder/BaseBinderProvider.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/ModelBinder/BaseModelBinder.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/ModelBinder/BinderObject.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/ExpressValidator/GeneralOptions.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/ExpressValidator/MethodsValidator.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/ExpressValidator/ObjectModelValidatorState.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/Filters/ObjectGeneralValidatorFilter.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/Filters/ObjectModelValidatorFilter.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/NullObjectModelValidator.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/ObjectActionValidator/ValidationContainer.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Properties/launchSettings.json 代码管理/WMS/WMS_Server/WIDESEA_Core/Services/ActionExecutingLogger.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Services/Logger.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Tenancy/TenancyManager.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/UserManager/DepartmentContext.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/UserManager/RoleContext.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/UserManager/UserContext.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/ApiAuthorizeRequire.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/DateTimeExtension.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/DateTimeHelper.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/DynamicPropertyBag .cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/EPPlusHelper.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/FileHelper.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/HttpContext.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/HttpManager.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/JwtHelper.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/MailHelper.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/NPOIHelper.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/PDFHelper/IPDFService.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/PDFHelper/PDFService.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/Response/FilterResponse.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/Response/WebResponseContent.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/SecurityEncDecrypt.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/VierificationCode.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/VierificationCodeHelpers.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/VierificationCodeServices.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/Utilities/XmlHelper.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/WIDESEA_Core.csproj 代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/AuditBack.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/AuditRefuse.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/AuditStatus.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/FieldFilter.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/StepType.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/WorkFlowContainer.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/WorkFlowFilter.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/WorkFlowManager.cs 代码管理/WMS/WMS_Server/WIDESEA_Core/WorkFlow/WorkFlowTableOptions.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/AttributeManager/EntityAttribute.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/AttributeManager/PermissionTableAttribute.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/BaseCore/MappingManager.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/ApiEntity/Input/ApiSys_UserInput.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/ApiEntity/OutPut/ApiSys_UserOutput.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Core/LoadSingleDataModel.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Core/PageGridData.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Core/SaveDataModel.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Core/Sys_TableColumn.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Core/Sys_TableInfo.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/LoginInfo.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Permissions.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/RoleAuthor.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_Department.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_Dictionary.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_DictionaryList.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_Log.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_Menu.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_Role.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_RoleAuth.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_User.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/Sys_UserDepartment.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/TableColumnInfo.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/UserInfo.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/base_routing_table.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/dt_log.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/dt_stationinfo.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/Sys_Department.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/Sys_User.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/Sys_UserDepartment.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/base_routing_table.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/dt_log.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/partial/dt_stationinfo.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/System/vSys_Dictionary.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Taskinfo/dt_agvtask.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Taskinfo/dt_agvtask_hty.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Taskinfo/partial/dt_agvtask.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/Taskinfo/partial/dt_agvtask_hty.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/Sys_WorkFlow.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/Sys_WorkFlowStep.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/Sys_WorkFlowTable.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/Sys_WorkFlowTableAuditLog.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/Sys_WorkFlowTableStep.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/partial/Sys_WorkFlow.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/partial/Sys_WorkFlowStep.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/partial/Sys_WorkFlowTable.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/partial/Sys_WorkFlowTableAuditLog.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/DomainModels/flow/partial/Sys_WorkFlowTableStep.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/MappingManager.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_DepartmentMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_DictionaryListMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_DictionaryMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_LogMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_MenuMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_RoleMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_UserDepartmentMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/Sys_UserMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/base_routing_tableMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/dt_logMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/dt_stationinfoMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/System/vSys_DictionaryMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/Taskinfo/dt_agvtaskMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/Taskinfo/dt_agvtask_htyMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/flow/Sys_WorkFlowMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/flow/Sys_WorkFlowStepMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/flow/Sys_WorkFlowTableAuditLogMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/flow/Sys_WorkFlowTableMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/MappingConfiguration/flow/Sys_WorkFlowTableStepMapConfig.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/SystemModels/BaseEntity.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/SystemModels/Sys_MenuRole.cs 代码管理/WMS/WMS_Server/WIDESEA_Entity/WIDESEA_Entity.csproj 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_DepartmentRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_DictionaryListRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_DictionaryRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_LogRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_MenuRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_RoleRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/ISys_UserRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/Idt_logRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/System/IvSys_DictionaryRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/flow/ISys_WorkFlowRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/flow/ISys_WorkFlowStepRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/flow/ISys_WorkFlowTableAuditLogRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/flow/ISys_WorkFlowTableRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IRepositories/flow/ISys_WorkFlowTableStepRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_DepartmentService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_DictionaryListService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_DictionaryService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_LogService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_MenuService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_RoleService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/ISys_UserService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Idt_logService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/IvSys_DictionaryService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_DepartmentService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_DictionaryListService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_DictionaryService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_MenuService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_RoleService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/ISys_UserService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/System/Partial/Idt_logService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/ISys_WorkFlowService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/ISys_WorkFlowStepService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/ISys_WorkFlowTableAuditLogService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/ISys_WorkFlowTableService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/ISys_WorkFlowTableStepService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/Partial/ISys_WorkFlowService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/Partial/ISys_WorkFlowStepService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/Partial/ISys_WorkFlowTableAuditLogService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/Partial/ISys_WorkFlowTableService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/IServices/flow/Partial/ISys_WorkFlowTableStepService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Properties/launchSettings.json 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Partial/Sys_MenuRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_DepartmentRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_DictionaryListRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_DictionaryRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_LogRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_MenuRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_RoleRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/Sys_UserRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/dt_logRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/System/vSys_DictionaryRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/flow/Sys_WorkFlowRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/flow/Sys_WorkFlowStepRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/flow/Sys_WorkFlowTableAuditLogRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/flow/Sys_WorkFlowTableRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Repositories/flow/Sys_WorkFlowTableStepRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_DepartmentService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_DictionaryListService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_DictionaryService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_MenuService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_RoleService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/Sys_UserService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Partial/dt_logService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_DepartmentService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_DictionaryListService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_DictionaryService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_LogService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_MenuService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_RoleService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/Sys_UserService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/dt_logService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/System/vSys_DictionaryService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Partial/Sys_WorkFlowService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Partial/Sys_WorkFlowStepService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Partial/Sys_WorkFlowTableAuditLogService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Partial/Sys_WorkFlowTableService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Partial/Sys_WorkFlowTableStepService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Sys_WorkFlowService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Sys_WorkFlowStepService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Sys_WorkFlowTableAuditLogService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Sys_WorkFlowTableService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/Services/flow/Sys_WorkFlowTableStepService.cs 代码管理/WMS/WMS_Server/WIDESEA_System/WIDESEA_System.csproj 代码管理/WMS/WMS_Server/WIDESEA_WMS/IRepositories/Taskinfo/Idt_agvtaskRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IRepositories/Taskinfo/Idt_agvtask_htyRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IRepositories/system/Ibase_routing_tableRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IRepositories/system/Idt_stationinfoRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/Taskinfo/Idt_agvtaskService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/Taskinfo/Idt_agvtask_htyService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/Taskinfo/Partial/Idt_agvtaskService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/Taskinfo/Partial/Idt_agvtask_htyService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/system/Ibase_routing_tableService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/system/Idt_stationinfoService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/system/Partial/Ibase_routing_tableService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/IServices/system/Partial/Idt_stationinfoService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Repositories/Taskinfo/dt_agvtaskRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Repositories/Taskinfo/dt_agvtask_htyRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Repositories/system/base_routing_tableRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Repositories/system/dt_stationinfoRepository.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/Taskinfo/Partial/dt_agvtaskService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/Taskinfo/Partial/dt_agvtask_htyService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/Taskinfo/dt_agvtaskService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/Taskinfo/dt_agvtask_htyService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/system/Partial/base_routing_tableService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/system/Partial/dt_stationinfoService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/system/base_routing_tableService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/Services/system/dt_stationinfoService.cs 代码管理/WMS/WMS_Server/WIDESEA_WMS/WIDESEA_WMS.csproj 代码管理/WMS/WMS_Server/WIDESEA_WMSServe.sln 代码管理/WMS/WMS_Server/WIDESEA_WebApi/.config/dotnet-tools.json 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/ApiHomeController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/Builder/BuilderController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_DepartmentController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_DictionaryController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_DictionaryListController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_MenuController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_RoleController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_UserController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_WorkFlowController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_WorkFlowStepController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_WorkFlowTableAuditLogController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_WorkFlowTableController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Partial/Sys_WorkFlowTableStepController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_DepartmentController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_DictionaryController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_DictionaryListController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_LogController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_MenuController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_RoleController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_UserController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_WorkFlowController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_WorkFlowStepController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_WorkFlowTableAuditLogController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_WorkFlowTableController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/System/Sys_WorkFlowTableStepController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_System/Partial/dt_logController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_System/dt_logController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/Partial/base_routing_tableController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/Partial/dt_agvtaskController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/Partial/dt_agvtask_htyController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/Partial/dt_stationinfoController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/base_routing_tableController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/dt_agvtaskController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/dt_agvtask_htyController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Controllers/WIDESEA_WMS/dt_stationinfoController.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Dockerfile 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/20231208/Template/AGV任务20231208134657.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/20231208/Template/AGV任务20231208170607.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/20231208/Template/AGV任务20231208171603.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/20231208/Template/AGV任务20231208173403.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/20231208/Template/AGV任务20231208175204.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV任务20231208150437.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV任务20231208152432.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV任务20231208172503.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV任务20231208173004.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208154331.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208161840.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208162251.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208163634.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208163750.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Download/ExcelExport/20231208/AGV历史任务20231208165240.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Program.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Properties/launchSettings.json 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Startup.cs 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/AppHtml/news.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/AppHtml/productDesc.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Controller/Controller.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Controller/ControllerApi.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Controller/ControllerApiPartial.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Controller/ControllerPartial.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/DomianModel/ApiInputDomainModel.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/DomianModel/ApiOutputDomainModel.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/DomianModel/DomainModel.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/DomianModel/MappingConfiguration.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/IRepositorys/BaseIRepositorie.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/IServices/IServiceBase.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/IServices/IServiceBasePartial.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/SearchPage.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/Vue3SearchPage.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/VueExtension.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/VueSearchPage.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/app/extension.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/app/options.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/app/page.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/gridParameters.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Page/router.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Repositorys/BaseRepository.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Repositorys/BaseRepositoryPartial.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Services/ServiceBase.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Template/Services/ServiceBasePartial.html 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Upload/20231208/dt_agvtask/0a1819d1-6d55-44ba-b7c0-0a3e677cf62d_21KH231 苏州冠鸿 荆门亿纬H5项目软件系统任务-2022.11.10.xlsx 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Upload/20231208/dt_agvtask/147d9561-ba54-43dc-928a-2e5de0a05679_2014Z211-XM0603-1-BOM表-签字版.xls 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Upload/20231208/dt_agvtask/7449d43d-6d90-4e81-b6ef-81237b91e2e4_TSW449_3_103_PAR.SPF 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Upload/20231208/dt_agvtask/bae36617-a982-4c7b-a4db-2cfd08143f08_TSW449_3_C2_S2.SPF 代码管理/WMS/WMS_Server/WIDESEA_WebApi/Upload/20231208/dt_agvtask/ce28a3b3-1880-4c25-9bc6-46081bb66514_TSW449_3_103_PAR.SPF 代码管理/WMS/WMS_Server/WIDESEA_WebApi/WIDESEA_WebApi.csproj 代码管理/WMS/WMS_Server/WIDESEA_WebApi/appsettings.Development.json 代码管理/WMS/WMS_Server/WIDESEA_WebApi/appsettings.json 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/App_News/202204200018378581/img02.png 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/App_Transaction/202204172225478035/img03.png 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/App_Transaction/202204172225587342/img01.png 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/App_Transaction/202204172226012098/img04.png 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/Sys_User/202204130014502760/2.png 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/Upload/Tables/Sys_User/202307110945105304/Default.jpg.jpeg 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/css/site.css 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/favicon.ico 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/js/site.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/LICENSE 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap.css 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation/LICENSE.md 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation/dist/additional-methods.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation/dist/additional-methods.min.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation/dist/jquery.validate.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery/LICENSE.txt 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery/dist/jquery.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery/dist/jquery.min.js 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/lib/jquery/dist/jquery.min.map 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/test.txt 代码管理/WMS/WMS_Server/WIDESEA_WebApi/wwwroot/新建文本文档.txt