From c1c49429ce1e22757190bd5c19cded888ec3ec56 Mon Sep 17 00:00:00 2001 From: XinanXf <959700191@qq.com> Date: Wed, 11 Jun 2025 11:15:51 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9D=92=E7=9F=B3-=E5=8A=9E=E5=85=AC=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=90=8E=E5=8F=B0=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 46 + .mvn/wrapper/MavenWrapperDownloader.java | 117 ++ .mvn/wrapper/maven-wrapper.jar | Bin 0 -> 50710 bytes .mvn/wrapper/maven-wrapper.properties | 2 + README.md | 0 doc/trans_new_漫画翻译数据库文档_1.0.html | 1 + pom.xml | 275 +++ src/main/java/com/soft/SoftApplication.java | 23 + .../com/soft/annotations/HasPermission.java | 23 + .../java/com/soft/annotations/NotNull.java | 13 + src/main/java/com/soft/annotations/Valid.java | 10 + .../java/com/soft/aop/PermissionAspect.java | 83 + src/main/java/com/soft/bo/SuperBo.java | 4 + .../bo/purchase/QueryPurchaseOrderBo.java | 58 + .../com/soft/bo/sale/QuerySaleOrderBo.java | 59 + .../common/constants/ResponseConstants.java | 21 + .../com/soft/common/constants/StringPool.java | 9 + .../com/soft/common/functions/SFunction.java | 8 + .../com/soft/common/security/UserDetails.java | 21 + .../java/com/soft/common/util/DateUtils.java | 21 + .../security/PermissionCalcType.java | 10 + src/main/java/com/soft/config/BeanConfig.java | 17 + .../com/soft/config/DateConverterConfig.java | 64 + .../java/com/soft/config/DruidConfig.java | 69 + .../java/com/soft/config/RedisConfig.java | 121 ++ .../java/com/soft/config/SecurityConfig.java | 40 + .../java/com/soft/config/SwaggerConfig.java | 77 + .../soft/config/TransDataSourceConfig.java | 27 + .../soft/config/UnifiedResultErrorConfig.java | 16 + .../com/soft/config/WebConfiguration.java | 29 + .../com/soft/controller/AgentController.java | 52 + .../com/soft/controller/BaseController.java | 31 + .../controller/PurchaseOrderController.java | 115 ++ .../soft/controller/SaleOrderController.java | 130 ++ .../com/soft/controller/SoftController.java | 39 + .../com/soft/controller/UserController.java | 103 ++ .../soft/controller/VoiceQueryController.java | 192 ++ .../com/soft/dto/ApprovePassOrderDTO.java | 18 + src/main/java/com/soft/dto/BaseDto.java | 4 + .../java/com/soft/dto/BindPhoneNumberDTO.java | 21 + .../java/com/soft/dto/OrderProportionDto.java | 11 + src/main/java/com/soft/dto/PageUtilDTO.java | 14 + src/main/java/com/soft/dto/SaveDemandDTO.java | 51 + .../soft/dto/StatisticsProductStockDto.java | 14 + src/main/java/com/soft/dto/SysUserDTO.java | 91 + src/main/java/com/soft/dto/UserIdDTO.java | 11 + src/main/java/com/soft/dto/VoiceQueryDto.java | 9 + .../com/soft/dto/WeChatLoginRequestDTO.java | 17 + .../java/com/soft/entitys/BaseEntity.java | 35 + .../java/com/soft/entitys/OrderChart.java | 55 + .../java/com/soft/entitys/OrderPayType.java | 47 + src/main/java/com/soft/entitys/Page.java | 119 ++ .../java/com/soft/entitys/QueryParams.java | 18 + .../java/com/soft/entitys/demand/Demand.java | 56 + .../entitys/purchase/PurchaseOrderStatus.java | 4 + .../entitys/sale/SaleOrderDetailBundle.java | 77 + .../java/com/soft/entitys/sys/SysMenu.java | 148 ++ .../com/soft/entitys/sys/SysRoleMenu.java | 36 + .../com/soft/entitys/sys/SysUserRole.java | 34 + .../java/com/soft/entitys/user/Agent.java | 35 + .../java/com/soft/entitys/user/Category.java | 31 + .../com/soft/entitys/user/SystemUser.java | 36 + src/main/java/com/soft/entitys/user/User.java | 50 + .../java/com/soft/entitys/voice/Customer.java | 136 ++ .../java/com/soft/entitys/voice/Product.java | 117 ++ .../com/soft/entitys/voice/ProductStock.java | 50 + .../soft/entitys/voice/ProductStockLog.java | 94 + .../com/soft/entitys/voice/PurchaseOrder.java | 135 ++ .../entitys/voice/PurchaseOrderDetail.java | 71 + .../soft/entitys/voice/PurchaseReturn.java | 128 ++ .../entitys/voice/PurchaseReturnDetail.java | 72 + .../com/soft/entitys/voice/SaleOrder.java | 155 ++ .../soft/entitys/voice/SaleOrderDetail.java | 102 + .../com/soft/entitys/voice/SaleOutSheet.java | 120 ++ .../entitys/voice/SaleOutSheetDetail.java | 99 + .../soft/entitys/voice/SettleCheckSheet.java | 148 ++ .../entitys/voice/SettleCheckSheetDetail.java | 64 + .../com/soft/entitys/voice/SettleSheet.java | 121 ++ .../soft/entitys/voice/SettleSheetDetail.java | 57 + .../com/soft/entitys/voice/StoreCenter.java | 108 ++ .../java/com/soft/entitys/voice/Supplier.java | 164 ++ src/main/java/com/soft/enums/AuthEnum.java | 24 + src/main/java/com/soft/enums/CommEnum.java | 29 + .../com/soft/enums/OrderChartBizType.java | 30 + src/main/java/com/soft/enums/OrderStatus.java | 39 + src/main/java/com/soft/enums/ProductType.java | 27 + src/main/java/com/soft/enums/QueryType.java | 24 + .../enums/system/SysMenuComponentType.java | 27 + .../com/soft/enums/system/SysMenuDisplay.java | 27 + .../events/order/ApprovePassOrderEvent.java | 57 + .../impl/ApprovePassPurchaseOrderEvent.java | 18 + .../impl/ApprovePassPurchaseReturnEvent.java | 18 + .../impl/ApprovePassRetailOutSheetEvent.java | 18 + .../impl/ApprovePassRetailReturnEvent.java | 17 + .../order/impl/ApprovePassSaleOrderEvent.java | 18 + .../impl/ApprovePassSaleReturnEvent.java | 18 + .../java/com/soft/filter/CrossFilter.java | 196 ++ .../com/soft/listeners/OrderDataListener.java | 60 + .../java/com/soft/mapper/AgentMapper.java | 18 + .../java/com/soft/mapper/CategoryMapper.java | 13 + .../java/com/soft/mapper/CustomerMapper.java | 13 + .../java/com/soft/mapper/DemandMapper.java | 10 + .../com/soft/mapper/OrderChartMapper.java | 8 + .../com/soft/mapper/OrderPayTypeMapper.java | 12 + .../java/com/soft/mapper/ProductMapper.java | 18 + .../soft/mapper/ProductStockLogMapper.java | 15 + .../com/soft/mapper/ProductStockMapper.java | 22 + .../mapper/PurchaseOrderDetailMapper.java | 14 + .../com/soft/mapper/PurchaseOrderMapper.java | 45 + .../mapper/PurchaseReturnDetailMapper.java | 15 + .../com/soft/mapper/PurchaseReturnMapper.java | 14 + .../mapper/SaleOrderDetailBundleMapper.java | 12 + .../soft/mapper/SaleOrderDetailMapper.java | 15 + .../java/com/soft/mapper/SaleOrderMapper.java | 67 + .../soft/mapper/SaleOutSheetDetailMapper.java | 14 + .../com/soft/mapper/SaleOutSheetMapper.java | 16 + .../mapper/SettleCheckSheetDetailMapper.java | 10 + .../soft/mapper/SettleCheckSheetMapper.java | 16 + .../soft/mapper/SettleSheetDetailMapper.java | 10 + .../com/soft/mapper/SettleSheetMapper.java | 16 + .../com/soft/mapper/StoreCenterMapper.java | 12 + .../java/com/soft/mapper/SupplierMapper.java | 13 + .../java/com/soft/mapper/SysMenuMapper.java | 17 + .../com/soft/mapper/SysRoleMenuMapper.java | 12 + .../java/com/soft/mapper/SysUserMapper.java | 30 + .../com/soft/mapper/SysUserRoleMapper.java | 9 + src/main/java/com/soft/mapper/UserMapper.java | 20 + src/main/java/com/soft/resp/InvokeResult.java | 137 ++ .../com/soft/resp/InvokeResultBuilder.java | 54 + src/main/java/com/soft/resp/Result.java | 105 ++ src/main/java/com/soft/resp/ResultError.java | 5 + .../java/com/soft/service/AgentService.java | 18 + .../java/com/soft/service/DemandService.java | 17 + .../com/soft/service/OrderChartService.java | 13 + .../com/soft/service/OrderPayTypeService.java | 10 + .../com/soft/service/PermissionService.java | 8 + .../java/com/soft/service/ProductService.java | 14 + .../service/PurchaseOrderDetailService.java | 12 + .../soft/service/PurchaseOrderService.java | 17 + .../service/SaleOrderDetailBundleService.java | 17 + .../soft/service/SaleOrderDetailService.java | 16 + .../com/soft/service/SaleOrderService.java | 17 + .../java/com/soft/service/SysUserService.java | 12 + .../java/com/soft/service/UserService.java | 29 + .../com/soft/service/VoiceQueryService.java | 90 + .../soft/service/impl/AgentServiceImpl.java | 32 + .../soft/service/impl/DemandServiceImpl.java | 56 + .../service/impl/OrderChartServiceImpl.java | 44 + .../service/impl/OrderPayTypeServiceImpl.java | 21 + .../service/impl/PermissionServiceImpl.java | 57 + .../soft/service/impl/ProductServiceImpl.java | 19 + .../impl/PurchaseOrderDetailServiceImpl.java | 21 + .../impl/PurchaseOrderServiceImpl.java | 121 ++ .../SaleOrderDetailBundleServiceImpl.java | 26 + .../impl/SaleOrderDetailServiceImpl.java | 37 + .../service/impl/SaleOrderServiceImpl.java | 206 +++ .../soft/service/impl/SysUserServiceImpl.java | 41 + .../soft/service/impl/UserServiceImpl.java | 198 ++ .../service/impl/VoiceQueryServiceImpl.java | 1639 +++++++++++++++++ src/main/java/com/soft/utils/ApiReadUitl.java | 43 + src/main/java/com/soft/utils/Base64Util.java | 62 + .../java/com/soft/utils/ConstantUtil.java | 11 + .../java/com/soft/utils/CopyBeanUtil.java | 24 + .../java/com/soft/utils/DateParserUtil.java | 59 + .../com/soft/utils/EliminateImageUtil.java | 310 ++++ src/main/java/com/soft/utils/FileUtil.java | 67 + .../java/com/soft/utils/HttpPoolUtil.java | 238 +++ src/main/java/com/soft/utils/HttpUtil.java | 72 + src/main/java/com/soft/utils/HttpUtils.java | 374 ++++ .../java/com/soft/utils/IfNotEmptyUtils.java | 36 + src/main/java/com/soft/utils/ImageUtil.java | 92 + src/main/java/com/soft/utils/MinutesUtil.java | 19 + src/main/java/com/soft/utils/PageResult.java | 179 ++ .../java/com/soft/utils/PageResultUtil.java | 97 + .../java/com/soft/utils/PieChartData.java | 22 + .../java/com/soft/utils/PieChartsData.java | 26 + .../java/com/soft/utils/ProportionUtils.java | 93 + src/main/java/com/soft/utils/ResultUtil.java | 56 + .../java/com/soft/utils/SpringBeanUtil.java | 95 + src/main/java/com/soft/utils/StreamUtils.java | 49 + .../soft/utils/UnsupportedQueryException.java | 8 + .../java/com/soft/utils/VoiceQueryParser.java | 152 ++ src/main/java/com/soft/utils/WxUtil.java | 29 + .../purchase/QueryPurchaseOrderBOUtil.java | 23 + .../convert/sale/QuerySaleOrderBOUtil.java | 23 + .../com/soft/validator/PasswordValidator.java | 21 + src/main/java/com/soft/vo/AgentLevelVo.java | 26 + src/main/java/com/soft/vo/BindPhoneVo.java | 14 + .../com/soft/vo/CheckOrderAmountCountVo.java | 19 + .../soft/vo/CheckTodaysPurchaseAmountVo.java | 26 + .../com/soft/vo/CheckTodysSalesAmountVo.java | 26 + .../java/com/soft/vo/CreateOrderChartVo.java | 36 + .../java/com/soft/vo/OrderDataMonthVo.java | 23 + src/main/java/com/soft/vo/OrderDataVo.java | 27 + .../java/com/soft/vo/OrderDataWeekVo.java | 22 + .../com/soft/vo/OrderMonthContrastVo.java | 22 + .../java/com/soft/vo/OrderProportionVo.java | 20 + .../com/soft/vo/OrderTodaysContrastVo.java | 22 + .../java/com/soft/vo/ProductStockDataVo.java | 31 + .../com/soft/vo/ProductStockLogChartVo.java | 15 + .../java/com/soft/vo/ProductStockLogVo.java | 89 + .../com/soft/vo/ProductStockProportionVo.java | 17 + src/main/java/com/soft/vo/ProductVo.java | 104 ++ .../com/soft/vo/PurchaseOrderChartVo.java | 23 + .../java/com/soft/vo/PurchaseOrderVo.java | 129 ++ .../com/soft/vo/QueryProductInventoryVo.java | 16 + .../java/com/soft/vo/SaleOrderChartVo.java | 23 + .../soft/vo/SaleOrderCurrentYearAmountVo.java | 28 + .../com/soft/vo/SaleOrderGrossMarginVo.java | 20 + .../soft/vo/SaleOrderLastYearProfitVo.java | 21 + .../com/soft/vo/SaleOrderTotalProfitVo.java | 31 + src/main/java/com/soft/vo/SaleOrderVo.java | 155 ++ .../java/com/soft/vo/SaleOutSheetChartVo.java | 15 + src/main/java/com/soft/vo/SaleOutSheetVo.java | 109 ++ .../java/com/soft/vo/SaleSalerRankVo.java | 22 + .../java/com/soft/vo/SaleSalerWeekRankVo.java | 21 + .../soft/vo/SettleCheckAccountsPayableVo.java | 15 + .../soft/vo/SettleSheetPaymentOfFeesVo.java | 15 + .../vo/TodaysPurchaseOrderReturnChartVo.java | 24 + .../soft/vo/TodaysPurchaseOrderReturnVo.java | 118 ++ src/main/java/com/soft/vo/page/PageVo.java | 82 + .../com/soft/vo/sale/QuerySaleOrderVo.java | 20 + src/main/resources/IKAnalyzer.cfg.xml | 9 + src/main/resources/application-pro.yml | 49 + src/main/resources/application-test.yml | 52 + src/main/resources/application.yml | 8 + src/main/resources/ext.dic | 4 + src/main/resources/logback.xml | 95 + src/main/resources/mapper/AgentMapper.xml | 17 + src/main/resources/mapper/CategoryMapper.xml | 15 + src/main/resources/mapper/CustomerMapper.xml | 12 + src/main/resources/mapper/DemandMapper.xml | 7 + .../resources/mapper/OrderChartMapper.xml | 7 + .../resources/mapper/OrderPayTypeMapper.xml | 12 + src/main/resources/mapper/ProductMapper.xml | 22 + .../mapper/ProductStockLogMapper.xml | 9 + .../resources/mapper/ProductStockMapper.xml | 29 + .../mapper/PurchaseOrderDetailMapper.xml | 8 + .../resources/mapper/PurchaseOrderMapper.xml | 105 ++ .../mapper/PurchaseReturnDetailMapper.xml | 8 + .../resources/mapper/PurchaseReturnMapper.xml | 8 + .../mapper/SaleOrderDetailBundleMapper.xml | 11 + .../mapper/SaleOrderDetailMapper.xml | 13 + src/main/resources/mapper/SaleOrderMapper.xml | 186 ++ .../mapper/SaleOutSheetDetailMapper.xml | 8 + .../resources/mapper/SaleOutSheetMapper.xml | 9 + .../mapper/SettleCheckSheetDetailMapper.xml | 5 + .../mapper/SettleCheckSheetMapper.xml | 9 + .../mapper/SettleSheetDetailMapper.xml | 5 + .../resources/mapper/SettleSheetMapper.xml | 8 + .../resources/mapper/StoreCenterMapper.xml | 10 + src/main/resources/mapper/SupplierMapper.xml | 8 + src/main/resources/mapper/SysMenuMapper.xml | 14 + .../resources/mapper/SysRoleMenuMapper.xml | 10 + src/main/resources/mapper/SysUserMapper.xml | 20 + .../resources/mapper/SysUserRoleMapper.xml | 6 + src/main/resources/mapper/UserMapper.xml | 25 + src/test/java/com/soft/Test.java | 10 + 258 files changed, 13710 insertions(+) create mode 100644 .gitignore create mode 100644 .mvn/wrapper/MavenWrapperDownloader.java create mode 100644 .mvn/wrapper/maven-wrapper.jar create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100644 README.md create mode 100644 doc/trans_new_漫画翻译数据库文档_1.0.html create mode 100644 pom.xml create mode 100644 src/main/java/com/soft/SoftApplication.java create mode 100644 src/main/java/com/soft/annotations/HasPermission.java create mode 100644 src/main/java/com/soft/annotations/NotNull.java create mode 100644 src/main/java/com/soft/annotations/Valid.java create mode 100644 src/main/java/com/soft/aop/PermissionAspect.java create mode 100644 src/main/java/com/soft/bo/SuperBo.java create mode 100644 src/main/java/com/soft/bo/purchase/QueryPurchaseOrderBo.java create mode 100644 src/main/java/com/soft/bo/sale/QuerySaleOrderBo.java create mode 100644 src/main/java/com/soft/common/constants/ResponseConstants.java create mode 100644 src/main/java/com/soft/common/constants/StringPool.java create mode 100644 src/main/java/com/soft/common/functions/SFunction.java create mode 100644 src/main/java/com/soft/common/security/UserDetails.java create mode 100644 src/main/java/com/soft/common/util/DateUtils.java create mode 100644 src/main/java/com/soft/components/security/PermissionCalcType.java create mode 100644 src/main/java/com/soft/config/BeanConfig.java create mode 100644 src/main/java/com/soft/config/DateConverterConfig.java create mode 100644 src/main/java/com/soft/config/DruidConfig.java create mode 100644 src/main/java/com/soft/config/RedisConfig.java create mode 100644 src/main/java/com/soft/config/SecurityConfig.java create mode 100644 src/main/java/com/soft/config/SwaggerConfig.java create mode 100644 src/main/java/com/soft/config/TransDataSourceConfig.java create mode 100644 src/main/java/com/soft/config/UnifiedResultErrorConfig.java create mode 100644 src/main/java/com/soft/config/WebConfiguration.java create mode 100644 src/main/java/com/soft/controller/AgentController.java create mode 100644 src/main/java/com/soft/controller/BaseController.java create mode 100644 src/main/java/com/soft/controller/PurchaseOrderController.java create mode 100644 src/main/java/com/soft/controller/SaleOrderController.java create mode 100644 src/main/java/com/soft/controller/SoftController.java create mode 100644 src/main/java/com/soft/controller/UserController.java create mode 100644 src/main/java/com/soft/controller/VoiceQueryController.java create mode 100644 src/main/java/com/soft/dto/ApprovePassOrderDTO.java create mode 100644 src/main/java/com/soft/dto/BaseDto.java create mode 100644 src/main/java/com/soft/dto/BindPhoneNumberDTO.java create mode 100644 src/main/java/com/soft/dto/OrderProportionDto.java create mode 100644 src/main/java/com/soft/dto/PageUtilDTO.java create mode 100644 src/main/java/com/soft/dto/SaveDemandDTO.java create mode 100644 src/main/java/com/soft/dto/StatisticsProductStockDto.java create mode 100644 src/main/java/com/soft/dto/SysUserDTO.java create mode 100644 src/main/java/com/soft/dto/UserIdDTO.java create mode 100644 src/main/java/com/soft/dto/VoiceQueryDto.java create mode 100644 src/main/java/com/soft/dto/WeChatLoginRequestDTO.java create mode 100644 src/main/java/com/soft/entitys/BaseEntity.java create mode 100644 src/main/java/com/soft/entitys/OrderChart.java create mode 100644 src/main/java/com/soft/entitys/OrderPayType.java create mode 100644 src/main/java/com/soft/entitys/Page.java create mode 100644 src/main/java/com/soft/entitys/QueryParams.java create mode 100644 src/main/java/com/soft/entitys/demand/Demand.java create mode 100644 src/main/java/com/soft/entitys/purchase/PurchaseOrderStatus.java create mode 100644 src/main/java/com/soft/entitys/sale/SaleOrderDetailBundle.java create mode 100644 src/main/java/com/soft/entitys/sys/SysMenu.java create mode 100644 src/main/java/com/soft/entitys/sys/SysRoleMenu.java create mode 100644 src/main/java/com/soft/entitys/sys/SysUserRole.java create mode 100644 src/main/java/com/soft/entitys/user/Agent.java create mode 100644 src/main/java/com/soft/entitys/user/Category.java create mode 100644 src/main/java/com/soft/entitys/user/SystemUser.java create mode 100644 src/main/java/com/soft/entitys/user/User.java create mode 100644 src/main/java/com/soft/entitys/voice/Customer.java create mode 100644 src/main/java/com/soft/entitys/voice/Product.java create mode 100644 src/main/java/com/soft/entitys/voice/ProductStock.java create mode 100644 src/main/java/com/soft/entitys/voice/ProductStockLog.java create mode 100644 src/main/java/com/soft/entitys/voice/PurchaseOrder.java create mode 100644 src/main/java/com/soft/entitys/voice/PurchaseOrderDetail.java create mode 100644 src/main/java/com/soft/entitys/voice/PurchaseReturn.java create mode 100644 src/main/java/com/soft/entitys/voice/PurchaseReturnDetail.java create mode 100644 src/main/java/com/soft/entitys/voice/SaleOrder.java create mode 100644 src/main/java/com/soft/entitys/voice/SaleOrderDetail.java create mode 100644 src/main/java/com/soft/entitys/voice/SaleOutSheet.java create mode 100644 src/main/java/com/soft/entitys/voice/SaleOutSheetDetail.java create mode 100644 src/main/java/com/soft/entitys/voice/SettleCheckSheet.java create mode 100644 src/main/java/com/soft/entitys/voice/SettleCheckSheetDetail.java create mode 100644 src/main/java/com/soft/entitys/voice/SettleSheet.java create mode 100644 src/main/java/com/soft/entitys/voice/SettleSheetDetail.java create mode 100644 src/main/java/com/soft/entitys/voice/StoreCenter.java create mode 100644 src/main/java/com/soft/entitys/voice/Supplier.java create mode 100644 src/main/java/com/soft/enums/AuthEnum.java create mode 100644 src/main/java/com/soft/enums/CommEnum.java create mode 100644 src/main/java/com/soft/enums/OrderChartBizType.java create mode 100644 src/main/java/com/soft/enums/OrderStatus.java create mode 100644 src/main/java/com/soft/enums/ProductType.java create mode 100644 src/main/java/com/soft/enums/QueryType.java create mode 100644 src/main/java/com/soft/enums/system/SysMenuComponentType.java create mode 100644 src/main/java/com/soft/enums/system/SysMenuDisplay.java create mode 100644 src/main/java/com/soft/events/order/ApprovePassOrderEvent.java create mode 100644 src/main/java/com/soft/events/order/impl/ApprovePassPurchaseOrderEvent.java create mode 100644 src/main/java/com/soft/events/order/impl/ApprovePassPurchaseReturnEvent.java create mode 100644 src/main/java/com/soft/events/order/impl/ApprovePassRetailOutSheetEvent.java create mode 100644 src/main/java/com/soft/events/order/impl/ApprovePassRetailReturnEvent.java create mode 100644 src/main/java/com/soft/events/order/impl/ApprovePassSaleOrderEvent.java create mode 100644 src/main/java/com/soft/events/order/impl/ApprovePassSaleReturnEvent.java create mode 100644 src/main/java/com/soft/filter/CrossFilter.java create mode 100644 src/main/java/com/soft/listeners/OrderDataListener.java create mode 100644 src/main/java/com/soft/mapper/AgentMapper.java create mode 100644 src/main/java/com/soft/mapper/CategoryMapper.java create mode 100644 src/main/java/com/soft/mapper/CustomerMapper.java create mode 100644 src/main/java/com/soft/mapper/DemandMapper.java create mode 100644 src/main/java/com/soft/mapper/OrderChartMapper.java create mode 100644 src/main/java/com/soft/mapper/OrderPayTypeMapper.java create mode 100644 src/main/java/com/soft/mapper/ProductMapper.java create mode 100644 src/main/java/com/soft/mapper/ProductStockLogMapper.java create mode 100644 src/main/java/com/soft/mapper/ProductStockMapper.java create mode 100644 src/main/java/com/soft/mapper/PurchaseOrderDetailMapper.java create mode 100644 src/main/java/com/soft/mapper/PurchaseOrderMapper.java create mode 100644 src/main/java/com/soft/mapper/PurchaseReturnDetailMapper.java create mode 100644 src/main/java/com/soft/mapper/PurchaseReturnMapper.java create mode 100644 src/main/java/com/soft/mapper/SaleOrderDetailBundleMapper.java create mode 100644 src/main/java/com/soft/mapper/SaleOrderDetailMapper.java create mode 100644 src/main/java/com/soft/mapper/SaleOrderMapper.java create mode 100644 src/main/java/com/soft/mapper/SaleOutSheetDetailMapper.java create mode 100644 src/main/java/com/soft/mapper/SaleOutSheetMapper.java create mode 100644 src/main/java/com/soft/mapper/SettleCheckSheetDetailMapper.java create mode 100644 src/main/java/com/soft/mapper/SettleCheckSheetMapper.java create mode 100644 src/main/java/com/soft/mapper/SettleSheetDetailMapper.java create mode 100644 src/main/java/com/soft/mapper/SettleSheetMapper.java create mode 100644 src/main/java/com/soft/mapper/StoreCenterMapper.java create mode 100644 src/main/java/com/soft/mapper/SupplierMapper.java create mode 100644 src/main/java/com/soft/mapper/SysMenuMapper.java create mode 100644 src/main/java/com/soft/mapper/SysRoleMenuMapper.java create mode 100644 src/main/java/com/soft/mapper/SysUserMapper.java create mode 100644 src/main/java/com/soft/mapper/SysUserRoleMapper.java create mode 100644 src/main/java/com/soft/mapper/UserMapper.java create mode 100644 src/main/java/com/soft/resp/InvokeResult.java create mode 100644 src/main/java/com/soft/resp/InvokeResultBuilder.java create mode 100644 src/main/java/com/soft/resp/Result.java create mode 100644 src/main/java/com/soft/resp/ResultError.java create mode 100644 src/main/java/com/soft/service/AgentService.java create mode 100644 src/main/java/com/soft/service/DemandService.java create mode 100644 src/main/java/com/soft/service/OrderChartService.java create mode 100644 src/main/java/com/soft/service/OrderPayTypeService.java create mode 100644 src/main/java/com/soft/service/PermissionService.java create mode 100644 src/main/java/com/soft/service/ProductService.java create mode 100644 src/main/java/com/soft/service/PurchaseOrderDetailService.java create mode 100644 src/main/java/com/soft/service/PurchaseOrderService.java create mode 100644 src/main/java/com/soft/service/SaleOrderDetailBundleService.java create mode 100644 src/main/java/com/soft/service/SaleOrderDetailService.java create mode 100644 src/main/java/com/soft/service/SaleOrderService.java create mode 100644 src/main/java/com/soft/service/SysUserService.java create mode 100644 src/main/java/com/soft/service/UserService.java create mode 100644 src/main/java/com/soft/service/VoiceQueryService.java create mode 100644 src/main/java/com/soft/service/impl/AgentServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/DemandServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/OrderChartServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/OrderPayTypeServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/PermissionServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/ProductServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/PurchaseOrderDetailServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/PurchaseOrderServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/SaleOrderDetailBundleServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/SaleOrderDetailServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/SaleOrderServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/SysUserServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/UserServiceImpl.java create mode 100644 src/main/java/com/soft/service/impl/VoiceQueryServiceImpl.java create mode 100644 src/main/java/com/soft/utils/ApiReadUitl.java create mode 100644 src/main/java/com/soft/utils/Base64Util.java create mode 100644 src/main/java/com/soft/utils/ConstantUtil.java create mode 100644 src/main/java/com/soft/utils/CopyBeanUtil.java create mode 100644 src/main/java/com/soft/utils/DateParserUtil.java create mode 100644 src/main/java/com/soft/utils/EliminateImageUtil.java create mode 100644 src/main/java/com/soft/utils/FileUtil.java create mode 100644 src/main/java/com/soft/utils/HttpPoolUtil.java create mode 100644 src/main/java/com/soft/utils/HttpUtil.java create mode 100644 src/main/java/com/soft/utils/HttpUtils.java create mode 100644 src/main/java/com/soft/utils/IfNotEmptyUtils.java create mode 100644 src/main/java/com/soft/utils/ImageUtil.java create mode 100644 src/main/java/com/soft/utils/MinutesUtil.java create mode 100644 src/main/java/com/soft/utils/PageResult.java create mode 100644 src/main/java/com/soft/utils/PageResultUtil.java create mode 100644 src/main/java/com/soft/utils/PieChartData.java create mode 100644 src/main/java/com/soft/utils/PieChartsData.java create mode 100644 src/main/java/com/soft/utils/ProportionUtils.java create mode 100644 src/main/java/com/soft/utils/ResultUtil.java create mode 100644 src/main/java/com/soft/utils/SpringBeanUtil.java create mode 100644 src/main/java/com/soft/utils/StreamUtils.java create mode 100644 src/main/java/com/soft/utils/UnsupportedQueryException.java create mode 100644 src/main/java/com/soft/utils/VoiceQueryParser.java create mode 100644 src/main/java/com/soft/utils/WxUtil.java create mode 100644 src/main/java/com/soft/utils/convert/purchase/QueryPurchaseOrderBOUtil.java create mode 100644 src/main/java/com/soft/utils/convert/sale/QuerySaleOrderBOUtil.java create mode 100644 src/main/java/com/soft/validator/PasswordValidator.java create mode 100644 src/main/java/com/soft/vo/AgentLevelVo.java create mode 100644 src/main/java/com/soft/vo/BindPhoneVo.java create mode 100644 src/main/java/com/soft/vo/CheckOrderAmountCountVo.java create mode 100644 src/main/java/com/soft/vo/CheckTodaysPurchaseAmountVo.java create mode 100644 src/main/java/com/soft/vo/CheckTodysSalesAmountVo.java create mode 100644 src/main/java/com/soft/vo/CreateOrderChartVo.java create mode 100644 src/main/java/com/soft/vo/OrderDataMonthVo.java create mode 100644 src/main/java/com/soft/vo/OrderDataVo.java create mode 100644 src/main/java/com/soft/vo/OrderDataWeekVo.java create mode 100644 src/main/java/com/soft/vo/OrderMonthContrastVo.java create mode 100644 src/main/java/com/soft/vo/OrderProportionVo.java create mode 100644 src/main/java/com/soft/vo/OrderTodaysContrastVo.java create mode 100644 src/main/java/com/soft/vo/ProductStockDataVo.java create mode 100644 src/main/java/com/soft/vo/ProductStockLogChartVo.java create mode 100644 src/main/java/com/soft/vo/ProductStockLogVo.java create mode 100644 src/main/java/com/soft/vo/ProductStockProportionVo.java create mode 100644 src/main/java/com/soft/vo/ProductVo.java create mode 100644 src/main/java/com/soft/vo/PurchaseOrderChartVo.java create mode 100644 src/main/java/com/soft/vo/PurchaseOrderVo.java create mode 100644 src/main/java/com/soft/vo/QueryProductInventoryVo.java create mode 100644 src/main/java/com/soft/vo/SaleOrderChartVo.java create mode 100644 src/main/java/com/soft/vo/SaleOrderCurrentYearAmountVo.java create mode 100644 src/main/java/com/soft/vo/SaleOrderGrossMarginVo.java create mode 100644 src/main/java/com/soft/vo/SaleOrderLastYearProfitVo.java create mode 100644 src/main/java/com/soft/vo/SaleOrderTotalProfitVo.java create mode 100644 src/main/java/com/soft/vo/SaleOrderVo.java create mode 100644 src/main/java/com/soft/vo/SaleOutSheetChartVo.java create mode 100644 src/main/java/com/soft/vo/SaleOutSheetVo.java create mode 100644 src/main/java/com/soft/vo/SaleSalerRankVo.java create mode 100644 src/main/java/com/soft/vo/SaleSalerWeekRankVo.java create mode 100644 src/main/java/com/soft/vo/SettleCheckAccountsPayableVo.java create mode 100644 src/main/java/com/soft/vo/SettleSheetPaymentOfFeesVo.java create mode 100644 src/main/java/com/soft/vo/TodaysPurchaseOrderReturnChartVo.java create mode 100644 src/main/java/com/soft/vo/TodaysPurchaseOrderReturnVo.java create mode 100644 src/main/java/com/soft/vo/page/PageVo.java create mode 100644 src/main/java/com/soft/vo/sale/QuerySaleOrderVo.java create mode 100644 src/main/resources/IKAnalyzer.cfg.xml create mode 100644 src/main/resources/application-pro.yml create mode 100644 src/main/resources/application-test.yml create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/ext.dic create mode 100644 src/main/resources/logback.xml create mode 100644 src/main/resources/mapper/AgentMapper.xml create mode 100644 src/main/resources/mapper/CategoryMapper.xml create mode 100644 src/main/resources/mapper/CustomerMapper.xml create mode 100644 src/main/resources/mapper/DemandMapper.xml create mode 100644 src/main/resources/mapper/OrderChartMapper.xml create mode 100644 src/main/resources/mapper/OrderPayTypeMapper.xml create mode 100644 src/main/resources/mapper/ProductMapper.xml create mode 100644 src/main/resources/mapper/ProductStockLogMapper.xml create mode 100644 src/main/resources/mapper/ProductStockMapper.xml create mode 100644 src/main/resources/mapper/PurchaseOrderDetailMapper.xml create mode 100644 src/main/resources/mapper/PurchaseOrderMapper.xml create mode 100644 src/main/resources/mapper/PurchaseReturnDetailMapper.xml create mode 100644 src/main/resources/mapper/PurchaseReturnMapper.xml create mode 100644 src/main/resources/mapper/SaleOrderDetailBundleMapper.xml create mode 100644 src/main/resources/mapper/SaleOrderDetailMapper.xml create mode 100644 src/main/resources/mapper/SaleOrderMapper.xml create mode 100644 src/main/resources/mapper/SaleOutSheetDetailMapper.xml create mode 100644 src/main/resources/mapper/SaleOutSheetMapper.xml create mode 100644 src/main/resources/mapper/SettleCheckSheetDetailMapper.xml create mode 100644 src/main/resources/mapper/SettleCheckSheetMapper.xml create mode 100644 src/main/resources/mapper/SettleSheetDetailMapper.xml create mode 100644 src/main/resources/mapper/SettleSheetMapper.xml create mode 100644 src/main/resources/mapper/StoreCenterMapper.xml create mode 100644 src/main/resources/mapper/SupplierMapper.xml create mode 100644 src/main/resources/mapper/SysMenuMapper.xml create mode 100644 src/main/resources/mapper/SysRoleMenuMapper.xml create mode 100644 src/main/resources/mapper/SysUserMapper.xml create mode 100644 src/main/resources/mapper/SysUserRoleMapper.xml create mode 100644 src/main/resources/mapper/UserMapper.xml create mode 100644 src/test/java/com/soft/Test.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8249d68 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +<<<<<<< HEAD +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +======= +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ +>>>>>>> firstcommit diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000..e76d1f3 --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,117 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..2cc7d4a55c0cd0092912bf49ae38b3a9e3fd0054 GIT binary patch literal 50710 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 EfAhh=DF6Tf literal 0 HcmV?d00001 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..642d572 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/trans_new_漫画翻译数据库文档_1.0.html b/doc/trans_new_漫画翻译数据库文档_1.0.html new file mode 100644 index 0000000..3e17594 --- /dev/null +++ b/doc/trans_new_漫画翻译数据库文档_1.0.html @@ -0,0 +1 @@ +fire数据库文档

fire数据库文档

数据库名:trans_new
文档版本:1.0
文档描述:漫画翻译数据库文档
序号表名说明
1font
2language
3permission权限表
4role角色表
5role_permission角色权限字典表
6trans_worker
7user用户表
8worker_content
9worker_dir
10worker_image
返回目录表名:font
说明:
数据列:
序号名称数据类型长度小数位允许空值主键默认值说明
1idint unsigned100NYid
2font_namevarchar200NN字体名称
返回目录表名:language
说明:
数据列:
序号名称数据类型长度小数位允许空值主键默认值说明
1idint unsigned100NYid
2language_namevarchar300NN语言名称
3language_codevarchar100NN语言代码
4split_typeint100NN分割字数方式 1中文 2英文
返回目录表名:permission
说明:权限表
数据列:
序号名称数据类型长度小数位允许空值主键默认值说明
1idint unsigned100NY
2parent_idint100NN父级id
3namevarchar500NN名称
4urlvarchar2000YN地址
5sortint100NN1排序
返回目录表名:role
说明:角色表
数据列:
序号名称数据类型长度小数位允许空值主键默认值说明
1idint unsigned100NY
2namevarchar500NN名称
3levelint100NN10级别
返回目录表名:role_permission
说明:角色权限字典表
数据列:
序号名称数据类型长度小数位允许空值主键默认值说明
1idint unsigned100NY
2role_idint100NN角色id
3permission_idint100NN权限id
返回目录表名:trans_worker
说明:
数据列:
序号名称数据类型长度小数位允许空值主键默认值说明
1idint unsigned100NYid
2user_idint100NN用户id
3work_namevarchar500NN工程名
4worker_labelvarchar500YN工程标签
5worker_cover_urlvarchar2000YN工程封面
6dir_idint100NN父文件夹id
7widthint100NN宽度
8heightint100NN高度
9from_language_idint100NN原语言id
10to_language_idint100NN翻译目标语言id
11font_idint100NN默认字体
12image_countint100NN0工程图片数
13auto_clear_wordint100NN0是否自动清除文字
14auto_ocrint100NN0是否自动识别文字
15auto_translateint100NN0是否自动翻译
16word_countint100NN0工程源语言字数
17worker_sizeint100NN0工程占空间大小
18worker_statusint100NN1工程状态
19create_timedatetime190NN创建时间
20update_timetimestamp190NNCURRENT_TIMESTAMP更新时间
返回目录表名:user
说明:用户表
数据列:
序号名称数据类型长度小数位允许空值主键默认值说明
1idint unsigned100NY
2user_namevarchar500NN账号
3passwordvarchar2000NN密码
4nickvarchar500NN用户名
5role_idint100NN角色id
6user_statusint100NN10不可用 1可用
7create_timetimestamp190NNCURRENT_TIMESTAMP创建时间
返回目录表名:worker_content
说明:
数据列:
序号名称数据类型长度小数位允许空值主键默认值说明
1idint unsigned100NYid
2worker_idint100NN工程id
3worker_image_idint100NN工程图片id
4ocr_contenttext655350NNOCR识别出的文字
5trans_contenttext655350NN翻译出的文字
6content_statusint100NN0翻译状态 0:未翻译 1:已翻译
7left_xint100NN左边界定位
8right_xint100NN右边界定位
9up_yint100NN上边界定位
10down_yint100NN下边界定位
11font_sizeint100NN字体大小
12font_idint100NN文字字体id
13content_colorvarchar100NN文本颜色 例:#FFFFFF
14content_word_countint100NN文本长度
15trans_img_pathvarchar2000YN翻译保存的图片路劲
16is_hideint100NN0是否隐藏翻译后图片 0:隐藏 1:显示
17create_timedatetime190NN创建时间
返回目录表名:worker_dir
说明:
数据列:
序号名称数据类型长度小数位允许空值主键默认值说明
1idint unsigned100NYid
2parent_idint100NN0父级id
3user_idint100NN用户id
4dir_namevarchar300NN文件夹名称
5dir_sizeint100NN0文件大小
6dir_sub_totalint100NN0子文件数量
7worker_sub_totalint100NN0子工程数量
8dir_statusint100NN1文件状态
9create_timedatetime190NN创建时间
10update_timetimestamp190NNCURRENT_TIMESTAMP更新时间
返回目录表名:worker_image
说明:
数据列:
序号名称数据类型长度小数位允许空值主键默认值说明
1idint unsigned100NYid
2worker_idint100NN工程id
3file_pathvarchar2000NN图片存储路径
4file_numint100NN图片编号
5widthint100NN图片宽度
6heightint100NN图片高度
7image_word_countint100NN0源语言字数
8image_statusint100NN0图片状态 0:没有OCR 1:已OCR
9create_timedatetime190NN创建时间
\ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..602faee --- /dev/null +++ b/pom.xml @@ -0,0 +1,275 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.3.2.RELEASE + + + com.soft + soft + 1.0 + soft + Demo project for Spring Boot + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-aop + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework + spring-expression + + + + org.apache.poi + poi + 5.2.3 + + + org.apache.poi + poi-ooxml + 5.2.3 + + + org.apache.poi + poi-ooxml-schemas + 4.1.2 + + + org.apache.xmlbeans + xmlbeans + 5.0.2 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + + org.springframework.boot + spring-boot-starter-data-redis + 2.2.4.RELEASE + + + + com.baomidou + mybatis-plus-boot-starter + 3.4.3.4 + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + com.baomidou + mybatis-plus-extension + 3.5.1 + + + + org.jsoup + jsoup + 1.14.3 + + + + mysql + mysql-connector-java + runtime + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.3.1 + + + + + com.janeluo + ikanalyzer + 2012_u6 + + + com.huaban + jieba-analysis + 1.0.2 + + + + org.bouncycastle + bcprov-jdk15on + 1.60 + + + + com.baidubce + bce-java-sdk + 0.10.154 + + + com.google.guava + guava + + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + cn.hutool + hutool-all + 5.2.5 + + + com.alibaba + fastjson + 1.2.58 + + + + + org.projectlombok + lombok + 1.18.6 + + + + net.sf.json-lib + json-lib-ext-spring + 1.0.2 + + + + + io.springfox + springfox-swagger2 + 2.9.2 + + + + + + com.github.xiaoymin + knife4j-spring-boot-starter + + 2.0.9 + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + org.pegdown + pegdown + 1.4.2 + + + + commons-codec + commons-codec + 1.13 + + + org.apache.commons + commons-lang3 + 3.9 + + + commons-io + commons-io + 2.11.0 + + + org.apache.httpcomponents + httpclient + 4.5.9 + + + org.apache.commons + commons-collections4 + 4.4 + + + junit + junit + 4.12-beta-3 + + + com.github.wechatpay-apiv3 + wechatpay-apache-httpclient + 0.4.7 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + + diff --git a/src/main/java/com/soft/SoftApplication.java b/src/main/java/com/soft/SoftApplication.java new file mode 100644 index 0000000..77dc6fa --- /dev/null +++ b/src/main/java/com/soft/SoftApplication.java @@ -0,0 +1,23 @@ +package com.soft; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.scheduling.annotation.EnableScheduling; + + +@SpringBootApplication +@EnableAspectJAutoProxy +@EnableScheduling +public class SoftApplication { + public static void main(String[] args) { + SpringApplication.run(SoftApplication.class, args); +// RedisTemplate redisTemplate= SpringBeanUtil.getBean(RedisTemplate.class); +// redisTemplate.opsForValue().set("user1", new User1(2,"lumia")); +// System.out.println(redisTemplate.opsForValue().getOperations().getExpire("user1")); +// Object name = redisTemplate.opsForValue().get("shopping_car1"); +// System.out.println(name); + + } +} \ No newline at end of file diff --git a/src/main/java/com/soft/annotations/HasPermission.java b/src/main/java/com/soft/annotations/HasPermission.java new file mode 100644 index 0000000..4cb3af1 --- /dev/null +++ b/src/main/java/com/soft/annotations/HasPermission.java @@ -0,0 +1,23 @@ +package com.soft.annotations; + +import com.soft.components.security.PermissionCalcType; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface HasPermission { + String[] value(); + + PermissionCalcType calcType() default PermissionCalcType.OR; + + /** + * 用户ID的 SpEL 表达式(例如:#userId 或 #user.id) + */ + String userId() default ""; +} diff --git a/src/main/java/com/soft/annotations/NotNull.java b/src/main/java/com/soft/annotations/NotNull.java new file mode 100644 index 0000000..ca9ef56 --- /dev/null +++ b/src/main/java/com/soft/annotations/NotNull.java @@ -0,0 +1,13 @@ +package com.soft.annotations; + + +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface NotNull { + + String message() default ""; + +} diff --git a/src/main/java/com/soft/annotations/Valid.java b/src/main/java/com/soft/annotations/Valid.java new file mode 100644 index 0000000..a280b96 --- /dev/null +++ b/src/main/java/com/soft/annotations/Valid.java @@ -0,0 +1,10 @@ +package com.soft.annotations; + +import java.lang.annotation.*; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Valid { + +} diff --git a/src/main/java/com/soft/aop/PermissionAspect.java b/src/main/java/com/soft/aop/PermissionAspect.java new file mode 100644 index 0000000..cecfe52 --- /dev/null +++ b/src/main/java/com/soft/aop/PermissionAspect.java @@ -0,0 +1,83 @@ +package com.soft.aop; + +import com.alibaba.druid.util.StringUtils; +import com.soft.annotations.HasPermission; +import com.soft.service.PermissionService; +import com.sun.tools.example.debug.expr.ExpressionParser; +import org.apache.hadoop.hbase.security.AccessDeniedException; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.DefaultParameterNameDiscoverer; +import org.springframework.expression.EvaluationContext; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + + +import java.lang.reflect.Method; + +@Aspect +public class PermissionAspect { + + @Autowired + private PermissionService permissionService; // 权限服务(需自行实现) + + public PermissionAspect() { + } + + @Pointcut("@annotation(com.soft.annotations.HasPermission) && execution(public * *(..))") + public void permissionPointCut() { + } + + @Around("permissionPointCut()") + public Object permission(ProceedingJoinPoint joinPoint) throws Throwable { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + HasPermission hasPermission = method.getAnnotation(HasPermission.class); + + // 1. 解析用户ID(通过SpEL表达式) + String userIdSpEL = hasPermission.userId(); + String userId = parseUserId(joinPoint, method, userIdSpEL); + + // 2. 校验权限 + if (!permissionService.hasPermission( + userId, + hasPermission.value(), + hasPermission.calcType())) { + throw new AccessDeniedException("用户[" + userId + "]无操作权限"); + } + + // 3. 执行目标方法 + return joinPoint.proceed(); + } + + /** + * 解析SpEL表达式获取用户ID + */ + private String parseUserId(ProceedingJoinPoint joinPoint, Method method, String spEL) { + if (StringUtils.isEmpty(spEL)) { + // 默认从安全上下文获取当前用户ID(例如Spring Security) + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + return authentication.getName(); + } + + // 使用Spring的SpEL解析器 + SpelExpressionParser parser = new SpelExpressionParser(); + EvaluationContext context = new StandardEvaluationContext(); + + // 将方法参数绑定到上下文 + Object[] args = joinPoint.getArgs(); + String[] paramNames = new DefaultParameterNameDiscoverer().getParameterNames(method); + for (int i = 0; i < args.length; i++) { + context.setVariable(paramNames[i], args[i]); + } + // 解析表达式并获取用户ID + return parser.parseExpression(spEL).getValue(context, String.class); + } +} + diff --git a/src/main/java/com/soft/bo/SuperBo.java b/src/main/java/com/soft/bo/SuperBo.java new file mode 100644 index 0000000..a6bc603 --- /dev/null +++ b/src/main/java/com/soft/bo/SuperBo.java @@ -0,0 +1,4 @@ +package com.soft.bo; + +public interface SuperBo { +} diff --git a/src/main/java/com/soft/bo/purchase/QueryPurchaseOrderBo.java b/src/main/java/com/soft/bo/purchase/QueryPurchaseOrderBo.java new file mode 100644 index 0000000..b630e84 --- /dev/null +++ b/src/main/java/com/soft/bo/purchase/QueryPurchaseOrderBo.java @@ -0,0 +1,58 @@ +package com.soft.bo.purchase; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.soft.common.constants.StringPool; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +public class QueryPurchaseOrderBo { + /** + * ID + */ + @ApiModelProperty("ID") + private String id; + + /** + * 单号 + */ + @ApiModelProperty("单号") + private String code; + + /** + * 销售金额 + */ + @ApiModelProperty("销售金额") + private BigDecimal totalAmount; + + /** + * 销售总商品数 + */ + @ApiModelProperty("销售总商品数") + private BigDecimal productAmount; + + /** + * 创建人 + */ + @ApiModelProperty("创建人") + private String createBy; + + /** + * 创建时间 + */ + @ApiModelProperty("创建时间") + @JsonFormat(pattern = StringPool.DATE_TIME_PATTERN) + private LocalDateTime createTime; + + /** + * 状态 + */ + @ApiModelProperty("状态") + private Integer status; + + @ApiModelProperty(value = "商品名称") + private String productName; +} diff --git a/src/main/java/com/soft/bo/sale/QuerySaleOrderBo.java b/src/main/java/com/soft/bo/sale/QuerySaleOrderBo.java new file mode 100644 index 0000000..70bc529 --- /dev/null +++ b/src/main/java/com/soft/bo/sale/QuerySaleOrderBo.java @@ -0,0 +1,59 @@ +package com.soft.bo.sale; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.soft.common.constants.StringPool; +import com.soft.entitys.voice.SaleOrder; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +public class QuerySaleOrderBo { + /** + * ID + */ + @ApiModelProperty("ID") + private String id; + + /** + * 单号 + */ + @ApiModelProperty("单号") + private String code; + + /** + * 销售金额 + */ + @ApiModelProperty("销售金额") + private BigDecimal totalAmount; + + /** + * 销售总商品数 + */ + @ApiModelProperty("销售总商品数") + private BigDecimal productAmount; + + /** + * 创建人 + */ + @ApiModelProperty("创建人") + private String createBy; + + /** + * 创建时间 + */ + @ApiModelProperty("创建时间") + @JsonFormat(pattern = StringPool.DATE_TIME_PATTERN) + private LocalDateTime createTime; + + /** + * 状态 + */ + @ApiModelProperty("状态") + private Integer status; + + @ApiModelProperty(value = "商品名称") + private String productName; +} diff --git a/src/main/java/com/soft/common/constants/ResponseConstants.java b/src/main/java/com/soft/common/constants/ResponseConstants.java new file mode 100644 index 0000000..46cecf6 --- /dev/null +++ b/src/main/java/com/soft/common/constants/ResponseConstants.java @@ -0,0 +1,21 @@ +package com.soft.common.constants; + +public class ResponseConstants { + public static final Integer INVOKE_RESULT_SUCCESS_CODE = 200; + public static final Integer INVOKE_RESULT_FAIL_CODE_INPUT_ERROR = 400; + public static final Integer INVOKE_RESULT_FAIL_CODE_AUTH_EXPIRED = 401; + public static final Integer INVOKE_RESULT_FAIL_CODE_ACCESS_DENIED = 403; + public static final Integer INVOKE_RESULT_FAIL_CODE_REPEAT_REQUEST = 410; + public static final Integer INVOKE_RESULT_FAIL_USER_LOGIN_FAIL = 419; + public static final Integer INVOKE_RESULT_FAIL_CODE = 500; + public static final String INVOKE_RESULT_SUCCESS_MSG = "success"; + public static final String INVOKE_RESULT_FAIL_MSG = "fail"; + public static final String INVOKE_RESULT_ERROR_MSG = "系统出现内部错误,请联系系统管理员!"; + public static final String INVOKE_RESULT_ERROR_MSG_INPUT_ERROR = "传入参数有误!"; + public static final String INVOKE_RESULT_ERROR_MSG_AUTH_EXPIRED = "请重新登录!"; + public static final String INVOKE_RESULT_ERROR_MSG_ACCESS_DENIED = "无系统权限!"; + public static final String INVOKE_RESULT_ERROR_MSG_REPEAT_REQUEST = "请求过于频繁,请稍后再试!"; + + public ResponseConstants() { + } +} diff --git a/src/main/java/com/soft/common/constants/StringPool.java b/src/main/java/com/soft/common/constants/StringPool.java new file mode 100644 index 0000000..bdba60c --- /dev/null +++ b/src/main/java/com/soft/common/constants/StringPool.java @@ -0,0 +1,9 @@ +package com.soft.common.constants; + +public interface StringPool { + String EXCEL_DATE_PATTERN = "yyyy/MM/dd"; + String DATE_PATTERN = "yyyy-MM-dd"; + String TIME_PATTERN = "HH:mm:ss"; + String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + String DATE_TIME_HOUR_PATTER = "yyyy-MM-dd HH"; +} diff --git a/src/main/java/com/soft/common/functions/SFunction.java b/src/main/java/com/soft/common/functions/SFunction.java new file mode 100644 index 0000000..e06fc78 --- /dev/null +++ b/src/main/java/com/soft/common/functions/SFunction.java @@ -0,0 +1,8 @@ +package com.soft.common.functions; + +import java.io.Serializable; +import java.util.function.Function; + +@FunctionalInterface +public interface SFunction extends Function, Serializable { +} diff --git a/src/main/java/com/soft/common/security/UserDetails.java b/src/main/java/com/soft/common/security/UserDetails.java new file mode 100644 index 0000000..6e21782 --- /dev/null +++ b/src/main/java/com/soft/common/security/UserDetails.java @@ -0,0 +1,21 @@ +package com.soft.common.security; + +import java.io.Serializable; + +public interface UserDetails extends Serializable { + String getPassword(); + + String getUsername(); + + boolean isAccountNonExpired(); + + boolean isAccountNonLocked(); + + boolean isCredentialsNonExpired(); + + boolean isEnabled(); + + boolean isAdmin(); + + boolean hasAdminPermission(); +} diff --git a/src/main/java/com/soft/common/util/DateUtils.java b/src/main/java/com/soft/common/util/DateUtils.java new file mode 100644 index 0000000..d40b9a3 --- /dev/null +++ b/src/main/java/com/soft/common/util/DateUtils.java @@ -0,0 +1,21 @@ +package com.soft.common.util; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +public class DateUtils { + // Date 转 LocalDateTime(默认时区) + public static LocalDateTime toLocalDateTime(Date date) { + if (date == null) return null; + return date.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + } + + // LocalDateTime 转 Date(按需反向转换) + public static Date toDate(LocalDateTime localDateTime) { + if (localDateTime == null) return null; + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); + } +} diff --git a/src/main/java/com/soft/components/security/PermissionCalcType.java b/src/main/java/com/soft/components/security/PermissionCalcType.java new file mode 100644 index 0000000..35e14e1 --- /dev/null +++ b/src/main/java/com/soft/components/security/PermissionCalcType.java @@ -0,0 +1,10 @@ +package com.soft.components.security; + +public enum PermissionCalcType { + OR, + AND; + + private PermissionCalcType() { + } +} + diff --git a/src/main/java/com/soft/config/BeanConfig.java b/src/main/java/com/soft/config/BeanConfig.java new file mode 100644 index 0000000..1e45d19 --- /dev/null +++ b/src/main/java/com/soft/config/BeanConfig.java @@ -0,0 +1,17 @@ +package com.soft.config; + +import com.soft.utils.SpringBeanUtil; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +@Configuration +@Order(25) +public class BeanConfig { + + @Bean + public SpringBeanUtil getSpringBeanUtil(){ + return new SpringBeanUtil(); + } + +} diff --git a/src/main/java/com/soft/config/DateConverterConfig.java b/src/main/java/com/soft/config/DateConverterConfig.java new file mode 100644 index 0000000..e38d242 --- /dev/null +++ b/src/main/java/com/soft/config/DateConverterConfig.java @@ -0,0 +1,64 @@ +package com.soft.config; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import org.apache.commons.lang3.StringUtils; +import org.springframework.boot.jackson.JsonComponent; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class DateConverterConfig implements Converter { + + + private static final String YYYY_MM_DD = "yyyy-MM-dd"; + private static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + @JsonComponent + public static class DateJsonSerializer extends JsonSerializer { + @Override + public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + SimpleDateFormat sdf=new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS); + jsonGenerator.writeString(sdf.format(date)); + } + } + + @Override + public Date convert(String source) { + if (StringUtils.isBlank(source)) { + return null; + } + source = source.trim(); + if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){ + return parseDate(source, YYYY_MM_DD); + }else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){ + return parseDate(source, YYYY_MM_DD_HH_MM_SS); + }else { + throw new IllegalArgumentException("Invalid false value '" + source + "'"); + } + } + + /** + * 格式化日期 + * @param dateStr String 字符型日期 + * @param format String 格式 + * @return Date 日期 + */ + private Date parseDate(String dateStr, String format) { + Date date; + try { + DateFormat dateFormat = new SimpleDateFormat(format); + date = dateFormat.parse(dateStr); + } catch (Exception e) { + throw new IllegalArgumentException(e.getLocalizedMessage()); + } + return date; + } + +} \ No newline at end of file diff --git a/src/main/java/com/soft/config/DruidConfig.java b/src/main/java/com/soft/config/DruidConfig.java new file mode 100644 index 0000000..319f7ff --- /dev/null +++ b/src/main/java/com/soft/config/DruidConfig.java @@ -0,0 +1,69 @@ +package com.soft.config; + +import com.alibaba.druid.support.http.StatViewServlet; +import com.alibaba.druid.support.http.WebStatFilter; +import com.alibaba.druid.support.spring.stat.DruidStatInterceptor; +import org.springframework.aop.support.DefaultPointcutAdvisor; +import org.springframework.aop.support.JdkRegexpMethodPointcut; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import org.springframework.core.annotation.Order; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +@Order(1) +public class DruidConfig { + + @Bean + public ServletRegistrationBean druidServlet() { + ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); + Map initParam = new HashMap<>(); + initParam.put("loginUsername","druid"); + initParam.put("loginPassword","123456"); + initParam.put("allow",""); //默认就是允许所有访问 + initParam.put("deny",""); //默认访问 + servletRegistrationBean.setInitParameters(initParam); + return servletRegistrationBean; + } + + @Bean + public FilterRegistrationBean webStatFilter() { + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); + filterRegistrationBean.setFilter(new WebStatFilter()); + Map initParams = new HashMap<>(); + initParams.put("exclusions", "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"); + filterRegistrationBean.setInitParameters(initParams); + filterRegistrationBean.addUrlPatterns("/*"); + filterRegistrationBean.setOrder(2); + filterRegistrationBean.setName("webStatFilter"); + return filterRegistrationBean; + } + + @Bean + public DruidStatInterceptor druidStatInterceptor() { + DruidStatInterceptor dsInterceptor = new DruidStatInterceptor(); + return dsInterceptor; + } + + @Bean + @Scope("prototype") + public JdkRegexpMethodPointcut druidStatPointcut() { + JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut(); + pointcut.setPattern("com.soft.mapper.*"); + return pointcut; + } + + @Bean + public DefaultPointcutAdvisor druidStatAdvisor(DruidStatInterceptor druidStatInterceptor, JdkRegexpMethodPointcut druidStatPointcut) { + DefaultPointcutAdvisor defaultPointAdvisor = new DefaultPointcutAdvisor(); + defaultPointAdvisor.setPointcut(druidStatPointcut); + defaultPointAdvisor.setAdvice(druidStatInterceptor); + return defaultPointAdvisor; + } + +} diff --git a/src/main/java/com/soft/config/RedisConfig.java b/src/main/java/com/soft/config/RedisConfig.java new file mode 100644 index 0000000..7cdbc38 --- /dev/null +++ b/src/main/java/com/soft/config/RedisConfig.java @@ -0,0 +1,121 @@ +package com.soft.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.cache.CacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.annotation.Order; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.*; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.time.Duration; + +//@RefreshScope +@Configuration +@Order(20) +public class RedisConfig { + + @Bean + //如使用注解的话需要配置cacheManager + CacheManager cacheManager(RedisConnectionFactory connectionFactory) { + //初始化一个RedisCacheWriter + RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory); + RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig(); + //设置默认超过期时间是1天 + //defaultCacheConfig.entryTtl(Duration.ofDays(1)); + defaultCacheConfig.entryTtl(Duration.ofDays(-1)); + //初始化RedisCacheManager + RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig); + return cacheManager; + } + + @Bean + @Primary + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + + RedisTemplate template = new RedisTemplate<>(); // 配置连接工厂 + template.setConnectionFactory(factory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式) + Jackson2JsonRedisSerializer jacksonSerial = new Jackson2JsonRedisSerializer(Object.class); + + ObjectMapper om = new ObjectMapper(); // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常 + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jacksonSerial.setObjectMapper(om); // 值采用json序列化 + template.setValueSerializer(jacksonSerial); //使用StringRedisSerializer来序列化和反序列化redis的key值 + template.setKeySerializer(new StringRedisSerializer()); // 设置hash key 和value序列化模式 + template.setHashKeySerializer(new StringRedisSerializer()); + template.setHashValueSerializer(jacksonSerial); + template.afterPropertiesSet(); + return template; + } + + /** + * 对hash类型的数据操作 + * + * @param redisTemplate + * @return + */ + + @Bean + public HashOperations hashOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForHash(); + } + + /** + * 对redis字符串类型数据操作 + * + * @param redisTemplate + * @return + */ + + @Bean + public ValueOperations valueOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForValue(); + } + + /** + * 对链表类型的数据操作 + * + * @param redisTemplate + * @return + */ + + @Bean + public ListOperations listOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForList(); + } + + /** + * 对无序集合类型的数据操作 + * + * @param redisTemplate + * @return + */ + + + @Bean + public SetOperations setOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForSet(); + } + + /** + * 对有序集合类型的数据操作 + * + * @param redisTemplate + * @return + */ + @Bean + public ZSetOperations zSetOperations(RedisTemplate redisTemplate) { + return redisTemplate.opsForZSet(); + } + + +} diff --git a/src/main/java/com/soft/config/SecurityConfig.java b/src/main/java/com/soft/config/SecurityConfig.java new file mode 100644 index 0000000..e8623fd --- /dev/null +++ b/src/main/java/com/soft/config/SecurityConfig.java @@ -0,0 +1,40 @@ +package com.soft.config; + + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + + +@Configuration +@EnableWebSecurity +@Order(0) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/**").permitAll() // 所有路径无需认证 + .anyRequest().permitAll() + .and() + .csrf().disable(); // 禁用CSRF + } + + // 可选:忽略静态资源(如果不需要认证) + @Override + public void configure(WebSecurity web) throws Exception { + web.ignoring().antMatchers("/static/**"); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(BCryptPasswordEncoder.BCryptVersion.$2A, 10); + } +} diff --git a/src/main/java/com/soft/config/SwaggerConfig.java b/src/main/java/com/soft/config/SwaggerConfig.java new file mode 100644 index 0000000..6f3be1b --- /dev/null +++ b/src/main/java/com/soft/config/SwaggerConfig.java @@ -0,0 +1,77 @@ +package com.soft.config; + +import com.soft.enums.AuthEnum; +import com.soft.enums.CommEnum; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.web.bind.annotation.RequestMethod; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.builders.ResponseMessageBuilder; +import springfox.documentation.service.Contact; +import springfox.documentation.service.ResponseMessage; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@Configuration +@EnableSwagger2 +@Order(55) +public class SwaggerConfig extends WebSecurityConfigurerAdapter { + + @Value("http:localhost:${server.port:8088}") + private String url; + + @Bean + public Docket docketCommon() { + List responseMessageList = new ArrayList<>(); + Arrays.stream(CommEnum.values()).forEach(enums -> { + responseMessageList.add( + new ResponseMessageBuilder().code(enums.getCode()).message(enums.getMessage()).build() + ); + }); + Arrays.stream(AuthEnum.values()).forEach(enums -> { + responseMessageList.add( + new ResponseMessageBuilder().code(enums.getCode()).message(enums.getMessage()).build() + ); + }); + return new Docket(DocumentationType.SWAGGER_2) + .globalResponseMessage(RequestMethod.GET, responseMessageList) + .globalResponseMessage(RequestMethod.POST, responseMessageList) + .globalResponseMessage(RequestMethod.PUT, responseMessageList) + .globalResponseMessage(RequestMethod.DELETE, responseMessageList) + .groupName("soft").select() + .apis(RequestHandlerSelectors.basePackage("com.soft.controller")) + .paths(PathSelectors.any()) + .build() + .apiInfo(new ApiInfoBuilder(). + title("soft API"). + description("接口API"). + contact(new Contact("", "", "")).termsOfServiceUrl(url). + version("1.0"). + build()); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + // 限制 Swagger 路径需要 ADMIN 权限 + .antMatchers("/swagger-ui/**", "/v3/api-docs/**").hasRole("ADMIN") + // 其他接口放行 + .anyRequest().permitAll() + .and() + // 启用 Basic 认证(浏览器弹窗登录) + .httpBasic(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/soft/config/TransDataSourceConfig.java b/src/main/java/com/soft/config/TransDataSourceConfig.java new file mode 100644 index 0000000..c2d136e --- /dev/null +++ b/src/main/java/com/soft/config/TransDataSourceConfig.java @@ -0,0 +1,27 @@ +package com.soft.config; + +import com.alibaba.druid.pool.DruidDataSource; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.annotation.Order; + +import javax.sql.DataSource; + +@Configuration +@MapperScan(basePackages = "com.soft.mapper") +@Order(10) +public class TransDataSourceConfig { + + + @Bean + @Primary + @ConfigurationProperties(prefix = "spring.datasource") + public DataSource getDataSource() { + return new DruidDataSource(); + } + + +} diff --git a/src/main/java/com/soft/config/UnifiedResultErrorConfig.java b/src/main/java/com/soft/config/UnifiedResultErrorConfig.java new file mode 100644 index 0000000..9ad3792 --- /dev/null +++ b/src/main/java/com/soft/config/UnifiedResultErrorConfig.java @@ -0,0 +1,16 @@ +package com.soft.config; + +import com.soft.resp.Result; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class UnifiedResultErrorConfig { + + @ExceptionHandler(value = RuntimeException.class) + public Result exception(RuntimeException e){ + e.printStackTrace(); + return Result.error(); + } + +} diff --git a/src/main/java/com/soft/config/WebConfiguration.java b/src/main/java/com/soft/config/WebConfiguration.java new file mode 100644 index 0000000..51f0ca9 --- /dev/null +++ b/src/main/java/com/soft/config/WebConfiguration.java @@ -0,0 +1,29 @@ +package com.soft.config; + +import com.soft.filter.CrossFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @description WebConfiguration + * @author TDW + * @date 2021年3月4日 + * + */ +//@Configuration +public class WebConfiguration implements WebMvcConfigurer { + + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Bean + public FilterRegistrationBean crossFilter(CrossFilter crossFilter) { + FilterRegistrationBean registrationBean = new FilterRegistrationBean(crossFilter); + registrationBean.setFilter(crossFilter); + registrationBean.addUrlPatterns("/*"); + registrationBean.setOrder(1); + registrationBean.setName("crossFilter"); + return registrationBean; + } + +} diff --git a/src/main/java/com/soft/controller/AgentController.java b/src/main/java/com/soft/controller/AgentController.java new file mode 100644 index 0000000..a656953 --- /dev/null +++ b/src/main/java/com/soft/controller/AgentController.java @@ -0,0 +1,52 @@ +package com.soft.controller; + +import com.soft.dto.UserIdDTO; +import com.soft.resp.Result; +import com.soft.entitys.user.User; +import com.soft.mapper.UserMapper; +import com.soft.service.AgentService; +import com.soft.vo.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/agent") +@Api(tags = "代理中心api") +public class AgentController { + + private Logger logger = LoggerFactory.getLogger(com.soft.controller.AgentController.class); + + @Autowired + private AgentService agentService; + + @Autowired + private UserMapper userMapper; + + @GetMapping("/getAgentLevelList") + @ApiOperation(value = "代理等级和利润") + public Result> getAgentLevelList(){ + + return Result.success(agentService.getAgentLevelList()); + } + + @PostMapping("/getMySilverAgent") + @ApiOperation(value = "我的银牌代理") + public Result> getMySilverAgent(@RequestBody UserIdDTO userIdDTO){ + + return Result.success(userMapper.getMySilverAgent(userIdDTO.getUserId())); + } + + @PostMapping("/getMyGoldMedalAgent") + @ApiOperation(value = "我的金牌代理") + public Result> getMyGoldMedalAgent(@RequestBody UserIdDTO userIdDTO){ + + return Result.success(userMapper.getMyGoldMedalAgent(userIdDTO.getUserId())); + } + +} diff --git a/src/main/java/com/soft/controller/BaseController.java b/src/main/java/com/soft/controller/BaseController.java new file mode 100644 index 0000000..49dbccf --- /dev/null +++ b/src/main/java/com/soft/controller/BaseController.java @@ -0,0 +1,31 @@ +package com.soft.controller; + +import cn.hutool.core.util.ObjectUtil; +import com.soft.vo.page.PageVo; + +public abstract class BaseController { + public BaseController() { + } + + public int getPageIndex(PageVo vo) { + return !ObjectUtil.isNull(vo) && !ObjectUtil.isNull(vo.getPageIndex()) && vo.getPageIndex() > 0 ? vo.getPageIndex() : 1; + } + + public int getPageSize(PageVo vo) { + return !ObjectUtil.isNull(vo) && !ObjectUtil.isNull(vo.getPageSize()) && vo.getPageSize() > 0 ? vo.getPageSize() : 20; + } + + public int getPageIndex() { + return this.getPageIndex((PageVo)null); + } + + public int getPageSize() { + return this.getPageSize((PageVo)null); + } + + public int getExportSize() { + return 2000; + } + +} + diff --git a/src/main/java/com/soft/controller/PurchaseOrderController.java b/src/main/java/com/soft/controller/PurchaseOrderController.java new file mode 100644 index 0000000..13e905e --- /dev/null +++ b/src/main/java/com/soft/controller/PurchaseOrderController.java @@ -0,0 +1,115 @@ +package com.soft.controller; + + +import cn.hutool.core.collection.CollectionUtil; +import com.soft.annotations.HasPermission; +import com.soft.annotations.Valid; +import com.soft.bo.purchase.QueryPurchaseOrderBo; +import com.soft.dto.ApprovePassOrderDTO; +import com.soft.entitys.voice.Product; +import com.soft.entitys.voice.PurchaseOrderDetail; +import com.soft.entitys.voice.SaleOrder; +import com.soft.enums.OrderStatus; +import com.soft.resp.InvokeResult; +import com.soft.resp.InvokeResultBuilder; +import com.soft.service.ProductService; +import com.soft.service.PurchaseOrderDetailService; +import com.soft.service.PurchaseOrderService; +import com.soft.utils.PageResult; +import com.soft.utils.PageResultUtil; +import com.soft.utils.convert.purchase.QueryPurchaseOrderBOUtil; +import com.soft.vo.sale.QuerySaleOrderVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.soft.resp.Result; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("/purchase/order") +@Api(tags = "采购订单") +public class PurchaseOrderController extends BaseController{ + + @Autowired + private PurchaseOrderService purchaseOrderService; + + @Autowired + private PurchaseOrderDetailService purchaseOrderDetailService; + + @Autowired + private ProductService productService; + + + /** + * 根据状态查询采购订单总数 + */ + @ApiOperation("根据状态查询采购订单总数") + @ApiImplicitParams({ + @ApiImplicitParam(value = "订单审核状态(0-待审核,3-审核通过,6-审核拒绝)", name = "status", paramType = "query")}) + @GetMapping("/total") + public Result queryPurchaseTotal( + Integer status) { + if (OrderStatus.valueOfCode(status) == null){ + return Result.success(0); + } + Integer total = purchaseOrderService.getOrderSumByStatus(status); + return Result.success(total); + } + + /** + * 采购订单审核 + */ + @ApiOperation("采购订单审核") + @HasPermission( + value = {"sale:order:approve"}, + userId = "#approveOrder.sysUserId" // 使用SpEL引用方法参数 + ) + @GetMapping("/approve") + public Result approvePass(@RequestBody @Valid ApprovePassOrderDTO dto) { + purchaseOrderService.approvePass(dto); + return Result.success(); + + } + + /** + * 查询未审核采购订单列表 + */ + @ApiOperation("查询未审核采购订单列表") + @GetMapping("/pendList") + public InvokeResult> pendApproveList(QuerySaleOrderVo vo) { + PageResult pageResult = purchaseOrderService.pendApproveList(getPageIndex(vo), getPageSize(vo), vo.getStatus()); + + List datas = pageResult.getDatas(); + List results = null; + + if (!CollectionUtil.isEmpty(datas)) { + results = datas.stream().map(QueryPurchaseOrderBOUtil::toQueryPurchaseOrderBo).collect(Collectors.toList()); + } + //商品名称处理 + if(results!=null){ + for (QueryPurchaseOrderBo result : results) { + List orderDetails=purchaseOrderDetailService.getByOrderId(result.getId()); + + List productNames = new ArrayList<>(); + for (PurchaseOrderDetail orderDetail : orderDetails) { + Product product= productService.findById(orderDetail.getProductId()); + if (product != null && product.getName() != null) { + productNames.add(product.getName()); + } + + } + result.setProductName(String.join(", ", productNames)); + } + } + return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results)); + } +} diff --git a/src/main/java/com/soft/controller/SaleOrderController.java b/src/main/java/com/soft/controller/SaleOrderController.java new file mode 100644 index 0000000..0a461aa --- /dev/null +++ b/src/main/java/com/soft/controller/SaleOrderController.java @@ -0,0 +1,130 @@ +package com.soft.controller; + +import cn.hutool.core.collection.CollectionUtil; +import com.soft.annotations.HasPermission; +import com.soft.annotations.Valid; +import com.soft.bo.sale.QuerySaleOrderBo; +import com.soft.dto.ApprovePassOrderDTO; +import com.soft.dto.SysUserDTO; +import com.soft.entitys.voice.Product; +import com.soft.entitys.voice.SaleOrder; +import com.soft.entitys.voice.SaleOrderDetail; +import com.soft.enums.OrderStatus; +import com.soft.resp.InvokeResult; +import com.soft.resp.InvokeResultBuilder; +import com.soft.service.ProductService; +import com.soft.service.SaleOrderDetailService; +import com.soft.service.SaleOrderService; +import com.soft.service.SysUserService; +import com.soft.utils.PageResult; +import com.soft.utils.PageResultUtil; +import com.soft.utils.convert.sale.QuerySaleOrderBOUtil; +import com.soft.vo.sale.QuerySaleOrderVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.soft.resp.Result; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Api(tags = "销售订单") +@Validated +@RestController +@RequestMapping("/sale/order") +public class SaleOrderController extends BaseController{ + + @Autowired + private SaleOrderService saleOrderService; + + @Autowired + private SysUserService sysUserService; + + @Autowired + private SaleOrderDetailService saleOrderDetailService; + + @Autowired + private ProductService productService; + + /** + * 根据状态查询销售订单总数 + */ + @ApiOperation("根据状态查询销售订单总数") + @ApiImplicitParams({ + @ApiImplicitParam(value = "订单审核状态(0-待审核,3-审核通过,6-审核拒绝)", name = "status", paramType = "query")}) + @GetMapping("/total") + public Result querySaleTotal( + Integer status) { + if (OrderStatus.valueOfCode(status) == null){ + return Result.success(0); + } + Integer total = saleOrderService.getOrderSumByStatus(status); + return Result.success(total); + } + + + /** + * 销售订单审核 + */ + @ApiOperation("销售订单审核") + @HasPermission( + value = {"sale:order:approve"}, //判断用户是否具有审核权限 + userId = "#approveOrder.sysUserId" // 使用SpEL引用方法参数 + ) + @GetMapping("/approve") + public Result approvePass(@RequestBody @Valid ApprovePassOrderDTO approveOrder) { + //1. 查询用户id 关联的后台用户id; 3.判断订单是否存在,且状态是否是已审核状态 + SysUserDTO sysUserDTO = sysUserService.selectById(approveOrder.getSysUserId()); + if (sysUserDTO == null){ + return Result.fail("系统用户不存在,请检查后重试!"); + } + // 审核 修改订单状态 + saleOrderService.approve(approveOrder.getOrderId(), approveOrder.getSysUserId()); + return null; + } + + /** + * 查询未审核销售订单 + */ + @ApiOperation("查询未审核销售订单列表") + @GetMapping("/pendList") + public InvokeResult> pendApproveList(QuerySaleOrderVo vo) { + PageResult pageResult = saleOrderService.pendApproveList(getPageIndex(vo), getPageSize(vo), vo.getStatus()); + + List datas = pageResult.getDatas(); + List results = null; + + //转换 + if (!CollectionUtil.isEmpty(datas)) { + results = datas.stream().map(QuerySaleOrderBOUtil::toQuerySaleOrderBo).collect(Collectors.toList()); + } + //商品名称处理 + if(results!=null){ + for (QuerySaleOrderBo result : results) { + List orderDetails=saleOrderDetailService.getBySaleOrderId(result.getId()); + + List productNames = new ArrayList<>(); + for (SaleOrderDetail orderDetail : orderDetails) { + Product product= productService.findById(orderDetail.getProductId()); + if (product != null && product.getName() != null) { + productNames.add(product.getName()); + } + + } + result.setProductName(String.join(", ", productNames)); + } + } + return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results)); + } + + + +} diff --git a/src/main/java/com/soft/controller/SoftController.java b/src/main/java/com/soft/controller/SoftController.java new file mode 100644 index 0000000..0573e52 --- /dev/null +++ b/src/main/java/com/soft/controller/SoftController.java @@ -0,0 +1,39 @@ +package com.soft.controller; + +import com.soft.dto.SaveDemandDTO; +import com.soft.resp.Result; +import com.soft.service.DemandService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/soft") +@Api(tags = "api") +public class SoftController { + + @Autowired + private DemandService demandService; + + + @PostMapping("/saveSoftWareDemand") + @ApiOperation(value = "提交表单") + public Result saveSoftWareDemand(@RequestBody SaveDemandDTO saveDemandDTO) { + if (saveDemandDTO == null) { + return Result.isEmpty(); + } + Integer result=demandService.saveSoftWareDemand(saveDemandDTO); + + if(result>0){ + return Result.success("ok"); + }else{ + return Result.fail("fail"); + } + + } + +} diff --git a/src/main/java/com/soft/controller/UserController.java b/src/main/java/com/soft/controller/UserController.java new file mode 100644 index 0000000..50ec452 --- /dev/null +++ b/src/main/java/com/soft/controller/UserController.java @@ -0,0 +1,103 @@ +package com.soft.controller; + +import com.soft.dto.BindPhoneNumberDTO; +import com.soft.dto.WeChatLoginRequestDTO; +import com.soft.resp.Result; +import com.soft.entitys.user.SystemUser; +import com.soft.dto.SysUserDTO; +import com.soft.entitys.user.User; +import com.soft.service.SysUserService; +import com.soft.service.UserService; +import com.soft.vo.BindPhoneVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; +import java.util.Objects; + +@RestController +@RequestMapping("/user") +@Api(tags = "用户api") +public class UserController { + + @Autowired + private UserService userService; + + @Autowired + private SysUserService sysUserService; + + + @PostMapping("/wxLogin") + @ApiOperation(value = "微信授权登录") + public Result> login(@RequestBody WeChatLoginRequestDTO weChatLoginRequestDTO) { + + if(weChatLoginRequestDTO==null){ + return null; + } + + Map userInfoMap = userService.getUserInfoMap(weChatLoginRequestDTO); + + return Result.success(userInfoMap); + + } + + @PostMapping("/getPhoneNumber") + @ApiOperation(value = "绑定手机号及上级") + public Result getPhoneNumber(@RequestBody BindPhoneNumberDTO bindPhoneNumberDto){ + if(bindPhoneNumberDto==null){ + return null; + } + + return Result.success(userService.getPhoneNumber(bindPhoneNumberDto.getCode(),bindPhoneNumberDto.getPid(),bindPhoneNumberDto.getUId(),bindPhoneNumberDto.getType())); + } + + + @PostMapping("/bindSysUser") + @ApiOperation(value = "绑定后台系统用户") + public Result bindSysUser(@RequestBody SystemUser systemUser){ + User user = userService.queryByOpenId(systemUser.getOpenId()); + if (user == null ){ + return Result.fail("用户未登录,请先登录!"); + } + String[] tmpArr = systemUser.getUsername().split("@"); + if (tmpArr.length <= 1) { + throw new RuntimeException("用户名或密码错误!"); + } + String tenantId = tmpArr[0]; + String username = tmpArr[1]; + systemUser.setUsername(username); + + SysUserDTO sysUserDTO = sysUserService.query(systemUser); + if(sysUserDTO == null ){ + return Result.fail("绑定失败,系统用户不存在!"); + } + // 查询系统用户是否已经被绑定 + User user1 = userService.queryBySysUserId(sysUserDTO.getId()); + if (Objects.nonNull(user1)){ + return Result.fail("系统用户已被绑定!"); + } + + User updateUser = new User(); + updateUser.setId(user.getId()); + updateUser.setSysUserId(sysUserDTO.getId()); + int update = userService.updateUserById(updateUser); + if (update > 0 ){ + return Result.success("绑定成功!"); + } + return Result.fail("绑定失败,请排查!"); + } + + @GetMapping("/query") + @ApiOperation(value = "查询用户信息") + @ApiImplicitParams({ + @ApiImplicitParam(value = "小程序用户id", name = "id", paramType = "query")}) + public Result bindSysUser(Integer id){ + User user = userService.getUserById(id); + return Result.success(user); + } + +} diff --git a/src/main/java/com/soft/controller/VoiceQueryController.java b/src/main/java/com/soft/controller/VoiceQueryController.java new file mode 100644 index 0000000..132216e --- /dev/null +++ b/src/main/java/com/soft/controller/VoiceQueryController.java @@ -0,0 +1,192 @@ +package com.soft.controller; + +import com.soft.dto.OrderProportionDto; +import com.soft.dto.StatisticsProductStockDto; +import com.soft.dto.VoiceQueryDto; +import com.soft.entitys.Page; +import com.soft.entitys.QueryParams; +import com.soft.resp.Result; +import com.soft.service.VoiceQueryService; +import com.soft.utils.UnsupportedQueryException; +import com.soft.utils.VoiceQueryParser; +import com.soft.vo.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/voice") +@Api(tags = "语音api") +public class VoiceQueryController { + + + @Autowired + private VoiceQueryService voiceQueryService; + + + private final VoiceQueryParser queryParser; + + public VoiceQueryController(VoiceQueryService voiceQueryService) { + this.queryParser = new VoiceQueryParser(); + this.voiceQueryService = voiceQueryService; + + } + + @PostMapping("/handleVoiceQuery") + @ApiOperation(value = "语音助手") + public Result handleVoiceQuery(@RequestBody VoiceQueryDto voiceQueryDto) { + // 1. 解析语音文本 + + try { + QueryParams params = queryParser.parse(voiceQueryDto.getText()); + + // 2. 执行查询 + return Result.success(voiceQueryService.processQuery(params)); + }catch (UnsupportedQueryException e){ +// Map errorResponse = new HashMap<>(); +// errorResponse.put("error", "不支持的查询类型"); +// errorResponse.put("received", voiceQueryDto.getText()); +// errorResponse.put("message", "请尝试以下查询类型:今日采购订单金额、今日销售订单金额"); + + return Result.fail("请尝试以下查询类型:今日采购订单、今日销售订单"); + + }catch (Exception e) { + // 其他异常返回500 + return Result.fail("其他错误,请稍后重试!"); + } + + } + + @GetMapping("/statisticsTodaysOrderData") + @ApiOperation(value = "今日-销售与采购情况") + public Result statisticsTodaysOrderData() { + + OrderDataVo orderDataVo=voiceQueryService.statisticsTodaysOrderData(); + + return Result.success(orderDataVo); + + } + + @GetMapping("/statisticsMonthOrderData") + @ApiOperation(value = "近30日-销售与采购情况") + public Result statisticsMonthOrderData() { + + OrderDataMonthVo orderDataVo=voiceQueryService.statisticsMonthOrderData(); + + return Result.success(orderDataVo); + + } + + @GetMapping("/statisticsWeekOrderData") + @ApiOperation(value = "近7日-销售与采购情况") + public Result statisticsWeekOrderData() { + + OrderDataWeekVo orderDataVo=voiceQueryService.statisticsWeekOrderData(); + + return Result.success(orderDataVo); + + } + + @GetMapping("/orderMonthContrast") + @ApiOperation(value = "每月-订单对比分析") + public Result orderMonthContrast() { + + OrderMonthContrastVo orderContrastVo=voiceQueryService.orderMonthContrast(); + + return Result.success(orderContrastVo); + + } + + @GetMapping("/orderTodaysContrast") + @ApiOperation(value = "每日-订单对比分析") + public Result orderTodaysContrast() { + + OrderTodaysContrastVo orderContrastVo=voiceQueryService.orderTodaysContrast(); + + return Result.success(orderContrastVo); + + } + + @PostMapping("/orderProportion") + @ApiOperation(value = "订单占比") + public Result orderProportion(@RequestBody OrderProportionDto orderProportionDto) { + + OrderProportionVo orderProportionVo=voiceQueryService.orderProportion(orderProportionDto); + + return Result.success(orderProportionVo); + + } + + @GetMapping("/productProductStockProportion") + @ApiOperation(value = "商品库存占比") + public Result> productProductStockProportion() { + + List list=voiceQueryService.productProductStockProportion(); + + return Result.success(list); + + } + + @GetMapping("/saleSalerMonthRank") + @ApiOperation(value = "本月-销售人员排名") + public Result> saleSalerMonthRank() { + + List list=voiceQueryService.saleSalerMonthRank(); + + return Result.success(list); + + } + + @GetMapping("/saleSalerWeekRank") + @ApiOperation(value = "本周-销售人员排名") + public Result> saleSalerWeekRank() { + + List list=voiceQueryService.saleSalerWeekRank(); + + return Result.success(list); + + } + + @GetMapping("/saleOrderGrossMargin") + @ApiOperation(value = "最近12个月-销售毛利分析") + public Result saleOrderGrossMargin() { + + SaleOrderGrossMarginVo saleOrderGrossMarginVo=voiceQueryService.saleOrderGrossMargin(); + + return Result.success(saleOrderGrossMarginVo); + + } + + @GetMapping("/saleOrderLastYearProfit") + @ApiOperation(value = "去年-销售毛利分析") + public Result saleOrderLastYearProfit() { + + SaleOrderLastYearProfitVo saleOrderLastYearProfitVo=voiceQueryService.saleOrderLastYearProfit(); + + return Result.success(saleOrderLastYearProfitVo); + + } + + @GetMapping("/saleOrderCurrentYearAmount") + @ApiOperation(value = "年度累计销售额,销售数量,销售成本,毛利率") + public Result saleOrderCurrentYearAmount() { + + SaleOrderCurrentYearAmountVo saleOrderCurrentYearAmountVo=voiceQueryService.saleOrderCurrentYearAmount(); + + return Result.success(saleOrderCurrentYearAmountVo); + + } + + @PostMapping("/statisticsProductStock") + @ApiOperation(value = "商品库存") + public Result>> statisticsProductStock(@RequestBody StatisticsProductStockDto statisticsProductStockDto) { + + Page> list=voiceQueryService.statisticsProductStock(statisticsProductStockDto); + return Result.success(list); + } + + +} diff --git a/src/main/java/com/soft/dto/ApprovePassOrderDTO.java b/src/main/java/com/soft/dto/ApprovePassOrderDTO.java new file mode 100644 index 0000000..8df1e80 --- /dev/null +++ b/src/main/java/com/soft/dto/ApprovePassOrderDTO.java @@ -0,0 +1,18 @@ +package com.soft.dto; + + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NonNull; + +@Data +public class ApprovePassOrderDTO { + + @ApiModelProperty(value = "订单id",required = true) + @NonNull + private String orderId; + + @ApiModelProperty(value = "审核人-后台用户Id",required = true) + @NonNull + private String sysUserId; +} diff --git a/src/main/java/com/soft/dto/BaseDto.java b/src/main/java/com/soft/dto/BaseDto.java new file mode 100644 index 0000000..19a25fc --- /dev/null +++ b/src/main/java/com/soft/dto/BaseDto.java @@ -0,0 +1,4 @@ +package com.soft.dto; + +public interface BaseDto { +} diff --git a/src/main/java/com/soft/dto/BindPhoneNumberDTO.java b/src/main/java/com/soft/dto/BindPhoneNumberDTO.java new file mode 100644 index 0000000..805e527 --- /dev/null +++ b/src/main/java/com/soft/dto/BindPhoneNumberDTO.java @@ -0,0 +1,21 @@ +package com.soft.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class BindPhoneNumberDTO { + + @ApiModelProperty(value = "code",required = true) + private String code; + + @ApiModelProperty(value = "推荐人ID") + private Integer pid; + + @ApiModelProperty(value = "用户ID") + private Integer uId; + + @ApiModelProperty(value = "推广类型 1:推广代理") + private Integer type; + +} diff --git a/src/main/java/com/soft/dto/OrderProportionDto.java b/src/main/java/com/soft/dto/OrderProportionDto.java new file mode 100644 index 0000000..10ec9b7 --- /dev/null +++ b/src/main/java/com/soft/dto/OrderProportionDto.java @@ -0,0 +1,11 @@ +package com.soft.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class OrderProportionDto { + + @ApiModelProperty(value = "月份") + private Integer month; +} diff --git a/src/main/java/com/soft/dto/PageUtilDTO.java b/src/main/java/com/soft/dto/PageUtilDTO.java new file mode 100644 index 0000000..6efa5d0 --- /dev/null +++ b/src/main/java/com/soft/dto/PageUtilDTO.java @@ -0,0 +1,14 @@ +package com.soft.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class PageUtilDTO { + + @ApiModelProperty(value = "起始页") + private Integer pageNum; + + @ApiModelProperty(value = "一页数量") + private Integer pageSize; +} diff --git a/src/main/java/com/soft/dto/SaveDemandDTO.java b/src/main/java/com/soft/dto/SaveDemandDTO.java new file mode 100644 index 0000000..9bd577e --- /dev/null +++ b/src/main/java/com/soft/dto/SaveDemandDTO.java @@ -0,0 +1,51 @@ +package com.soft.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class SaveDemandDTO { + + + @ApiModelProperty(value = "用户ID") + private Integer userId; + + @ApiModelProperty(value = "公司名") + private String companyName; + + @ApiModelProperty(value = "公司地址") + private String companyAddress; + + @ApiModelProperty(value = "对接人") + private String person; + + @ApiModelProperty(value = "对接人手机号") + private String personPhone; + + @ApiModelProperty(value = "需要使用的系统") + private String demandSystem; + + @ApiModelProperty(value = "邮箱") + private String email; + + @ApiModelProperty(value = "公司类型") + private String companyType; + + @ApiModelProperty(value = "公司规模") + private String companyScale; + + @ApiModelProperty(value = "公司经营范围") + private String companyScope; + + @ApiModelProperty(value = "公司组织架构") + private String companyFramework; + + @ApiModelProperty(value = "公司业务范围") + private String companyBusinessScope; + + @ApiModelProperty(value = "意向代理级别") + private String agentLevel; + + @ApiModelProperty(value = "备注") + private String remarks; +} diff --git a/src/main/java/com/soft/dto/StatisticsProductStockDto.java b/src/main/java/com/soft/dto/StatisticsProductStockDto.java new file mode 100644 index 0000000..80802f2 --- /dev/null +++ b/src/main/java/com/soft/dto/StatisticsProductStockDto.java @@ -0,0 +1,14 @@ +package com.soft.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class StatisticsProductStockDto { + + @ApiModelProperty(value = "起始页",required = true) + private Integer pageNum; + + @ApiModelProperty(value = "一页数量",required = true) + private Integer pageSize; +} diff --git a/src/main/java/com/soft/dto/SysUserDTO.java b/src/main/java/com/soft/dto/SysUserDTO.java new file mode 100644 index 0000000..6e52f6c --- /dev/null +++ b/src/main/java/com/soft/dto/SysUserDTO.java @@ -0,0 +1,91 @@ +package com.soft.dto; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.Date; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-07-04 + */ +@Data +@TableName("sys_user") +public class SysUserDTO { + + private String id; + + /** + * 编号 + */ + private String code; + + /** + * 姓名 + */ + private String name; + + /** + * 用户名 + */ + private String username; + + /** + * 密码 + */ + private String password; + + /** + * 邮箱 + */ + private String email; + + /** + * 联系电话 + */ + private String telephone; + + + /** + * 状态 1-在用 0停用 + */ + private Boolean available; + + /** + * 锁定状态 + */ + private Boolean lockStatus; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + private String createById; + + /** + * 创建人 新增时赋值 + */ + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + private Date createTime; + + private String updateBy; + + private String updateById; + + private Date updateTime; +} diff --git a/src/main/java/com/soft/dto/UserIdDTO.java b/src/main/java/com/soft/dto/UserIdDTO.java new file mode 100644 index 0000000..2dc2334 --- /dev/null +++ b/src/main/java/com/soft/dto/UserIdDTO.java @@ -0,0 +1,11 @@ +package com.soft.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class UserIdDTO { + + @ApiModelProperty(value = "用户ID") + private Integer userId; +} diff --git a/src/main/java/com/soft/dto/VoiceQueryDto.java b/src/main/java/com/soft/dto/VoiceQueryDto.java new file mode 100644 index 0000000..a6baf02 --- /dev/null +++ b/src/main/java/com/soft/dto/VoiceQueryDto.java @@ -0,0 +1,9 @@ +package com.soft.dto; + +import lombok.Data; + +@Data +public class VoiceQueryDto { + + private String text; +} diff --git a/src/main/java/com/soft/dto/WeChatLoginRequestDTO.java b/src/main/java/com/soft/dto/WeChatLoginRequestDTO.java new file mode 100644 index 0000000..04a3dc0 --- /dev/null +++ b/src/main/java/com/soft/dto/WeChatLoginRequestDTO.java @@ -0,0 +1,17 @@ +package com.soft.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class WeChatLoginRequestDTO { + + @ApiModelProperty(value = "微信code", required = true) + private String code; + + @ApiModelProperty(value = "用户敏感字段",required = true) + private String encryptedData; + + @ApiModelProperty(value = "解密向量",required = true) + private String iv; +} diff --git a/src/main/java/com/soft/entitys/BaseEntity.java b/src/main/java/com/soft/entitys/BaseEntity.java new file mode 100644 index 0000000..9016014 --- /dev/null +++ b/src/main/java/com/soft/entitys/BaseEntity.java @@ -0,0 +1,35 @@ +package com.soft.entitys; + +import java.io.Serializable; + +public abstract class BaseEntity implements Serializable { + private static final long serialVersionUID = 1L; + + public BaseEntity() { + } + + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (!(o instanceof BaseEntity)) { + return false; + } else { + BaseEntity other = (BaseEntity)o; + return other.canEqual(this); + } + } + + protected boolean canEqual(Object other) { + return other instanceof BaseEntity; + } + + public int hashCode() { + boolean result = true; + return 1; + } + + public String toString() { + return "BaseEntity()"; + } +} + diff --git a/src/main/java/com/soft/entitys/OrderChart.java b/src/main/java/com/soft/entitys/OrderChart.java new file mode 100644 index 0000000..53ea386 --- /dev/null +++ b/src/main/java/com/soft/entitys/OrderChart.java @@ -0,0 +1,55 @@ +package com.soft.entitys; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-11-19 + */ +@Data +@TableName("tbl_order_chart") +public class OrderChart extends BaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * ID + */ + private String id; + + /** + * 单据总金额 + */ + private BigDecimal totalAmount; + + /** + * 创建时间 新增时赋值 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createTime; + + /** + * 创建日期 + */ + private String createDate; + + /** + * 创建时间(小时) + */ + private String createHour; + + /** + * 业务类型 + */ + private int bizType; +} diff --git a/src/main/java/com/soft/entitys/OrderPayType.java b/src/main/java/com/soft/entitys/OrderPayType.java new file mode 100644 index 0000000..da48ec0 --- /dev/null +++ b/src/main/java/com/soft/entitys/OrderPayType.java @@ -0,0 +1,47 @@ +package com.soft.entitys; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2023-03-28 + */ +@Data +@TableName("tbl_order_pay_type") +public class OrderPayType { + + public static final String CACHE_NAME = "OrderPayType"; + private static final long serialVersionUID = 1L; + + /** + * ID + */ + private String id; + + /** + * 订单ID + */ + private String orderId; + + /** + * 支付方式ID + */ + private String payTypeId; + + /** + * 支付金额 + */ + private BigDecimal payAmount; + + /** + * 支付内容 + */ + private String text; +} diff --git a/src/main/java/com/soft/entitys/Page.java b/src/main/java/com/soft/entitys/Page.java new file mode 100644 index 0000000..15d601e --- /dev/null +++ b/src/main/java/com/soft/entitys/Page.java @@ -0,0 +1,119 @@ +package com.soft.entitys; + +import io.swagger.annotations.ApiModelProperty; + +public class Page { + + @ApiModelProperty("当前页数") + private int pageNum; + + @ApiModelProperty("总记录数") + private int total; + + @ApiModelProperty("总页数") + private int pageTotal; + + @ApiModelProperty("一页记录数") + private int pageSize; + + @ApiModelProperty("当前页记录数") + private int size; + + @ApiModelProperty("是否还有下一页") + private boolean hasNext; + + @ApiModelProperty("数据记录") + private T data; + + public Page(int pageNum, int total, int pageSize, T data){ + this.pageNum=pageNum; + this.pageSize=pageSize; + this.total = total; + this.data=data; + int model=total%pageSize; + boolean bool=model==0; + int pageTotal=bool?total/pageSize:total/pageSize+1; + this.pageTotal=pageTotal; + if(pageTotal>pageNum){ + this.hasNext=true; + this.size=pageSize; + }else if(pageTotal==pageNum){ + this.size=bool?pageSize:model; + } + } + + public Page(){ + + } + + public static Integer getStartNum(Integer pageNum, Integer pageSize){ + return (pageNum-1)*pageSize; + } + + public static String sqlLimit(Integer pageNum, Integer pageSize){ + Integer startNum=getStartNum(pageNum,pageSize); + return "LIMIT "+startNum+","+pageSize; + } + + public int getPageNum() { + return pageNum; + } + + public void setPageNum(int pageNum) { + this.pageNum = pageNum; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + int pageTotal=total%pageSize==0?total/pageSize:total/pageSize+1; + this.pageTotal=pageTotal; + if(pageTotal>pageNum){ + hasNext=true; + } + this.total = total; + } + + public int getPageTotal() { + return pageTotal; + } + + public void setPageTotal(int pageTotal) { + this.pageTotal = pageTotal; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public boolean isHasNext() { + return hasNext; + } + + public void setHasNext(boolean hasNext) { + this.hasNext = hasNext; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + +} diff --git a/src/main/java/com/soft/entitys/QueryParams.java b/src/main/java/com/soft/entitys/QueryParams.java new file mode 100644 index 0000000..0c28d70 --- /dev/null +++ b/src/main/java/com/soft/entitys/QueryParams.java @@ -0,0 +1,18 @@ +package com.soft.entitys; + +import com.soft.enums.QueryType; +import lombok.Data; + +import java.time.LocalDate; + +@Data +public class QueryParams { + + private QueryType type; + private String productName; + private String userName; + private LocalDate date; + private String customerName; + private String queryDate; // 新增查询日期字段 + +} diff --git a/src/main/java/com/soft/entitys/demand/Demand.java b/src/main/java/com/soft/entitys/demand/Demand.java new file mode 100644 index 0000000..e2c5d23 --- /dev/null +++ b/src/main/java/com/soft/entitys/demand/Demand.java @@ -0,0 +1,56 @@ +package com.soft.entitys.demand; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@TableName("soft_demand") +@Api(tags = "表单收集表") +public class Demand { + + private Integer id; + + @ApiModelProperty(value = "用户ID") + private Integer userId; + + @ApiModelProperty(value = "公司名") + private String companyName; + + @ApiModelProperty(value = "公司地址") + private String companyAddress; + + @ApiModelProperty(value = "对接人") + private String person; + + @ApiModelProperty(value = "对接人手机号") + private String personPhone; + + @ApiModelProperty(value = "需要使用的系统") + private String demandSystem; + + @ApiModelProperty(value = "邮箱") + private String email; + + @ApiModelProperty(value = "公司类型") + private String companyType; + + @ApiModelProperty(value = "公司规模") + private String companyScale; + + @ApiModelProperty(value = "公司经营范围") + private String companyScope; + + @ApiModelProperty(value = "公司组织架构") + private String companyFramework; + + @ApiModelProperty(value = "公司业务范围") + private String companyBusinessScope; + + @ApiModelProperty(value = "意向代理级别") + private String agentLevel; + + @ApiModelProperty(value = "备注") + private String remarks; +} diff --git a/src/main/java/com/soft/entitys/purchase/PurchaseOrderStatus.java b/src/main/java/com/soft/entitys/purchase/PurchaseOrderStatus.java new file mode 100644 index 0000000..7244c65 --- /dev/null +++ b/src/main/java/com/soft/entitys/purchase/PurchaseOrderStatus.java @@ -0,0 +1,4 @@ +package com.soft.entitys.purchase; + +public class PurchaseOrderStatus { +} diff --git a/src/main/java/com/soft/entitys/sale/SaleOrderDetailBundle.java b/src/main/java/com/soft/entitys/sale/SaleOrderDetailBundle.java new file mode 100644 index 0000000..be77ba2 --- /dev/null +++ b/src/main/java/com/soft/entitys/sale/SaleOrderDetailBundle.java @@ -0,0 +1,77 @@ +package com.soft.entitys.sale; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2023-05-26 + */ +@Data +@TableName("tbl_sale_order_detail_bundle") +public class SaleOrderDetailBundle{ + + public static final String CACHE_NAME = "SaleOrderDetailBundle"; + private static final long serialVersionUID = 1L; + + /** + * ID + */ + private String id; + + /** + * 销售单ID + */ + private String orderId; + + /** + * 明细ID + */ + private String detailId; + + /** + * 组合商品ID + */ + private String mainProductId; + + /** + * 组合商品数量 + */ + private Integer orderNum; + + /** + * 单品ID + */ + private String productId; + + /** + * 单品数量 + */ + private Integer productOrderNum; + + /** + * 单品原价 + */ + private BigDecimal productOriPrice; + + /** + * 单品含税价格 + */ + private BigDecimal productTaxPrice; + + /** + * 单品税率 + */ + private BigDecimal productTaxRate; + + /** + * 单品明细ID + */ + private String productDetailId; +} diff --git a/src/main/java/com/soft/entitys/sys/SysMenu.java b/src/main/java/com/soft/entitys/sys/SysMenu.java new file mode 100644 index 0000000..964e54c --- /dev/null +++ b/src/main/java/com/soft/entitys/sys/SysMenu.java @@ -0,0 +1,148 @@ +package com.soft.entitys.sys; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.soft.enums.system.SysMenuComponentType; +import com.soft.enums.system.SysMenuDisplay; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + *

+ * 系统菜单 + *

+ * + * @author zmj + * @since 2021-05-10 + */ +@Data +@TableName("sys_menu") +public class SysMenu { + + private static final long serialVersionUID = 1L; + + public static final String CACHE_NAME = "SysMenu"; + + /** + * ID + */ + private String id; + + /** + * 编号 + */ + private String code; + + /** + * 名称(前端使用) + */ + private String name; + + /** + * 标题 + */ + private String title; + + /** + * 图标 + */ + private String icon; + + /** + * 组件类型 + */ + private SysMenuComponentType componentType; + + /** + * 组件(前端使用) + */ + private String component; + + /** + * 自定义请求参数 + */ + private String requestParam; + + /** + * 父级ID + */ + private String parentId; + + /** + * 路由路径(前端使用) + */ + private String path; + + /** + * 是否缓存(前端使用) + */ + private Boolean noCache; + + /** + * 类型 0-目录 1-菜单 2-功能 + */ + private SysMenuDisplay display; + + /** + * 是否隐藏(前端使用) + */ + private Boolean hidden; + + /** + * 权限 + */ + private String permission; + + /** + * 是否特殊菜单 + */ + private Boolean isSpecial; + + /** + * 状态 + */ + private Boolean available; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + @TableField(fill = FieldFill.INSERT) + private String createById; + + /** + * 创建人 新增时赋值 + */ + @TableField(fill = FieldFill.INSERT) + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createTime; + + /** + * 修改人 新增和修改时赋值 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private LocalDateTime updateTime; +} diff --git a/src/main/java/com/soft/entitys/sys/SysRoleMenu.java b/src/main/java/com/soft/entitys/sys/SysRoleMenu.java new file mode 100644 index 0000000..d3d02c9 --- /dev/null +++ b/src/main/java/com/soft/entitys/sys/SysRoleMenu.java @@ -0,0 +1,36 @@ +package com.soft.entitys.sys; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-07-04 + */ +@Data +@TableName("sys_role_menu") +public class SysRoleMenu{ + + private static final long serialVersionUID = 1L; + + /** + * ID + */ + private String id; + + /** + * 角色ID + */ + private String roleId; + + /** + * 菜单ID + */ + private String menuId; + + +} diff --git a/src/main/java/com/soft/entitys/sys/SysUserRole.java b/src/main/java/com/soft/entitys/sys/SysUserRole.java new file mode 100644 index 0000000..fdbfbde --- /dev/null +++ b/src/main/java/com/soft/entitys/sys/SysUserRole.java @@ -0,0 +1,34 @@ +package com.soft.entitys.sys; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-07-04 + */ +@Data +@TableName("sys_user_role") +public class SysUserRole{ + + private static final long serialVersionUID = 1L; + + /** + * ID + */ + private String id; + + /** + * 用户ID + */ + private String userId; + + /** + * 角色ID + */ + private String roleId; +} diff --git a/src/main/java/com/soft/entitys/user/Agent.java b/src/main/java/com/soft/entitys/user/Agent.java new file mode 100644 index 0000000..2611d5a --- /dev/null +++ b/src/main/java/com/soft/entitys/user/Agent.java @@ -0,0 +1,35 @@ +package com.soft.entitys.user; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("soft_agent") +@Api(tags = "代理表") +public class Agent { + + private Integer id; + + @ApiModelProperty(value = "代理类型") + private Integer type; + + @ApiModelProperty(value = "代理等级") + private Integer level; + + @ApiModelProperty(value = "利润返点") + private String profitRebate; + + @ApiModelProperty(value = "利润比率") + private String profit; + + @ApiModelProperty(value = "升级所需") + private Integer count; + + @ApiModelProperty(value = "添加时间") + private Date addTime; + +} diff --git a/src/main/java/com/soft/entitys/user/Category.java b/src/main/java/com/soft/entitys/user/Category.java new file mode 100644 index 0000000..7b8e802 --- /dev/null +++ b/src/main/java/com/soft/entitys/user/Category.java @@ -0,0 +1,31 @@ +package com.soft.entitys.user; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("soft_category") +@Api(tags = "分类表") +public class Category { + + private Integer id; + + @ApiModelProperty(value = "pid") + private Integer pid; + + @ApiModelProperty(value = "栏目类型") + private String type; + + @ApiModelProperty(value = "栏目名") + private String name; + + @ApiModelProperty(value = "状态") + private Integer status; + + @ApiModelProperty(value = "创建时间") + private Date createTime; +} diff --git a/src/main/java/com/soft/entitys/user/SystemUser.java b/src/main/java/com/soft/entitys/user/SystemUser.java new file mode 100644 index 0000000..4b7087c --- /dev/null +++ b/src/main/java/com/soft/entitys/user/SystemUser.java @@ -0,0 +1,36 @@ +package com.soft.entitys.user; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + + +@Data +@TableName("sys_user") +@Api(tags = "系统用户表") +public class SystemUser { + + /** + * 用户名 + */ + @ApiModelProperty(value = "微信用户openId", required = true) + @NotBlank(message = "微信用户openId不能为空!") + private String openId; + + /** + * 用户名 + */ + @ApiModelProperty(value = "用户名", required = true) + @NotBlank(message = "用户名不能为空!") + private String username; + + /** + * 密码 + */ + @ApiModelProperty(value = "密码", required = true) + @NotBlank(message = "密码不能为空!") + private String password; +} diff --git a/src/main/java/com/soft/entitys/user/User.java b/src/main/java/com/soft/entitys/user/User.java new file mode 100644 index 0000000..51d5903 --- /dev/null +++ b/src/main/java/com/soft/entitys/user/User.java @@ -0,0 +1,50 @@ +package com.soft.entitys.user; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("soft_user") +@Api(tags = "用户表") +public class User { + + @ApiModelProperty(value = "用户id") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "绑定ID") + private Integer pid; + + @ApiModelProperty(value = "推广员关联时间") + private Date spreadTime; + + @ApiModelProperty(value = "用户昵称") + private String nickName; + + @ApiModelProperty(value = "等级") + private Integer levelId; + + @ApiModelProperty(value = "用户头像") + private String avatar; + + @ApiModelProperty(value = "手机号") + private String phone; + + @ApiModelProperty(value = "小程序唯一标识") + private String openId;//小程序唯一标识 + + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "最后一次登录时间") + private Date lastLoginTime; + + @ApiModelProperty(value = "后台系统用户地id") + private String sysUserId; +} diff --git a/src/main/java/com/soft/entitys/voice/Customer.java b/src/main/java/com/soft/entitys/voice/Customer.java new file mode 100644 index 0000000..a0b32ed --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/Customer.java @@ -0,0 +1,136 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("base_data_customer") +public class Customer { + /** + * ID + */ + private String id; + + /** + * 编号 + */ + private String code; + + /** + * 名称 + */ + private String name; + + /** + * 简码 + */ + private String mnemonicCode; + + /** + * 联系人 + */ + private String contact; + + /** + * 联系电话 + */ + private String telephone; + + /** + * 电子邮箱 + */ + private String email; + + /** + * 邮编 + */ + private String zipCode; + + /** + * 传真 + */ + private String fax; + + /** + * 地区ID + */ + private String cityId; + + /** + * 地址 + */ + private String address; + + + + /** + * 统一社会信用代码 + */ + private String creditCode; + + /** + * 纳税人识别号 + */ + private String taxIdentifyNo; + + /** + * 开户银行 + */ + private String bankName; + + /** + * 户名 + */ + private String accountName; + + /** + * 银行账号 + */ + private String accountNo; + + /** + * 状态 + */ + private Boolean available; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + private String createById; + + /** + * 创建人 新增时赋值 + */ + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + private Date createTime; + + /** + * 修改人 新增和修改时赋值 + */ + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + private Date updateTime; + + +} diff --git a/src/main/java/com/soft/entitys/voice/Product.java b/src/main/java/com/soft/entitys/voice/Product.java new file mode 100644 index 0000000..2d0e3cb --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/Product.java @@ -0,0 +1,117 @@ +package com.soft.entitys.voice; + + +import com.baomidou.mybatisplus.annotation.TableName; +import com.soft.enums.ProductType; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 商品 + *

+ * + * @author zmj + * @since 2021-07-11 + */ +@Data +@TableName("base_data_product") +public class Product { + + + /** + * ID + */ + + private String id; + + /** + * 编号 + */ + private String code; + + /** + * 名称 + */ + private String name; + + /** + * 简称 + */ + private String shortName; + + /** + * SKU + */ + private String skuCode; + + /** + * 简码 + */ + private String externalCode; + + /** + * 分类ID + */ + private String categoryId; + + /** + * 品牌ID + */ + private String brandId; + + /** + * 商品类型 + */ + private int productType; + + + /** + * 进项税率(%) + */ + private BigDecimal taxRate; + + /** + * 销项税率(%) + */ + private BigDecimal saleTaxRate; + + /** + * 规格 + */ + private String spec; + + /** + * 单位 + */ + private String unit; + + /** + * 重量(kg) + */ + private BigDecimal weight; + + /** + * 体积(cm3) + */ + private BigDecimal volume; + + /** + * 状态 + */ + private Boolean available; + + private String createById; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private String updateById; + + private Date updateTime; +} diff --git a/src/main/java/com/soft/entitys/voice/ProductStock.java b/src/main/java/com/soft/entitys/voice/ProductStock.java new file mode 100644 index 0000000..09a52ac --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/ProductStock.java @@ -0,0 +1,50 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-09-12 + */ +@Data +@TableName("tbl_product_stock") +public class ProductStock { + + + /** + * ID + */ + private String id; + + /** + * 仓库ID + */ + private String scId; + + /** + * 商品ID + */ + private String productId; + + /** + * 库存数量 + */ + private Integer stockNum; + + /** + * 含税价格 + */ + private BigDecimal taxPrice; + + /** + * 含税金额 + */ + private BigDecimal taxAmount; +} diff --git a/src/main/java/com/soft/entitys/voice/ProductStockLog.java b/src/main/java/com/soft/entitys/voice/ProductStockLog.java new file mode 100644 index 0000000..05ce251 --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/ProductStockLog.java @@ -0,0 +1,94 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.Date; + + +@Data +@TableName("tbl_product_stock_log") +public class ProductStockLog{ + + + + /** + * ID + */ + private String id; + + /** + * 仓库ID + */ + private String scId; + + /** + * 商品ID + */ + private String productId; + + /** + * 原库存数量 + */ + private Integer oriStockNum; + + /** + * 现库存数量 + */ + private Integer curStockNum; + + /** + * 原含税成本价 + */ + private BigDecimal oriTaxPrice; + + /** + * 现含税成本价 + */ + private BigDecimal curTaxPrice; + + /** + * 变动库存数量 + */ + private Integer stockNum; + + /** + * 变动含税金额 + */ + private BigDecimal taxAmount; + + + private String createById; + + + private String createBy; + + + private Date createTime; + + /** + * 业务单据ID + */ + private String bizId; + + /** + * 业务单据号 + */ + private String bizCode; + + /** + * 业务单据明细ID + */ + private String bizDetailId; + + /** + * 业务类型 + */ + private Integer bizType; + + +} diff --git a/src/main/java/com/soft/entitys/voice/PurchaseOrder.java b/src/main/java/com/soft/entitys/voice/PurchaseOrder.java new file mode 100644 index 0000000..3b7904d --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/PurchaseOrder.java @@ -0,0 +1,135 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.TableName; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.Date; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-09-12 + */ +@Data +@TableName("tbl_purchase_order") +public class PurchaseOrder{ + + + /** + * ID + */ + private String id; + + /** + * 单号 + */ + private String code; + + /** + * 仓库ID + */ + private String scId; + + /** + * 供应商ID + */ + private String supplierId; + + /** + * 采购员ID + */ + private String purchaserId; + + /** + * 预计到货日期 + */ + private LocalDate expectArriveDate; + + /** + * 采购数量 + */ + private Integer totalNum; + + /** + * 赠品数量 + */ + private Integer totalGiftNum; + + /** + * 采购金额 + */ + private BigDecimal totalAmount; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + + private String createById; + + /** + * 创建人 新增时赋值 + */ + + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + + private Date createTime; + + /** + * 修改人 新增和修改时赋值 + */ + + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + + private Date updateTime; + + /** + * 审核人 + */ + private String approveBy; + + /** + * 审核时间 + */ + private Date approveTime; + + /** + * 订单审核状态 + */ + + private Integer status; + + /** + * 拒绝原因 + */ + private String refuseReason; + + /** + * 关联订单号 + */ + private String linkNumber; +} diff --git a/src/main/java/com/soft/entitys/voice/PurchaseOrderDetail.java b/src/main/java/com/soft/entitys/voice/PurchaseOrderDetail.java new file mode 100644 index 0000000..975346a --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/PurchaseOrderDetail.java @@ -0,0 +1,71 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-09-12 + */ +@Data +@TableName("tbl_purchase_order_detail") +public class PurchaseOrderDetail { + + private static final long serialVersionUID = 1L; + + /** + * ID + */ + private String id; + + /** + * 订单ID + */ + private String orderId; + + /** + * 商品ID + */ + private String productId; + + /** + * 采购数量 + */ + private Integer orderNum; + + /** + * 采购价 + */ + private BigDecimal taxPrice; + + /** + * 是否赠品 + */ + private Boolean isGift; + + /** + * 税率(%) + */ + private BigDecimal taxRate; + + /** + * 备注 + */ + private String description; + + /** + * 排序编号 + */ + private Integer orderNo; + + /** + * 已收货数量 + */ + private Integer receiveNum; +} diff --git a/src/main/java/com/soft/entitys/voice/PurchaseReturn.java b/src/main/java/com/soft/entitys/voice/PurchaseReturn.java new file mode 100644 index 0000000..65c8a41 --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/PurchaseReturn.java @@ -0,0 +1,128 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.Date; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-10-16 + */ +@Data +@TableName("tbl_purchase_return") +public class PurchaseReturn { + + + /** + * ID + */ + private String id; + + /** + * 单号 + */ + private String code; + + /** + * 仓库ID + */ + private String scId; + + /** + * 供应商ID + */ + private String supplierId; + + /** + * 采购员ID + */ + private String purchaserId; + + /** + * 付款日期 + */ + private LocalDate paymentDate; + + /** + * 收货单ID + */ + private String receiveSheetId; + + /** + * 商品数量 + */ + private Integer totalNum; + + /** + * 赠品数量 + */ + private Integer totalGiftNum; + + /** + * 退货金额 + */ + private BigDecimal totalAmount; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + private String createById; + + /** + * 创建人 新增时赋值 + */ + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + private Date createTime; + + /** + * 修改人 新增和修改时赋值 + */ + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + private Date updateTime; + + /** + * 审核人 + */ + private String approveBy; + + /** + * 审核时间 + */ + private Date approveTime; + + + /** + * 拒绝原因 + */ + private String refuseReason; + + +} diff --git a/src/main/java/com/soft/entitys/voice/PurchaseReturnDetail.java b/src/main/java/com/soft/entitys/voice/PurchaseReturnDetail.java new file mode 100644 index 0000000..66033c1 --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/PurchaseReturnDetail.java @@ -0,0 +1,72 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-10-16 + */ +@Data +@TableName("tbl_purchase_return_detail") +public class PurchaseReturnDetail { + + + /** + * ID + */ + private String id; + + /** + * 收货单ID + */ + private String returnId; + + /** + * 商品ID + */ + private String productId; + + /** + * 退货数量 + */ + private Integer returnNum; + + /** + * 采购价 + */ + private BigDecimal taxPrice; + + /** + * 是否赠品 + */ + private Boolean isGift; + + /** + * 税率(%) + */ + private BigDecimal taxRate; + + /** + * 备注 + */ + private String description; + + /** + * 排序编号 + */ + private Integer orderNo; + + /** + * 收货单明细ID + */ + private String receiveSheetDetailId; + + +} diff --git a/src/main/java/com/soft/entitys/voice/SaleOrder.java b/src/main/java/com/soft/entitys/voice/SaleOrder.java new file mode 100644 index 0000000..e6deeb3 --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/SaleOrder.java @@ -0,0 +1,155 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.*; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +@TableName("tbl_sale_order") +public class SaleOrder { + + /** + * ID + */ + @TableId(value = "id", type = IdType.AUTO) + private String id; + + /** + * 单号 + */ + private String code; + + /** + * 仓库ID + */ + private String scId; + + /** + * 客户ID + */ + private String customerId; + + /** + * 销售员ID + */ + private String salerId; + + /** + * 销售数量 + */ + private Integer totalNum; + + /** + * 赠品数量 + */ + private Integer totalGiftNum; + + /** + * 销售金额 + */ + private BigDecimal totalAmount; + + /** + * 备注 + */ + private String description; + + + private String createById; + + /** + * 创建人 新增时赋值 + */ + + private String createBy; + + + private Date createTime; + + /** + * 修改人 新增和修改时赋值 + */ + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + + private Date updateTime; + + /** + * 审核人 + */ + private String approveBy; + + /** + * 审核时间 + */ + private Date approveTime; + + /** + * 审核状态 + */ + private Integer status; + + /** + * 拒绝原因 + */ + private String refuseReason; + + /** + * 本单利润 + */ + private BigDecimal thisOrderProfit; + + /** + * 客户费用 + */ + private BigDecimal customMoney; + + /** + * 采购价 + */ + private BigDecimal purchaseDecimal; + + /** + * 采购总价 + */ + private BigDecimal totalPurchasePrice; + + /** + * 运费 + */ + private BigDecimal shippingFee; + + /** + * 是否租赁订单 + */ + private Integer isLease; + + + private Integer purchaseStatus; + + /** + * 租赁起始日期 + */ + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date leaseStartTime; + + /** + * 租赁结束日期 + */ + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date leaseEndTime; +} diff --git a/src/main/java/com/soft/entitys/voice/SaleOrderDetail.java b/src/main/java/com/soft/entitys/voice/SaleOrderDetail.java new file mode 100644 index 0000000..8cc8b58 --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/SaleOrderDetail.java @@ -0,0 +1,102 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.TableName; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-10-21 + */ +@Data +@TableName("tbl_sale_order_detail") +public class SaleOrderDetail { + + + /** + * ID + */ + private String id; + + /** + * 订单ID + */ + private String orderId; + + /** + * 商品ID + */ + private String productId; + + /** + * 销售数量 + */ + private Integer orderNum; + + /** + * 原价 + */ + private BigDecimal oriPrice; + + /** + * 现价 + */ + private BigDecimal taxPrice; + + /** + * 折扣率(%) + */ + private BigDecimal discountRate; + + /** + * 是否赠品 + */ + private Boolean isGift; + + /** + * 税率(%) + */ + private BigDecimal taxRate; + + /** + * 备注 + */ + private String description; + + /** + * 排序编号 + */ + private Integer orderNo; + + /** + * 已出库数量 + */ + private Integer outNum; + + /** + * 组合商品原始明细ID + */ + private String oriBundleDetailId; + + /** + * 采购价 + */ + private BigDecimal purchaseDecimal; + + /** + * 采购总价 + */ + private BigDecimal totalPurchasePrice; + + + /** + * 仓库ID + */ + private String scId; +} diff --git a/src/main/java/com/soft/entitys/voice/SaleOutSheet.java b/src/main/java/com/soft/entitys/voice/SaleOutSheet.java new file mode 100644 index 0000000..1ff665e --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/SaleOutSheet.java @@ -0,0 +1,120 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-10-26 + */ +@Data +@TableName("tbl_sale_out_sheet") +public class SaleOutSheet { + + + /** + * ID + */ + private String id; + + /** + * 单号 + */ + private String code; + + /** + * 仓库ID + */ + private String scId; + + /** + * 客户ID + */ + private String customerId; + + /** + * 销售员ID + */ + private String salerId; + + /** + * 付款日期 + */ + private Date paymentDate; + + /** + * 销售单ID + */ + private String saleOrderId; + + /** + * 商品数量 + */ + private Integer totalNum; + + /** + * 赠品数量 + */ + private Integer totalGiftNum; + + /** + * 出库金额 + */ + private BigDecimal totalAmount; + + /** + * 备注 + */ + private String description; + + + private String createById; + + + private String createBy; + + + private Date createTime; + + + private String updateBy; + + + private String updateById; + + + private Date updateTime; + + /** + * 审核人 + */ + private String approveBy; + + /** + * 审核时间 + */ + private Date approveTime; + + /** + * 拒绝原因 + */ + private String refuseReason; + + /** + * 结算状态 + */ + private Integer settleStatus; + + +} diff --git a/src/main/java/com/soft/entitys/voice/SaleOutSheetDetail.java b/src/main/java/com/soft/entitys/voice/SaleOutSheetDetail.java new file mode 100644 index 0000000..86d9b0a --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/SaleOutSheetDetail.java @@ -0,0 +1,99 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-10-26 + */ +@Data +@TableName("tbl_sale_out_sheet_detail") +public class SaleOutSheetDetail { + + /** + * ID + */ + private String id; + + /** + * 出库单ID + */ + private String sheetId; + + /** + * 商品ID + */ + private String productId; + + /** + * 出库数量 + */ + private Integer orderNum; + + /** + * 原价 + */ + private BigDecimal oriPrice; + + /** + * 现价 + */ + private BigDecimal taxPrice; + + /** + * 折扣率(%) + */ + private BigDecimal discountRate; + + /** + * 是否赠品 + */ + private Boolean isGift; + + /** + * 税率(%) + */ + private BigDecimal taxRate; + + /** + * 备注 + */ + private String description; + + /** + * 排序编号 + */ + private Integer orderNo; + + /** + * 结算状态 + */ + private Integer settleStatus; + + /** + * 销售订单明细ID + */ + private String saleOrderDetailId; + + /** + * 已退货数量 + */ + private Integer returnNum; + + /** + * 组合商品原始明细ID + */ + private String oriBundleDetailId; + + /** + * 仓库ID + */ + private String scId; +} diff --git a/src/main/java/com/soft/entitys/voice/SettleCheckSheet.java b/src/main/java/com/soft/entitys/voice/SettleCheckSheet.java new file mode 100644 index 0000000..0c7b597 --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/SettleCheckSheet.java @@ -0,0 +1,148 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; + +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-12-02 + */ +@Data +@TableName("settle_check_sheet") +public class SettleCheckSheet { + + private String id; + + /** + * 单号 + */ + private String code; + + /** + * 供应商ID + */ + private String supplierId; + + /** + * 总金额 + */ + private BigDecimal totalAmount; + + /** + * 应付金额 + */ + private BigDecimal totalPayAmount; + + /** + * 已付金额 + */ + private BigDecimal totalPayedAmount; + + /** + * 已优惠金额 + */ + private BigDecimal totalDiscountAmount; + + /** + * 起始时间 + */ + private Date startDate; + + /** + * 截止日期 + */ + private Date endDate; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + + private String createById; + + /** + * 创建人 新增时赋值 + */ + + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + + private Date createTime; + + /** + * 修改人 新增和修改时赋值 + */ + + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + + private Date updateTime; + + /** + * 审核人 + */ + private String approveBy; + + /** + * 审核时间 + */ + private Date approveTime; + + /** + * 状态 + */ + private Integer status; + + /** + * 拒绝原因 + */ + private String refuseReason; + + /** + * 结算状态 + */ + private Integer settleStatus; + + /** + * 应付 + */ + private BigDecimal numberOne; + + + /** + * 已付 + */ + private BigDecimal numberTwo; + + + + +} diff --git a/src/main/java/com/soft/entitys/voice/SettleCheckSheetDetail.java b/src/main/java/com/soft/entitys/voice/SettleCheckSheetDetail.java new file mode 100644 index 0000000..c3a0992 --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/SettleCheckSheetDetail.java @@ -0,0 +1,64 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.TableName; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-12-02 + */ +@Data +@TableName("settle_check_sheet_detail") +public class SettleCheckSheetDetail { + + + + /** + * ID + */ + private String id; + + /** + * 对账单ID + */ + private String sheetId; + + /** + * 单据ID + */ + private String bizId; + + /** + * 业务类型 + */ + private Integer bizType; + + /** + * 计算方式 + */ + private Integer calcType; + + /** + * 应付金额 + */ + private BigDecimal payAmount; + + /** + * 备注 + */ + private String description; + + /** + * 排序编号 + */ + private Integer orderNo; + + +} diff --git a/src/main/java/com/soft/entitys/voice/SettleSheet.java b/src/main/java/com/soft/entitys/voice/SettleSheet.java new file mode 100644 index 0000000..5763b54 --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/SettleSheet.java @@ -0,0 +1,121 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-12-05 + */ +@Data +@TableName("settle_sheet") +public class SettleSheet { + + + /** + * ID + */ + private String id; + + /** + * 单号 + */ + private String code; + + /** + * 供应商ID + */ + private String supplierId; + + /** + * 总金额 + */ + private BigDecimal totalAmount; + + /** + * 已优惠金额 + */ + private BigDecimal totalDiscountAmount; + + /** + * 起始时间 + */ + private Date startDate; + + /** + * 截止日期 + */ + private Date endDate; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + + private String createById; + + /** + * 创建人 新增时赋值 + */ + + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + + private LocalDateTime createTime; + + /** + * 修改人 新增和修改时赋值 + */ + + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + + private Date updateTime; + + /** + * 审核人 + */ + private String approveBy; + + /** + * 审核时间 + */ + private Date approveTime; + + /** + * 状态 + */ + private Integer status; + + /** + * 拒绝原因 + */ + private String refuseReason; +} diff --git a/src/main/java/com/soft/entitys/voice/SettleSheetDetail.java b/src/main/java/com/soft/entitys/voice/SettleSheetDetail.java new file mode 100644 index 0000000..41e4845 --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/SettleSheetDetail.java @@ -0,0 +1,57 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.math.BigDecimal; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-12-05 + */ +@Data +@TableName("settle_sheet_detail") +public class SettleSheetDetail { + + + /** + * ID + */ + private String id; + + /** + * 结算单ID + */ + private String sheetId; + + /** + * 单据ID + */ + private String bizId; + + /** + * 实付金额 + */ + private BigDecimal payAmount; + + /** + * 优惠金额 + */ + private BigDecimal discountAmount; + + /** + * 备注 + */ + private String description; + + /** + * 排序编号 + */ + private Integer orderNo; + + +} diff --git a/src/main/java/com/soft/entitys/voice/StoreCenter.java b/src/main/java/com/soft/entitys/voice/StoreCenter.java new file mode 100644 index 0000000..c1ab0be --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/StoreCenter.java @@ -0,0 +1,108 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-07-07 + */ +@Data +@TableName("base_data_store_center") +public class StoreCenter { + + + /** + * ID + */ + private String id; + + /** + * 编号 + */ + private String code; + + /** + * 名称 + */ + private String name; + + /** + * 联系人 + */ + private String contact; + + /** + * 联系人手机号码 + */ + private String telephone; + + /** + * 地区ID + */ + private String cityId; + + /** + * 地址 + */ + private String address; + + /** + * 仓库人数 + */ + private Integer peopleNum; + + /** + * 状态 + */ + private Boolean available; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + @TableField(fill = FieldFill.INSERT) + private String createById; + + /** + * 创建人 新增时赋值 + */ + @TableField(fill = FieldFill.INSERT) + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + @TableField(fill = FieldFill.INSERT) + private Date createTime; + + /** + * 修改人 新增和修改时赋值 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Date updateTime; +} diff --git a/src/main/java/com/soft/entitys/voice/Supplier.java b/src/main/java/com/soft/entitys/voice/Supplier.java new file mode 100644 index 0000000..64099b0 --- /dev/null +++ b/src/main/java/com/soft/entitys/voice/Supplier.java @@ -0,0 +1,164 @@ +package com.soft.entitys.voice; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.Date; + +/** + *

+ * + *

+ * + * @author zmj + * @since 2021-07-11 + */ +@Data +@TableName("base_data_supplier") +public class Supplier { + + + /** + * ID + */ + private String id; + + /** + * 编号 + */ + private String code; + + /** + * 名称 + */ + private String name; + + /** + * 简码 + */ + private String mnemonicCode; + + /** + * 联系人 + */ + private String contact; + + /** + * 联系电话 + */ + private String telephone; + + /** + * 电子邮箱 + */ + private String email; + + /** + * 邮编 + */ + private String zipCode; + + /** + * 传真 + */ + private String fax; + + /** + * 地区ID + */ + private String cityId; + + /** + * 地址 + */ + private String address; + + /** + * 送货周期(天) + */ + private Integer deliveryCycle; + + /** + * 经营方式 + */ + private Integer manageType; + + /** + * 结算方式 + */ + private Integer settleType; + + /** + * 统一社会信用代码 + */ + private String creditCode; + + /** + * 纳税人识别号 + */ + private String taxIdentifyNo; + + /** + * 开户银行 + */ + private String bankName; + + /** + * 户名 + */ + private String accountName; + + /** + * 银行账号 + */ + private String accountNo; + + /** + * 状态 + */ + private Boolean available; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + + private String createById; + + /** + * 创建人 新增时赋值 + */ + + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + + private Date createTime; + + /** + * 修改人 新增和修改时赋值 + */ + + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + + private Date updateTime; +} diff --git a/src/main/java/com/soft/enums/AuthEnum.java b/src/main/java/com/soft/enums/AuthEnum.java new file mode 100644 index 0000000..0785c14 --- /dev/null +++ b/src/main/java/com/soft/enums/AuthEnum.java @@ -0,0 +1,24 @@ +package com.soft.enums; + +import com.soft.utils.ResultUtil; + +public enum AuthEnum { + + NOT_AUTHENTICATION(ResultUtil.NOT_AUTHENTICATION_CODE), + LOGIN_TOKEN_INVALID(ResultUtil.LOGIN_TOKEN_INVALID_CODE); + private AuthEnum(int code){ + this.code=code; + this.message=ResultUtil.getMessage(code); + } + + private int code; + private String message; + + public int getCode() { + return code; + } + public String getMessage() { + return message; + } + +} diff --git a/src/main/java/com/soft/enums/CommEnum.java b/src/main/java/com/soft/enums/CommEnum.java new file mode 100644 index 0000000..55b4cbf --- /dev/null +++ b/src/main/java/com/soft/enums/CommEnum.java @@ -0,0 +1,29 @@ +package com.soft.enums; + +import com.soft.utils.ResultUtil; + +/** + * 通用返回信息 + */ +public enum CommEnum { + + SUCCESS(ResultUtil.SUCCESS_CODE), + FAIL(ResultUtil.FAIL_CODE), + EMPTY_PARAM(ResultUtil.EMPTY_PARAM_CODE), + ERROR(ResultUtil.ERROR_CODE); + private CommEnum(int code){ + this.code=code; + this.message=ResultUtil.getMessage(code); + } + + private int code; + private String message; + + public int getCode() { + return code; + } + public String getMessage() { + return message; + } + +} diff --git a/src/main/java/com/soft/enums/OrderChartBizType.java b/src/main/java/com/soft/enums/OrderChartBizType.java new file mode 100644 index 0000000..784acfc --- /dev/null +++ b/src/main/java/com/soft/enums/OrderChartBizType.java @@ -0,0 +1,30 @@ +package com.soft.enums; + +import com.baomidou.mybatisplus.annotation.EnumValue; + + +public enum OrderChartBizType{ + PURCHASE_ORDER(0, "采购订单"), PURCHASE_RETURN(1, "采购退单"), SALE_ORDER(2, "销售订单"), SALE_RETURN(3, + "销售退单"), RETAIL_OUT_SHEET(4, "零售出库单"), RETAIL_RETURN(5, "零售退单"); + + @EnumValue + private final Integer code; + + private final String desc; + + OrderChartBizType(Integer code, String desc) { + + this.code = code; + this.desc = desc; + } + + public Integer getCode() { + + return this.code; + } + + public String getDesc() { + + return this.desc; + } +} diff --git a/src/main/java/com/soft/enums/OrderStatus.java b/src/main/java/com/soft/enums/OrderStatus.java new file mode 100644 index 0000000..a292d93 --- /dev/null +++ b/src/main/java/com/soft/enums/OrderStatus.java @@ -0,0 +1,39 @@ +package com.soft.enums; + +import com.baomidou.mybatisplus.annotation.EnumValue; + +import java.util.Objects; + +public enum OrderStatus { + CREATED(0, "待审核"), APPROVE_PASS(3, "审核通过"), APPROVE_REFUSE(6, "审核拒绝"); + + @EnumValue + private Integer code; + + private String desc; + + OrderStatus(Integer code, String desc) { + + this.code = code; + this.desc = desc; + } + + public Integer getCode() { + + return this.code; + } + + public String getDesc() { + + return this.desc; + } + + public static String valueOfCode(Integer code) { + for (OrderStatus status : values()) { + if (Objects.equals(status.getCode(), code)) { + return status.getDesc(); + } + } + return null; + } +} diff --git a/src/main/java/com/soft/enums/ProductType.java b/src/main/java/com/soft/enums/ProductType.java new file mode 100644 index 0000000..edaa2dc --- /dev/null +++ b/src/main/java/com/soft/enums/ProductType.java @@ -0,0 +1,27 @@ +package com.soft.enums; + +import com.baomidou.mybatisplus.annotation.EnumValue; + +public enum ProductType { + NORMAL(1, "普通商品"), BUNDLE(2, "组合商品"); + + @EnumValue + private final Integer code; + + private final String desc; + + ProductType(Integer code, String desc) { + + this.code = code; + this.desc = desc; + } + + public Integer getCode() { + + return this.code; + } + + public String getDesc() { + return this.desc; + } +} diff --git a/src/main/java/com/soft/enums/QueryType.java b/src/main/java/com/soft/enums/QueryType.java new file mode 100644 index 0000000..c8510ce --- /dev/null +++ b/src/main/java/com/soft/enums/QueryType.java @@ -0,0 +1,24 @@ +package com.soft.enums; + +public enum QueryType { + + TODAY_PURCHASE_AMOUNT, // 今日采购订单金额 + TODAY_SALES_AMOUNT, // 今日销售订单金额 + PRODUCT_INVENTORY, // 商品库存查询 + TODAY_OUTBOUND_ORDERS, // 今日销售出库订单 + TODAY_PURCHASE_ORDERS, //今天采购入库订单 + TODAY_PURCHASE_RETURN, //今日销售退货订单 + CUSTOMER_NAME_SEARCH, //根据客户名搜索 + USER_NAME_ORDERS_SEARCH, + SALES_ORDERS_BY_DATE, //时间查询销售订单 + PURCHASE_ORDERS_BY_DATE, //时间查询采购订单 + PRODUCT_STOCK_LOG_BY_NAME, //出入库流水 + REVENUE_COUNT, //营收账款 + ACCOUNTS_PAYABLE, //应付账款 + PAYMENT_TOF_FEES, //费用支付 + TOTAL_PROFIT, //利润总和 + MONTH_SALE_AMOUNT, //本月销售订单 + MONTH_PURCHASE_AMOUNT, //本月采购订单 + YEAR_SALE_AMOUNT, //本年销售订单 + YEAR_PURCHASE_AMOUNT //本年采购订单 + } diff --git a/src/main/java/com/soft/enums/system/SysMenuComponentType.java b/src/main/java/com/soft/enums/system/SysMenuComponentType.java new file mode 100644 index 0000000..1d4cb92 --- /dev/null +++ b/src/main/java/com/soft/enums/system/SysMenuComponentType.java @@ -0,0 +1,27 @@ +package com.soft.enums.system; + +import com.baomidou.mybatisplus.annotation.EnumValue; + +public enum SysMenuComponentType { + + NORMAL(0, "普通"), CUSTOM_LIST(1, "自定义列表"), CUSTOM_PAGE(3, "自定义页面"); + + @EnumValue + private final Integer code; + + private final String desc; + + SysMenuComponentType(Integer code, String desc) { + + this.code = code; + this.desc = desc; + } + + public Integer getCode() { + return code; + } + + public String getDesc() { + return desc; + } +} diff --git a/src/main/java/com/soft/enums/system/SysMenuDisplay.java b/src/main/java/com/soft/enums/system/SysMenuDisplay.java new file mode 100644 index 0000000..b272f83 --- /dev/null +++ b/src/main/java/com/soft/enums/system/SysMenuDisplay.java @@ -0,0 +1,27 @@ +package com.soft.enums.system; + +import com.baomidou.mybatisplus.annotation.EnumValue; + +public enum SysMenuDisplay { + + CATALOG(0, "目录"), FUNCTION(1, "菜单"), PERMISSION(2, "权限"); + + @EnumValue + private final Integer code; + + private final String desc; + + SysMenuDisplay(Integer code, String desc) { + + this.code = code; + this.desc = desc; + } + + public Integer getCode() { + return this.code; + } + + public String getDesc() { + return this.desc; + } +} diff --git a/src/main/java/com/soft/events/order/ApprovePassOrderEvent.java b/src/main/java/com/soft/events/order/ApprovePassOrderEvent.java new file mode 100644 index 0000000..be6e873 --- /dev/null +++ b/src/main/java/com/soft/events/order/ApprovePassOrderEvent.java @@ -0,0 +1,57 @@ +package com.soft.events.order; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.context.ApplicationEvent; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 业务单据审核通过Event + */ +public abstract class ApprovePassOrderEvent extends ApplicationEvent { + + /** + * 业务单据ID + */ + @Getter + @Setter + private String id; + + /** + * 单据总金额 + */ + @Getter + @Setter + private BigDecimal totalAmount; + + /** + * 审核时间 + */ + @Getter + @Setter + private LocalDateTime approveTime = LocalDateTime.now(); + + /** + * 单据类型 + */ + @Getter + private OrderType orderType; + + /** + * Create a new {@code ApplicationEvent}. + * + * @param source the object on which the event initially occurred or with which the event is + * associated (never {@code null}) + */ + public ApprovePassOrderEvent(Object source, OrderType orderType) { + + super(source); + this.orderType = orderType; + } + + public enum OrderType { + PURCHASE_ORDER, PURCHASE_RETURN, SALE_ORDER, SALE_RETURN, RETAIL_OUT_SHEET, RETAIL_RETURN + } +} diff --git a/src/main/java/com/soft/events/order/impl/ApprovePassPurchaseOrderEvent.java b/src/main/java/com/soft/events/order/impl/ApprovePassPurchaseOrderEvent.java new file mode 100644 index 0000000..7add914 --- /dev/null +++ b/src/main/java/com/soft/events/order/impl/ApprovePassPurchaseOrderEvent.java @@ -0,0 +1,18 @@ +package com.soft.events.order.impl; + + +import com.soft.events.order.ApprovePassOrderEvent; + +public class ApprovePassPurchaseOrderEvent extends ApprovePassOrderEvent { + + /** + * Create a new {@code ApplicationEvent}. + * + * @param source the object on which the event initially occurred or with which the event is + * associated (never {@code null}) + */ + public ApprovePassPurchaseOrderEvent(Object source) { + + super(source, OrderType.PURCHASE_ORDER); + } +} diff --git a/src/main/java/com/soft/events/order/impl/ApprovePassPurchaseReturnEvent.java b/src/main/java/com/soft/events/order/impl/ApprovePassPurchaseReturnEvent.java new file mode 100644 index 0000000..b7aadfd --- /dev/null +++ b/src/main/java/com/soft/events/order/impl/ApprovePassPurchaseReturnEvent.java @@ -0,0 +1,18 @@ +package com.soft.events.order.impl; + + +import com.soft.events.order.ApprovePassOrderEvent; + +public class ApprovePassPurchaseReturnEvent extends ApprovePassOrderEvent { + + /** + * Create a new {@code ApplicationEvent}. + * + * @param source the object on which the event initially occurred or with which the event is + * associated (never {@code null}) + */ + public ApprovePassPurchaseReturnEvent(Object source) { + + super(source, OrderType.PURCHASE_RETURN); + } +} diff --git a/src/main/java/com/soft/events/order/impl/ApprovePassRetailOutSheetEvent.java b/src/main/java/com/soft/events/order/impl/ApprovePassRetailOutSheetEvent.java new file mode 100644 index 0000000..61d7637 --- /dev/null +++ b/src/main/java/com/soft/events/order/impl/ApprovePassRetailOutSheetEvent.java @@ -0,0 +1,18 @@ +package com.soft.events.order.impl; + + +import com.soft.events.order.ApprovePassOrderEvent; + +public class ApprovePassRetailOutSheetEvent extends ApprovePassOrderEvent { + + /** + * Create a new {@code ApplicationEvent}. + * + * @param source the object on which the event initially occurred or with which the event is + * associated (never {@code null}) + */ + public ApprovePassRetailOutSheetEvent(Object source) { + + super(source, OrderType.RETAIL_OUT_SHEET); + } +} diff --git a/src/main/java/com/soft/events/order/impl/ApprovePassRetailReturnEvent.java b/src/main/java/com/soft/events/order/impl/ApprovePassRetailReturnEvent.java new file mode 100644 index 0000000..5b113f9 --- /dev/null +++ b/src/main/java/com/soft/events/order/impl/ApprovePassRetailReturnEvent.java @@ -0,0 +1,17 @@ +package com.soft.events.order.impl; + +import com.soft.events.order.ApprovePassOrderEvent; + +public class ApprovePassRetailReturnEvent extends ApprovePassOrderEvent { + + /** + * Create a new {@code ApplicationEvent}. + * + * @param source the object on which the event initially occurred or with which the event is + * associated (never {@code null}) + */ + public ApprovePassRetailReturnEvent(Object source) { + + super(source, OrderType.RETAIL_RETURN); + } +} diff --git a/src/main/java/com/soft/events/order/impl/ApprovePassSaleOrderEvent.java b/src/main/java/com/soft/events/order/impl/ApprovePassSaleOrderEvent.java new file mode 100644 index 0000000..9427d34 --- /dev/null +++ b/src/main/java/com/soft/events/order/impl/ApprovePassSaleOrderEvent.java @@ -0,0 +1,18 @@ +package com.soft.events.order.impl; + + +import com.soft.events.order.ApprovePassOrderEvent; + +public class ApprovePassSaleOrderEvent extends ApprovePassOrderEvent { + + /** + * Create a new {@code ApplicationEvent}. + * + * @param source the object on which the event initially occurred or with which the event is + * associated (never {@code null}) + */ + public ApprovePassSaleOrderEvent(Object source) { + + super(source, OrderType.SALE_ORDER); + } +} diff --git a/src/main/java/com/soft/events/order/impl/ApprovePassSaleReturnEvent.java b/src/main/java/com/soft/events/order/impl/ApprovePassSaleReturnEvent.java new file mode 100644 index 0000000..279da5a --- /dev/null +++ b/src/main/java/com/soft/events/order/impl/ApprovePassSaleReturnEvent.java @@ -0,0 +1,18 @@ +package com.soft.events.order.impl; + + +import com.soft.events.order.ApprovePassOrderEvent; + +public class ApprovePassSaleReturnEvent extends ApprovePassOrderEvent { + + /** + * Create a new {@code ApplicationEvent}. + * + * @param source the object on which the event initially occurred or with which the event is + * associated (never {@code null}) + */ + public ApprovePassSaleReturnEvent(Object source) { + + super(source, OrderType.SALE_RETURN); + } +} diff --git a/src/main/java/com/soft/filter/CrossFilter.java b/src/main/java/com/soft/filter/CrossFilter.java new file mode 100644 index 0000000..c6790c8 --- /dev/null +++ b/src/main/java/com/soft/filter/CrossFilter.java @@ -0,0 +1,196 @@ +package com.soft.filter; + +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; + + +/** + * @description CrossFilter + * @author TDW + * @date 2017年6月22日 + * + */ +@Component +@WebFilter(urlPatterns = "/*", filterName = "crossFilter") +public class CrossFilter implements Filter { + + private static final boolean debug = true; + // The filter configuration object we are associated with. If + // this value is null, this filter instance is not currently + // configured. + private FilterConfig filterConfig = null; + + public CrossFilter() { + } + + private void doBeforeProcessing(ServletRequest request, ServletResponse response) + throws IOException, ServletException { + if (debug) { + log("CrossFilter:DoBeforeProcessing"); + } + + } + + private void doAfterProcessing(ServletRequest request, ServletResponse response) + throws IOException, ServletException { + if (debug) { + log("CrossFilter:DoAfterProcessing"); + } + + + } + + private void addHeadersFor200Response(HttpServletResponse response){ + //TODO: externalize the Allow-Origin + response.addHeader("Access-Control-Allow-Origin", "*"); + response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD"); + response.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept"); + response.addHeader("Access-Control-Max-Age", "1728000"); + } + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) + throws IOException, ServletException { + if (debug) { + log("CrossFilter:doFilter()"); + } + + if(response instanceof HttpServletResponse){ + HttpServletResponse alteredResponse = ((HttpServletResponse)response); + // I need to find a way to make sure this only gets called on 200-300 http responses + // TODO: see above comment + addHeadersFor200Response(alteredResponse); + } + + doBeforeProcessing(request, response); + + Throwable problem = null; + try { + chain.doFilter(request, response); + } catch (Throwable t) { + // If an exception is thrown somewhere down the filter chain, + // we still want to execute our after processing, and then + // rethrow the problem after that. + problem = t; + t.printStackTrace(); + } + + doAfterProcessing(request, response); + + // If there was a problem, we want to rethrow it if it is + // a known type, otherwise log it. + if (problem != null) { + if (problem instanceof ServletException) { + throw (ServletException) problem; + } + if (problem instanceof IOException) { + throw (IOException) problem; + } + sendProcessingError(problem, response); + } + } + + /** + * Return the filter configuration object for this filter. + */ + public FilterConfig getFilterConfig() { + return (this.filterConfig); + } + + /** + * Set the filter configuration object for this filter. + * + * @param filterConfig The filter configuration object + */ + public void setFilterConfig(FilterConfig filterConfig) { + this.filterConfig = filterConfig; + } + + + /** + * Destroy method for this filter + */ + public void destroy() { + } + + /** + * Init method for this filter + */ + public void init(FilterConfig filterConfig) throws ServletException{ + this.filterConfig = filterConfig; + if (filterConfig != null) { + if (debug) { + log("CrossFilter:Initializing filter"); + } + } + } + + /** + * Return a String representation of this object. + */ + @Override + public String toString() { + if (filterConfig == null) { + return ("CrossFilter()"); + } + StringBuffer sb = new StringBuffer("CrossFilter("); + sb.append(filterConfig); + sb.append(")"); + return (sb.toString()); + } + + private void sendProcessingError(Throwable t, ServletResponse response) { + String stackTrace = getStackTrace(t); + + if (stackTrace != null && !stackTrace.equals("")) { + try { + response.setContentType("text/html"); + PrintStream ps = new PrintStream(response.getOutputStream()); + PrintWriter pw = new PrintWriter(ps); + pw.print("\n\nError\n\n\n"); //NOI18N + + // PENDING! Localize this for next official release + pw.print("

The resource did not process correctly

\n
\n");
+                pw.print(stackTrace);
+                pw.print("
\n"); //NOI18N + pw.close(); + ps.close(); + response.getOutputStream().close(); + } catch (Exception ex) { + } + } else { + try { + PrintStream ps = new PrintStream(response.getOutputStream()); + t.printStackTrace(ps); + ps.close(); + response.getOutputStream().close(); + } catch (Exception ex) { + } + } + } + + public static String getStackTrace(Throwable t) { + String stackTrace = null; + try { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + t.printStackTrace(pw); + pw.close(); + sw.close(); + stackTrace = sw.getBuffer().toString(); + } catch (Exception ex) { + } + return stackTrace; + } + + public void log(String msg) { + filterConfig.getServletContext().log(msg); + } +} diff --git a/src/main/java/com/soft/listeners/OrderDataListener.java b/src/main/java/com/soft/listeners/OrderDataListener.java new file mode 100644 index 0000000..b7eb91f --- /dev/null +++ b/src/main/java/com/soft/listeners/OrderDataListener.java @@ -0,0 +1,60 @@ +package com.soft.listeners; + +import com.soft.enums.OrderChartBizType; +import com.soft.events.order.ApprovePassOrderEvent; +import com.soft.service.OrderChartService; +import com.soft.vo.CreateOrderChartVo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + + +@Slf4j +@Component +public class OrderDataListener implements ApplicationListener { + + @Autowired + private OrderChartService orderChartService; + + @Override + public void onApplicationEvent(ApprovePassOrderEvent event) { + + OrderChartBizType bizType = this.convertBizType(event.getOrderType()); + if (event.getOrderType() == null) { + log.error("orderType={},无法匹配业务类型", event.getOrderType()); + return; + } + + CreateOrderChartVo vo = new CreateOrderChartVo(); + vo.setTotalAmount(event.getTotalAmount()); + vo.setCreateTime(event.getApproveTime()); + vo.setBizType(bizType); + + orderChartService.create(vo); + } + + private OrderChartBizType convertBizType(ApprovePassOrderEvent.OrderType orderType) { + + if (orderType == ApprovePassOrderEvent.OrderType.PURCHASE_ORDER) { + return OrderChartBizType.PURCHASE_ORDER; + } + if (orderType == ApprovePassOrderEvent.OrderType.PURCHASE_RETURN) { + return OrderChartBizType.PURCHASE_RETURN; + } + if (orderType == ApprovePassOrderEvent.OrderType.SALE_ORDER) { + return OrderChartBizType.SALE_ORDER; + } + if (orderType == ApprovePassOrderEvent.OrderType.SALE_RETURN) { + return OrderChartBizType.SALE_RETURN; + } + if (orderType == ApprovePassOrderEvent.OrderType.RETAIL_OUT_SHEET) { + return OrderChartBizType.RETAIL_OUT_SHEET; + } + if (orderType == ApprovePassOrderEvent.OrderType.RETAIL_RETURN) { + return OrderChartBizType.RETAIL_RETURN; + } + + return null; + } +} diff --git a/src/main/java/com/soft/mapper/AgentMapper.java b/src/main/java/com/soft/mapper/AgentMapper.java new file mode 100644 index 0000000..9b539e2 --- /dev/null +++ b/src/main/java/com/soft/mapper/AgentMapper.java @@ -0,0 +1,18 @@ +package com.soft.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.user.Agent; +import com.soft.vo.AgentLevelVo; + +import java.util.List; + +public interface AgentMapper extends BaseMapper { + + Agent getAgentByLevel(Integer levelId); + + List getAgentLevelList(); + + Agent getAgentById(Integer id); + + +} diff --git a/src/main/java/com/soft/mapper/CategoryMapper.java b/src/main/java/com/soft/mapper/CategoryMapper.java new file mode 100644 index 0000000..ea07643 --- /dev/null +++ b/src/main/java/com/soft/mapper/CategoryMapper.java @@ -0,0 +1,13 @@ +package com.soft.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.user.Category; + +public interface CategoryMapper extends BaseMapper { + + Category getAllCategoryById(String id); + + + Category getAllCategory(Integer id); + +} diff --git a/src/main/java/com/soft/mapper/CustomerMapper.java b/src/main/java/com/soft/mapper/CustomerMapper.java new file mode 100644 index 0000000..c4fea4f --- /dev/null +++ b/src/main/java/com/soft/mapper/CustomerMapper.java @@ -0,0 +1,13 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.Customer; + + +public interface CustomerMapper extends BaseMapper { + + Customer QueryCustomerName(String customerName); + + +} diff --git a/src/main/java/com/soft/mapper/DemandMapper.java b/src/main/java/com/soft/mapper/DemandMapper.java new file mode 100644 index 0000000..9fa8c5a --- /dev/null +++ b/src/main/java/com/soft/mapper/DemandMapper.java @@ -0,0 +1,10 @@ +package com.soft.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.demand.Demand; + +public interface DemandMapper extends BaseMapper { + + + +} diff --git a/src/main/java/com/soft/mapper/OrderChartMapper.java b/src/main/java/com/soft/mapper/OrderChartMapper.java new file mode 100644 index 0000000..613fa6a --- /dev/null +++ b/src/main/java/com/soft/mapper/OrderChartMapper.java @@ -0,0 +1,8 @@ +package com.soft.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.OrderChart; + + +public interface OrderChartMapper extends BaseMapper { +} diff --git a/src/main/java/com/soft/mapper/OrderPayTypeMapper.java b/src/main/java/com/soft/mapper/OrderPayTypeMapper.java new file mode 100644 index 0000000..7434a70 --- /dev/null +++ b/src/main/java/com/soft/mapper/OrderPayTypeMapper.java @@ -0,0 +1,12 @@ +package com.soft.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.OrderPayType; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface OrderPayTypeMapper extends BaseMapper { + + List findByOrderId(@Param("orderId") String orderId); +} diff --git a/src/main/java/com/soft/mapper/ProductMapper.java b/src/main/java/com/soft/mapper/ProductMapper.java new file mode 100644 index 0000000..566e6da --- /dev/null +++ b/src/main/java/com/soft/mapper/ProductMapper.java @@ -0,0 +1,18 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.Product; +import com.soft.vo.ProductVo; + +import java.util.List; + + +public interface ProductMapper extends BaseMapper { + + List QueryProductInventory(String productName); + + List QueryProductByName(String productName); + + Product getProductById(String id); +} diff --git a/src/main/java/com/soft/mapper/ProductStockLogMapper.java b/src/main/java/com/soft/mapper/ProductStockLogMapper.java new file mode 100644 index 0000000..2accd27 --- /dev/null +++ b/src/main/java/com/soft/mapper/ProductStockLogMapper.java @@ -0,0 +1,15 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.ProductStockLog; +import com.soft.vo.ProductStockLogVo; + + +import java.util.List; + + +public interface ProductStockLogMapper extends BaseMapper { + + List getProductStockLogByProductId(String productId); +} diff --git a/src/main/java/com/soft/mapper/ProductStockMapper.java b/src/main/java/com/soft/mapper/ProductStockMapper.java new file mode 100644 index 0000000..2bc433e --- /dev/null +++ b/src/main/java/com/soft/mapper/ProductStockMapper.java @@ -0,0 +1,22 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.ProductStock; +import com.soft.vo.ProductStockDataVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + + +public interface ProductStockMapper extends BaseMapper { + + Integer getProductStockNum(); + + List getProductStockList(@Param("startNum")Integer startNum, @Param("pageSize")Integer pageSize); + + List getProductStockProportion(); + + Integer getProductStockListCount(); + +} diff --git a/src/main/java/com/soft/mapper/PurchaseOrderDetailMapper.java b/src/main/java/com/soft/mapper/PurchaseOrderDetailMapper.java new file mode 100644 index 0000000..cc5de09 --- /dev/null +++ b/src/main/java/com/soft/mapper/PurchaseOrderDetailMapper.java @@ -0,0 +1,14 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.PurchaseOrderDetail; +import com.soft.entitys.voice.SaleOrder; + +import java.math.BigDecimal; +import java.util.List; + +public interface PurchaseOrderDetailMapper extends BaseMapper { + + List getPurchaseOrderDetailById(String orderId); +} diff --git a/src/main/java/com/soft/mapper/PurchaseOrderMapper.java b/src/main/java/com/soft/mapper/PurchaseOrderMapper.java new file mode 100644 index 0000000..914c612 --- /dev/null +++ b/src/main/java/com/soft/mapper/PurchaseOrderMapper.java @@ -0,0 +1,45 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.PurchaseOrder; +import com.soft.entitys.voice.SaleOrder; +import com.soft.vo.PurchaseOrderVo; +import com.soft.vo.SaleOrderVo; +import org.apache.ibatis.annotations.Param; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + + +public interface PurchaseOrderMapper extends BaseMapper { + + BigDecimal CheckTodaysPurchaseAmount(); + + BigDecimal CheckMonthPurchaseAmount(); + + BigDecimal CheckYearPurchaseAmount(); + + List TodaysPurchaseOrder(); + + List MonthPurchaseOrder(); + + List YearPurchaseOrder(); + + List thisMonthPurchaseOrder(); + + List thisWeekPurchaseOrder(); + + List selectPruchaseOrdersByDate(@Param("targetDate") String targetDate); + + List> orderMonthContrastPurchaseOrder(); + + List> orderTodaysContrastPurchaseOrder(); + + BigDecimal getPurchaseAmountByMonth(@Param("year") Integer year, @Param("month") Integer month); + + Integer getOrderSumByStatus(@Param("status") Integer status); + + List selectListByStatus(@Param("pageSize") int pageSize, @Param("offset") int offset, @Param("status") Integer status); +} diff --git a/src/main/java/com/soft/mapper/PurchaseReturnDetailMapper.java b/src/main/java/com/soft/mapper/PurchaseReturnDetailMapper.java new file mode 100644 index 0000000..502f8a4 --- /dev/null +++ b/src/main/java/com/soft/mapper/PurchaseReturnDetailMapper.java @@ -0,0 +1,15 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.PurchaseOrderDetail; +import com.soft.entitys.voice.PurchaseReturnDetail; + +import java.util.List; + + +public interface PurchaseReturnDetailMapper extends BaseMapper { + + List getPurchaseReturnById(String returnId); + +} diff --git a/src/main/java/com/soft/mapper/PurchaseReturnMapper.java b/src/main/java/com/soft/mapper/PurchaseReturnMapper.java new file mode 100644 index 0000000..3bdfe73 --- /dev/null +++ b/src/main/java/com/soft/mapper/PurchaseReturnMapper.java @@ -0,0 +1,14 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.PurchaseReturn; +import com.soft.vo.TodaysPurchaseOrderReturnVo; + +import java.util.List; + + +public interface PurchaseReturnMapper extends BaseMapper { + + List TodaysPurchaseOrderReturn(); +} diff --git a/src/main/java/com/soft/mapper/SaleOrderDetailBundleMapper.java b/src/main/java/com/soft/mapper/SaleOrderDetailBundleMapper.java new file mode 100644 index 0000000..c1b7f8e --- /dev/null +++ b/src/main/java/com/soft/mapper/SaleOrderDetailBundleMapper.java @@ -0,0 +1,12 @@ +package com.soft.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.sale.SaleOrderDetailBundle; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface SaleOrderDetailBundleMapper extends BaseMapper { + + List listByOrderDetailId(@Param("orderId") String orderId, @Param("detailId") String detailId); +} diff --git a/src/main/java/com/soft/mapper/SaleOrderDetailMapper.java b/src/main/java/com/soft/mapper/SaleOrderDetailMapper.java new file mode 100644 index 0000000..46c4104 --- /dev/null +++ b/src/main/java/com/soft/mapper/SaleOrderDetailMapper.java @@ -0,0 +1,15 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.SaleOrderDetail; + +import java.util.List; + + +public interface SaleOrderDetailMapper extends BaseMapper { + + List getSaleOrderDetailById(String orderId); + + List listByOrderId(String id); +} diff --git a/src/main/java/com/soft/mapper/SaleOrderMapper.java b/src/main/java/com/soft/mapper/SaleOrderMapper.java new file mode 100644 index 0000000..fabfa07 --- /dev/null +++ b/src/main/java/com/soft/mapper/SaleOrderMapper.java @@ -0,0 +1,67 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.SaleOrder; +import com.soft.vo.SaleOrderVo; +import org.apache.ibatis.annotations.Param; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +public interface SaleOrderMapper extends BaseMapper { + + BigDecimal CheckTodaysOrderAmount(); + + BigDecimal CheckMonthOrderAmount(); + + BigDecimal CheckYearOrderAmount(); + + List selectSaleOrdersByDate(@Param("targetDate") String targetDate); + + List getSaleOrderByCustomerId(String customerId); + + List getSaleOrderBySalerId(String salerId); + + BigDecimal CheckOrderAmountCount(); + + BigDecimal CheckOrderPurchasePrice(); + + List getTotalProfit(); + + List CheckTodysSaleOrderLits(); + + List CheckMonthSaleOrderLits(); + + List CheckYearSaleOrderLits(); + + List CheckThisMonthSaleOrderList(); + + List CheckThisWeekSaleOrderList(); + + List> orderMonthContrastSaleOrder(); + + List> orderTodaysContrastSaleOrder(); + + BigDecimal getSaleAmountByMonth(@Param("year") Integer year, @Param("month") Integer month); + + List saleSalerMonthRank(); + + List saleSalerWeekRank(); + + List latelyDecemberSaleOrderProfit(); + + List lastYearSaleOrderProfit(); + + List> getYearlyComparisonData(); + + Integer getOrderSumByStatus(@Param("status") Integer status); + + List selectListByStatus(@Param("pageSize") int pageSize, @Param("offset") int offset, @Param("status") Integer status); + + int updateApproveById(@Param("sysUserId")String sysUserId, @Param("now")LocalDateTime now, + @Param("id")String id, @Param("statusList")List statusList); + +} diff --git a/src/main/java/com/soft/mapper/SaleOutSheetDetailMapper.java b/src/main/java/com/soft/mapper/SaleOutSheetDetailMapper.java new file mode 100644 index 0000000..87c7618 --- /dev/null +++ b/src/main/java/com/soft/mapper/SaleOutSheetDetailMapper.java @@ -0,0 +1,14 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.SaleOutSheetDetail; + +import java.util.List; + + +public interface SaleOutSheetDetailMapper extends BaseMapper { + + List getSaleOutSheetDetailById(String sheetId); + +} diff --git a/src/main/java/com/soft/mapper/SaleOutSheetMapper.java b/src/main/java/com/soft/mapper/SaleOutSheetMapper.java new file mode 100644 index 0000000..09719af --- /dev/null +++ b/src/main/java/com/soft/mapper/SaleOutSheetMapper.java @@ -0,0 +1,16 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.SaleOutSheet; +import com.soft.vo.SaleOutSheetVo; + +import java.math.BigDecimal; +import java.util.List; + + +public interface SaleOutSheetMapper extends BaseMapper { + + List getTodysSaleOutSheet(); + +} diff --git a/src/main/java/com/soft/mapper/SettleCheckSheetDetailMapper.java b/src/main/java/com/soft/mapper/SettleCheckSheetDetailMapper.java new file mode 100644 index 0000000..84dd7f4 --- /dev/null +++ b/src/main/java/com/soft/mapper/SettleCheckSheetDetailMapper.java @@ -0,0 +1,10 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.SettleCheckSheetDetail; + + +public interface SettleCheckSheetDetailMapper extends BaseMapper { + +} diff --git a/src/main/java/com/soft/mapper/SettleCheckSheetMapper.java b/src/main/java/com/soft/mapper/SettleCheckSheetMapper.java new file mode 100644 index 0000000..a3badca --- /dev/null +++ b/src/main/java/com/soft/mapper/SettleCheckSheetMapper.java @@ -0,0 +1,16 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.SettleCheckSheet; + +import java.math.BigDecimal; + + +public interface SettleCheckSheetMapper extends BaseMapper { + + BigDecimal settleCheckAccountsPayable(); + + + +} diff --git a/src/main/java/com/soft/mapper/SettleSheetDetailMapper.java b/src/main/java/com/soft/mapper/SettleSheetDetailMapper.java new file mode 100644 index 0000000..bddfd69 --- /dev/null +++ b/src/main/java/com/soft/mapper/SettleSheetDetailMapper.java @@ -0,0 +1,10 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.SettleSheetDetail; + + +public interface SettleSheetDetailMapper extends BaseMapper { + +} diff --git a/src/main/java/com/soft/mapper/SettleSheetMapper.java b/src/main/java/com/soft/mapper/SettleSheetMapper.java new file mode 100644 index 0000000..4f2905d --- /dev/null +++ b/src/main/java/com/soft/mapper/SettleSheetMapper.java @@ -0,0 +1,16 @@ +package com.soft.mapper; + + + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.SettleSheet; + +import java.math.BigDecimal; + + +public interface SettleSheetMapper extends BaseMapper { + + BigDecimal settleSheetPaymentOfFees(); + +} diff --git a/src/main/java/com/soft/mapper/StoreCenterMapper.java b/src/main/java/com/soft/mapper/StoreCenterMapper.java new file mode 100644 index 0000000..81f76e6 --- /dev/null +++ b/src/main/java/com/soft/mapper/StoreCenterMapper.java @@ -0,0 +1,12 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.StoreCenter; + + +public interface StoreCenterMapper extends BaseMapper { + + StoreCenter getStoreCenterById(String id); + +} diff --git a/src/main/java/com/soft/mapper/SupplierMapper.java b/src/main/java/com/soft/mapper/SupplierMapper.java new file mode 100644 index 0000000..0dd2583 --- /dev/null +++ b/src/main/java/com/soft/mapper/SupplierMapper.java @@ -0,0 +1,13 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.voice.Supplier; + + + + +public interface SupplierMapper extends BaseMapper { + + Supplier getSupplierById(String id); +} diff --git a/src/main/java/com/soft/mapper/SysMenuMapper.java b/src/main/java/com/soft/mapper/SysMenuMapper.java new file mode 100644 index 0000000..0338143 --- /dev/null +++ b/src/main/java/com/soft/mapper/SysMenuMapper.java @@ -0,0 +1,17 @@ +package com.soft.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.sys.SysMenu; +import org.apache.ibatis.annotations.Param; + +import java.util.Set; + +public interface SysMenuMapper extends BaseMapper { + /** + * 根据用户ID查询角色权限 + * + * @param userId + * @return + */ + Set getRolePermissionByUserId(@Param("userId") String userId); +} diff --git a/src/main/java/com/soft/mapper/SysRoleMenuMapper.java b/src/main/java/com/soft/mapper/SysRoleMenuMapper.java new file mode 100644 index 0000000..78d4ca6 --- /dev/null +++ b/src/main/java/com/soft/mapper/SysRoleMenuMapper.java @@ -0,0 +1,12 @@ +package com.soft.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.sys.SysRoleMenu; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface SysRoleMenuMapper extends BaseMapper { + + List selectByRoleId(@Param("roleId") String roleId); +} diff --git a/src/main/java/com/soft/mapper/SysUserMapper.java b/src/main/java/com/soft/mapper/SysUserMapper.java new file mode 100644 index 0000000..88a69a7 --- /dev/null +++ b/src/main/java/com/soft/mapper/SysUserMapper.java @@ -0,0 +1,30 @@ +package com.soft.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.dto.SysUserDTO; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; +import java.util.Set; + + +public interface SysUserMapper extends BaseMapper { + + SysUserDTO getSysUserByName(String userName); + + SysUserDTO getSysUserById(String id); + + @Select({ + "" + }) + List selectUsersByIds(@Param("ids") Set ids); + + SysUserDTO query(@Param("username") String username); +} diff --git a/src/main/java/com/soft/mapper/SysUserRoleMapper.java b/src/main/java/com/soft/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..e406272 --- /dev/null +++ b/src/main/java/com/soft/mapper/SysUserRoleMapper.java @@ -0,0 +1,9 @@ +package com.soft.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.sys.SysUserRole; + +public interface SysUserRoleMapper extends BaseMapper { + + +} diff --git a/src/main/java/com/soft/mapper/UserMapper.java b/src/main/java/com/soft/mapper/UserMapper.java new file mode 100644 index 0000000..959f605 --- /dev/null +++ b/src/main/java/com/soft/mapper/UserMapper.java @@ -0,0 +1,20 @@ +package com.soft.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.soft.entitys.user.User; + +import java.util.List; + +public interface UserMapper extends BaseMapper { + + + User getUserListByUid(Integer userId); + + User getByOpenId(String openId); + + Integer getUpLevelUser(Integer userId); + + List getMySilverAgent(Integer userId); + + List getMyGoldMedalAgent(Integer userId); +} diff --git a/src/main/java/com/soft/resp/InvokeResult.java b/src/main/java/com/soft/resp/InvokeResult.java new file mode 100644 index 0000000..8c88ccc --- /dev/null +++ b/src/main/java/com/soft/resp/InvokeResult.java @@ -0,0 +1,137 @@ +package com.soft.resp; + +import io.swagger.annotations.ApiModelProperty; + +public class InvokeResult{ + private static final long serialVersionUID = 1L; + @ApiModelProperty( + value = "响应码,2开头的响应码为成功,否则为失败", + example = "200" + ) + private Integer code; + @ApiModelProperty( + value = "响应信息", + example = "success" + ) + private String msg; + @ApiModelProperty("数据") + private T data; + @ApiModelProperty("TraceId") + private String traceId; + + public InvokeResult() { + } + + public Integer getCode() { + return this.code; + } + + public String getMsg() { + return this.msg; + } + + public T getData() { + return this.data; + } + + public String getTraceId() { + return this.traceId; + } + + public void setCode(Integer code) { + this.code = code; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public void setData(T data) { + this.data = data; + } + + public void setTraceId(String traceId) { + this.traceId = traceId; + } + + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (!(o instanceof InvokeResult)) { + return false; + } else { + InvokeResult other = (InvokeResult)o; + if (!other.canEqual(this)) { + return false; + } else { + label59: { + Object this$code = this.getCode(); + Object other$code = other.getCode(); + if (this$code == null) { + if (other$code == null) { + break label59; + } + } else if (this$code.equals(other$code)) { + break label59; + } + + return false; + } + + Object this$msg = this.getMsg(); + Object other$msg = other.getMsg(); + if (this$msg == null) { + if (other$msg != null) { + return false; + } + } else if (!this$msg.equals(other$msg)) { + return false; + } + + Object this$data = this.getData(); + Object other$data = other.getData(); + if (this$data == null) { + if (other$data != null) { + return false; + } + } else if (!this$data.equals(other$data)) { + return false; + } + + Object this$traceId = this.getTraceId(); + Object other$traceId = other.getTraceId(); + if (this$traceId == null) { + if (other$traceId != null) { + return false; + } + } else if (!this$traceId.equals(other$traceId)) { + return false; + } + + return true; + } + } + } + + protected boolean canEqual(Object other) { + return other instanceof InvokeResult; + } + + public int hashCode() { + boolean PRIME = true; + int result = 1; + Object $code = this.getCode(); + result = result * 59 + ($code == null ? 43 : $code.hashCode()); + Object $msg = this.getMsg(); + result = result * 59 + ($msg == null ? 43 : $msg.hashCode()); + Object $data = this.getData(); + result = result * 59 + ($data == null ? 43 : $data.hashCode()); + Object $traceId = this.getTraceId(); + result = result * 59 + ($traceId == null ? 43 : $traceId.hashCode()); + return result; + } + + public String toString() { + return "InvokeResult(code=" + this.getCode() + ", msg=" + this.getMsg() + ", data=" + this.getData() + ", traceId=" + this.getTraceId() + ")"; + } +} diff --git a/src/main/java/com/soft/resp/InvokeResultBuilder.java b/src/main/java/com/soft/resp/InvokeResultBuilder.java new file mode 100644 index 0000000..45b9f09 --- /dev/null +++ b/src/main/java/com/soft/resp/InvokeResultBuilder.java @@ -0,0 +1,54 @@ +package com.soft.resp; + +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// +import com.soft.common.constants.ResponseConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class InvokeResultBuilder { + private static final Logger log = LoggerFactory.getLogger(InvokeResultBuilder.class); + + public InvokeResultBuilder() { + } + + public static InvokeResult success() { + InvokeResult invokeResult = new InvokeResult(); + invokeResult.setCode(ResponseConstants.INVOKE_RESULT_SUCCESS_CODE); + invokeResult.setMsg("success"); + return invokeResult; + } + + public static InvokeResult success(T data) { + InvokeResult invokeResult = new InvokeResult(); + invokeResult.setCode(ResponseConstants.INVOKE_RESULT_SUCCESS_CODE); + invokeResult.setMsg("success"); + invokeResult.setData(data); + return invokeResult; + } + + public static InvokeResult fail() { + InvokeResult invokeResult = new InvokeResult(); + invokeResult.setCode(ResponseConstants.INVOKE_RESULT_FAIL_CODE); + invokeResult.setMsg("fail"); + return invokeResult; + } + + public static InvokeResult fail(String msg) { + InvokeResult invokeResult = new InvokeResult(); + invokeResult.setCode(ResponseConstants.INVOKE_RESULT_FAIL_CODE); + invokeResult.setMsg(msg); + return invokeResult; + } + + public static InvokeResult fail(String msg, T data) { + InvokeResult invokeResult = new InvokeResult(); + invokeResult.setCode(ResponseConstants.INVOKE_RESULT_FAIL_CODE); + invokeResult.setMsg(msg); + invokeResult.setData(data); + return invokeResult; + } +} + diff --git a/src/main/java/com/soft/resp/Result.java b/src/main/java/com/soft/resp/Result.java new file mode 100644 index 0000000..570f9b2 --- /dev/null +++ b/src/main/java/com/soft/resp/Result.java @@ -0,0 +1,105 @@ +package com.soft.resp; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.soft.enums.CommEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(description = "统一返回") +public class Result { + + @ApiModelProperty("数据") + private T data; + @ApiModelProperty("请求状态码") + private int code; + @ApiModelProperty("消息") + private String message; + + private Result(int code, String message, T data) { + this.code = code; + this.message = message; + this.data = data; + } + + private Result(int code, String message) { + this.code = code; + this.message = message; + } + + public static Result success() { + CommEnum e= CommEnum.SUCCESS; + int code=e.getCode(); + String message=e.getMessage(); + return new Result(code,message); + } + + public static Result success(T data) { + CommEnum e= CommEnum.SUCCESS; + int code=e.getCode(); + String message=e.getMessage(); + return new Result(code,message,data); + } + + public static Result fail(String message) { + CommEnum e= CommEnum.FAIL; + int code=e.getCode(); + return new Result(code,message); + } + + public static Result fail() { + CommEnum e= CommEnum.FAIL; + int code=e.getCode(); + String message=e.getMessage(); + return new Result(code,message); + } + + public static Result fail(Enum e){ + SerializeConfig config = new SerializeConfig(); + config.configEnumAsJavaBean(e.getClass()); + String json= JSON.toJSONString(e,config); + JSONObject jsonObject=JSON.parseObject(json); + int code=jsonObject.getIntValue("code"); + String message=jsonObject.getString("message"); + return new Result(code,message); + } + + public static Result fail(Enum e, T data){ + SerializeConfig config = new SerializeConfig(); + config.configEnumAsJavaBean(e.getClass()); + String json= JSON.toJSONString(e,config); + JSONObject jsonObject=JSON.parseObject(json); + int code=jsonObject.getIntValue("code"); + String message=jsonObject.getString("message"); + return new Result(code,message,data); + } + + + public static Result isEmpty(){ + CommEnum e= CommEnum.EMPTY_PARAM; + int code=e.getCode(); + String message=e.getMessage(); + return new Result(code,message); + } + + public static Result isEmpty(String message){ + CommEnum e= CommEnum.EMPTY_PARAM; + int code=e.getCode(); + return new Result(code,message); + } + + public static Result error(){ + CommEnum e= CommEnum.ERROR; + int code=e.getCode(); + return new Result(code,e.getMessage()); + } + + @Override + public String toString(){ + return JSON.toJSONString(this); + } + +} diff --git a/src/main/java/com/soft/resp/ResultError.java b/src/main/java/com/soft/resp/ResultError.java new file mode 100644 index 0000000..a2133c0 --- /dev/null +++ b/src/main/java/com/soft/resp/ResultError.java @@ -0,0 +1,5 @@ +package com.soft.resp; + +public class ResultError { + +} diff --git a/src/main/java/com/soft/service/AgentService.java b/src/main/java/com/soft/service/AgentService.java new file mode 100644 index 0000000..7174bee --- /dev/null +++ b/src/main/java/com/soft/service/AgentService.java @@ -0,0 +1,18 @@ +package com.soft.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.soft.entitys.user.Agent; +import com.soft.vo.AgentLevelVo; + +import java.util.List; + + +public interface AgentService extends IService { + + Agent getAgentByLevel(Integer levelId); + + List getAgentLevelList(); + + Agent getAgentById(Integer id); + +} diff --git a/src/main/java/com/soft/service/DemandService.java b/src/main/java/com/soft/service/DemandService.java new file mode 100644 index 0000000..51b1603 --- /dev/null +++ b/src/main/java/com/soft/service/DemandService.java @@ -0,0 +1,17 @@ +package com.soft.service; + + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.IService; +import com.soft.dto.SaveDemandDTO; +import com.soft.dto.WeChatLoginRequestDTO; +import com.soft.entitys.demand.Demand; + + +import java.util.Map; + +public interface DemandService extends IService{ + + + Integer saveSoftWareDemand(SaveDemandDTO saveDemandDTO); +} diff --git a/src/main/java/com/soft/service/OrderChartService.java b/src/main/java/com/soft/service/OrderChartService.java new file mode 100644 index 0000000..cf41089 --- /dev/null +++ b/src/main/java/com/soft/service/OrderChartService.java @@ -0,0 +1,13 @@ +package com.soft.service; + +import com.soft.vo.CreateOrderChartVo; + +public interface OrderChartService { + /** + * 创建 + * + * @param vo + * @return + */ + String create(CreateOrderChartVo vo); +} diff --git a/src/main/java/com/soft/service/OrderPayTypeService.java b/src/main/java/com/soft/service/OrderPayTypeService.java new file mode 100644 index 0000000..b635865 --- /dev/null +++ b/src/main/java/com/soft/service/OrderPayTypeService.java @@ -0,0 +1,10 @@ +package com.soft.service; + +import com.soft.entitys.OrderPayType; + +import java.util.List; + +public interface OrderPayTypeService { + + List findByOrderId(String id); +} diff --git a/src/main/java/com/soft/service/PermissionService.java b/src/main/java/com/soft/service/PermissionService.java new file mode 100644 index 0000000..6da4dec --- /dev/null +++ b/src/main/java/com/soft/service/PermissionService.java @@ -0,0 +1,8 @@ +package com.soft.service; + +import com.soft.components.security.PermissionCalcType; + +public interface PermissionService { + + boolean hasPermission(String userId, String[] value, PermissionCalcType calcType); +} diff --git a/src/main/java/com/soft/service/ProductService.java b/src/main/java/com/soft/service/ProductService.java new file mode 100644 index 0000000..ccba3fd --- /dev/null +++ b/src/main/java/com/soft/service/ProductService.java @@ -0,0 +1,14 @@ +package com.soft.service; + +import com.soft.entitys.voice.Product; + +public interface ProductService { + + /** + * 根据ID查询 + * + * @param id + * @return + */ + Product findById(String id); +} diff --git a/src/main/java/com/soft/service/PurchaseOrderDetailService.java b/src/main/java/com/soft/service/PurchaseOrderDetailService.java new file mode 100644 index 0000000..ffc85bb --- /dev/null +++ b/src/main/java/com/soft/service/PurchaseOrderDetailService.java @@ -0,0 +1,12 @@ +package com.soft.service; + +import com.soft.entitys.voice.PurchaseOrderDetail; +import com.soft.entitys.voice.SaleOrderDetail; + +import java.util.List; + +public interface PurchaseOrderDetailService { + + List getByOrderId(String id); + +} diff --git a/src/main/java/com/soft/service/PurchaseOrderService.java b/src/main/java/com/soft/service/PurchaseOrderService.java new file mode 100644 index 0000000..e634223 --- /dev/null +++ b/src/main/java/com/soft/service/PurchaseOrderService.java @@ -0,0 +1,17 @@ +package com.soft.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.soft.dto.ApprovePassOrderDTO; +import com.soft.entitys.voice.PurchaseOrder; +import com.soft.entitys.voice.SaleOrder; +import com.soft.utils.PageResult; + +public interface PurchaseOrderService { + + Integer getOrderSumByStatus(Integer status); + + PageResult pendApproveList(int pageIndex, int pageSize, Integer status); + + void approvePass(ApprovePassOrderDTO dto); + +} diff --git a/src/main/java/com/soft/service/SaleOrderDetailBundleService.java b/src/main/java/com/soft/service/SaleOrderDetailBundleService.java new file mode 100644 index 0000000..ca5a1ff --- /dev/null +++ b/src/main/java/com/soft/service/SaleOrderDetailBundleService.java @@ -0,0 +1,17 @@ +package com.soft.service; + +import com.soft.entitys.sale.SaleOrderDetailBundle; + +import java.util.List; + +public interface SaleOrderDetailBundleService { + /** + * 根据订单id 和订单详情id 查询销售单组合商品 + * + * @return + */ + List listByOrderDetailId(String orderId, String detailId); + + int updateById(SaleOrderDetailBundle saleOrderDetailBundle); + +} diff --git a/src/main/java/com/soft/service/SaleOrderDetailService.java b/src/main/java/com/soft/service/SaleOrderDetailService.java new file mode 100644 index 0000000..2a62962 --- /dev/null +++ b/src/main/java/com/soft/service/SaleOrderDetailService.java @@ -0,0 +1,16 @@ +package com.soft.service; + +import com.soft.entitys.voice.SaleOrderDetail; + +import java.util.List; + +public interface SaleOrderDetailService { + + List listByOrderIdAsc(String id); + + int save(SaleOrderDetail newDetail); + + int removeById(String id); + + List getBySaleOrderId(String id); +} diff --git a/src/main/java/com/soft/service/SaleOrderService.java b/src/main/java/com/soft/service/SaleOrderService.java new file mode 100644 index 0000000..cf979f6 --- /dev/null +++ b/src/main/java/com/soft/service/SaleOrderService.java @@ -0,0 +1,17 @@ +package com.soft.service; + +import com.soft.entitys.voice.SaleOrder; +import com.soft.utils.PageResult; + +public interface SaleOrderService { + + Integer getOrderSumByStatus(Integer status); + + void approve(String orderId, String sysUserId); + + PageResult pendApproveList(int pageIndex, int pageSize, Integer statsus); + + SaleOrder selectById(String linkNumber); + + int updatePurchaseStatusbyId(SaleOrder saleOrder); +} diff --git a/src/main/java/com/soft/service/SysUserService.java b/src/main/java/com/soft/service/SysUserService.java new file mode 100644 index 0000000..55102df --- /dev/null +++ b/src/main/java/com/soft/service/SysUserService.java @@ -0,0 +1,12 @@ +package com.soft.service; + +import com.soft.entitys.user.SystemUser; +import com.soft.dto.SysUserDTO; + +public interface SysUserService { + + SysUserDTO query(SystemUser systemUser); + + SysUserDTO selectById(String sysUserId); + +} diff --git a/src/main/java/com/soft/service/UserService.java b/src/main/java/com/soft/service/UserService.java new file mode 100644 index 0000000..9312deb --- /dev/null +++ b/src/main/java/com/soft/service/UserService.java @@ -0,0 +1,29 @@ +package com.soft.service; + + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.IService; +import com.soft.dto.WeChatLoginRequestDTO; +import com.soft.entitys.user.User; +import com.soft.vo.BindPhoneVo; + +import java.util.List; +import java.util.Map; + +public interface UserService extends IService{ + + Map getUserInfoMap(WeChatLoginRequestDTO loginRequest); + + JSONObject decryptData(String encryptedData, String sessionKey, String iv); + + BindPhoneVo getPhoneNumber(String code, Integer pid, Integer uId, Integer type); + + User queryByOpenId(String openId); + + int updateUserById(User user); + + User queryBySysUserId(String id); + + User getUserById(Integer userId); + +} diff --git a/src/main/java/com/soft/service/VoiceQueryService.java b/src/main/java/com/soft/service/VoiceQueryService.java new file mode 100644 index 0000000..274fa27 --- /dev/null +++ b/src/main/java/com/soft/service/VoiceQueryService.java @@ -0,0 +1,90 @@ +package com.soft.service; + +import com.soft.dto.OrderProportionDto; +import com.soft.dto.StatisticsProductStockDto; +import com.soft.entitys.Page; +import com.soft.entitys.QueryParams; +import com.soft.vo.*; + +import java.util.List; + +public interface VoiceQueryService { + + Object processQuery(QueryParams params); + + /** + * 今日销售与采购情况 + * @return + */ + OrderDataVo statisticsTodaysOrderData(); + + /** + * 近30日销售与采购情况 + * @return + */ + OrderDataMonthVo statisticsMonthOrderData(); + + /** + * 近7日销售与采购情况 + * @return + */ + OrderDataWeekVo statisticsWeekOrderData(); + + /** + * 订单对比分析-每月 + * @return + */ + OrderMonthContrastVo orderMonthContrast(); + + /** + * 订单对比分析-每日 + */ + OrderTodaysContrastVo orderTodaysContrast(); + + /** + * 订单占比 + * @return + */ + OrderProportionVo orderProportion(OrderProportionDto orderProportionDto); + + /** + * 商品库存占比 + * @return + */ + List productProductStockProportion(); + + + /** + * 销售人员排名-本月 + * @return + */ + List saleSalerMonthRank(); + + /** + * 销售人员排名-本周 + * @return + */ + List saleSalerWeekRank(); + + + /** + * 销售毛利分析-最近12月 + * @return + */ + SaleOrderGrossMarginVo saleOrderGrossMargin(); + + /** + * 销售毛利分析-去年 + * @return + */ + SaleOrderLastYearProfitVo saleOrderLastYearProfit(); + + /** + * 年度累计销售额,销售数量,销售成本,毛利率 + * @return + */ + SaleOrderCurrentYearAmountVo saleOrderCurrentYearAmount(); + + + Page> statisticsProductStock(StatisticsProductStockDto statisticsProductStockDto); +} diff --git a/src/main/java/com/soft/service/impl/AgentServiceImpl.java b/src/main/java/com/soft/service/impl/AgentServiceImpl.java new file mode 100644 index 0000000..602e717 --- /dev/null +++ b/src/main/java/com/soft/service/impl/AgentServiceImpl.java @@ -0,0 +1,32 @@ +package com.soft.service.impl; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.soft.entitys.user.Agent; +import com.soft.mapper.AgentMapper; +import com.soft.service.AgentService; +import com.soft.vo.AgentLevelVo; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class AgentServiceImpl extends ServiceImpl implements AgentService { + + + @Override + public Agent getAgentByLevel(Integer levelId) { + return super.baseMapper.getAgentByLevel(levelId); + } + + @Override + public List getAgentLevelList() { + return super.baseMapper.getAgentLevelList(); + } + + @Override + public Agent getAgentById(Integer id) { + return super.baseMapper.getAgentById(id); + } + +} diff --git a/src/main/java/com/soft/service/impl/DemandServiceImpl.java b/src/main/java/com/soft/service/impl/DemandServiceImpl.java new file mode 100644 index 0000000..58af615 --- /dev/null +++ b/src/main/java/com/soft/service/impl/DemandServiceImpl.java @@ -0,0 +1,56 @@ +package com.soft.service.impl; + +import cn.hutool.core.codec.Base64; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.soft.dto.SaveDemandDTO; +import com.soft.dto.WeChatLoginRequestDTO; +import com.soft.entitys.demand.Demand; +import com.soft.entitys.user.User; +import com.soft.mapper.DemandMapper; +import com.soft.mapper.UserMapper; +import com.soft.service.DemandService; +import com.soft.service.UserService; +import com.soft.utils.ConstantUtil; +import com.soft.utils.HttpUtils; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + + + + +@Service +public class DemandServiceImpl extends ServiceImpl implements DemandService { + + + private static final Logger logger = LoggerFactory.getLogger(DemandServiceImpl.class); + + ConstantUtil constantUtil = null; + + + @Override + public Integer saveSoftWareDemand(SaveDemandDTO saveDemandDTO) { + + Demand demand=new Demand(); + demand.setUserId(saveDemandDTO.getUserId()); + demand.setCompanyName(saveDemandDTO.getCompanyName()); + demand.setCompanyAddress(saveDemandDTO.getCompanyAddress()); + demand.setPerson(saveDemandDTO.getPerson()); + demand.setPersonPhone(saveDemandDTO.getPersonPhone()); + demand.setDemandSystem(saveDemandDTO.getDemandSystem()); + demand.setEmail(saveDemandDTO.getEmail()); + demand.setCompanyType(saveDemandDTO.getCompanyType()); + demand.setCompanyScale(saveDemandDTO.getCompanyScale()); + demand.setCompanyScope(saveDemandDTO.getCompanyScope()); + demand.setCompanyFramework(saveDemandDTO.getCompanyFramework()); + demand.setCompanyBusinessScope(saveDemandDTO.getCompanyBusinessScope()); + demand.setAgentLevel(saveDemandDTO.getAgentLevel()); + demand.setRemarks(saveDemandDTO.getRemarks()); + Integer result=super.baseMapper.insert(demand); + + return result; + } +} diff --git a/src/main/java/com/soft/service/impl/OrderChartServiceImpl.java b/src/main/java/com/soft/service/impl/OrderChartServiceImpl.java new file mode 100644 index 0000000..fe083f1 --- /dev/null +++ b/src/main/java/com/soft/service/impl/OrderChartServiceImpl.java @@ -0,0 +1,44 @@ +package com.soft.service.impl; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.EnumUtil; +import cn.hutool.core.util.IdUtil; +import com.soft.common.constants.StringPool; +import com.soft.common.util.DateUtils; +import com.soft.entitys.OrderChart; +import com.soft.enums.OrderChartBizType; +import com.soft.mapper.OrderChartMapper; +import com.soft.service.OrderChartService; +import com.soft.vo.CreateOrderChartVo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + +@Service +public class OrderChartServiceImpl implements OrderChartService { + + @Autowired + private OrderChartMapper orderChartMapper; + + + @Override + public String create(CreateOrderChartVo vo) { + if (vo.getCreateTime() == null) { + vo.setCreateTime(LocalDateTime.now()); + } + + OrderChart record = new OrderChart(); + Snowflake snowflake = IdUtil.createSnowflake(1, 1); + + record.setId(String.valueOf(snowflake.nextId())); + record.setTotalAmount(vo.getTotalAmount()); + record.setCreateTime(vo.getCreateTime()); + record.setBizType(vo.getBizType().getCode()); + record.setCreateDate(DateUtil.formatDate(DateUtils.toDate(vo.getCreateTime()))); + record.setCreateHour(DateUtil.format(vo.getCreateTime(), StringPool.DATE_TIME_HOUR_PATTER)); + orderChartMapper.insert(record); + return record.getId(); + } +} diff --git a/src/main/java/com/soft/service/impl/OrderPayTypeServiceImpl.java b/src/main/java/com/soft/service/impl/OrderPayTypeServiceImpl.java new file mode 100644 index 0000000..8f5fddc --- /dev/null +++ b/src/main/java/com/soft/service/impl/OrderPayTypeServiceImpl.java @@ -0,0 +1,21 @@ +package com.soft.service.impl; + +import com.soft.entitys.OrderPayType; +import com.soft.mapper.OrderPayTypeMapper; +import com.soft.service.OrderPayTypeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class OrderPayTypeServiceImpl implements OrderPayTypeService { + @Autowired + private OrderPayTypeMapper orderPayTypeMapper; + + @Override + public List findByOrderId(String id) { + + return orderPayTypeMapper.findByOrderId(id); + } +} diff --git a/src/main/java/com/soft/service/impl/PermissionServiceImpl.java b/src/main/java/com/soft/service/impl/PermissionServiceImpl.java new file mode 100644 index 0000000..b42fe3c --- /dev/null +++ b/src/main/java/com/soft/service/impl/PermissionServiceImpl.java @@ -0,0 +1,57 @@ +package com.soft.service.impl; + +import com.soft.components.security.PermissionCalcType; +import com.soft.entitys.sys.SysUserRole; +import com.soft.mapper.SysMenuMapper; +import com.soft.mapper.SysRoleMenuMapper; +import com.soft.mapper.SysUserRoleMapper; +import com.soft.service.PermissionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Set; + +@Service +public class PermissionServiceImpl implements PermissionService { + + @Autowired + private SysUserRoleMapper sysUserRoleMapper; + + @Autowired + private SysRoleMenuMapper sysRoleMenuMapper; + + @Autowired + private SysMenuMapper sysMenuMapper; + + + + + @Override + public boolean hasPermission(String sysUserId, String[] value, PermissionCalcType calcType) { + // 根据系统用户id查询具体角色,根据角色查询具体的权限菜单树 + SysUserRole sysUserRole = sysUserRoleMapper.selectById(sysUserId); + //根据角色id查询菜单权限集合 + Set rolePermissions = sysMenuMapper.getRolePermissionByUserId(sysUserRole.getRoleId()); + // 如果满足任意其中一个权限 + if (calcType == PermissionCalcType.OR) { + // 任意一个权限匹配即可 + for (String permission : value) { + if (rolePermissions.contains(permission)) { + return true; + } + } + return false; + } else if (calcType == PermissionCalcType.AND) { + // 必须全部权限匹配 + for (String permission : value) { + if (!rolePermissions.contains(permission)) { + return false; + } + } + return true; + } else { + throw new IllegalArgumentException("不支持的权限匹配类型: " + calcType); + } + } +} diff --git a/src/main/java/com/soft/service/impl/ProductServiceImpl.java b/src/main/java/com/soft/service/impl/ProductServiceImpl.java new file mode 100644 index 0000000..3659a60 --- /dev/null +++ b/src/main/java/com/soft/service/impl/ProductServiceImpl.java @@ -0,0 +1,19 @@ +package com.soft.service.impl; + +import com.soft.entitys.voice.Product; +import com.soft.mapper.ProductMapper; +import com.soft.service.ProductService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +@Service +public class ProductServiceImpl implements ProductService { + @Autowired + private ProductMapper productMapper; + + @Override + public Product findById(String id) { + return productMapper.getProductById(id); + } +} diff --git a/src/main/java/com/soft/service/impl/PurchaseOrderDetailServiceImpl.java b/src/main/java/com/soft/service/impl/PurchaseOrderDetailServiceImpl.java new file mode 100644 index 0000000..cd2bc9c --- /dev/null +++ b/src/main/java/com/soft/service/impl/PurchaseOrderDetailServiceImpl.java @@ -0,0 +1,21 @@ +package com.soft.service.impl; + +import com.soft.entitys.voice.PurchaseOrderDetail; +import com.soft.mapper.PurchaseOrderDetailMapper; +import com.soft.service.PurchaseOrderDetailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class PurchaseOrderDetailServiceImpl implements PurchaseOrderDetailService { + + @Autowired + private PurchaseOrderDetailMapper purchaseOrderDetailMapper; + + @Override + public List getByOrderId(String id) { + return purchaseOrderDetailMapper.getPurchaseOrderDetailById(id); + } +} diff --git a/src/main/java/com/soft/service/impl/PurchaseOrderServiceImpl.java b/src/main/java/com/soft/service/impl/PurchaseOrderServiceImpl.java new file mode 100644 index 0000000..ee1487c --- /dev/null +++ b/src/main/java/com/soft/service/impl/PurchaseOrderServiceImpl.java @@ -0,0 +1,121 @@ +package com.soft.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.github.pagehelper.PageInfo; +import com.soft.common.util.DateUtils; +import com.soft.dto.ApprovePassOrderDTO; +import com.soft.entitys.OrderPayType; +import com.soft.entitys.voice.PurchaseOrder; +import com.soft.entitys.voice.SaleOrder; +import com.soft.enums.OrderStatus; +import com.soft.events.order.impl.ApprovePassPurchaseOrderEvent; +import com.soft.mapper.PurchaseOrderMapper; +import com.soft.service.OrderPayTypeService; +import com.soft.service.PurchaseOrderService; +import com.soft.service.SaleOrderService; +import com.soft.utils.PageResult; +import com.soft.utils.PageResultUtil; +import org.apache.poi.util.StringUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Service +public class PurchaseOrderServiceImpl implements PurchaseOrderService { + + @Autowired + private PurchaseOrderMapper purchaseOrderMapper; + + @Autowired + private SaleOrderService saleOrderService; + + @Autowired + private OrderPayTypeService orderPayTypeService; + + @Autowired + private ApplicationEventPublisher eventPublisher; + + @Override + public Integer getOrderSumByStatus(Integer status) { + return purchaseOrderMapper.getOrderSumByStatus(status); + } + + @Override + public PageResult pendApproveList(int pageIndex, int pageSize, Integer status) { + int offset = (pageIndex - 1) * pageSize; + Integer total = getOrderSumByStatus(status); + //根据状态查询订单列表 + List datas = purchaseOrderMapper.selectListByStatus(pageSize, offset, status); + PageResult convert = PageResultUtil.convert(new PageInfo<>(datas)); + convert.setTotalCount(total); + return convert; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void approvePass(ApprovePassOrderDTO dto) { + + PurchaseOrder order = purchaseOrderMapper.selectById(dto.getOrderId()); + if (order == null) { + throw new RuntimeException("订单不存在!"); + } + + if (order.getStatus() != OrderStatus.CREATED.getCode() + && order.getStatus() != OrderStatus.APPROVE_REFUSE.getCode()) { + + if (order.getStatus() == OrderStatus.APPROVE_PASS.getCode()) { + throw new RuntimeException("订单已审核通过,不允许继续执行审核!"); + } + + throw new RuntimeException("订单无法审核通过!"); + } + + if(order.getLinkNumber()!=null && order.getLinkNumber()!=""){ + SaleOrder saleOrder=saleOrderService.selectById(order.getLinkNumber()); + saleOrder.setPurchaseStatus(2); + saleOrderService.updatePurchaseStatusbyId(saleOrder); + } + order.setStatus(OrderStatus.APPROVE_PASS.getCode()); + + List statusList = new ArrayList<>(); + statusList.add(OrderStatus.CREATED.getCode()); + statusList.add(OrderStatus.APPROVE_REFUSE.getCode()); + + LambdaUpdateWrapper updateOrderWrapper = Wrappers.lambdaUpdate( + PurchaseOrder.class) + .set(PurchaseOrder::getApproveBy, dto.getSysUserId()) + .set(PurchaseOrder::getApproveTime, LocalDateTime.now()) + .eq(PurchaseOrder::getId, order.getId()) + .in(PurchaseOrder::getStatus, statusList); + + if (purchaseOrderMapper.update(order, updateOrderWrapper) != 1) { + throw new RuntimeException("订单信息已过期,请刷新重试!"); + } + + if (order.getTotalAmount().compareTo(BigDecimal.ZERO) > 0) { + List orderPayTypes = orderPayTypeService.findByOrderId(order.getId()); + if (CollectionUtil.isEmpty(orderPayTypes)) { + throw new RuntimeException("单据没有约定支付,请检查!"); + } + } + + this.sendApprovePassEvent(order); + + } + private void sendApprovePassEvent(PurchaseOrder order) { + + ApprovePassPurchaseOrderEvent event = new ApprovePassPurchaseOrderEvent(this); + event.setId(order.getId()); + event.setTotalAmount(order.getTotalAmount()); + event.setApproveTime(DateUtils.toLocalDateTime(order.getApproveTime())); + eventPublisher.publishEvent(event); // 直接调用 Spring 方法 + } +} diff --git a/src/main/java/com/soft/service/impl/SaleOrderDetailBundleServiceImpl.java b/src/main/java/com/soft/service/impl/SaleOrderDetailBundleServiceImpl.java new file mode 100644 index 0000000..dbb45f5 --- /dev/null +++ b/src/main/java/com/soft/service/impl/SaleOrderDetailBundleServiceImpl.java @@ -0,0 +1,26 @@ +package com.soft.service.impl; + +import com.soft.entitys.sale.SaleOrderDetailBundle; +import com.soft.mapper.SaleOrderDetailBundleMapper; +import com.soft.service.SaleOrderDetailBundleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class SaleOrderDetailBundleServiceImpl implements SaleOrderDetailBundleService { + + @Autowired + private SaleOrderDetailBundleMapper saleOrderDetailBundleMapper; + + @Override + public List listByOrderDetailId(String orderId, String detailId) { + return saleOrderDetailBundleMapper.listByOrderDetailId(orderId,detailId); + } + + @Override + public int updateById(SaleOrderDetailBundle saleOrderDetailBundle) { + return saleOrderDetailBundleMapper.updateById(saleOrderDetailBundle); + } +} diff --git a/src/main/java/com/soft/service/impl/SaleOrderDetailServiceImpl.java b/src/main/java/com/soft/service/impl/SaleOrderDetailServiceImpl.java new file mode 100644 index 0000000..b592275 --- /dev/null +++ b/src/main/java/com/soft/service/impl/SaleOrderDetailServiceImpl.java @@ -0,0 +1,37 @@ +package com.soft.service.impl; + +import com.soft.entitys.voice.SaleOrderDetail; +import com.soft.mapper.SaleOrderDetailMapper; +import com.soft.service.SaleOrderDetailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class SaleOrderDetailServiceImpl implements SaleOrderDetailService { + + @Autowired + private SaleOrderDetailMapper saleOrderDetailMapper; + + + @Override + public List listByOrderIdAsc(String id) { + return saleOrderDetailMapper.listByOrderId(id); + } + + @Override + public int save(SaleOrderDetail newDetail) { + return saleOrderDetailMapper.insert(newDetail); + } + + @Override + public int removeById(String id) { + return saleOrderDetailMapper.deleteById(id); + } + + @Override + public List getBySaleOrderId(String id) { + return saleOrderDetailMapper.listByOrderId(id); + } +} diff --git a/src/main/java/com/soft/service/impl/SaleOrderServiceImpl.java b/src/main/java/com/soft/service/impl/SaleOrderServiceImpl.java new file mode 100644 index 0000000..77ee4f5 --- /dev/null +++ b/src/main/java/com/soft/service/impl/SaleOrderServiceImpl.java @@ -0,0 +1,206 @@ +package com.soft.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.NumberUtil; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.github.pagehelper.PageInfo; +import com.soft.common.util.DateUtils; +import com.soft.entitys.OrderPayType; +import com.soft.entitys.sale.SaleOrderDetailBundle; +import com.soft.entitys.voice.Product; +import com.soft.entitys.voice.SaleOrder; +import com.soft.entitys.voice.SaleOrderDetail; +import com.soft.enums.ProductType; +import com.soft.enums.OrderStatus; +import com.soft.events.order.impl.ApprovePassSaleOrderEvent; +import com.soft.mapper.SaleOrderMapper; +import com.soft.service.*; +import com.soft.utils.PageResult; +import com.soft.utils.PageResultUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Service +public class SaleOrderServiceImpl implements SaleOrderService { + + @Autowired + private SaleOrderMapper saleOrderMapper; + + @Autowired + private ProductService productService; + + @Autowired + private SaleOrderDetailBundleService saleOrderDetailBundleService; + + @Autowired + private SaleOrderDetailService saleOrderDetailService; + + @Autowired + private OrderPayTypeService orderPayTypeService; + + @Autowired + private ApplicationEventPublisher eventPublisher; + + + + + @Override + public Integer getOrderSumByStatus(Integer status) { + return saleOrderMapper.getOrderSumByStatus(status); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void approve(String orderId, String sysUserId) { + + SaleOrder order = saleOrderMapper.selectById(orderId); + if (order == null) { + throw new RuntimeException("订单不存在!"); + } + + if (order.getStatus() != OrderStatus.CREATED.getCode() + && order.getStatus() != OrderStatus.APPROVE_REFUSE.getCode()) { + + if (order.getStatus() == OrderStatus.APPROVE_PASS.getCode()) { + throw new RuntimeException("订单已审核通过,不允许继续执行审核!"); + } + throw new RuntimeException("订单无法审核通过!"); + } + + order.setStatus(OrderStatus.APPROVE_PASS.getCode()); + + List statusList = new ArrayList<>(); + //待审核 和审核通过 + statusList.add(OrderStatus.CREATED.getCode()); + statusList.add(OrderStatus.APPROVE_REFUSE.getCode()); + + int update = saleOrderMapper.updateApproveById(sysUserId, LocalDateTime.now(), order.getId(), statusList); + + if (update != 1) { + throw new RuntimeException("订单信息已过期,请刷新重试!"); + } + //订单金额大于 0,校验是否存在支付方式 + if (order.getTotalAmount().compareTo(BigDecimal.ZERO) > 0) { + List orderPayTypes = orderPayTypeService.findByOrderId(order.getId()); + if (CollectionUtil.isEmpty(orderPayTypes)) { + //如果没有找到支付方式,抛出异常提示用户检查支付信息 + throw new RuntimeException("单据没有约定支付,请检查!"); + } + } + //按订单号查询所有订单详情,并按顺序处理。 + List details = saleOrderDetailService.listByOrderIdAsc(order.getId()); + + //遍历每个订单详情,累加总金额、普通商品数量和赠品数量 + int totalNum = 0; + int giftNum = 0; // + BigDecimal totalAmount = BigDecimal.ZERO; //商品的总金额 + + for (SaleOrderDetail detail : details) { + boolean isGift = detail.getIsGift(); + // 计算单个商品的总金额:含税单价 × 购买数量。 + totalAmount = NumberUtil.add(totalAmount, + NumberUtil.mul(detail.getTaxPrice(), detail.getOrderNum())); + + Product product = productService.findById(detail.getProductId()); + if (product.getProductType() == ProductType.NORMAL.getCode()) { + if (isGift) { + giftNum += detail.getOrderNum(); + } else { + totalNum += detail.getOrderNum(); + } + } else { + //组合商品 + // 根据orderId 和detailId 查询组合商品;将组合商品存入销售单详情中,并替换掉原组合商品记录(拆细) + List saleOrderDetailBundles = saleOrderDetailBundleService.listByOrderDetailId(order.getId(), detail.getId()); + if(CollectionUtil.isEmpty(saleOrderDetailBundles)){ + return; + } + + for (SaleOrderDetailBundle saleOrderDetailBundle : saleOrderDetailBundles) { + SaleOrderDetail newDetail = new SaleOrderDetail(); + // 创建 Snowflake 实例 + Snowflake snowflake = IdUtil.createSnowflake(1, 1); + newDetail.setId(String.valueOf(snowflake.nextId())); + newDetail.setOrderId(order.getId()); + newDetail.setProductId(saleOrderDetailBundle.getProductId()); + newDetail.setOrderNum(saleOrderDetailBundle.getProductOrderNum()); + newDetail.setOriPrice(saleOrderDetailBundle.getProductOriPrice()); + newDetail.setTaxPrice(saleOrderDetailBundle.getProductTaxPrice()); + newDetail.setDiscountRate(detail.getDiscountRate()); + newDetail.setIsGift(detail.getIsGift()); + newDetail.setTaxRate(saleOrderDetailBundle.getProductTaxRate()); + newDetail.setDescription(detail.getDescription()); + newDetail.setOrderNo(detail.getOrderNo()); + newDetail.setOriBundleDetailId(detail.getId()); + + saleOrderDetailService.save(newDetail); + saleOrderDetailService.removeById(detail.getId()); + + saleOrderDetailBundle.setProductDetailId(newDetail.getId()); + saleOrderDetailBundleService.updateById(saleOrderDetailBundle); + + if (isGift) { + giftNum += newDetail.getOrderNum(); + } else { + totalNum += newDetail.getOrderNum(); + } + } + } + } + // 这里需要重新统计明细信息,因为明细发生变动了 + SaleOrder saleOrder = new SaleOrder(); + saleOrder.setTotalNum(totalNum); + saleOrder.setTotalGiftNum(giftNum); + saleOrder.setTotalAmount(totalAmount); + saleOrder.setId(order.getId()); + saleOrder.setStatus(OrderStatus.APPROVE_PASS.getCode()); + saleOrderMapper.updateById(saleOrder); + + this.sendApprovePassEvent(saleOrder); + } + + @Override + public PageResult pendApproveList(int pageIndex, int pageSize, Integer status) { + int offset = (pageIndex - 1) * pageSize; + Integer total = saleOrderMapper.getOrderSumByStatus(status); + //根据状态查询订单列表 + List datas = saleOrderMapper.selectListByStatus(pageSize, offset, status); + PageResult convert = PageResultUtil.convert(new PageInfo<>(datas)); + convert.setTotalCount(total); + return convert; + } + + @Override + public SaleOrder selectById(String id) { + return saleOrderMapper.selectById(id); + } + + @Override + public int updatePurchaseStatusbyId(SaleOrder saleOrder) { + + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper + .eq("id", saleOrder.getId()) + .set("purchase_status", saleOrder.getStatus()); + + return saleOrderMapper.update(null, updateWrapper); + } + + + private void sendApprovePassEvent(SaleOrder order) { + ApprovePassSaleOrderEvent event = new ApprovePassSaleOrderEvent(this); + event.setId(order.getId()); + event.setTotalAmount(order.getTotalAmount()); + event.setApproveTime(DateUtils.toLocalDateTime(order.getApproveTime())); + eventPublisher.publishEvent(event); // 直接调用 Spring 方法 + } +} diff --git a/src/main/java/com/soft/service/impl/SysUserServiceImpl.java b/src/main/java/com/soft/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..a298a88 --- /dev/null +++ b/src/main/java/com/soft/service/impl/SysUserServiceImpl.java @@ -0,0 +1,41 @@ +package com.soft.service.impl; + +import com.soft.entitys.user.SystemUser; +import com.soft.dto.SysUserDTO; +import com.soft.mapper.SysUserMapper; +import com.soft.service.SysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +@Service +public class SysUserServiceImpl implements SysUserService { + + @Autowired + private SysUserMapper sysUserMapper; + + @Autowired + private PasswordEncoder passwordEncode; + + @Override + public SysUserDTO query(SystemUser systemUser) { + SysUserDTO user = sysUserMapper.query(systemUser.getUsername()); + if(Objects.isNull(user)){ + return null; + } + //校验 + boolean matches = passwordEncode.matches(systemUser.getPassword(), user.getPassword()); + if (matches){ + return user; + } + return null; + } + + @Override + public SysUserDTO selectById(String sysUserId) { + SysUserDTO sysUserDTO = sysUserMapper.getSysUserById(sysUserId); + return sysUserDTO; + } +} diff --git a/src/main/java/com/soft/service/impl/UserServiceImpl.java b/src/main/java/com/soft/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..d6b7c91 --- /dev/null +++ b/src/main/java/com/soft/service/impl/UserServiceImpl.java @@ -0,0 +1,198 @@ +package com.soft.service.impl; + +import cn.hutool.core.codec.Base64; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.soft.dto.WeChatLoginRequestDTO; +import com.soft.entitys.user.User; +import com.soft.mapper.UserMapper; +import com.soft.service.UserService; +import com.soft.utils.ConstantUtil; +import com.soft.utils.HttpUtils; +import com.soft.utils.WxUtil; +import com.soft.vo.BindPhoneVo; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.math.BigDecimal; +import java.security.AlgorithmParameters; +import java.security.Security; +import java.util.*; + + +@Service +public class UserServiceImpl extends ServiceImpl implements UserService { + + + private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class); + + ConstantUtil constantUtil = null; + + @Override + public Map getUserInfoMap(WeChatLoginRequestDTO loginRequest) { + Map map = new HashMap<>(); + String appId = constantUtil.WX_APPID; + String secret = constantUtil.WX_SECRET; + String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + secret + "&js_code=" + loginRequest.getCode() + "&grant_type=authorization_code"; + String resultStr = HttpUtils.sendGet(url); + JSONObject SessionKeyOpenId = JSON.parseObject(resultStr); + String openid = SessionKeyOpenId.getString("openid"); + String sessionKey = SessionKeyOpenId.getString("session_key"); + System.out.println("openid=" + openid + ",session_key=" + sessionKey); + User user = super.baseMapper.getByOpenId(openid); + + JSONObject userInfo = decryptData(loginRequest.getEncryptedData(), sessionKey, loginRequest.getIv()); + + if (user == null) { + user = new User(); + String nickName = userInfo.getString("nickName"); + String avatarUrl = userInfo.getString("avatarUrl"); + user.setNickName(nickName); + user.setAvatar(avatarUrl); + user.setOpenId(openid); + user.setCreateTime(new Date()); + super.baseMapper.insert(user); + } else { + //已存在 + user.setLastLoginTime(new Date()); + super.baseMapper.updateById(user); + logger.info("用户openid已存在,不需要插入"); + } + User userInf = super.baseMapper.getUserListByUid(user.getId()); + System.out.println(userInf); + + map.put("userInfo", userInf); + map.put("sessionKey",sessionKey); + return map; + } + + @Override + public JSONObject decryptData(String encryptedData, String sessionKey, String iv) { + // 被加密的数据 + byte[] dataByte = Base64.decode(encryptedData); + // 加密秘钥 + byte[] keyByte = Base64.decode(sessionKey); + // 偏移量 + byte[] ivByte = Base64.decode(iv); + try { + // 如果密钥不足16位,那么就补足.这个if中的内容很重要 + int base = 16; + if (keyByte.length % base != 0) { + int groups = keyByte.length / base + 1; + byte[] temp = new byte[groups * base]; + Arrays.fill(temp, (byte) 0); + System.arraycopy(keyByte, 0, temp, 0, keyByte.length); + keyByte = temp; + } + // 初始化 + Security.addProvider(new BouncyCastleProvider()); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); + SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); + AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); + parameters.init(new IvParameterSpec(ivByte)); + cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化 + byte[] resultByte = cipher.doFinal(dataByte); + if (null != resultByte && resultByte.length > 0) { + String result = new String(resultByte, "UTF-8"); + return JSONObject.parseObject(result); + } + } catch (Exception e) { + logger.error("解密加密信息报错", e.getMessage()); + } + return null; + } + + @Override + public BindPhoneVo getPhoneNumber(String code, Integer pid, Integer uId, Integer type) { + + String accessToken = WxUtil.getToken(); + HashMap paramMap = new HashMap<>(); + paramMap.put("code", code); + String msgBody = JSONObject.toJSONString(paramMap);// + + String resultStr = HttpUtils.sendPost("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken, + "application/json; charset=UTF-8", msgBody, 5000, 5000, null); + System.out.println("resultStr :" + resultStr); + JSONObject resultJson = JSON.parseObject(resultStr); + + if (resultJson.getInteger("errcode") != 0) { + System.out.println("null"); + } + Object phoneNumber = resultJson.getJSONObject("phone_info").get("phoneNumber"); + BindPhoneVo bindPhoneVo = new BindPhoneVo(); + + User user = super.baseMapper.getUserListByUid(uId); + + if (type == null && pid == null) { + user.setPhone((String) phoneNumber); + } + + if ((pid != null && type != null)) { + if (type == 1) { + user.setLevelId(1); + bindPhoneVo.setLevel(1); + user.setPid(pid); + user.setSpreadTime(new Date()); + + Integer count=super.baseMapper.getUpLevelUser(pid); + + User pUser=super.baseMapper.getUserListByUid(pid); + if(pUser.getLevelId()==1){ + if(count >=9){ + QueryWrapper queryWrapperUser = new QueryWrapper<>(); + queryWrapperUser.eq("id", pid); + pUser.setLevelId(2); + super.baseMapper.update(pUser, queryWrapperUser); + } + } + + } + } + + user.setPhone((String) phoneNumber); + QueryWrapper queryWrapperUser = new QueryWrapper<>(); + queryWrapperUser.eq("id", user.getId()); + super.baseMapper.update(user, queryWrapperUser); + bindPhoneVo.setPhoneNumber((String) phoneNumber); + + return bindPhoneVo; + } + + @Override + public User queryByOpenId(String openId) { + return super.baseMapper.getByOpenId(openId); + } + + @Override + public int updateUserById(User user) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper + .eq("id", user.getId()) + .set("sys_user_id", user.getSysUserId()); + + return super.baseMapper.update(user, updateWrapper); + } + + @Override + public User queryBySysUserId(String sysUserId) { + QueryWrapper queryWrapperUser = new QueryWrapper<>(); + queryWrapperUser.eq("sys_user_id", sysUserId); + return super.baseMapper.selectOne(queryWrapperUser); + + } + + @Override + public User getUserById(Integer userId) { + QueryWrapper queryWrapperUser = new QueryWrapper<>(); + queryWrapperUser.eq("id", userId); + return super.baseMapper.selectOne(queryWrapperUser); + } + +} diff --git a/src/main/java/com/soft/service/impl/VoiceQueryServiceImpl.java b/src/main/java/com/soft/service/impl/VoiceQueryServiceImpl.java new file mode 100644 index 0000000..894a1f7 --- /dev/null +++ b/src/main/java/com/soft/service/impl/VoiceQueryServiceImpl.java @@ -0,0 +1,1639 @@ +package com.soft.service.impl; + +import com.soft.dto.OrderProportionDto; +import com.soft.dto.StatisticsProductStockDto; +import com.soft.dto.SysUserDTO; +import com.soft.entitys.Page; +import com.soft.entitys.QueryParams; +import com.soft.entitys.voice.*; +import com.soft.mapper.*; +import com.soft.service.VoiceQueryService; +import com.soft.utils.PieChartData; +import com.soft.utils.ProportionUtils; +import com.soft.utils.UnsupportedQueryException; +import com.soft.vo.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.Year; +import java.time.YearMonth; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class VoiceQueryServiceImpl implements VoiceQueryService { + + private static final Logger logger = LoggerFactory.getLogger(VoiceQueryServiceImpl.class); + + @Autowired + private SaleOrderMapper saleOrderMapper; + + @Autowired + private PurchaseOrderMapper purchaseOrderMapper; + + @Autowired + private ProductMapper productMapper; + + @Autowired + private PurchaseReturnMapper purchaseReturnMapper; + + @Autowired + private PurchaseReturnDetailMapper purchaseReturnDetailMapper; + + @Autowired + private PurchaseOrderDetailMapper purchaseOrderDetailMapper; + + @Autowired + private CustomerMapper customerMapper; + + @Autowired + private SaleOrderDetailMapper saleOrderDetailMapper; + + @Autowired + private SysUserMapper sysUserMapper; + + @Autowired + private ProductStockLogMapper productStockLogMapper; + + @Autowired + private SaleOutSheetMapper saleOutSheetMapper; + + @Autowired + private SaleOutSheetDetailMapper saleOutSheetDetailMapper; + + @Autowired + private SettleCheckSheetMapper settleCheckSheetMapper; + + @Autowired + private SettleCheckSheetDetailMapper settleCheckSheetDetailMapper; + + @Autowired + private SettleSheetMapper settleSheetMapper; + + @Autowired + private SettleSheetDetailMapper settleSheetDetailMapper; + + @Autowired + private SupplierMapper supplierMapper; + + @Autowired + private ProductStockMapper productStockMapper; + + @Autowired + private StoreCenterMapper storeCenterMapper; + + @Override + public Object processQuery(QueryParams params) { + if (params.getType() == null) { + throw new UnsupportedQueryException("未识别的查询类型"); + } else { + switch (params.getType()) { + case TODAY_PURCHASE_AMOUNT: + return getTodayPurchaseAmount(); + case TODAY_SALES_AMOUNT: + return getTodaySalesAmount(); + case PRODUCT_INVENTORY: + return QueryProductInventory(params.getProductName()); + case TODAY_PURCHASE_ORDERS: + return getTodayPurchaseOrder(); + case TODAY_PURCHASE_RETURN: + return getTodaysPurchaseOrderReturn(); + case CUSTOMER_NAME_SEARCH: + return getSaleOrderByCustomerName(params.getCustomerName()); + case USER_NAME_ORDERS_SEARCH: + return getSaleOrderByUserName(params.getUserName()); + case SALES_ORDERS_BY_DATE: + return selectSaleOrdersByDate(params.getQueryDate()); + case PURCHASE_ORDERS_BY_DATE: + return selectPurchaseOrdersByDate(params.getQueryDate()); + case PRODUCT_STOCK_LOG_BY_NAME: + return getProductStockLogs(params.getProductName()); + case TODAY_OUTBOUND_ORDERS: + return selectSaleOutSheetToDays(); + case REVENUE_COUNT: + return checkOrderAmountCount(); + case ACCOUNTS_PAYABLE: + return settleCheckAccountsPayable(); + case PAYMENT_TOF_FEES: + return settleSheetPaymentOfFees(); + case TOTAL_PROFIT: + return saleOrderTotalProfit(); + case MONTH_SALE_AMOUNT: + return getMonthSalesAmount(); + case MONTH_PURCHASE_AMOUNT: + return getMonthPurchaseAmount(); + case YEAR_SALE_AMOUNT: + return getYearSalesAmount(); + case YEAR_PURCHASE_AMOUNT: + return getYearPurchaseAmount(); + default: + throw new IllegalArgumentException("不支持的查询类型"); + } + } + + } + + @Override + public OrderDataVo statisticsTodaysOrderData() { + + + OrderDataVo orderDataVo=new OrderDataVo(); + List saleOrderVoList= saleOrderMapper.CheckTodysSaleOrderLits(); + + BigDecimal todayTotalSaleAmount = BigDecimal.ZERO; + + for (SaleOrderVo saleOrderVo : saleOrderVoList) { + if (saleOrderVo.getTotalAmount() != null) { + todayTotalSaleAmount = todayTotalSaleAmount.add(saleOrderVo.getTotalAmount()); + } + } + + orderDataVo.setTodaySaleOrderAmount(todayTotalSaleAmount); + orderDataVo.setTodaySaleQuantityCount(saleOrderVoList.size()); + + + BigDecimal todayTotalPurchaseAmount = BigDecimal.ZERO; + List purchaseOrderVoList=purchaseOrderMapper.TodaysPurchaseOrder(); + for (PurchaseOrderVo purchaseOrderVo : purchaseOrderVoList) { + if (purchaseOrderVo.getTotalAmount() != null) { + todayTotalPurchaseAmount = todayTotalPurchaseAmount.add(purchaseOrderVo.getTotalAmount()); + } + } + orderDataVo.setTodayPurchaseOrderAmount(todayTotalPurchaseAmount); + orderDataVo.setTodayPurchaseQuantityCount(purchaseOrderVoList.size()); + + + + + + return orderDataVo; + } + + @Override + public OrderDataMonthVo statisticsMonthOrderData() { + + OrderDataMonthVo orderDataMonthVo=new OrderDataMonthVo(); + BigDecimal thisMonthTotalPurchaseAmount = BigDecimal.ZERO; + List thisMonthPurchaseList=purchaseOrderMapper.thisMonthPurchaseOrder(); + + for (PurchaseOrderVo purchaseOrderVo : thisMonthPurchaseList) { + if (purchaseOrderVo.getTotalAmount() != null) { + thisMonthTotalPurchaseAmount = thisMonthTotalPurchaseAmount.add(purchaseOrderVo.getTotalAmount()); + } + } + + orderDataMonthVo.setThisMonthPurchaseOrderAmount(thisMonthTotalPurchaseAmount); + orderDataMonthVo.setThisMonthPurchaseQuantityCount(thisMonthPurchaseList.size()); + + + BigDecimal thisMonthTotalSaleAmount = BigDecimal.ZERO; + List thisMonthSaleList=saleOrderMapper.CheckThisMonthSaleOrderList(); + for (SaleOrderVo saleOrderVo : thisMonthSaleList) { + if (saleOrderVo.getTotalAmount() != null) { + thisMonthTotalSaleAmount = thisMonthTotalSaleAmount.add(saleOrderVo.getTotalAmount()); + } + } + + orderDataMonthVo.setThisMonthSaleOrderAmount(thisMonthTotalSaleAmount); + orderDataMonthVo.setThisMonthSaleQuantityCount(thisMonthSaleList.size()); + + return orderDataMonthVo; + } + + @Override + public OrderDataWeekVo statisticsWeekOrderData() { + + OrderDataWeekVo orderDataWeekVo=new OrderDataWeekVo(); + BigDecimal thisMonthTotalPurchaseAmount = BigDecimal.ZERO; + List thisMonthPurchaseList=purchaseOrderMapper.thisWeekPurchaseOrder(); + + for (PurchaseOrderVo purchaseOrderVo : thisMonthPurchaseList) { + if (purchaseOrderVo.getTotalAmount() != null) { + thisMonthTotalPurchaseAmount = thisMonthTotalPurchaseAmount.add(purchaseOrderVo.getTotalAmount()); + } + } + + orderDataWeekVo.setThisWeekPurchaseOrderAmount(thisMonthTotalPurchaseAmount); + orderDataWeekVo.setThisWeekPurchaseQuantityCount(thisMonthPurchaseList.size()); + + + BigDecimal thisMonthTotalSaleAmount = BigDecimal.ZERO; + List thisMonthSaleList=saleOrderMapper.CheckThisWeekSaleOrderList(); + for (SaleOrderVo saleOrderVo : thisMonthSaleList) { + if (saleOrderVo.getTotalAmount() != null) { + thisMonthTotalSaleAmount = thisMonthTotalSaleAmount.add(saleOrderVo.getTotalAmount()); + } + } + + orderDataWeekVo.setThisWeekSaleOrderAmount(thisMonthTotalSaleAmount); + orderDataWeekVo.setThisWeekSaleQuantityCount(thisMonthSaleList.size()); + + return orderDataWeekVo; + } + + @Override + public OrderMonthContrastVo orderMonthContrast() { + + OrderMonthContrastVo orderMonthContrastVo=new OrderMonthContrastVo(); + + // 生成最近12个月的月份标签 + LocalDate now = LocalDate.now(); + List months = new ArrayList<>(); + List yearMonths = new ArrayList<>(); + + // 倒序生成月份列表(从最早月份到当前月) + for (int i = 11; i >= 0; i--) { + YearMonth ym = YearMonth.from(now.minusMonths(i)); + yearMonths.add(ym); + months.add(ym.getMonthValue() + "月"); + } + + // 初始化金额列表(12个0) + List saleAmounts = ProportionUtils.initZeroList(12); + List purchaseAmounts = ProportionUtils.initZeroList(12); + + // 创建月份索引映射表 + Map indexMap = new HashMap<>(); + for (int i = 0; i < yearMonths.size(); i++) { + indexMap.put(yearMonths.get(i), i); + } + + // 处理销售数据 + List> sales = saleOrderMapper.orderMonthContrastSaleOrder(); + ProportionUtils.fillAmounts(sales, saleAmounts, indexMap, "sale_amount"); + + // 处理采购数据 + List> purchases = purchaseOrderMapper.orderMonthContrastPurchaseOrder(); + ProportionUtils.fillAmounts(purchases, purchaseAmounts, indexMap, "purchase_amount"); + + orderMonthContrastVo.setXAxisData(months); + orderMonthContrastVo.setSaleAmounts(saleAmounts); + orderMonthContrastVo.setPurchaseAmounts(purchaseAmounts); + orderMonthContrastVo.setChartType("chart"); // 标识为按月统 + + return orderMonthContrastVo; + } + + @Override + public OrderTodaysContrastVo orderTodaysContrast() { + OrderTodaysContrastVo vo = new OrderTodaysContrastVo(); + + // 生成最近30天的日期标签 + LocalDate now = LocalDate.now(); + List xAxisData = new ArrayList<>(); + for (int i = 30; i > 0; i--) { // 生成从30天前到昨天的日期(共30天) + LocalDate date = now.minusDays(i - 1); // i-1确保包含当天 + xAxisData.add(date.getMonthValue() + "/" + date.getDayOfMonth()); + } + + // 初始化金额列表 + List saleAmounts = new ArrayList<>(Collections.nCopies(30, BigDecimal.ZERO)); + List purchaseAmounts = new ArrayList<>(Collections.nCopies(30, BigDecimal.ZERO)); + + // 获取销售数据 + List> sales = saleOrderMapper.orderTodaysContrastSaleOrder(); + // 获取采购数据 + List> purchases = purchaseOrderMapper.orderTodaysContrastPurchaseOrder(); + + ProportionUtils.dayFillAmounts(purchases, purchaseAmounts, now, "purchase_amount"); // 采购用purchase_amount + ProportionUtils.dayFillAmounts(sales, saleAmounts, now, "sale_amount"); // 销售用sale_amount + + vo.setXAxisData(xAxisData); + vo.setSaleAmounts(saleAmounts); + vo.setPurchaseAmounts(purchaseAmounts); + vo.setChartType("chart"); + return vo; + } + + @Override + public OrderProportionVo orderProportion(OrderProportionDto orderProportionDto) { + + if (orderProportionDto.getMonth() == null || orderProportionDto.getMonth() < 1 || orderProportionDto.getMonth() > 12) { + throw new IllegalArgumentException("Invalid month"); + } + + //默认年份为当前年 + Integer currentYear = LocalDate.now().getYear(); + + //查询采购金额 + BigDecimal purchaseAmount = purchaseOrderMapper.getPurchaseAmountByMonth(currentYear, orderProportionDto.getMonth()); + + //查询销售金额 + BigDecimal saleAmount = saleOrderMapper.getSaleAmountByMonth(currentYear, orderProportionDto.getMonth()); + + //计算采销占比 + String proportion = ProportionUtils.calculateProportion(purchaseAmount, saleAmount); + + + OrderProportionVo vo = new OrderProportionVo(); + vo.setPurchaseAmount(purchaseAmount); + vo.setSaleAmount(saleAmount); + vo.setProportion(proportion); + return vo; + } + + @Override + public List productProductStockProportion() { + + //获取原始数据并计算总库存 + List dataList = productStockMapper.getProductStockProportion(); + int totalStock = dataList.stream() + .mapToInt(ProductStockDataVo::getStockNum) + .sum(); + + BigDecimal total = totalStock == 0 ? BigDecimal.ONE : new BigDecimal(totalStock); + + //按库存降序排序 + List sortedList = dataList.stream() + .sorted((d1, d2) -> Integer.compare(d2.getStockNum(), d1.getStockNum())) + .collect(Collectors.toList()); + + //分离前十和剩余商品 + List top10 = sortedList.stream() + .limit(10) + .collect(Collectors.toList()); + + List others = sortedList.stream() + .skip(10) + .collect(Collectors.toList()); + + List result = new ArrayList<>(); + + //添加总库存条目 + ProductStockProportionVo totalVo = new ProductStockProportionVo(); + totalVo.setProductName("总库存"); + totalVo.setStock(String.valueOf(totalStock)); + totalVo.setProportion(""); // 总库存不显示百分比 + result.add(totalVo); + + //处理前十商品(计算百分比) + top10.forEach(data -> { + ProductStockProportionVo vo = new ProductStockProportionVo(); + vo.setProductName(data.getProductName()); + vo.setStock(String.valueOf(data.getStockNum())); + + // 计算百分比 + BigDecimal ratio = new BigDecimal(data.getStockNum()) + .divide(total, 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal(100)); + vo.setProportion(String.format("%.2f%%", ratio)); + + result.add(vo); + }); + + //处理其他商品(合并并计算百分比) + if (!others.isEmpty()) { + int othersTotal = others.stream() + .mapToInt(ProductStockDataVo::getStockNum) + .sum(); + + ProductStockProportionVo othersVo = new ProductStockProportionVo(); + othersVo.setProductName("其他商品"); + othersVo.setStock(String.valueOf(othersTotal)); + + // 计算百分比 + BigDecimal othersRatio = new BigDecimal(othersTotal) + .divide(total, 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal(100)); + othersVo.setProportion(String.format("%.2f%%", othersRatio)); + + result.add(othersVo); + } + + return result; + } + + @Override + public List saleSalerMonthRank() { + //询本月所有销售订单 + List orders = saleOrderMapper.saleSalerMonthRank(); + + Set salerIds = orders.stream() + .filter(order -> order.getSalerId() != null) + .map(SaleOrderVo::getSalerId) + .collect(Collectors.toSet()); + + Map salerNameMap = sysUserMapper.selectUsersByIds(salerIds).stream() + .collect(Collectors.toMap(SysUserDTO::getId, SysUserDTO::getName)); + + Map salerAmountMap = new HashMap<>(); + for (SaleOrderVo order : orders) { + if (order.getSalerId() == null || order.getTotalAmount() == null) continue; + + String salerName = salerNameMap.getOrDefault(order.getSalerId(), "未知销售员"); + + // 获取订单金额(空值处理) + BigDecimal amount = Optional.ofNullable(order.getTotalAmount()).orElse(BigDecimal.ZERO); + + salerAmountMap.merge(salerName, amount, BigDecimal::add); + } + + return salerAmountMap.entrySet().stream() + .map(entry -> new SaleSalerRankVo( + entry.getKey(), + Optional.ofNullable(entry.getValue()).orElse(BigDecimal.ZERO) + )) + .sorted((a, b) -> { + BigDecimal aAmount = Optional.ofNullable(a.getSaleAmount()).orElse(BigDecimal.ZERO); + BigDecimal bAmount = Optional.ofNullable(b.getSaleAmount()).orElse(BigDecimal.ZERO); + return bAmount.compareTo(aAmount); + }) + .collect(Collectors.toList()); + } + + @Override + public List saleSalerWeekRank() { + List orders = saleOrderMapper.saleSalerWeekRank(); + + Set salerIds = orders.stream() + .filter(order -> order.getSalerId() != null) + .map(SaleOrderVo::getSalerId) + .collect(Collectors.toSet()); + + Map salerNameMap = sysUserMapper.selectUsersByIds(salerIds).stream() + .collect(Collectors.toMap(SysUserDTO::getId, SysUserDTO::getName)); + + Map salerAmountMap = new HashMap<>(); + for (SaleOrderVo order : orders) { + if (order.getSalerId() == null || order.getTotalAmount() == null) continue; + + String salerName = salerNameMap.getOrDefault(order.getSalerId(), "未知销售员"); + + // 获取订单金额(空值处理) + BigDecimal amount = Optional.ofNullable(order.getTotalAmount()).orElse(BigDecimal.ZERO); + + salerAmountMap.merge(salerName, amount, BigDecimal::add); + } + + return salerAmountMap.entrySet().stream() + .map(entry -> new SaleSalerRankVo( + entry.getKey(), + Optional.ofNullable(entry.getValue()).orElse(BigDecimal.ZERO) + )) + .sorted((a, b) -> { + BigDecimal aAmount = Optional.ofNullable(a.getSaleAmount()).orElse(BigDecimal.ZERO); + BigDecimal bAmount = Optional.ofNullable(b.getSaleAmount()).orElse(BigDecimal.ZERO); + return bAmount.compareTo(aAmount); + }) + .collect(Collectors.toList()); + } + + @Override + public SaleOrderGrossMarginVo saleOrderGrossMargin() { + + // 获取最近12个月的订单数据 + List list=saleOrderMapper.latelyDecemberSaleOrderProfit(); + + LocalDate currentDate = LocalDate.now(); + List months = new ArrayList<>(); + List yearMonths = new ArrayList<>(); + for (int i = 11; i >= 0; i--) { + YearMonth yearMonth = YearMonth.from(currentDate.minusMonths(i)); + yearMonths.add(yearMonth); + months.add(yearMonth.getMonthValue() + "月"); + } + List profits = yearMonths.stream() + .map(ym -> BigDecimal.ZERO) + .collect(Collectors.toCollection(ArrayList::new)); + + Map monthIndexMap = new HashMap<>(); + for (int i = 0; i < yearMonths.size(); i++) { + monthIndexMap.put(yearMonths.get(i), i); + } + + // 计算每个月的毛利总和 + for (SaleOrderVo order : list) { + // 转换时间到年月维度 + LocalDate orderDate = order.getCreateTime().toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate(); + YearMonth orderYearMonth = YearMonth.from(orderDate); + + // 找到对应的月份索引 + Integer index = monthIndexMap.get(orderYearMonth); + if (index != null) { + BigDecimal profit = order.getThisOrderProfit() != null ? + order.getThisOrderProfit() : BigDecimal.ZERO; + profits.set(index, profits.get(index).add(profit)); + } + } + + for (SaleOrderVo saleOrderVo : list) { + saleOrderVo.getThisOrderProfit(); + } + + SaleOrderGrossMarginVo result = new SaleOrderGrossMarginVo(); + result.setChartType("chart"); + result.setXAxisData(months); + result.setSaleAmounts(profits); + + return result; + } + + @Override + public SaleOrderLastYearProfitVo saleOrderLastYearProfit() { + + List orders = saleOrderMapper.lastYearSaleOrderProfit(); + + LocalDate currentDate = LocalDate.now(); + Year lastYear = Year.from(currentDate.minusYears(1)); + List months = new ArrayList<>(); + for (int month = 1; month <= 12; month++) { + months.add(String.valueOf(month) + "月"); + } + + List profits = months.stream() + .map(month -> BigDecimal.ZERO) + .collect(Collectors.toCollection(ArrayList::new)); + + Map monthIndexMap = new HashMap<>(); + for (int i = 0; i < 12; i++) { + monthIndexMap.put(i + 1, i); + } + + for (SaleOrderVo order : orders) { + // 转换时间到月份维度 + LocalDate orderDate = order.getCreateTime().toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate(); + int orderMonth = orderDate.getMonthValue(); + + // 找到对应的月份索引 + Integer index = monthIndexMap.get(orderMonth); + if (index != null) { + BigDecimal profit = order.getThisOrderProfit() != null ? + order.getThisOrderProfit() : BigDecimal.ZERO; + profits.set(index, profits.get(index).add(profit)); + } + } + + // 构建返回对象 + SaleOrderLastYearProfitVo result = new SaleOrderLastYearProfitVo(); + result.setChartType("chart"); + result.setXAxisData(months); + result.setSaleAmounts(profits); + + return result; + } + + @Override + public SaleOrderCurrentYearAmountVo saleOrderCurrentYearAmount() { + + SaleOrderCurrentYearAmountVo vo = new SaleOrderCurrentYearAmountVo(); + + // 获取数据:包含今年和去年(可能为0) + List> data = saleOrderMapper.getYearlyComparisonData(); + + // 提取今年和去年的数据 + BigDecimal currentYearAmount = BigDecimal.ZERO; + BigDecimal currentYearCost = BigDecimal.ZERO; + BigDecimal currentYearSales = BigDecimal.ZERO; + BigDecimal lastYearAmount = BigDecimal.ZERO; + BigDecimal lastYearCost = BigDecimal.ZERO; + BigDecimal lastYearSales = BigDecimal.ZERO; + + for (Map item : data) { + Long yearLong = (Long) item.get("year"); + if (yearLong != null) { + Integer year = yearLong.intValue(); // 安全地转换为 Integer + // 使用 year + BigDecimal amount = (BigDecimal) item.get("total_amount"); + BigDecimal sales = new BigDecimal(item.get("total_num").toString()); + BigDecimal cost = (BigDecimal) item.get("total_purchase_price"); + + if (year == Year.now().getValue()) { // 今年 + currentYearAmount = amount != null ? amount : BigDecimal.ZERO; + currentYearSales = sales; + currentYearCost = cost != null ? cost : BigDecimal.ZERO; + } else { // 去年 + lastYearAmount = amount != null ? amount : BigDecimal.ZERO; + lastYearSales = sales; + lastYearCost = cost != null ? cost : BigDecimal.ZERO; + } + } + + } + + // 填充基础数据 + vo.setCurrentYearAmount(currentYearAmount); + vo.setSaleCount(currentYearSales.toPlainString()); + vo.setTotalPurchasePrice(currentYearCost); + + // 计算毛利率(百分比) + if (currentYearAmount.compareTo(BigDecimal.ZERO) != 0) { + BigDecimal grossMargin = currentYearAmount.subtract(currentYearCost) + .divide(currentYearAmount, 4, RoundingMode.HALF_UP) + .multiply(BigDecimal.valueOf(100)); + vo.setGrossMarginPercent(String.format("%.2f%%", grossMargin)); + } else { + vo.setGrossMarginPercent("0.00%"); + } + + // 计算销售额同比增长率 + vo.setAmountGrowthPercent(ProportionUtils.calculateGrowth(currentYearAmount, lastYearAmount)); + + // 计算销售数量同比增长率 + vo.setSaleCountGrowthPercent(ProportionUtils.calculateGrowth(currentYearSales, lastYearSales)); + + // 计算成本同比增长率 + vo.setPurchasePriceGrowthPercent(ProportionUtils.calculateGrowth(currentYearCost, lastYearCost)); + + // 计算毛利率同比增长率(需要计算去年毛利率) + BigDecimal lastYearGrossMargin = BigDecimal.ZERO; + if (lastYearAmount.compareTo(BigDecimal.ZERO) != 0) { + lastYearGrossMargin = lastYearAmount.subtract(lastYearCost) + .divide(lastYearAmount, 4, RoundingMode.HALF_UP) + .multiply(BigDecimal.valueOf(100)); + } + BigDecimal currentYearGrossMargin = new BigDecimal(vo.getGrossMarginPercent().replace("%", "")); + vo.setGrossMarginGrowthPercent(ProportionUtils.calculateGrowth(currentYearGrossMargin, lastYearGrossMargin)); + + return vo; + + } + + @Override + public Page> statisticsProductStock(StatisticsProductStockDto statisticsProductStockDto) { + + + Integer count=productStockMapper.getProductStockListCount(); + Integer startNum=(statisticsProductStockDto.getPageNum()-1)*statisticsProductStockDto.getPageSize(); + + + List list=productStockMapper.getProductStockList(startNum,statisticsProductStockDto.getPageSize()); + + + + for (ProductStockDataVo productStockDataVo : list) { + Product product=productMapper.getProductById(productStockDataVo.getProductId()); + productStockDataVo.setProductName(product.getName()); + + StoreCenter storeCenter=storeCenterMapper.getStoreCenterById(productStockDataVo.getScId()); + productStockDataVo.setScName(storeCenter.getName()); + } + + return new Page<>(statisticsProductStockDto.getPageNum(),count,statisticsProductStockDto.getPageSize(),list); + } + + + private CheckTodaysPurchaseAmountVo getTodayPurchaseAmount() { + + CheckTodaysPurchaseAmountVo checkTodaysPurchaseAmountVo = new CheckTodaysPurchaseAmountVo(); + checkTodaysPurchaseAmountVo.setChartType("column"); + BigDecimal amount = purchaseOrderMapper.CheckTodaysPurchaseAmount(); + + + checkTodaysPurchaseAmountVo.setPurchaseAmount(amount); + + List list = purchaseOrderMapper.TodaysPurchaseOrder(); + Map supplierAmountMap = new HashMap<>(); + + for (PurchaseOrderVo purchaseOrderVo : list) { + Supplier supplier = supplierMapper.getSupplierById(purchaseOrderVo.getSupplierId()); + String supplierName = supplier.getName(); + purchaseOrderVo.setSupplierName(supplierName); + BigDecimal totalAmount = purchaseOrderVo.getTotalAmount(); + + supplierAmountMap.merge( + supplierName, + totalAmount, + BigDecimal::add // 相同供应商的金额相加 + ); + + } + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + LocalDate currentDate = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String formattedDate = currentDate.format(formatter); + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + + String formattedTotalAmount=null; + if(saleOrderMapper.CheckTodaysOrderAmount()!=null){ + formattedTotalAmount = currencyFormat.format(amount); + }else{ + formattedTotalAmount="0"; + } + + String msg = "好的," + formattedDate + ",采购订单金额为: " + formattedTotalAmount + ",有其他需求可以随时告诉我哦!"; + + + checkTodaysPurchaseAmountVo.setMsg(msg); + + checkTodaysPurchaseAmountVo.setXAxisData(xAxisData); + checkTodaysPurchaseAmountVo.setYAxisData(yAxisData); + + return checkTodaysPurchaseAmountVo; + } + + + private CheckTodysSalesAmountVo getTodaySalesAmount() { + CheckTodysSalesAmountVo checkTodysSalesAmountVo = new CheckTodysSalesAmountVo(); + checkTodysSalesAmountVo.setChartType("column"); + checkTodysSalesAmountVo.setSalesAmount(saleOrderMapper.CheckTodaysOrderAmount()); + + List list = saleOrderMapper.CheckTodysSaleOrderLits(); + + Map supplierAmountMap = new HashMap<>(); + for (SaleOrderVo saleOrderVo : list) { + if (saleOrderVo != null) { + if (saleOrderVo.getSalerId() != null) { + SysUserDTO sysUserDTO = sysUserMapper.getSysUserById(saleOrderVo.getSalerId()); + String name = sysUserDTO.getName(); + saleOrderVo.setSalerName(name); + BigDecimal totalAmount = saleOrderVo.getTotalAmount(); + + supplierAmountMap.merge( + name, + totalAmount, + BigDecimal::add // 相同供应商的金额相加 + ); + } + + } + + } + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + LocalDate currentDate = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String formattedDate = currentDate.format(formatter); + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + + String formattedTotalAmount=null; + if(saleOrderMapper.CheckTodaysOrderAmount()!=null){ + formattedTotalAmount = currencyFormat.format(saleOrderMapper.CheckTodaysOrderAmount()); + }else{ + formattedTotalAmount="0"; + } + + + String msg = "好的," + formattedDate + ",销售订单金额为: " + formattedTotalAmount + ",有其他需求可以随时告诉我哦!"; + checkTodysSalesAmountVo.setMsg(msg); + + checkTodysSalesAmountVo.setXAxisData(xAxisData); + checkTodysSalesAmountVo.setYAxisData(yAxisData); + + return checkTodysSalesAmountVo; + } + + private QueryProductInventoryVo QueryProductInventory(String productName) { + // 1. 查询匹配的商品列表(如所有"联想"商品) + List matchedProducts = productMapper.QueryProductInventory(productName); + + // 2. 获取全库总库存(包括匹配和非匹配商品) + Integer totalStock = productStockMapper.getProductStockNum(); + + // 3. 计算匹配商品的总库存 + int matchedStock = matchedProducts.stream() + .mapToInt(ProductVo::getStockNum) + .sum(); + + // 4. 计算其他商品库存(全库 - 匹配商品) + int otherStock = totalStock - matchedStock; + double otherPercent = (double) otherStock / totalStock * 100; + + // 5. 构建饼图数据(匹配商品 + 其他商品) + List pieChartData = new ArrayList<>(); + + // 5.1 添加匹配的各个商品 + matchedProducts.forEach(product -> { + double percent = (double) product.getStockNum() / totalStock * 100; + pieChartData.add(new PieChartData( + product.getName(), + product.getStockNum(), + String.format("%.2f%%", percent) + )); + }); + + // 5.2 添加"其他商品"选项 + pieChartData.add(new PieChartData( + "其他商品", + otherStock, + String.format("%.2f%%", otherPercent) + )); + + // 6. 构建消息文本 + StringBuilder msg = new StringBuilder("查询到的商品库存信息:\n"); + matchedProducts.forEach(product -> + msg.append("商品:") + .append(product.getName()) + .append(",剩余库存:") + .append(product.getStockNum()) + .append("\n") + ); + + // 7. 返回结果 + QueryProductInventoryVo vo = new QueryProductInventoryVo(); + vo.setChartType("ring"); + vo.setPieChartData(pieChartData); + vo.setMsg(msg.toString()); + return vo; + } + + + private PurchaseOrderChartVo getTodayPurchaseOrder() { + + PurchaseOrderChartVo purchaseOrderChartVo = new PurchaseOrderChartVo(); + List list = purchaseOrderMapper.TodaysPurchaseOrder(); + +// List xAxisSupplierNames = new ArrayList<>(); +// List yAxisOrderAmounts = new ArrayList<>(); + Map supplierAmountMap = new HashMap<>(); + + for (PurchaseOrderVo purchaseOrderVo : list) { + + purchaseOrderVo.setPurchaseOrderDetailList(purchaseOrderDetailMapper.getPurchaseOrderDetailById(purchaseOrderVo.getId())); + Supplier supplier = supplierMapper.getSupplierById(purchaseOrderVo.getSupplierId()); + String name = supplier.getName(); + BigDecimal totalAmount = purchaseOrderVo.getTotalAmount(); + + supplierAmountMap.merge( + name, + totalAmount, + BigDecimal::add // 相同供应商的金额相加 + ); +// xAxisSupplierNames.add(name); +// yAxisOrderAmounts.add(totalAmount); + } + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + LocalDate currentDate = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String formattedDate = currentDate.format(formatter); + String msg = "好的," + formattedDate + ",采购入库订单数量为: " + list.size() + ",有其他需求可以随时告诉我哦!"; + + purchaseOrderChartVo.setList(list); + purchaseOrderChartVo.setChartType("column"); + purchaseOrderChartVo.setMsg(msg); + purchaseOrderChartVo.setXAxisData(xAxisData); + purchaseOrderChartVo.setYAxisData(yAxisData); + + +// purchaseOrderChartVo.setXAxisData(xAxisSupplierNames); +// purchaseOrderChartVo.setYAxisData(yAxisOrderAmounts); + + return purchaseOrderChartVo; + + } + + private TodaysPurchaseOrderReturnChartVo getTodaysPurchaseOrderReturn() { + + TodaysPurchaseOrderReturnChartVo todaysPurchaseOrderReturnChartVo = new TodaysPurchaseOrderReturnChartVo(); + List list = purchaseReturnMapper.TodaysPurchaseOrderReturn(); + +// List xAxisSupplierNames = new ArrayList<>(); +// List yAxisOrderAmounts = new ArrayList<>(); + Map supplierAmountMap = new HashMap<>(); + for (TodaysPurchaseOrderReturnVo todaysPurchaseOrderReturnVo : list) { + Supplier supplier = supplierMapper.getSupplierById(todaysPurchaseOrderReturnVo.getSupplierId()); + todaysPurchaseOrderReturnVo.setPurchaseOrderDetailList(purchaseReturnDetailMapper.getPurchaseReturnById(todaysPurchaseOrderReturnVo.getId())); + + String name = supplier.getName(); + BigDecimal totalAmount = todaysPurchaseOrderReturnVo.getTotalAmount(); + + supplierAmountMap.merge( + name, + totalAmount, + BigDecimal::add // 相同供应商的金额相加 + ); +// xAxisSupplierNames.add(name); +// yAxisOrderAmounts.add(totalAmount); + } + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + todaysPurchaseOrderReturnChartVo.setList(list); + todaysPurchaseOrderReturnChartVo.setChartType("column"); + + LocalDate currentDate = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String formattedDate = currentDate.format(formatter); + String msg = "好的," + formattedDate + ",销售退货订单数量为: " + list.size() + ",有其他需求可以随时告诉我哦!"; + + todaysPurchaseOrderReturnChartVo.setMsg(msg); + todaysPurchaseOrderReturnChartVo.setXAxisData(xAxisData); + todaysPurchaseOrderReturnChartVo.setYAxisData(yAxisData); +// todaysPurchaseOrderReturnChartVo.setXAxisData(xAxisSupplierNames); +// todaysPurchaseOrderReturnChartVo.setYAxisData(yAxisOrderAmounts); + + return todaysPurchaseOrderReturnChartVo; + } + + private SaleOrderChartVo getSaleOrderByCustomerName(String customerName) { + + Customer customer = customerMapper.QueryCustomerName(customerName); + + + SaleOrderChartVo chartVo = new SaleOrderChartVo(); + if (customer != null) { + + BigDecimal totalAmountSum = BigDecimal.ZERO; + + List list = saleOrderMapper.getSaleOrderByCustomerId(customer.getId()); + +// List xAxisSupplierNames = new ArrayList<>(); +// List yAxisOrderAmounts = new ArrayList<>(); + Map supplierAmountMap = new HashMap<>(); + + for (SaleOrderVo saleOrderVo : list) { + BigDecimal amount = Optional.ofNullable(saleOrderVo.getTotalAmount()) + .orElse(BigDecimal.ZERO); + + // 累加到总金额 + totalAmountSum = totalAmountSum.add(amount); + + + saleOrderVo.setSaleOrderDetailList(saleOrderDetailMapper.getSaleOrderDetailById(saleOrderVo.getId())); + + if (customer != null && customer.getName() != null) { + // 累加当前订单金额到供应商金额映射表 + supplierAmountMap.merge( + customer.getName(), + amount, // 使用当前订单金额而非 totalAmountSum + BigDecimal::add + ); + } +// xAxisSupplierNames.add(customer.getName()); +// yAxisOrderAmounts.add(totalAmountSum); + } + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + + String formattedTotalAmount="0"; + if(totalAmountSum!=null){ + formattedTotalAmount = currencyFormat.format(totalAmountSum); + } + + + + String msg = "好的," + customer.getName() + + ",订单数量为: " + list.size() + + ",金额为:" + formattedTotalAmount; + + chartVo.setList(list); + chartVo.setChartType("column"); + chartVo.setMsg(msg); + chartVo.setXAxisData(xAxisData); + chartVo.setYAxisData(yAxisData); +// chartVo.setXAxisData(xAxisSupplierNames); +// chartVo.setYAxisData(yAxisOrderAmounts); + + + return chartVo; + } else { + throw new IllegalArgumentException("客户不存在!"); + } + + + } + + private SaleOrderChartVo getSaleOrderByUserName(String userName) { + + SysUserDTO user = sysUserMapper.getSysUserByName(userName); + + SaleOrderChartVo saleOrderChartVo = new SaleOrderChartVo(); + + if (user != null) { +// List xAxisSupplierNames = new ArrayList<>(); +// List yAxisOrderAmounts = new ArrayList<>(); + Map supplierAmountMap = new HashMap<>(); + + BigDecimal totalAmountSum = BigDecimal.ZERO; + List list = saleOrderMapper.getSaleOrderBySalerId(user.getId()); + for (SaleOrderVo saleOrderVo : list) { + BigDecimal amount = Optional.ofNullable(saleOrderVo.getTotalAmount()) + .orElse(BigDecimal.ZERO); + + // 累加到总金额 + totalAmountSum = totalAmountSum.add(amount); + saleOrderVo.setSaleOrderDetailList(saleOrderDetailMapper.getSaleOrderDetailById(saleOrderVo.getId())); + + if (user != null && user.getName() != null) { + // 累加当前订单金额到供应商金额映射表 + supplierAmountMap.merge( + user.getName(), + amount, // 使用当前订单金额而非 totalAmountSum + BigDecimal::add + ); + } +// xAxisSupplierNames.add(user.getName()); +// yAxisOrderAmounts.add(totalAmountSum); + } + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + String formattedTotalAmount="0"; + if(totalAmountSum!=null){ + formattedTotalAmount = currencyFormat.format(totalAmountSum); + } + + String msg = "好的," + user.getName() + + ",销售订单数量为: " + list.size() + + ",金额为:" + formattedTotalAmount; + + saleOrderChartVo.setList(list); + saleOrderChartVo.setChartType("column"); + saleOrderChartVo.setMsg(msg); + + saleOrderChartVo.setXAxisData(xAxisData); + saleOrderChartVo.setYAxisData(yAxisData); +// saleOrderChartVo.setXAxisData(xAxisSupplierNames); +// saleOrderChartVo.setYAxisData(yAxisOrderAmounts); + + + return saleOrderChartVo; + } else { + throw new IllegalArgumentException("销售员不存在!"); + } + } + + private SaleOrderChartVo selectSaleOrdersByDate(String targetDate) { + + SaleOrderChartVo saleOrderChartVo = new SaleOrderChartVo(); + List list = saleOrderMapper.selectSaleOrdersByDate(targetDate); + BigDecimal totalAmountSum = BigDecimal.ZERO; + +// List xAxisSupplierNames = new ArrayList<>(); +// List yAxisOrderAmounts = new ArrayList<>(); + Map supplierAmountMap = new HashMap<>(); + for (SaleOrderVo saleOrderVo : list) { + BigDecimal amount = Optional.ofNullable(saleOrderVo.getTotalAmount()) + .orElse(BigDecimal.ZERO); + + // 累加到总金额 + totalAmountSum = totalAmountSum.add(amount); + saleOrderVo.setSaleOrderDetailList(saleOrderDetailMapper.getSaleOrderDetailById(saleOrderVo.getId())); + + if (saleOrderVo.getSalerId() != null) { + SysUserDTO user = sysUserMapper.getSysUserById(saleOrderVo.getSalerId()); + + if (user != null && user.getName() != null) { + // 累加当前订单金额到供应商金额映射表 + supplierAmountMap.merge( + user.getName(), + amount, // 使用当前订单金额而非 totalAmountSum + BigDecimal::add + ); + } +// xAxisSupplierNames.add(user.getName()); +// yAxisOrderAmounts.add(totalAmountSum); + } + + + } + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + String formattedTotalAmount="0"; + if(totalAmountSum!=null){ + formattedTotalAmount = currencyFormat.format(totalAmountSum); + } + String msg = "好的," + targetDate + + ",销售订单数量为: " + list.size() + + ",金额为:" + formattedTotalAmount; + + saleOrderChartVo.setList(list); + saleOrderChartVo.setChartType("column"); + saleOrderChartVo.setMsg(msg); +// saleOrderChartVo.setXAxisData(xAxisSupplierNames); +// saleOrderChartVo.setYAxisData(yAxisOrderAmounts); + saleOrderChartVo.setXAxisData(xAxisData); + saleOrderChartVo.setYAxisData(yAxisData); + + return saleOrderChartVo; + } + + private PurchaseOrderChartVo selectPurchaseOrdersByDate(String targetDate) { + + PurchaseOrderChartVo purchaseOrderChartVo = new PurchaseOrderChartVo(); + List list = purchaseOrderMapper.selectPruchaseOrdersByDate(targetDate); + BigDecimal totalAmountSum = BigDecimal.ZERO; + + Map supplierAmountMap = new HashMap<>(); + for (PurchaseOrderVo purchaseOrderVo : list) { + + BigDecimal amount = Optional.ofNullable(purchaseOrderVo.getTotalAmount()) + .orElse(BigDecimal.ZERO); + + // 累加到总金额 + totalAmountSum = totalAmountSum.add(amount); + purchaseOrderVo.setPurchaseOrderDetailList(purchaseOrderDetailMapper.getPurchaseOrderDetailById(purchaseOrderVo.getId())); + + Supplier supplier = supplierMapper.getSupplierById(purchaseOrderVo.getSupplierId()); + if (supplier != null && supplier.getName() != null) { + // 累加当前订单金额到供应商金额映射表 + supplierAmountMap.merge( + supplier.getName(), + amount, // 使用当前订单金额而非 totalAmountSum + BigDecimal::add + ); + } + } + + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + String formattedTotalAmount="0"; + if(totalAmountSum!=null){ + formattedTotalAmount = currencyFormat.format(totalAmountSum); + } + + String msg = "好的," + targetDate + + ",采购订单数量为: " + list.size() + + ",金额为:" + formattedTotalAmount; + + purchaseOrderChartVo.setMsg(msg); + purchaseOrderChartVo.setList(list); + purchaseOrderChartVo.setChartType("column"); + + purchaseOrderChartVo.setXAxisData(xAxisData); + purchaseOrderChartVo.setYAxisData(yAxisData); + return purchaseOrderChartVo; + } + + public ProductStockLogChartVo getProductStockLogs(String productName) { + + ProductStockLogChartVo productStockLogChartVo = new ProductStockLogChartVo(); + List products = productMapper.QueryProductByName(productName); + List allLogs = new ArrayList<>(); + + for (Product product : products) { + List logs = productStockLogMapper.getProductStockLogByProductId(product.getId()); + if (logs != null && !logs.isEmpty()) { + logs.forEach(log -> log.setProductName(product.getName())); // 设置商品名 + allLogs.addAll(logs); + } + } + + Collections.sort(allLogs, Comparator.comparing(ProductStockLogVo::getCreateTime)); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d"); + StringBuilder msgBuilder = new StringBuilder(); + + if (allLogs.isEmpty()) { + msgBuilder.append("暂无库存变动记录"); + } else { + // 获取截止日期(最后一条日志的日期) + Date latestDate = allLogs.get(allLogs.size() - 1).getCreateTime(); + msgBuilder.append("截止(").append(sdf.format(latestDate)).append(")库存变动记录如下,"); + + // 拼接每条记录 + List entries = new ArrayList<>(); + for (ProductStockLogVo log : allLogs) { + String dateStr = sdf.format(log.getCreateTime()); + String action = log.getStockNum() > 0 ? "入库" : "出库"; + // 重点修改:商品名用括号包裹 + String entry = String.format("(%s)%s%s%d", + log.getProductName(), dateStr, action, Math.abs(log.getStockNum())); + entries.add(entry); + } + msgBuilder.append(String.join(",", entries)).append("。"); + } + + productStockLogChartVo.setList(allLogs); + productStockLogChartVo.setChartType("null"); + productStockLogChartVo.setMsg(msgBuilder.toString()); + + return productStockLogChartVo; + } + + private SaleOutSheetChartVo selectSaleOutSheetToDays() { + + SaleOutSheetChartVo saleOutSheetChartVo = new SaleOutSheetChartVo(); + List list = saleOutSheetMapper.getTodysSaleOutSheet(); + + for (SaleOutSheetVo saleOutSheetVo : list) { + saleOutSheetVo.setSaleOutSheetDetailList(saleOutSheetDetailMapper.getSaleOutSheetDetailById(saleOutSheetVo.getId())); + } + + LocalDate currentDate = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String formattedDate = currentDate.format(formatter); + String msg = "好的," + formattedDate + ",销售出库订单数量为: " + list.size() + ",有其他需求可以随时告诉我哦!"; + + saleOutSheetChartVo.setList(list); + saleOutSheetChartVo.setChartType("null"); + saleOutSheetChartVo.setMsg(msg); + + return saleOutSheetChartVo; + } + + private CheckOrderAmountCountVo checkOrderAmountCount() { + + CheckOrderAmountCountVo vo = new CheckOrderAmountCountVo(); + LocalDate currentDate = LocalDate.now(); + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + + // 获取BigDecimal数据(处理null值) + BigDecimal totalAmount = saleOrderMapper.CheckOrderAmountCount() != null ? + saleOrderMapper.CheckOrderAmountCount() : BigDecimal.ZERO; + BigDecimal purchasePrice = saleOrderMapper.CheckOrderPurchasePrice() != null ? + saleOrderMapper.CheckOrderPurchasePrice() : BigDecimal.ZERO; + + // 计算总和(BigDecimal运算) + BigDecimal total = totalAmount.add(purchasePrice); + + // 计算百分比(带精度控制) + DecimalFormat percentFormat = new DecimalFormat("0.00%"); + String revenuePercent = "0.00%"; + String costPercent = "0.00%"; + if (total.compareTo(BigDecimal.ZERO) != 0) { + revenuePercent = percentFormat.format( + totalAmount.divide(total, 4, RoundingMode.HALF_UP) + ); + costPercent = percentFormat.format( + purchasePrice.divide(total, 4, RoundingMode.HALF_UP) + ); + } + + // 构建饼图数据(处理数值类型转换) + List pieData = new ArrayList<>(); + pieData.add(new PieChartData( + "营收账款", + totalAmount.setScale(0, RoundingMode.HALF_UP).intValueExact(), + revenuePercent + )); + pieData.add(new PieChartData( + "成本", + purchasePrice.setScale(0, RoundingMode.HALF_UP).intValueExact(), + costPercent + )); + + // 构建消息(BigDecimal格式化) + String msg = String.format("好的,截止%s,营收账款: %s,成本: %s,营收占比%s。有需求随时告诉我!", + currentDate.format(dateFormatter), + currencyFormat.format(totalAmount), + currencyFormat.format(purchasePrice), + revenuePercent); + + // 设置VO对象 + vo.setAmountCount(totalAmount); // 保持与现有字段兼容 + vo.setChartType("ring"); + vo.setMsg(msg); + vo.setPieChartData(pieData); + + return vo; + } + + private SettleCheckAccountsPayableVo settleCheckAccountsPayable() { + + SettleCheckAccountsPayableVo settleCheckAccountsPayableVo = new SettleCheckAccountsPayableVo(); + + LocalDate currentDate = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String formattedDate = currentDate.format(formatter); + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + + String formattedTotalAmount="0"; + + if(saleOrderMapper.CheckOrderAmountCount()!=null){ + formattedTotalAmount = currencyFormat.format(settleCheckSheetMapper.settleCheckAccountsPayable()); + } + + + String msg = "好的,截止" + formattedDate + ",应付账款为: " + formattedTotalAmount + ",有其他需求可以随时告诉我哦!"; + + settleCheckAccountsPayableVo.setTotalAmount(settleCheckSheetMapper.settleCheckAccountsPayable()); + settleCheckAccountsPayableVo.setChartType("null"); + settleCheckAccountsPayableVo.setMsg(msg); + return settleCheckAccountsPayableVo; + } + + private SettleSheetPaymentOfFeesVo settleSheetPaymentOfFees() { + + SettleSheetPaymentOfFeesVo settleSheetPaymentOfFeesVo = new SettleSheetPaymentOfFeesVo(); + + LocalDate currentDate = LocalDate.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String formattedDate = currentDate.format(formatter); + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + + String formattedTotalAmount="0"; + + if(saleOrderMapper.CheckOrderAmountCount()!=null){ + formattedTotalAmount = currencyFormat.format(settleSheetMapper.settleSheetPaymentOfFees()); + } + + String msg = "好的,截止" + formattedDate + ",费用支付为: " + formattedTotalAmount + ",有其他需求可以随时告诉我哦!"; + + settleSheetPaymentOfFeesVo.setTotalAmount(settleSheetMapper.settleSheetPaymentOfFees()); + settleSheetPaymentOfFeesVo.setChartType("null"); + settleSheetPaymentOfFeesVo.setMsg(msg); + return settleSheetPaymentOfFeesVo; + } + + private BigDecimal safeDivide(BigDecimal dividend, BigDecimal divisor, int scale) { + return divisor.compareTo(BigDecimal.ZERO) != 0 ? + dividend.divide(divisor, scale, RoundingMode.HALF_UP) : + BigDecimal.ZERO; + } + + private SaleOrderTotalProfitVo saleOrderTotalProfit() { + + SaleOrderTotalProfitVo vo = new SaleOrderTotalProfitVo(); + List orders = saleOrderMapper.getTotalProfit(); + + // 初始化累计值 + BigDecimal totalRevenue = BigDecimal.ZERO; + BigDecimal totalCost = BigDecimal.ZERO; + + // 累计计算(使用BigDecimal精确计算) + for (SaleOrder order : orders) { + totalRevenue = totalRevenue.add( + Optional.ofNullable(order.getTotalAmount()).orElse(BigDecimal.ZERO) + ); + totalCost = totalCost.add( + Optional.ofNullable(order.getTotalPurchasePrice()).orElse(BigDecimal.ZERO) + ); + } + + // 计算利润(营收 - 成本) + BigDecimal totalProfit = totalRevenue.subtract(totalCost); + + // 计算利润占比(带安全校验) + DecimalFormat percentFormat = new DecimalFormat("0.00%"); + BigDecimal profitRatio = totalRevenue.compareTo(BigDecimal.ZERO) != 0 ? + totalProfit.divide(totalRevenue, 4, RoundingMode.HALF_UP) : + BigDecimal.ZERO; + + // 构建饼图数据(包含两种维度) + List pieData = new ArrayList<>(); + + // 维度1:利润/成本结构 + try { + int profitValue = totalProfit.setScale(0, RoundingMode.HALF_UP).intValueExact(); + pieData.add(new PieChartData("利润", profitValue, percentFormat.format(profitRatio))); + } catch (ArithmeticException e) { + // 如果发生溢出或无法精确转换,记录日志并设置一个默认值 + pieData.add(new PieChartData("利润", Integer.MAX_VALUE, percentFormat.format(profitRatio))); + } + + try { + int costValue = totalCost.setScale(0, RoundingMode.HALF_UP).intValueExact(); + pieData.add(new PieChartData("成本", costValue, percentFormat.format(totalCost.divide(totalRevenue, 4, RoundingMode.HALF_UP)))); + } catch (ArithmeticException e) { + pieData.add(new PieChartData("成本", Integer.MAX_VALUE, percentFormat.format(totalCost.divide(totalRevenue, 4, RoundingMode.HALF_UP)))); + } + + // 维度2:利润率分布(可选) +// BigDecimal profitMargin = totalRevenue.compareTo(BigDecimal.ZERO) != 0 ? +// totalProfit.divide(totalRevenue, 4, RoundingMode.HALF_UP) : +// BigDecimal.ZERO; +// +// BigDecimal profitMarginPercent = profitMargin.multiply(BigDecimal.valueOf(100)) +// .setScale(0, RoundingMode.HALF_UP); // 四舍五入到整数 +// +// BigDecimal otherPercent = BigDecimal.valueOf(100) +// .subtract(profitMarginPercent) +// .setScale(0, RoundingMode.HALF_UP); +// +// List marginData = Arrays.asList( +// new PieChartData("利润率", profitMarginPercent.intValueExact(), percentFormat.format(profitMargin)), +// new PieChartData("其他", otherPercent.intValueExact(), "") +// ); + + // 消息构建 + String msg = String.format("截止%s,总营收%s,总成本%s,总利润%s,利润占比%s。", + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), + new DecimalFormat("¥#,##0.00").format(totalRevenue), + new DecimalFormat("¥#,##0.00").format(totalCost), + new DecimalFormat("¥#,##0.00").format(totalProfit), + percentFormat.format(profitRatio) + ); + + // VO对象装配 + vo.setRevenue(totalRevenue); + vo.setCost(totalCost); + vo.setTotalProfit(totalProfit); + vo.setChartType("ring"); + vo.setMsg(msg); + vo.setPieChartData(pieData); // 核心业务数据 + // vo.setMarginChartData(marginData); // 扩展维度数据 + + return vo; + } + + + private CheckTodysSalesAmountVo getMonthSalesAmount() { + + CheckTodysSalesAmountVo checkTodysSalesAmountVo = new CheckTodysSalesAmountVo(); + checkTodysSalesAmountVo.setChartType("column"); + checkTodysSalesAmountVo.setSalesAmount(saleOrderMapper.CheckMonthOrderAmount()); + + List list = saleOrderMapper.CheckMonthSaleOrderLits(); + + Map supplierAmountMap = new HashMap<>(); + for (SaleOrderVo saleOrderVo : list) { + if (saleOrderVo != null) { + if (saleOrderVo.getSalerId() != null) { + SysUserDTO sysUserDTO = sysUserMapper.getSysUserById(saleOrderVo.getSalerId()); + String name = sysUserDTO.getName(); + saleOrderVo.setSalerName(name); + BigDecimal totalAmount = saleOrderVo.getTotalAmount(); + + supplierAmountMap.merge( + name, + totalAmount, + BigDecimal::add // 相同供应商的金额相加 + ); + } + + } + + } + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + + String formattedTotalAmount=null; + if(saleOrderMapper.CheckMonthOrderAmount()!=null){ + formattedTotalAmount = currencyFormat.format(saleOrderMapper.CheckMonthOrderAmount()); + }else{ + formattedTotalAmount="0"; + } + + + String msg = "好的," + "本月销售订单金额为: " + formattedTotalAmount + ",有其他需求可以随时告诉我哦!"; + checkTodysSalesAmountVo.setMsg(msg); + + checkTodysSalesAmountVo.setXAxisData(xAxisData); + checkTodysSalesAmountVo.setYAxisData(yAxisData); + + return checkTodysSalesAmountVo; + } + + private CheckTodysSalesAmountVo getYearSalesAmount() { + + CheckTodysSalesAmountVo checkTodysSalesAmountVo = new CheckTodysSalesAmountVo(); + checkTodysSalesAmountVo.setChartType("column"); + checkTodysSalesAmountVo.setSalesAmount(saleOrderMapper.CheckYearOrderAmount()); + + List list = saleOrderMapper.CheckYearSaleOrderLits(); + + Map supplierAmountMap = new HashMap<>(); + for (SaleOrderVo saleOrderVo : list) { + if (saleOrderVo != null) { + if (saleOrderVo.getSalerId() != null) { + SysUserDTO sysUserDTO = sysUserMapper.getSysUserById(saleOrderVo.getSalerId()); + String name = sysUserDTO.getName(); + saleOrderVo.setSalerName(name); + BigDecimal totalAmount = saleOrderVo.getTotalAmount(); + + supplierAmountMap.merge( + name, + totalAmount, + BigDecimal::add // 相同供应商的金额相加 + ); + } + + } + + } + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + + String formattedTotalAmount=null; + if(saleOrderMapper.CheckYearOrderAmount()!=null){ + formattedTotalAmount = currencyFormat.format(saleOrderMapper.CheckYearOrderAmount()); + }else{ + formattedTotalAmount="0"; + } + + + String msg = "好的," + "本年销售订单金额为: " + formattedTotalAmount + ",有其他需求可以随时告诉我哦!"; + checkTodysSalesAmountVo.setMsg(msg); + + checkTodysSalesAmountVo.setXAxisData(xAxisData); + checkTodysSalesAmountVo.setYAxisData(yAxisData); + + return checkTodysSalesAmountVo; + } + + private CheckTodaysPurchaseAmountVo getMonthPurchaseAmount() { + + CheckTodaysPurchaseAmountVo checkTodaysPurchaseAmountVo = new CheckTodaysPurchaseAmountVo(); + checkTodaysPurchaseAmountVo.setChartType("column"); + BigDecimal amount = purchaseOrderMapper.CheckMonthPurchaseAmount(); + + + checkTodaysPurchaseAmountVo.setPurchaseAmount(amount); + + List list = purchaseOrderMapper.MonthPurchaseOrder(); + Map supplierAmountMap = new HashMap<>(); + + for (PurchaseOrderVo purchaseOrderVo : list) { + Supplier supplier = supplierMapper.getSupplierById(purchaseOrderVo.getSupplierId()); + String supplierName = supplier.getName(); + purchaseOrderVo.setSupplierName(supplierName); + BigDecimal totalAmount = purchaseOrderVo.getTotalAmount(); + + supplierAmountMap.merge( + supplierName, + totalAmount, + BigDecimal::add // 相同供应商的金额相加 + ); + + } + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + + String formattedTotalAmount=null; + if(purchaseOrderMapper.CheckMonthPurchaseAmount()!=null){ + formattedTotalAmount = currencyFormat.format(amount); + }else{ + formattedTotalAmount="0"; + } + + String msg = "好的,本月采购订单金额为: " + formattedTotalAmount + ",有其他需求可以随时告诉我哦!"; + + checkTodaysPurchaseAmountVo.setMsg(msg); + checkTodaysPurchaseAmountVo.setXAxisData(xAxisData); + checkTodaysPurchaseAmountVo.setYAxisData(yAxisData); + + return checkTodaysPurchaseAmountVo; + } + + private CheckTodaysPurchaseAmountVo getYearPurchaseAmount() { + + CheckTodaysPurchaseAmountVo checkTodaysPurchaseAmountVo = new CheckTodaysPurchaseAmountVo(); + checkTodaysPurchaseAmountVo.setChartType("column"); + BigDecimal amount = purchaseOrderMapper.CheckYearPurchaseAmount(); + + + checkTodaysPurchaseAmountVo.setPurchaseAmount(amount); + + List list = purchaseOrderMapper.YearPurchaseOrder(); + Map supplierAmountMap = new HashMap<>(); + + for (PurchaseOrderVo purchaseOrderVo : list) { + Supplier supplier = supplierMapper.getSupplierById(purchaseOrderVo.getSupplierId()); + String supplierName = supplier.getName(); + purchaseOrderVo.setSupplierName(supplierName); + BigDecimal totalAmount = purchaseOrderVo.getTotalAmount(); + + supplierAmountMap.merge( + supplierName, + totalAmount, + BigDecimal::add // 相同供应商的金额相加 + ); + + } + + List xAxisData = new ArrayList<>(supplierAmountMap.keySet()); // 横轴 + List yAxisData = new ArrayList<>(supplierAmountMap.values()); // 纵轴 + + DecimalFormat currencyFormat = new DecimalFormat("¥####.00"); + + String formattedTotalAmount=null; + if(purchaseOrderMapper.CheckYearPurchaseAmount()!=null){ + formattedTotalAmount = currencyFormat.format(amount); + }else{ + formattedTotalAmount="0"; + } + + String msg = "好的,本年采购订单金额为: " + formattedTotalAmount + ",有其他需求可以随时告诉我哦!"; + + checkTodaysPurchaseAmountVo.setMsg(msg); + checkTodaysPurchaseAmountVo.setXAxisData(xAxisData); + checkTodaysPurchaseAmountVo.setYAxisData(yAxisData); + + return checkTodaysPurchaseAmountVo; + } + +} diff --git a/src/main/java/com/soft/utils/ApiReadUitl.java b/src/main/java/com/soft/utils/ApiReadUitl.java new file mode 100644 index 0000000..74c462b --- /dev/null +++ b/src/main/java/com/soft/utils/ApiReadUitl.java @@ -0,0 +1,43 @@ +package com.soft.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + + +public class ApiReadUitl { + /* + * 读取返回结果 + */ + public static String read(InputStream is) throws IOException { + StringBuffer sb = new StringBuffer(); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + String line = null; + while ((line = br.readLine()) != null) { + line = new String(line.getBytes(), "utf-8"); + sb.append(line); + } + br.close(); + return sb.toString(); + } + + //去“ "号 + public static String removeDoubleQuotes(String result) { + //去掉" "号 + return result.replace("\"", ""); + } + + //截取字符串后四位 + public static String getCardTailNum(String cardNum){ + StringBuffer tailNum = new StringBuffer(); + if (cardNum != null) { + int len = cardNum.length(); + for (int i = len - 1; i >= len - 4; i--) { + tailNum.append(cardNum.charAt(i)); + } + tailNum.reverse(); + } + return tailNum.toString(); + } +} diff --git a/src/main/java/com/soft/utils/Base64Util.java b/src/main/java/com/soft/utils/Base64Util.java new file mode 100644 index 0000000..26e04ea --- /dev/null +++ b/src/main/java/com/soft/utils/Base64Util.java @@ -0,0 +1,62 @@ +package com.soft.utils; + +public class Base64Util { + private static final char last2byte = (char) Integer.parseInt("00000011", 2); + private static final char last4byte = (char) Integer.parseInt("00001111", 2); + private static final char last6byte = (char) Integer.parseInt("00111111", 2); + private static final char lead6byte = (char) Integer.parseInt("11111100", 2); + private static final char lead4byte = (char) Integer.parseInt("11110000", 2); + private static final char lead2byte = (char) Integer.parseInt("11000000", 2); + private static final char[] encodeTable = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; + + public Base64Util() { + } + + public static String encode(byte[] from) { + StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3); + int num = 0; + char currentByte = 0; + + int i; + for (i = 0; i < from.length; ++i) { + for (num %= 8; num < 8; num += 6) { + switch (num) { + case 0: + currentByte = (char) (from[i] & lead6byte); + currentByte = (char) (currentByte >>> 2); + case 1: + case 3: + case 5: + default: + break; + case 2: + currentByte = (char) (from[i] & last6byte); + break; + case 4: + currentByte = (char) (from[i] & last4byte); + currentByte = (char) (currentByte << 2); + if (i + 1 < from.length) { + currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6); + } + break; + case 6: + currentByte = (char) (from[i] & last2byte); + currentByte = (char) (currentByte << 4); + if (i + 1 < from.length) { + currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4); + } + } + + to.append(encodeTable[currentByte]); + } + } + + if (to.length() % 4 != 0) { + for (i = 4 - to.length() % 4; i > 0; --i) { + to.append("="); + } + } + + return to.toString(); + } +} diff --git a/src/main/java/com/soft/utils/ConstantUtil.java b/src/main/java/com/soft/utils/ConstantUtil.java new file mode 100644 index 0000000..73b63f0 --- /dev/null +++ b/src/main/java/com/soft/utils/ConstantUtil.java @@ -0,0 +1,11 @@ +package com.soft.utils; + + +public class ConstantUtil { + + public static final String WX_APPID="wx47c6adab96801fda"; + public static final String WX_SECRET="38f2d467c62d5572118b02017d347721"; + + public static final String WX_TOKEN_URL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+WX_APPID+"&secret="+WX_SECRET; + +} diff --git a/src/main/java/com/soft/utils/CopyBeanUtil.java b/src/main/java/com/soft/utils/CopyBeanUtil.java new file mode 100644 index 0000000..41dd454 --- /dev/null +++ b/src/main/java/com/soft/utils/CopyBeanUtil.java @@ -0,0 +1,24 @@ +package com.soft.utils; + +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +public class CopyBeanUtil extends BeanUtils { + + public static List copyListProperties (List source, Supplier target){ + List list=new ArrayList<>(); + if(source==null||source.isEmpty()){ + return new ArrayList<>(); + } + for (S s:source) { + T t=target.get(); + copyProperties(s,t); + list.add(t); + } + return list; + } + +} diff --git a/src/main/java/com/soft/utils/DateParserUtil.java b/src/main/java/com/soft/utils/DateParserUtil.java new file mode 100644 index 0000000..a50ce88 --- /dev/null +++ b/src/main/java/com/soft/utils/DateParserUtil.java @@ -0,0 +1,59 @@ +package com.soft.utils; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DateParserUtil { + private static final DateTimeFormatter STANDARD_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + // 支持的中文日期格式正则 + private static final Pattern[] DATE_PATTERNS = { + Pattern.compile("(\\d{1,2})月(\\d{1,2})[日号]"), // 4月25日 或 4月25号 + Pattern.compile("(\\d{4})年(\\d{1,2})月(\\d{1,2})[日号]"), // 2025年4月25日 + Pattern.compile("(\\d{1,2})\\/(\\d{1,2})"), // 4/25 + Pattern.compile("(\\d{4})\\/(\\d{1,2})\\/(\\d{1,2})") // 2025/4/25 + }; + + /** + * 将中文日期转换为标准格式 + * @param chineseDate 中文日期字符串 + * @return 标准格式日期字符串 (yyyy-MM-dd) + */ + public static String parseChineseDate(String chineseDate) { + // 统一处理输入 + String normalized = chineseDate.replaceAll("\\s+", "") + .replace("号", "日"); + + try { + // 处理"4月28日"格式 + if (normalized.matches("\\d{1,2}月\\d{1,2}日")) { + String[] parts = normalized.split("月|日"); + int month = Integer.parseInt(parts[0]); + int day = Integer.parseInt(parts[1]); + return LocalDate.now() + .withMonth(month) + .withDayOfMonth(day) + .format(STANDARD_FORMATTER); + } + + // 处理"2024年4月28日"格式 + if (normalized.matches("\\d{4}年\\d{1,2}月\\d{1,2}日")) { + String[] parts = normalized.split("年|月|日"); + int year = Integer.parseInt(parts[0]); + int month = Integer.parseInt(parts[1]); + int day = Integer.parseInt(parts[2]); + return LocalDate.of(year, month, day) + .format(STANDARD_FORMATTER); + } + } catch (Exception e) { + // 记录错误 + System.err.println("日期解析错误: " + chineseDate); + } + + // 默认返回当天 + return LocalDate.now().format(STANDARD_FORMATTER); + } +} diff --git a/src/main/java/com/soft/utils/EliminateImageUtil.java b/src/main/java/com/soft/utils/EliminateImageUtil.java new file mode 100644 index 0000000..5986a0b --- /dev/null +++ b/src/main/java/com/soft/utils/EliminateImageUtil.java @@ -0,0 +1,310 @@ +package com.soft.utils; + + +import java.awt.*; +import java.awt.image.BufferedImage; + +import java.util.*; +import java.util.List; + +public class EliminateImageUtil { + + /** + * 坐标嘞 + */ + private static class Coordinate { + private int x; + + private int y; + + public Coordinate(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Coordinate that = (Coordinate) o; + return x == that.x && + y == that.y; + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } + + } + + private static class CoordinateWithCenter extends Coordinate implements Comparable { + + private Coordinate center; + + private int distance; + + public int getDistance() { + return distance; + } + + public void setDistance(int distance) { + this.distance = distance; + } + + public CoordinateWithCenter(int x, int y) { + super(x,y); + this.center = new Coordinate(0,0); + } + public CoordinateWithCenter(int x, int y,Coordinate center) { + super(x,y); + this.center = center; + this.distance = Math.abs(this.getX()-center.getX())+Math.abs(this.getY()-center.getY()); + } + @Override + public int compareTo(CoordinateWithCenter o) { + //负整数是小于 + //0为等于 + return Integer.compare(o.distance, this.distance); //正整数是大于 + } + } + + private static int RANGE = 5; + private static int WEIGHT = 1; + + + public static String imageEliminate(String primaryBase64,String eraseBase64){ + BufferedImage bufferedImage = ImageUtil.bufferedImage(primaryBase64); + BufferedImage bufferedMask = ImageUtil.bufferedImage(eraseBase64); + /*获取涂抹中心区域*/ + Coordinate wipeCenter = getWipeCenter(bufferedMask); + /* 被涂抹的坐标,需要处理 */ + List coordinateWithCenters = getWipeCoordinate(bufferedMask, wipeCenter); + + System.out.println("大小:"+bufferedImage.getWidth() + "x" + bufferedImage.getHeight()); + //平均颜色 + Color colorAvg = getBorderAvgColor(bufferedImage, bufferedMask); + //Color colorAvg = getMostColor(bufferedImage,bufferedMask); + //已处理的坐标 + Set hasDoneSet = new HashSet<>(); + for (CoordinateWithCenter c : coordinateWithCenters) { + /* 获取像素点周围平均像素点 */ + Color color = getAvgColor(bufferedImage, bufferedMask, c.getX(), c.getY(),colorAvg,hasDoneSet); + bufferedImage.setRGB(c.getX(), c.getY(), color.getRGB()); + Coordinate coordinate = new Coordinate(c.getX(), c.getY()); + hasDoneSet.add(coordinate); + } + return ImageUtil.imageToBase64(bufferedImage); + } + + private static List getWipeCoordinate(BufferedImage bufferedMask, Coordinate wipeCenter) { + List list = new ArrayList<>(); + int height = bufferedMask.getHeight(); + int width = bufferedMask.getWidth(); + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + if (bufferedMask.getRGB(i, j) != -1) { + list.add(new CoordinateWithCenter(i, j, wipeCenter)); + } + } + } + Collections.sort(list); + return list; + } + + /*** + *获取周围的像素点的平均像素 + * @param bufferedImage + * @param bufferedMask + * @param x 像素点坐标x + * @param y 像素点坐标y + * @param colorAvg 填充颜色 + * @return + */ + private static Color getAvgColor(BufferedImage bufferedImage, BufferedImage bufferedMask, int x, int y, Color colorAvg,Set hasDoneSet) { + int count = 0; + int aRed = 0, aBlue = 0, aGreen = 0; + + for (int a = x - RANGE; a < x + RANGE; a++) { + for (int b = y - RANGE; b < y + RANGE; b++) { + //越界 + if (a <= 0 || a > (bufferedImage.getWidth() - 1) + || b < 0 || b > (bufferedImage.getHeight() - 1) + || (a == x && b == y)) { + continue; + } + //没涂抹的区域,或者已经处理过 + if (bufferedMask.getRGB(a, b) == -1 ||hasDoneSet.contains(new Coordinate(a, b))) { + int ragb = bufferedImage.getRGB(a, b); + Color color = new Color(ragb, true); + int blue = color.getBlue(); + int red = color.getRed(); + int green = color.getGreen(); + aRed = aRed + red * WEIGHT; + aBlue = aBlue + blue * WEIGHT; + aGreen = aGreen + green * WEIGHT; + count = count + WEIGHT; + } + } + } + if (count == 0) { + + return colorAvg; + } + + return new Color(aRed / count, aGreen / count, aBlue / count); + } + + /*** + * 获取掩码涂抹的中心位置 + * @param bufferedMask 掩码图 + * @return 返回中心坐标 + */ + private static Coordinate getWipeCenter(BufferedImage bufferedMask) { + int width = bufferedMask.getWidth(); + int height = bufferedMask.getHeight(); + int top = height - 1, bottom = 0, left = height - 1, right = 0; + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + if (bufferedMask.getRGB(i, j) != -1) { + right = Math.max(right, i); + left = Math.min(left, i); + bottom = Math.max(bottom, j); + top = Math.min(top, j); + } + } + } + return new Coordinate((left + right) / 2, (top + bottom) / 2); + } + + /*** + * 获取掩码未涂抹的平均颜色,如果全部涂抹,返回整个图的平均颜色,用于填充涂抹区域 + * @param bufferedImage 原图 + * @param bufferedMask 掩码图 + * @return 返回平均颜色 + */ + private static Color getAllAvgColor(BufferedImage bufferedImage, BufferedImage bufferedMask) { + int aRed = 0, aBlue = 0, aGreen = 0, count = 0, bRed = 0, bBlue = 0, bGreen = 0; + int width = bufferedMask.getWidth(); + int height = bufferedMask.getHeight(); + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + int ragb = bufferedImage.getRGB(i, j); + Color color = new Color(ragb, true); + if (bufferedMask.getRGB(i, j) == -1) {//未被涂抹区域 + aRed = aRed + color.getRed(); + aBlue = aBlue + color.getBlue(); + aGreen = aGreen + color.getGreen(); + count++; + } + bRed = bRed + color.getRed(); + bBlue = bBlue + color.getBlue(); + bGreen = bGreen + color.getGreen(); + } + } + //全部涂抹 + if (count == 0) { + count = width*height; + return new Color(bRed / count, bGreen / count, bBlue / count); + } else { + return new Color(aRed / count, aGreen / count, aBlue / count); + } + } + + + /*** + * 获取边界平均颜色 + * @param bufferedImage + * @param bufferedMask + * @return + */ + private static Color getBorderAvgColor(BufferedImage bufferedImage, BufferedImage bufferedMask) { + int aRed = 0, aBlue = 0, aGreen = 0, count = 0, bRed = 0, bBlue = 0, bGreen = 0; + Set coordinates = new HashSet<>(); + int width = bufferedMask.getWidth(); + int height = bufferedMask.getHeight(); + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + int ragb = bufferedImage.getRGB(i, j); + Color color = new Color(ragb, true); + if (bufferedMask.getRGB(i,j)==-1){//没被涂抹 + for (int a = i - 1; a < i + 1; a++) { + for (int b = j - 1; b < j + 1; b++) { + //越界 + if (a <= 0 || a > (bufferedImage.getWidth() - 1) + || b < 0 || b > (bufferedImage.getHeight() - 1) + || (a == i && b == j)) { + continue; + } + if (bufferedMask.getRGB(a,b)!=-1) {//是边界点 + if (coordinates.add(new Coordinate(i,j))) { + aRed = aRed + color.getRed(); + aBlue = aBlue + color.getBlue(); + aGreen = aGreen + color.getGreen(); + count++; + break; + } + } + } + } + } + bRed = bRed + color.getRed(); + bBlue = bBlue + color.getBlue(); + bGreen = bGreen + color.getGreen(); + } + } + //全部涂抹 + if (coordinates.size() == 0) {//全部涂抹,取平均色 + count = width*height; + return new Color(bRed / count, bGreen / count, bBlue / count); + } else { + return new Color(aRed / count, aGreen / count, aBlue / count); + } + } + + /*** + * 获取颜色最多的 + * @param bufferedImage 原图 + * @param bufferedMask 掩码图 + * @return 返回最多的颜色 + */ + private static Color getMostColor(BufferedImage bufferedImage, BufferedImage bufferedMask) { + int countArgb = 0, retArgb = 0; + int width = bufferedMask.getWidth(); + int height = bufferedMask.getHeight(); + HashMap map = new HashMap(); + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + if (bufferedMask.getRGB(i, j) == -1) {//未被涂抹区域 + int ragb = bufferedImage.getRGB(i, j); + map.put(ragb, map.get(ragb) == null ? 0 : map.get(ragb) + 1); + } + } + } + for (Integer key : map.keySet()) { + if (map.get(key) > countArgb) { + countArgb = map.get(key); + retArgb = key; + } + } + return new Color(retArgb); + } + + +} diff --git a/src/main/java/com/soft/utils/FileUtil.java b/src/main/java/com/soft/utils/FileUtil.java new file mode 100644 index 0000000..2392dc1 --- /dev/null +++ b/src/main/java/com/soft/utils/FileUtil.java @@ -0,0 +1,67 @@ +package com.soft.utils; + +import java.io.*; +public class FileUtil { + /** + * 读取文件内容,作为字符串返回 + */ + public static String readFileAsString(String filePath) throws IOException { + File file = new File(filePath); + if (!file.exists()) { + throw new FileNotFoundException(filePath); + } + + if (file.length() > 1024 * 1024 * 1024) { + throw new IOException("File is too large"); + } + + StringBuilder sb = new StringBuilder((int) (file.length())); + // 创建字节输入流 + FileInputStream fis = new FileInputStream(filePath); + // 创建一个长度为10240的Buffer + byte[] bbuf = new byte[10240]; + // 用于保存实际读取的字节数 + int hasRead = 0; + while ( (hasRead = fis.read(bbuf)) > 0 ) { + sb.append(new String(bbuf, 0, hasRead)); + } + fis.close(); + return sb.toString(); + } + + /** + * 根据文件路径读取byte[] 数组 + */ + public static byte[] readFileByBytes(String filePath) throws IOException { + File file = new File(filePath); + if (!file.exists()) { + throw new FileNotFoundException(filePath); + } else { + ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length()); + BufferedInputStream in = null; + + try { + in = new BufferedInputStream(new FileInputStream(file)); + short bufSize = 1024; + byte[] buffer = new byte[bufSize]; + int len1; + while (-1 != (len1 = in.read(buffer, 0, bufSize))) { + bos.write(buffer, 0, len1); + } + + byte[] var7 = bos.toByteArray(); + return var7; + } finally { + try { + if (in != null) { + in.close(); + } + } catch (IOException var14) { + var14.printStackTrace(); + } + + bos.close(); + } + } + } +} diff --git a/src/main/java/com/soft/utils/HttpPoolUtil.java b/src/main/java/com/soft/utils/HttpPoolUtil.java new file mode 100644 index 0000000..ca76be0 --- /dev/null +++ b/src/main/java/com/soft/utils/HttpPoolUtil.java @@ -0,0 +1,238 @@ +package com.soft.utils; + +import org.apache.http.*; +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.config.ConnectionConfig; +import org.apache.http.config.MessageConstraints; +import org.apache.http.config.SocketConfig; +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.conn.HttpClientConnectionManager; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.EntityUtils; + +import javax.net.ssl.SSLException; +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.UnknownHostException; +import java.nio.charset.CodingErrorAction; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class HttpPoolUtil { + //连接池管理器 + private static PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); + + static { + connManager.setMaxTotal(200); //设置最大连接数 + connManager.setDefaultMaxPerRoute(50); //设置默认路由最大连接数 + connManager.setMaxPerRoute(new HttpRoute(new HttpHost("localhost", 80)), 100); + + /** + * socket配置(默认配置 和 某个host的配置) + */ + SocketConfig socketConfig = SocketConfig.custom() + .setTcpNoDelay(true) //是否立即发送数据,设置为true会关闭Socket缓冲,默认为false + .setSoReuseAddress(true) //是否可以在一个进程关闭Socket后,即使它还没有释放端口,其它进程还可以立即重用端口 + .setSoTimeout(500) //接收数据的等待超时时间,单位ms + .setSoLinger(60) //关闭Socket时,要么发送完所有数据,要么等待60s后,就关闭连接,此时socket.close()是阻塞的 + .setSoKeepAlive(true) //开启监视TCP连接是否有效 + .build(); + connManager.setDefaultSocketConfig(socketConfig); + connManager.setSocketConfig(new HttpHost("localhost", 80), socketConfig); + + /** + * HTTP connection相关配置(默认配置 和 某个host的配置) + * 一般不修改HTTP connection相关配置,故不设置 + */ + //消息约束 + MessageConstraints messageConstraints = MessageConstraints.custom() + .setMaxHeaderCount(200) + .setMaxLineLength(2000) + .build(); + //Http connection相关配置 + ConnectionConfig connectionConfig = ConnectionConfig.custom() + .setMalformedInputAction(CodingErrorAction.IGNORE) + .setUnmappableInputAction(CodingErrorAction.IGNORE) + .setCharset(Consts.UTF_8) + .setMessageConstraints(messageConstraints) + .build(); + //一般不修改HTTP connection相关配置,故不设置 + //connManager.setDefaultConnectionConfig(connectionConfig); + //connManager.setConnectionConfig(new HttpHost("somehost", 80), ConnectionConfig.DEFAULT); + /** + * 重试处理 + * 默认是重试3次 + */ + //禁用重试(参数:retryCount、requestSentRetryEnabled) + HttpRequestRetryHandler requestRetryHandler = new DefaultHttpRequestRetryHandler(0, false); + //自定义重试策略 + } + + + static RequestConfig defaultRequestConfig = RequestConfig.custom() + .setConnectTimeout(2 * 1000) //连接超时时间 + .setSocketTimeout(2 * 1000) //读超时时间(等待数据超时时间) + .setConnectionRequestTimeout(500) //从池中获取连接超时时间 + // .setStaleConnectionCheckEnabled(true)//检查是否为陈旧的连接,默认为true,类似testOnBorrow + .build(); + + + static HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() { + + public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { + //Do not retry if over max retry count + if (executionCount >= 3) { + return false; + } + //Timeout + if (exception instanceof InterruptedIOException) { + return false; + } + //Unknown host + if (exception instanceof UnknownHostException) { + return false; + } + //Connection refused + if (exception instanceof ConnectTimeoutException) { + return false; + } + //SSL handshake exception + if (exception instanceof SSLException) { + return false; + } + + HttpClientContext clientContext = HttpClientContext.adapt(context); + HttpRequest request = clientContext.getRequest(); + boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); + //Retry if the request is considered idempotent + //如果请求类型不是HttpEntityEnclosingRequest,被认为是幂等的,那么就重试 + //HttpEntityEnclosingRequest指的是有请求体的request,比HttpRequest多一个Entity属性 + //而常用的GET请求是没有请求体的,POST、PUT都是有请求体的 + //Rest一般用GET请求获取数据,故幂等,POST用于新增数据,故不幂等 + if (idempotent) { + return true; + } + + return false; + } + }; + + static CloseableHttpClient httpClient = HttpClients.custom() + .setConnectionManager(connManager) //连接管理器 + // .setProxy(new HttpHost("192.168.1.156", 1080)) //设置代理 + .setDefaultRequestConfig(defaultRequestConfig) //默认请求配置 + .setRetryHandler(myRetryHandler) //重试策略 + .build(); + + + public static String get(String url){ + return get(url, null); + } + + + public static String get(String url, Map param) { + //创建一个Get请求,并重新设置请求参数,覆盖默认 + try { + URIBuilder uriBuilder = new URIBuilder(url); + if (param != null){ + for (Object o : param.keySet()) { + String value = param.get(o).toString(); + uriBuilder.addParameter(o.toString(), value); + } + } + URI uri = uriBuilder.build(); + HttpGet httpget = new HttpGet(uri); + RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig) + .setSocketTimeout(5000) + .setConnectTimeout(5000) + .setConnectionRequestTimeout(5000) + //设置代理 + //.setProxy(new HttpHost("myotherproxy", 8080)) + .build(); + httpget.setConfig(requestConfig); + + CloseableHttpResponse response = null; + //执行请求 + try { + response = httpClient.execute(httpget); + HttpEntity entity = response.getEntity(); + if (entity != null) { + return EntityUtils.toString(entity); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (response != null) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } catch (URISyntaxException e) { + e.printStackTrace(); + } + return null; + } + + + + + + + + public static class IdleConnectionMonitorThread extends Thread { + + private final HttpClientConnectionManager connMgr; + private volatile boolean shutdown; + + public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) { + super(); + this.connMgr = connMgr; + } + + @Override + public void run() { + try { + while (!shutdown) { + synchronized (this) { + wait(5000); + // Close expired connections + connMgr.closeExpiredConnections(); + // Optionally, close connections + // that have been idle longer than 30 sec + connMgr.closeIdleConnections(30, TimeUnit.SECONDS); + } + } + } catch (InterruptedException ex) { + // terminate + } + } + + public void shutdown() { + shutdown = true; + synchronized (this) { + notifyAll(); + } + } + } + +} + + + + + diff --git a/src/main/java/com/soft/utils/HttpUtil.java b/src/main/java/com/soft/utils/HttpUtil.java new file mode 100644 index 0000000..957271c --- /dev/null +++ b/src/main/java/com/soft/utils/HttpUtil.java @@ -0,0 +1,72 @@ +package com.soft.utils; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.List; +import java.util.Map; +public class HttpUtil { + public static String post(String requestUrl, String accessToken, String params) + throws Exception { + String contentType = "application/x-www-form-urlencoded"; + return HttpUtil.post(requestUrl, accessToken, contentType, params); + } + + public static String post(String requestUrl, String accessToken, String contentType, String params) + throws Exception { + String encoding = "UTF-8"; + if (requestUrl.contains("nlp")) { + encoding = "GBK"; + } + return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding); + } + + public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding) + throws Exception { + String url = requestUrl + "?access_token=" + accessToken; + return HttpUtil.postGeneralUrl(url, contentType, params, encoding); + } + + public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding) + throws Exception { + URL url = new URL(generalUrl); + // 打开和URL之间的连接 + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + // 设置通用的请求属性 + connection.setRequestProperty("Content-Type", contentType); + connection.setRequestProperty("Connection", "Keep-Alive"); + connection.setUseCaches(false); + connection.setDoOutput(true); + connection.setDoInput(true); + + // 得到请求的输出流对象 + DataOutputStream out = new DataOutputStream(connection.getOutputStream()); + out.write(params.getBytes(encoding)); + out.flush(); + out.close(); + + // 建立实际的连接 + connection.connect(); + // 获取所有响应头字段 + Map> headers = connection.getHeaderFields(); + // 遍历所有的响应头字段 + for (String key : headers.keySet()) { + System.err.println(key + "--->" + headers.get(key)); + } + // 定义 BufferedReader输入流来读取URL的响应 + BufferedReader in = null; + in = new BufferedReader( + new InputStreamReader(connection.getInputStream(), encoding)); + String result = ""; + String getLine; + while ((getLine = in.readLine()) != null) { + result += getLine; + } + in.close(); + System.err.println("result:" + result); + return result; + } +} diff --git a/src/main/java/com/soft/utils/HttpUtils.java b/src/main/java/com/soft/utils/HttpUtils.java new file mode 100644 index 0000000..de5ed30 --- /dev/null +++ b/src/main/java/com/soft/utils/HttpUtils.java @@ -0,0 +1,374 @@ + +package com.soft.utils; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.net.ssl.*; +import javax.servlet.http.HttpServletRequest; +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.StandardCharsets; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.List; +import java.util.Map; + + +/** + * http context工具类 + */ +public class HttpUtils { + + private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); + + private static int connectTimeout = 3000; + private static int ios_connectTimeout = 10000; + + private static class TrustAnyTrustManager implements X509TrustManager { + + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[]{}; + } + } + + private static class TrustAnyHostnameVerifier implements HostnameVerifier { + public boolean verify(String hostname, SSLSession session) { + return true; + } + } + + public static String sendGet(String url) { + String result = ""; + BufferedReader in = null; + try { +// String urlNameString = url; + URL realUrl = new URL(url); + + // 打开和URL之间的连接 + URLConnection connection = realUrl.openConnection(); + + // 设置通用的请求属性 + connection.setRequestProperty("accept", "*/*"); + connection.setRequestProperty("connection", "Keep-Alive"); + connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + + // 建立实际的连接 + connection.connect(); + + // 获取所有响应头字段 + Map> map = connection.getHeaderFields(); + + // 遍历所有的响应头字段 + for (String key : map.keySet()) { + System.out.println(key + "--->" + map.get(key)); + } + + // 定义 BufferedReader输入流来读取URL的响应 + in = new BufferedReader(new InputStreamReader( + connection.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + result += line; + } + } catch (Exception e) { + System.out.println("发送GET请求出现异常!" + e); + e.printStackTrace(); + } + + // 使用finally块来关闭输入流 + finally { + try { + if (in != null) { + in.close(); + } + } catch (Exception e2) { + e2.printStackTrace(); + } + } + return result; + } + + /** + * @param url + * @param param + * @return + */ + public static String sendGet(String url, String param) { + String result = ""; + BufferedReader in = null; + try { + String urlNameString = url + "?" + param; + URL realUrl = new URL(urlNameString); + // 打开和URL之间的连接 + URLConnection connection = realUrl.openConnection(); + // 设置通用的请求属性 + connection.setRequestProperty("accept", "*/*"); + connection.setRequestProperty("connection", "Keep-Alive"); + connection.setRequestProperty("xm-sign","d9fdda2188c52dc128cd0d3ba157f957(79)1626234305702(74)1626232895270"); + connection.setRequestProperty("user-agent", + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + // 建立实际的连接 + connection.connect(); + + // 定义 BufferedReader输入流来读取URL的响应 + in = new BufferedReader(new InputStreamReader( + connection.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + result += line; + } + } catch (Exception e) { + System.out.println("发送GET请求出现异常!" + e); + e.printStackTrace(); + } + // 使用finally块来关闭输入流 + finally { + try { + if (in != null) { + in.close(); + } + } catch (Exception e2) { + e2.printStackTrace(); + } + } + return result; + } + + public static String sendSSLPost(String url, String param) { + try { + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom()); + URL console = new URL(url); + HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); + conn.setSSLSocketFactory(sc.getSocketFactory()); + conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/json"); + conn.setRequestProperty("Proxy-Connection", "Keep-Alive"); + conn.setConnectTimeout(ios_connectTimeout); + conn.setDoInput(true); + conn.setDoOutput(true); + BufferedOutputStream hurlBufOus = new BufferedOutputStream(conn.getOutputStream()); + hurlBufOus.write(param.getBytes(StandardCharsets.UTF_8)); + hurlBufOus.flush(); + + InputStream is = conn.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuffer result = new StringBuffer(); + String line; + while ((line = reader.readLine()) != null) { + result.append(line); + } + return result.toString(); + } catch (Exception e) { + // log.error("[" + BaseConstants.LOG_FLAG_PRE_ERROR + "http]:", e); + return null; + } + } + + public static String sendPost(String url, String param) { + try { + URLConnection conn = null; + + URL realUrl = new URL(url); + // 打开和URL之间的连接 + conn = realUrl.openConnection(); + // 设置通用的请求属性 + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + // 发送POST请求必须设置如下两行 + conn.setDoOutput(true); + conn.setDoInput(true); + conn.setConnectTimeout(connectTimeout); + try (PrintWriter out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8))) { + out.print(param); + out.flush(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) { + StringBuffer result = new StringBuffer(); + String line; + while ((line = in.readLine()) != null) { + result.append(line); + } + return result.toString(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + + /** + * Http post的工具方法 + * + * @param httpUrl 请求地址 + * @param data 请求数据 + * @param connectTimeout 连接超时时间 + * @param readTimeout 读取超时时间 + * @param headers 请求头 + * @return 将响应body作为String返回 + * @throws IOException 请求中的IO异常 + */ + public static String sendPost(String httpUrl, String contentType, String data, int connectTimeout, int readTimeout, Map headers) { + OutputStream output = null; + InputStream in = null; + HttpURLConnection urlConnection = null; + BufferedReader bufferedReader = null; + InputStreamReader inputStreamReader = null; + try { + URL url = new URL(httpUrl); + urlConnection = (HttpURLConnection) url.openConnection(); + urlConnection.setRequestMethod("POST"); + urlConnection.setDoOutput(true); + urlConnection.setDoInput(true); + urlConnection.setRequestProperty("Content-Type", contentType); + if (headers != null) { + for (String key : headers.keySet()) { + urlConnection.setRequestProperty(key, headers.get(key)); + } + } + urlConnection.setConnectTimeout(connectTimeout); + urlConnection.setReadTimeout(readTimeout); + urlConnection.connect(); + // 发送数据 + output = urlConnection.getOutputStream(); + output.write(data.getBytes(StandardCharsets.UTF_8)); + output.flush(); + // 读取响应 + if (urlConnection.getResponseCode() < 400) { + in = urlConnection.getInputStream(); + } else { + in = urlConnection.getErrorStream(); + } + inputStreamReader = new InputStreamReader(in, StandardCharsets.UTF_8); + bufferedReader = new BufferedReader(inputStreamReader); + StringBuilder strBuf = new StringBuilder(); + String str; + while ((str = bufferedReader.readLine()) != null) { + strBuf.append(str); + } + return strBuf.toString(); + } catch (Exception ignored) { + } finally { + try { + if (bufferedReader != null) { + bufferedReader.close(); + } + if (inputStreamReader != null) { + inputStreamReader.close(); + } + if (in != null) { + in.close(); + } + if (urlConnection != null) { + urlConnection.disconnect(); + } + } catch (IOException ignored) { + } + } + return null; + } + + public static HttpServletRequest getHttpServletRequest() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + } + + public static String getDomain() { + HttpServletRequest request = getHttpServletRequest(); + StringBuffer url = request.getRequestURL(); + return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString(); + } + + public static String getOrigin() { + HttpServletRequest request = getHttpServletRequest(); + return request.getHeader("Origin"); + } + + /** + * 获取request中body数据 + * + * @param request + * @return + */ + public static String getBody(HttpServletRequest request) { + StringBuilder sb = new StringBuilder(); + try (InputStream inputStream = request.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));) { + String line = ""; + while ((line = reader.readLine()) != null) {//todo 换行 + sb.append(line); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + return sb.toString(); + } + + public static byte[] getByteArrBody(HttpServletRequest request) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + try (InputStream inputStream = request.getInputStream(); BufferedInputStream byteOutputStream = new BufferedInputStream(inputStream);) { + byte[] bytes = new byte[1024]; + int a; + while ((a = byteOutputStream.read(bytes)) != -1) { + byteArrayOutputStream.write(bytes, 0, a); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + return byteArrayOutputStream.toByteArray(); + } + + /** + * 获取request中body数据 + * + * @param request + * @return + */ + public static String writeToBody(HttpServletRequest request, Map params) { + StringBuilder sb = new StringBuilder(); + try (InputStream inputStream = request.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));) { + String line = ""; + while ((line = reader.readLine()) != null) {//todo 换行 + sb.append(line); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + return sb.toString(); + } + + + public static String getRealClientIp(HttpServletRequest request) { + String ip = request.getHeader("x-forwarded-for"); + if (ip != null) { + ip = ip.split(",")[0]; + } + if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Real-IP"); + } + if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + return ip; + } + +} diff --git a/src/main/java/com/soft/utils/IfNotEmptyUtils.java b/src/main/java/com/soft/utils/IfNotEmptyUtils.java new file mode 100644 index 0000000..bfa7589 --- /dev/null +++ b/src/main/java/com/soft/utils/IfNotEmptyUtils.java @@ -0,0 +1,36 @@ +package com.soft.utils; + +import java.math.BigDecimal; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.function.Consumer; + +public class IfNotEmptyUtils { + + private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 定义日期格式 + + public static void setIfNotEmpty(String value, Consumer setter) { + if (value != null && !value.isEmpty()) { + setter.accept(value); + } + } + + public static void setIfNotEmptyDate(String value, Consumer setter) throws ParseException { + if (value != null && !value.isEmpty()) { + Date date = dateFormat.parse(value); + setter.accept(date); + } + } + + public static BigDecimal parseBigDecimal(String value) { + if (value != null && !value.isEmpty()) { + try { + return new BigDecimal(value); + } catch (NumberFormatException e) { + System.err.println("Invalid amount format: " + value); + } + } + return null; // 或者返回 BigDecimal.ZERO + } +} diff --git a/src/main/java/com/soft/utils/ImageUtil.java b/src/main/java/com/soft/utils/ImageUtil.java new file mode 100644 index 0000000..c090518 --- /dev/null +++ b/src/main/java/com/soft/utils/ImageUtil.java @@ -0,0 +1,92 @@ +package com.soft.utils; + +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; + +public class ImageUtil { + + public static boolean isImage(InputStream inputStream) { + try { + BufferedImage image = ImageIO.read(inputStream); + if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) { + return false; + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public static BufferedImage bufferedImage(File file) { + try { + BufferedImage image = ImageIO.read(file); + if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) { + return null; + } + return image; + } catch (Exception e) { + return null; + } + } + + public static BufferedImage bufferedImage(String base64) { + try { + BASE64Decoder decoder = new sun.misc.BASE64Decoder(); + byte[] bytes = decoder.decodeBuffer(base64); + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + BufferedImage image = ImageIO.read(bais); + if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) { + return null; + } + return image; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public static BufferedImage bufferedImage(InputStream inputStream) { + try { + BufferedImage image = ImageIO.read(inputStream); + if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) { + return null; + } + return image; + } catch (Exception e) { + return null; + } + } + + public static byte[] imageToBytes(BufferedImage bImage) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + ImageIO.write(bImage, "png", out); + } catch (IOException e) { + e.printStackTrace(); + } + return out.toByteArray(); + } + + public static byte[] imageToBytes(String base64) { + BufferedImage bImage=bufferedImage(base64); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + ImageIO.write(bImage, "png", out); + } catch (IOException e) { + e.printStackTrace(); + } + return out.toByteArray(); + } + + public static String imageToBase64(BufferedImage bufferedImage){ + BASE64Encoder encoder = new sun.misc.BASE64Encoder(); + byte[] bytes=imageToBytes(bufferedImage); + return encoder.encodeBuffer(bytes).trim(); + } + +} diff --git a/src/main/java/com/soft/utils/MinutesUtil.java b/src/main/java/com/soft/utils/MinutesUtil.java new file mode 100644 index 0000000..38c9303 --- /dev/null +++ b/src/main/java/com/soft/utils/MinutesUtil.java @@ -0,0 +1,19 @@ +package com.soft.utils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class MinutesUtil { + + public static Integer extractMinutes(String minutesString) { + Pattern pattern = Pattern.compile("\\d+"); // 匹配一个或多个数字 + Matcher matcher = pattern.matcher(minutesString); + + if (matcher.find()) { + String extractedString = matcher.group(); // 提取匹配到的数字部分 + return Integer.parseInt(extractedString); + } + + return 0; // 默认返回0或抛出异常,根据实际需求进行处理 + } +} diff --git a/src/main/java/com/soft/utils/PageResult.java b/src/main/java/com/soft/utils/PageResult.java new file mode 100644 index 0000000..0e5c4bc --- /dev/null +++ b/src/main/java/com/soft/utils/PageResult.java @@ -0,0 +1,179 @@ +package com.soft.utils; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +public class PageResult implements Serializable { + private static final long serialVersionUID = 1L; +// @ApiModelProperty("是否有上一页") +// private boolean hasPrev; +// @ApiModelProperty("是否有下一页") +// private boolean hasNext; + @ApiModelProperty("总记录数") + private long totalCount; + @ApiModelProperty("每页条数") + private long pageSize; + @ApiModelProperty("当前页码") + private long pageIndex; +// @ApiModelProperty("总页数") +// private int totalPage; + @ApiModelProperty("数据") + private List datas; + @ApiModelProperty("附加数据") + private Map extra; + + public PageResult() { + } + +// public boolean isHasPrev() { +// return this.hasPrev; +// } +// +// public boolean isHasNext() { +// return this.hasNext; +// } + + public long getTotalCount() { + return this.totalCount; + } + + public long getPageSize() { + return this.pageSize; + } + + public long getPageIndex() { + return this.pageIndex; + } + +// public int getTotalPage() { +// return this.totalPage; +// } + + public List getDatas() { + return this.datas; + } + + public Map getExtra() { + return this.extra; + } + +// public void setHasPrev(boolean hasPrev) { +// this.hasPrev = hasPrev; +// } +// +// public void setHasNext(boolean hasNext) { +// this.hasNext = hasNext; +// } + + public void setTotalCount(long totalCount) { + this.totalCount = totalCount; + } + + public void setPageSize(long pageSize) { + this.pageSize = pageSize; + } + + public void setPageIndex(long pageIndex) { + this.pageIndex = pageIndex; + } + +// public void setTotalPage(int totalPage) { +// this.totalPage = totalPage; +// } + + public void setDatas(List datas) { + this.datas = datas; + } + + public void setExtra(Map extra) { + this.extra = extra; + } + + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (!(o instanceof PageResult)) { + return false; + } else { + PageResult other = (PageResult)o; + if (!other.canEqual(this)) { + return false; +// } else if (this.isHasPrev() != other.isHasPrev()) { +// return false; +// } else if (this.isHasNext() != other.isHasNext()) { +// return false; + } else if (this.getTotalCount() != other.getTotalCount()) { + return false; + } else if (this.getPageSize() != other.getPageSize()) { + return false; + } else if (this.getPageIndex() != other.getPageIndex()) { + return false; +// } else if (this.getTotalPage() != other.getTotalPage()) { +// return false; + } else { + Object this$datas = this.getDatas(); + Object other$datas = other.getDatas(); + if (this$datas == null) { + if (other$datas != null) { + return false; + } + } else if (!this$datas.equals(other$datas)) { + return false; + } + + Object this$extra = this.getExtra(); + Object other$extra = other.getExtra(); + if (this$extra == null) { + if (other$extra != null) { + return false; + } + } else if (!this$extra.equals(other$extra)) { + return false; + } + + return true; + } + } + } + + protected boolean canEqual(Object other) { + return other instanceof PageResult; + } + + public int hashCode() { + boolean PRIME = true; + int result = 1; +// result = result * 59 + (this.isHasPrev() ? 79 : 97); +// result = result * 59 + (this.isHasNext() ? 79 : 97); + long $totalCount = this.getTotalCount(); + result = result * 59 + (int)($totalCount >>> 32 ^ $totalCount); + long $pageSize = this.getPageSize(); + result = result * 59 + (int)($pageSize >>> 32 ^ $pageSize); + long $pageIndex = this.getPageIndex(); + result = result * 59 + (int)($pageIndex >>> 32 ^ $pageIndex); +// result = result * 59 + this.getTotalPage(); + Object $datas = this.getDatas(); + result = result * 59 + ($datas == null ? 43 : $datas.hashCode()); + Object $extra = this.getExtra(); + result = result * 59 + ($extra == null ? 43 : $extra.hashCode()); + return result; + } + +// public String toString() { +// return "PageResult(hasPrev=" + this.isHasPrev() + ", hasNext=" + this.isHasNext() + ", totalCount=" + this.getTotalCount() + ", pageSize=" + this.getPageSize() + ", pageIndex=" + this.getPageIndex() + ", totalPage=" + this.getTotalPage() + ", datas=" + this.getDatas() + ", extra=" + this.getExtra() + ")"; +// } + + @Override + public String toString() { + return "PageResult{" + + "totalCount=" + totalCount + + ", pageSize=" + pageSize + + ", pageIndex=" + pageIndex + + ", datas=" + datas + + ", extra=" + extra + + '}'; + } +} diff --git a/src/main/java/com/soft/utils/PageResultUtil.java b/src/main/java/com/soft/utils/PageResultUtil.java new file mode 100644 index 0000000..8aa7cae --- /dev/null +++ b/src/main/java/com/soft/utils/PageResultUtil.java @@ -0,0 +1,97 @@ +package com.soft.utils; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.github.pagehelper.PageInfo; +import lombok.NonNull; + +import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class PageResultUtil { + public PageResultUtil() { + } + + public static PageResult convert(@NonNull IPage page) { + if (page == null) { + throw new NullPointerException("page is marked non-null but is null"); + } else { + return convert((IPage)page, (Map)null); + } + } + + public static PageResult convert(@NonNull PageInfo pageInfo) { + if (pageInfo == null) { + throw new NullPointerException("pageInfo is marked non-null but is null"); + } else { + return convert((PageInfo)pageInfo, (Map)null); + } + } + + public static PageResult convert(@NotNull IPage page, Map extra) { + PageResult pageResult = new PageResult(); + List datas = new ArrayList(page.getRecords()); + pageResult.setDatas(datas); +// pageResult.setHasNext(page.getCurrent() > 1L); +// pageResult.setHasPrev(page.getCurrent() < page.getPages()); + pageResult.setPageIndex(page.getCurrent()); + pageResult.setPageSize(page.getSize()); + pageResult.setTotalCount(page.getTotal()); +// pageResult.setTotalPage((int)page.getPages()); + if (!ObjectUtil.isEmpty(extra)) { + pageResult.setExtra(extra); + } + + return pageResult; + } + + public static PageResult convert(@NonNull PageInfo pageInfo, Map extra) { + if (pageInfo == null) { + throw new NullPointerException("pageInfo is marked non-null but is null"); + } else { + PageResult pageResult = new PageResult(); + List datas = new ArrayList(pageInfo.getList()); + pageResult.setDatas(datas); +// pageResult.setHasNext(pageInfo.isHasNextPage()); +// pageResult.setHasPrev(pageInfo.isHasPreviousPage()); + pageResult.setPageIndex((long)pageInfo.getPageNum()); + pageResult.setPageSize((long)pageInfo.getPageSize()); + pageResult.setTotalCount(pageInfo.getTotal()); +// pageResult.setTotalPage(pageInfo.getPages()); + if (!ObjectUtil.isEmpty(extra)) { + pageResult.setExtra(extra); + } + + return pageResult; + } + } + + public static PageResult rebuild(PageResult pageResult, List datas) { + PageResult result = new PageResult(); + BeanUtil.copyProperties(pageResult, result, new String[]{"datas"}); + result.setDatas(datas == null ? Collections.emptyList() : datas); + pageResult.setDatas(datas); + return result; + } + + public static PageResult newInstance(long pageIndex, long pageSize, long totalCount, List datas) { + return newInstance(pageIndex, pageSize, totalCount, datas, (Map)null); + } + + public static PageResult newInstance(long pageIndex, long pageSize, long totalCount, List datas, Map extra) { + PageResult pageResult = new PageResult(); + pageResult.setTotalCount(totalCount); + pageResult.setPageSize(pageSize); + pageResult.setPageIndex(pageIndex); +// pageResult.setTotalPage((int)(totalCount / pageSize) + (totalCount % pageSize > 0L ? 1 : 0)); + pageResult.setDatas(datas); + pageResult.setExtra(extra); +// pageResult.setHasNext(pageResult.getPageIndex() < (long)pageResult.getTotalPage()); +// pageResult.setHasPrev(pageResult.getPageIndex() > 1L); + return pageResult; + } +} diff --git a/src/main/java/com/soft/utils/PieChartData.java b/src/main/java/com/soft/utils/PieChartData.java new file mode 100644 index 0000000..a1884ff --- /dev/null +++ b/src/main/java/com/soft/utils/PieChartData.java @@ -0,0 +1,22 @@ +package com.soft.utils; + +import lombok.Data; + +@Data +public class PieChartData { + private String name; // 商品名称 + private Integer value; // 库存数量 + private String percent; // 百分比字符串 + + // 全参构造方法(必须正确赋值字段!) + public PieChartData(String name, Integer value, String percent) { + this.name = name; + this.value = value; + this.percent = percent; + } + + // 无参构造方法(JSON反序列化需要) + public PieChartData() { + + } +} diff --git a/src/main/java/com/soft/utils/PieChartsData.java b/src/main/java/com/soft/utils/PieChartsData.java new file mode 100644 index 0000000..e4ca7ac --- /dev/null +++ b/src/main/java/com/soft/utils/PieChartsData.java @@ -0,0 +1,26 @@ +package com.soft.utils; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class PieChartsData { + + private String name; // 商品名称 + private BigDecimal value; // 库存数量 + private String percent; // 百分比字符串 + + // 全参构造方法(必须正确赋值字段!) + public PieChartsData(String name, BigDecimal value, String percent) { + this.name = name; + this.value = value; + this.percent = percent; + } + + // 无参构造方法(JSON反序列化需要) + public PieChartsData() { + + } + +} diff --git a/src/main/java/com/soft/utils/ProportionUtils.java b/src/main/java/com/soft/utils/ProportionUtils.java new file mode 100644 index 0000000..e93a04c --- /dev/null +++ b/src/main/java/com/soft/utils/ProportionUtils.java @@ -0,0 +1,93 @@ +package com.soft.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.YearMonth; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class ProportionUtils { + + public static Logger log = LoggerFactory.getLogger(ProportionUtils.class); + + + public static String calculateProportion(BigDecimal purchase, BigDecimal sale) { + if (sale == null || sale.compareTo(BigDecimal.ZERO) == 0) { + return "0.00%"; + } + BigDecimal ratio = purchase.divide(sale, 4, RoundingMode.HALF_UP); // 保留4位小数 + DecimalFormat df = new DecimalFormat("0.00%"); + return df.format(ratio); + } + + public static List initZeroList(int size) { + return IntStream.range(0, size) + .mapToObj(i -> BigDecimal.ZERO) + .collect(Collectors.toList()); + } + + public static void fillAmounts(List> data, List amounts, + Map indexMap, String amountKey) { + for (Map item : data) { + try { + String ymStr = (String) item.get("month"); + YearMonth ym = YearMonth.parse(ymStr, DateTimeFormatter.ofPattern("yyyy-MM")); + BigDecimal amount = (BigDecimal) item.get(amountKey); + + Integer index = indexMap.get(ym); + if (index != null && amount != null) { + amounts.set(index, amounts.get(index).add(amount)); + } + } catch (Exception e) { + log.error("数据格式异常: {}", item, e); + } + } + } + + public static void dayFillAmounts(List> data, List amounts, LocalDate now,String amountKey) { + for (Map item : data) { + try { + String dateStr = (String) item.get("date"); + LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ISO_DATE); + + // 计算日期索引(0=30天前,29=当天) + long daysBetween = ChronoUnit.DAYS.between(now.minusDays(29), date); + if (daysBetween < 0 || daysBetween >= 30) continue; + + BigDecimal amount = (BigDecimal) item.get(amountKey); // 动态获取金额字段 + if (amount != null) { + amounts.set((int) daysBetween, amount); + } + } catch (Exception e) { + log.error("数据处理异常: {}", item, e); + } + } + } + + public static String calculateGrowth(BigDecimal current, BigDecimal last) { + // 处理去年为0但当前年有数据的情况 + if (last.compareTo(BigDecimal.ZERO) == 0) { + if (current.compareTo(BigDecimal.ZERO) > 0) { + return "100.00%"; // 从零到有,增长100% + } else { + return "0.00%"; // 两年均为零,无增长 + } + } + + // 正常计算 + BigDecimal growth = current.subtract(last) + .divide(last, 4, RoundingMode.HALF_UP) + .multiply(BigDecimal.valueOf(100)); + return String.format("%.2f%%", growth); + } + +} diff --git a/src/main/java/com/soft/utils/ResultUtil.java b/src/main/java/com/soft/utils/ResultUtil.java new file mode 100644 index 0000000..2ff2401 --- /dev/null +++ b/src/main/java/com/soft/utils/ResultUtil.java @@ -0,0 +1,56 @@ +package com.soft.utils; + +import java.util.HashMap; +import java.util.Map; + +/** + * 状态码 + */ +public class ResultUtil { + + /** + * 常用 + */ + public static final int SUCCESS_CODE=200;//成功 + public static final int FAIL_CODE=300;//失败 + public static final int EMPTY_PARAM_CODE=400;//空参数 + public static final int ERROR_CODE=500;//异常 + + /** + * 权限 + */ + public static final int LOGIN_TOKEN_INVALID_CODE=401;//token无效 + public static final int NOT_AUTHENTICATION_CODE=403;//没权限 + + /** + * 图片格式 + */ + public static final int NO_SUPPORT_FILE_FORMAT_CODE=505;//不支持文件形式 + + + + private static Map messageMap; + + static { + messageMap=new HashMap<>(); + messageMap.put(SUCCESS_CODE,"Success"); + messageMap.put(FAIL_CODE,"Fail"); + messageMap.put(EMPTY_PARAM_CODE,"Fount required isEmpty"); + messageMap.put(ERROR_CODE,"Error"); + + messageMap.put(LOGIN_TOKEN_INVALID_CODE,"Token is invalid. Please login again"); + messageMap.put(NOT_AUTHENTICATION_CODE,"Full authentication is required to access this resource"); + + messageMap.put(NO_SUPPORT_FILE_FORMAT_CODE,"File format is not supported"); + } + + /** + * 根据状态码获取返回消息 + * @param code + * @return + */ + public static String getMessage(int code){ + return messageMap.get(code); + } + +} diff --git a/src/main/java/com/soft/utils/SpringBeanUtil.java b/src/main/java/com/soft/utils/SpringBeanUtil.java new file mode 100644 index 0000000..248b502 --- /dev/null +++ b/src/main/java/com/soft/utils/SpringBeanUtil.java @@ -0,0 +1,95 @@ +package com.soft.utils; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.env.Environment; + +public class SpringBeanUtil implements ApplicationContextAware { + + + private static ApplicationContext context; + + /*** + * 当继承了ApplicationContextAware类之后,那么程序在调用 + * getBean(String)的时候会自动调用该方法,不用自己操作 + */ + @Override + public void setApplicationContext(ApplicationContext context) throws BeansException { + SpringBeanUtil.context = context; + } + + /*** + * 根据一个bean的id获取配置文件中相应的bean + * @param name + * @return + * @throws BeansException + */ + public static Object getSpringBean(String beanName) { + return context==null?null:context.getBean(beanName); + } + + /*** + * 类似于getBean(String name)只是在参数中提供了需要返回到的类型。 + * @param name + * @param requiredType + * @return + * @throws BeansException + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static T getBean(String name, Class requiredType) throws BeansException { + return context.getBean(name, requiredType); + } + + public static T getBean(Class requiredType) throws BeansException { + return context.getBean(requiredType); + } + + public static T getProperty(String name, Class requiredType){ + Environment environment=getBean(Environment.class); + return environment.getProperty(name,requiredType); + } + + /** + * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true + * @param name + * @return boolean + */ + public static boolean containsBean(String name) { + return context.containsBean(name); + } + + /** + * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 + * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) + * @param name + * @return boolean + * @throws NoSuchBeanDefinitionException + */ + public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { + return context.isSingleton(name); + } + + /** + * @param name + * @return Class 注册对象的类型 + * @throws NoSuchBeanDefinitionException + */ + @SuppressWarnings("rawtypes") + public static Class getType(String name) throws NoSuchBeanDefinitionException { + return context.getType(name); + } + + /** + * 如果给定的bean名字在bean定义中有别名,则返回这些别名 + * @param name + * @return + * @throws NoSuchBeanDefinitionException + */ + public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { + return context.getAliases(name); + } + + +} diff --git a/src/main/java/com/soft/utils/StreamUtils.java b/src/main/java/com/soft/utils/StreamUtils.java new file mode 100644 index 0000000..9b13ecd --- /dev/null +++ b/src/main/java/com/soft/utils/StreamUtils.java @@ -0,0 +1,49 @@ +package com.soft.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public class StreamUtils { + private static int _buffer_size = 1024; + /** + * InputStream流转换成String字符串 + * @param inStream InputStream流 + * @param encoding 编码格式 + * @return String字符串 + */ + public static String inputStream2String(InputStream inStream, String encoding){ + String result = null; + ByteArrayOutputStream outStream = null; + try { + if(inStream != null){ + outStream = new ByteArrayOutputStream(); + byte[] tempBytes = new byte[_buffer_size]; + int count = -1; + while((count = inStream.read(tempBytes, 0, _buffer_size)) != -1){ + outStream.write(tempBytes, 0, count); + } + tempBytes = null; + outStream.flush(); + result = new String(outStream.toByteArray(), encoding); + outStream.close(); + } + } catch (Exception e) { + result = null; + } finally { + try { + if(inStream != null) { + inStream.close(); + inStream = null; + } + if(outStream != null) { + outStream.close(); + outStream = null; + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return result; + } +} diff --git a/src/main/java/com/soft/utils/UnsupportedQueryException.java b/src/main/java/com/soft/utils/UnsupportedQueryException.java new file mode 100644 index 0000000..b5234ba --- /dev/null +++ b/src/main/java/com/soft/utils/UnsupportedQueryException.java @@ -0,0 +1,8 @@ +package com.soft.utils; + +public class UnsupportedQueryException extends RuntimeException { + + public UnsupportedQueryException(String message) { + super(message); + } +} diff --git a/src/main/java/com/soft/utils/VoiceQueryParser.java b/src/main/java/com/soft/utils/VoiceQueryParser.java new file mode 100644 index 0000000..0013731 --- /dev/null +++ b/src/main/java/com/soft/utils/VoiceQueryParser.java @@ -0,0 +1,152 @@ +package com.soft.utils; + +import com.soft.entitys.QueryParams; +import com.soft.enums.QueryType; + +import javax.management.Query; +import java.time.LocalDate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class VoiceQueryParser { + + public QueryParams parse(String voiceText) { + + QueryParams params = new QueryParams(); + + + // 解析查询类型和参数 + + if (voiceText.contains("今日采购订单") || voiceText.contains("今天采购订单") ) { + params.setType(QueryType.TODAY_PURCHASE_AMOUNT); + } + else if (voiceText.contains("今日销售订单") || voiceText.contains("今天销售订单")) { + params.setType(QueryType.TODAY_SALES_AMOUNT); + } + else if(voiceText.contains("日") &&voiceText.contains("销售订单") || voiceText.contains("号") &&voiceText.contains("销售订单")){ + params.setType(QueryType.SALES_ORDERS_BY_DATE); + extractDateFromText(voiceText,params); + } + else if(voiceText.contains("日") &&voiceText.contains("采购订单") || voiceText.contains("号") &&voiceText.contains("采购订单")){ + params.setType(QueryType.PURCHASE_ORDERS_BY_DATE); + extractDateFromText(voiceText,params); + } + else if(voiceText.contains("本月销售订单")){ + params.setType(QueryType.MONTH_SALE_AMOUNT); + extractDateFromText(voiceText,params); + } + else if(voiceText.contains("本月采购订单")){ + params.setType(QueryType.MONTH_PURCHASE_AMOUNT); + extractDateFromText(voiceText,params); + } + else if(voiceText.contains("本年销售订单")){ + params.setType(QueryType.YEAR_SALE_AMOUNT); + extractDateFromText(voiceText,params); + } + else if(voiceText.contains("本年采购订单")){ + params.setType(QueryType.YEAR_PURCHASE_AMOUNT); + extractDateFromText(voiceText,params); + } + else if (voiceText.contains("库存") && voiceText.contains("多少") ||voiceText.contains("库存") && voiceText.contains("剩余")) { + params.setType(QueryType.PRODUCT_INVENTORY); + extractProductName(voiceText, params); + } + else if(voiceText.contains("采购入库订单")&& voiceText.contains("今日") || voiceText.contains("采购入库订单") &&voiceText.contains("今天")){ + params.setType(QueryType.TODAY_PURCHASE_ORDERS); + } + else if(voiceText.contains("采购退货订单") && voiceText.contains("今日") || voiceText.contains("采购退货订单") && voiceText.contains("今天")){ + params.setType(QueryType.TODAY_PURCHASE_RETURN); + } + else if(voiceText.contains("的订单")){ + params.setType(QueryType.CUSTOMER_NAME_SEARCH); + extractCustomer(voiceText,params); + } + else if(voiceText.contains("销售订单") ||voiceText.contains("销售记录") ){ + params.setType(QueryType.USER_NAME_ORDERS_SEARCH); + extractSalesperson(voiceText,params); + } + else if(voiceText.contains("出入库记录")||voiceText.contains("出入库流水记录")){ + params.setType(QueryType.PRODUCT_STOCK_LOG_BY_NAME); + extractProductStock(voiceText,params); + } + else if(voiceText.contains("今日销售出库订单")||voiceText.contains("今天销售出库订单")){ + params.setType(QueryType.TODAY_OUTBOUND_ORDERS); + } + else if(voiceText.contains("营收账款") || voiceText.contains("合同金额")){ + params.setType(QueryType.REVENUE_COUNT); + } + else if(voiceText.contains("应付账款")){ + params.setType(QueryType.ACCOUNTS_PAYABLE); + } + else if(voiceText.contains("费用支付")){ + params.setType(QueryType.PAYMENT_TOF_FEES); + } + else if(voiceText.contains("利润总和")){ + params.setType(QueryType.TOTAL_PROFIT); + } + + return params; + } + + private void extractProductName(String text, QueryParams params) { + // 使用正则表达式提取商品名 + Pattern pattern = Pattern.compile("(?:查询|查看|查找|查)(.+?)(?:的?)(?:库存|存货|余量|数量|剩下|剩余)"); + Matcher matcher = pattern.matcher(text); + if (matcher.find()) { + params.setProductName(matcher.group(1).trim()); + } else { + // 尝试其他模式 + pattern = Pattern.compile("(?:库存|存货|余量|数量|剩下|剩余)(.+?)(?:的?)(?:有多少|是多少|多少|几多)"); + matcher = pattern.matcher(text); + if (matcher.find()) { + params.setProductName(matcher.group(1).trim()); + } + } + } + + private void extractProductStock(String text, QueryParams params) { + // 使用正则表达式提取销售人员 + Pattern pattern = Pattern.compile("(?:查询|查看|查找|查)(.+?)(?:的?)(?:出入库记录|出入库流水记录)"); + Matcher matcher = pattern.matcher(text); + if (matcher.find()) { + params.setProductName(matcher.group(1).trim()); + } + } + + private void extractSalesperson(String text, QueryParams params) { + // 使用正则表达式提取销售人员 + Pattern pattern = Pattern.compile("(?:查询|查看|查找|查)(.+?)(?:的?)(?:销售记录|销售订单)"); + Matcher matcher = pattern.matcher(text); + if (matcher.find()) { + params.setUserName(matcher.group(1).trim()); + } + } + + private void extractCustomer(String text, QueryParams params) { + // 更灵活的正则表达式,支持多种表达方式 + Pattern pattern = Pattern.compile("(?:查询|查看|查找|查)(.+?)(?:的?)(?:订单)"); + Matcher matcher = pattern.matcher(text); + if (matcher.find()) { + params.setCustomerName(matcher.group(1).trim()); + } + + } + + private void extractDateFromText(String text, QueryParams param) { + // 更灵活的正则表达式,处理各种情况 + Pattern datePattern = Pattern.compile( + "(?:查询|查看|查找)?\\s*" + // 可选前缀 + "(\\d{1,2}\\s*月\\s*\\d{1,2}\\s*[日号]|" + // 4月28号 + "\\d{4}\\s*年\\s*\\d{1,2}\\s*月\\s*\\d{1,2}\\s*[日号])" // 2024年4月28日 + ); + + Matcher matcher = datePattern.matcher(text.replaceAll("\\s+", "")); // 去除所有空格 + if (matcher.find()) { + String matchedDate = matcher.group(1).trim(); + String standardDate = DateParserUtil.parseChineseDate(matchedDate); + param.setQueryDate(standardDate); + } + } + + +} diff --git a/src/main/java/com/soft/utils/WxUtil.java b/src/main/java/com/soft/utils/WxUtil.java new file mode 100644 index 0000000..77414da --- /dev/null +++ b/src/main/java/com/soft/utils/WxUtil.java @@ -0,0 +1,29 @@ +package com.soft.utils; + +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WxUtil { + + private static Logger logger= LoggerFactory.getLogger(com.soft.utils.WxUtil.class); + + + + /** + * 获取微信小程序token + * @return + */ + public static String getToken(){ + String result= HttpUtils.sendGet(ConstantUtil.WX_TOKEN_URL); + logger.info("result :"+result); + if(StringUtils.isBlank(result)){ + return null; + } + JSONObject jsonObject = JSONObject.parseObject(result); + return jsonObject.getString("access_token"); + } + + +} diff --git a/src/main/java/com/soft/utils/convert/purchase/QueryPurchaseOrderBOUtil.java b/src/main/java/com/soft/utils/convert/purchase/QueryPurchaseOrderBOUtil.java new file mode 100644 index 0000000..1a641a9 --- /dev/null +++ b/src/main/java/com/soft/utils/convert/purchase/QueryPurchaseOrderBOUtil.java @@ -0,0 +1,23 @@ +package com.soft.utils.convert.purchase; + +import com.soft.bo.purchase.QueryPurchaseOrderBo; +import com.soft.bo.sale.QuerySaleOrderBo; +import com.soft.common.util.DateUtils; +import com.soft.entitys.voice.SaleOrder; + +import java.math.BigDecimal; + +public class QueryPurchaseOrderBOUtil { + + public static QueryPurchaseOrderBo toQueryPurchaseOrderBo(SaleOrder data) { + QueryPurchaseOrderBo bo = new QueryPurchaseOrderBo(); + bo.setId(data.getId()); + bo.setCode(data.getCode()); + bo.setTotalAmount(data.getTotalAmount()); + bo.setProductAmount(BigDecimal.valueOf(data.getTotalNum())); + bo.setCreateBy(data.getCreateBy()); + bo.setCreateTime(DateUtils.toLocalDateTime(data.getCreateTime())); + bo.setStatus(data.getStatus()); + return bo; + } +} diff --git a/src/main/java/com/soft/utils/convert/sale/QuerySaleOrderBOUtil.java b/src/main/java/com/soft/utils/convert/sale/QuerySaleOrderBOUtil.java new file mode 100644 index 0000000..8e3189f --- /dev/null +++ b/src/main/java/com/soft/utils/convert/sale/QuerySaleOrderBOUtil.java @@ -0,0 +1,23 @@ +package com.soft.utils.convert.sale; + +import com.soft.bo.sale.QuerySaleOrderBo; +import com.soft.common.util.DateUtils; +import com.soft.entitys.voice.SaleOrder; + +import java.math.BigDecimal; +import java.util.List; + +public class QuerySaleOrderBOUtil { + + public static QuerySaleOrderBo toQuerySaleOrderBo(SaleOrder data) { + QuerySaleOrderBo bo = new QuerySaleOrderBo(); + bo.setId(data.getId()); + bo.setCode(data.getCode()); + bo.setTotalAmount(data.getTotalAmount()); + bo.setProductAmount(BigDecimal.valueOf(data.getTotalNum())); + bo.setCreateBy(data.getCreateBy()); + bo.setCreateTime(DateUtils.toLocalDateTime(data.getCreateTime())); + bo.setStatus(data.getStatus()); + return bo; + } +} diff --git a/src/main/java/com/soft/validator/PasswordValidator.java b/src/main/java/com/soft/validator/PasswordValidator.java new file mode 100644 index 0000000..3d6c34a --- /dev/null +++ b/src/main/java/com/soft/validator/PasswordValidator.java @@ -0,0 +1,21 @@ +package com.soft.validator; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; + +public class PasswordValidator { + + @Autowired + private static PasswordEncoder passwordEncode; + + public static boolean validatePassword(String rawPassword, String encodedPassword) { + return passwordEncode.matches(rawPassword, encodedPassword); + } + + + public static void main(String[] args) { + String rawPassword = "123456"; // 用户输入的明文密码 + String dbHash = "$2a$10$urKiyPeegUkABEtb03ZeV.gSixN.6EGDtiN9dDY4kjkJJ1znnLixC"; + System.out.println(validatePassword(rawPassword, dbHash)); + } +} \ No newline at end of file diff --git a/src/main/java/com/soft/vo/AgentLevelVo.java b/src/main/java/com/soft/vo/AgentLevelVo.java new file mode 100644 index 0000000..67390c6 --- /dev/null +++ b/src/main/java/com/soft/vo/AgentLevelVo.java @@ -0,0 +1,26 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class AgentLevelVo { + + @ApiModelProperty(value = "代理等级") + private Integer id; + + @ApiModelProperty(value = "代理名称") + private String name; + + @ApiModelProperty(value = "返点比率") + private String profit; + + @ApiModelProperty(value = "返点百分比") + private String profitRebate; + + @ApiModelProperty(value = "升级所需") + private Integer count; + +} diff --git a/src/main/java/com/soft/vo/BindPhoneVo.java b/src/main/java/com/soft/vo/BindPhoneVo.java new file mode 100644 index 0000000..40b0d06 --- /dev/null +++ b/src/main/java/com/soft/vo/BindPhoneVo.java @@ -0,0 +1,14 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class BindPhoneVo { + + @ApiModelProperty(value = "手机号码") + private String phoneNumber; + + @ApiModelProperty(value = "等级") + private Integer level; +} diff --git a/src/main/java/com/soft/vo/CheckOrderAmountCountVo.java b/src/main/java/com/soft/vo/CheckOrderAmountCountVo.java new file mode 100644 index 0000000..823b555 --- /dev/null +++ b/src/main/java/com/soft/vo/CheckOrderAmountCountVo.java @@ -0,0 +1,19 @@ +package com.soft.vo; + +import com.soft.utils.PieChartData; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class CheckOrderAmountCountVo { + + private BigDecimal amountCount; + + private String chartType; + + private String msg; + + private List pieChartData; // 饼图数据列表 +} diff --git a/src/main/java/com/soft/vo/CheckTodaysPurchaseAmountVo.java b/src/main/java/com/soft/vo/CheckTodaysPurchaseAmountVo.java new file mode 100644 index 0000000..0e0d150 --- /dev/null +++ b/src/main/java/com/soft/vo/CheckTodaysPurchaseAmountVo.java @@ -0,0 +1,26 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class CheckTodaysPurchaseAmountVo { + + +// private List list; + + private BigDecimal purchaseAmount; + + private String chartType; + + private String msg; + + @ApiModelProperty(value = "横轴:供应商名称") + private List xAxisData; + + @ApiModelProperty(value = "纵轴:订单金额") + private List yAxisData; +} diff --git a/src/main/java/com/soft/vo/CheckTodysSalesAmountVo.java b/src/main/java/com/soft/vo/CheckTodysSalesAmountVo.java new file mode 100644 index 0000000..7939420 --- /dev/null +++ b/src/main/java/com/soft/vo/CheckTodysSalesAmountVo.java @@ -0,0 +1,26 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class CheckTodysSalesAmountVo { + + + + private BigDecimal salesAmount; + + private String chartType; + + private String msg; + + @ApiModelProperty(value = "横轴:业务员名称") + private List xAxisData; // 横轴:业务员名称 + + @ApiModelProperty(value = "纵轴:订单金额") + private List yAxisData; // 纵轴:订单金额 + +} diff --git a/src/main/java/com/soft/vo/CreateOrderChartVo.java b/src/main/java/com/soft/vo/CreateOrderChartVo.java new file mode 100644 index 0000000..4740b15 --- /dev/null +++ b/src/main/java/com/soft/vo/CreateOrderChartVo.java @@ -0,0 +1,36 @@ +package com.soft.vo; + +import com.soft.enums.OrderChartBizType; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +@Data +public class CreateOrderChartVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 单据总金额 + */ + @ApiModelProperty(value = "单据总金额", required = true) + @NotNull(message = "单据总金额不能为空!") + private BigDecimal totalAmount; + + /** + * 创建时间 + */ + @ApiModelProperty("创建时间") + private LocalDateTime createTime; + + /** + * 业务类型 + */ + @ApiModelProperty(value = "业务类型", required = true) + @NotNull(message = "业务类型不能为空!") + private OrderChartBizType bizType; +} diff --git a/src/main/java/com/soft/vo/OrderDataMonthVo.java b/src/main/java/com/soft/vo/OrderDataMonthVo.java new file mode 100644 index 0000000..48549eb --- /dev/null +++ b/src/main/java/com/soft/vo/OrderDataMonthVo.java @@ -0,0 +1,23 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class OrderDataMonthVo { + + + @ApiModelProperty(value = "本月销售订单金额") + private BigDecimal thisMonthSaleOrderAmount; + + @ApiModelProperty(value = "本月销售订单数量") + private Integer thisMonthSaleQuantityCount; + + @ApiModelProperty(value = "本月采购订单金额") + private BigDecimal thisMonthPurchaseOrderAmount; + + @ApiModelProperty(value = "本月采购订单数量") + private Integer thisMonthPurchaseQuantityCount; +} diff --git a/src/main/java/com/soft/vo/OrderDataVo.java b/src/main/java/com/soft/vo/OrderDataVo.java new file mode 100644 index 0000000..cb0fc3d --- /dev/null +++ b/src/main/java/com/soft/vo/OrderDataVo.java @@ -0,0 +1,27 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class OrderDataVo { + + @ApiModelProperty(value = "今日采购订单金额") + private BigDecimal todayPurchaseOrderAmount; // 订单金额 + + @ApiModelProperty(value = "今日采购订单数量") + private Integer todayPurchaseQuantityCount; // 商品数量 + + @ApiModelProperty(value = "今日销售订单金额") + private BigDecimal todaySaleOrderAmount; // 订单金额 + + @ApiModelProperty(value = "今日销售订单数量") + private Integer todaySaleQuantityCount; // 商品数量 + + + + + +} diff --git a/src/main/java/com/soft/vo/OrderDataWeekVo.java b/src/main/java/com/soft/vo/OrderDataWeekVo.java new file mode 100644 index 0000000..b2a38e1 --- /dev/null +++ b/src/main/java/com/soft/vo/OrderDataWeekVo.java @@ -0,0 +1,22 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class OrderDataWeekVo { + + @ApiModelProperty(value = "本周销售订单金额") + private BigDecimal thisWeekSaleOrderAmount; + + @ApiModelProperty(value = "本周销售订单数量") + private Integer thisWeekSaleQuantityCount; + + @ApiModelProperty(value = "本周采购订单金额") + private BigDecimal thisWeekPurchaseOrderAmount; + + @ApiModelProperty(value = "本周采购订单数量") + private Integer thisWeekPurchaseQuantityCount; +} diff --git a/src/main/java/com/soft/vo/OrderMonthContrastVo.java b/src/main/java/com/soft/vo/OrderMonthContrastVo.java new file mode 100644 index 0000000..1479d22 --- /dev/null +++ b/src/main/java/com/soft/vo/OrderMonthContrastVo.java @@ -0,0 +1,22 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class OrderMonthContrastVo { + + private String chartType; + + @ApiModelProperty(value = "横轴:月份") + private List xAxisData;//月份列表:["1", "2", "3", "4", "5"] + + @ApiModelProperty(value = "销售订单金额列表") + private List saleAmounts; // 每个月的销售金额 + + @ApiModelProperty(value = "采购订单金额列表") + private List purchaseAmounts; // 每个月的采购金额 +} \ No newline at end of file diff --git a/src/main/java/com/soft/vo/OrderProportionVo.java b/src/main/java/com/soft/vo/OrderProportionVo.java new file mode 100644 index 0000000..aec7cd1 --- /dev/null +++ b/src/main/java/com/soft/vo/OrderProportionVo.java @@ -0,0 +1,20 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class OrderProportionVo { + + @ApiModelProperty(value = "采购金额") + private BigDecimal purchaseAmount; + + @ApiModelProperty(value = "销售金额") + private BigDecimal SaleAmount; + + @ApiModelProperty(value = "采销占比") + private String proportion; + +} diff --git a/src/main/java/com/soft/vo/OrderTodaysContrastVo.java b/src/main/java/com/soft/vo/OrderTodaysContrastVo.java new file mode 100644 index 0000000..a0efac2 --- /dev/null +++ b/src/main/java/com/soft/vo/OrderTodaysContrastVo.java @@ -0,0 +1,22 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class OrderTodaysContrastVo { + + private String chartType; + + @ApiModelProperty(value = "横轴:每日") + private List xAxisData;//每日列表:["1", "2", "3", "4", "5","6" .....] + + @ApiModelProperty(value = "销售订单金额列表") + private List saleAmounts; // 每天的销售金额 + + @ApiModelProperty(value = "采购订单金额列表") + private List purchaseAmounts; // 每天的采购金额 +} diff --git a/src/main/java/com/soft/vo/ProductStockDataVo.java b/src/main/java/com/soft/vo/ProductStockDataVo.java new file mode 100644 index 0000000..df47c4c --- /dev/null +++ b/src/main/java/com/soft/vo/ProductStockDataVo.java @@ -0,0 +1,31 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import javafx.scene.chart.ValueAxis; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class ProductStockDataVo { + + private String id; + + @ApiModelProperty(value = "仓库ID") + private String scId; + + @ApiModelProperty(value = "仓库名") + private String scName; + + @ApiModelProperty(value = "商品ID") + private String productId; + + @ApiModelProperty(value = "商品名") + private String productName; + + @ApiModelProperty(value = "库存数量") + private Integer stockNum; + + + +} diff --git a/src/main/java/com/soft/vo/ProductStockLogChartVo.java b/src/main/java/com/soft/vo/ProductStockLogChartVo.java new file mode 100644 index 0000000..3006279 --- /dev/null +++ b/src/main/java/com/soft/vo/ProductStockLogChartVo.java @@ -0,0 +1,15 @@ +package com.soft.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class ProductStockLogChartVo { + + private List list; + + private String chartType; + + private String msg; +} diff --git a/src/main/java/com/soft/vo/ProductStockLogVo.java b/src/main/java/com/soft/vo/ProductStockLogVo.java new file mode 100644 index 0000000..e0e6dae --- /dev/null +++ b/src/main/java/com/soft/vo/ProductStockLogVo.java @@ -0,0 +1,89 @@ +package com.soft.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +public class ProductStockLogVo { + + /** + * ID + */ + private String id; + + /** + * 仓库ID + */ + private String scId; + + /** + * 商品ID + */ + private String productId; + + /** + * 商品名 + */ + private String productName; + + /** + * 原库存数量 + */ + private Integer oriStockNum; + + /** + * 现库存数量 + */ + private Integer curStockNum; + + /** + * 原含税成本价 + */ + private BigDecimal oriTaxPrice; + + /** + * 现含税成本价 + */ + private BigDecimal curTaxPrice; + + /** + * 变动库存数量 + */ + private Integer stockNum; + + /** + * 变动含税金额 + */ + private BigDecimal taxAmount; + + + private String createById; + + + private String createBy; + + + private Date createTime; + + /** + * 业务单据ID + */ + private String bizId; + + /** + * 业务单据号 + */ + private String bizCode; + + /** + * 业务单据明细ID + */ + private String bizDetailId; + + /** + * 业务类型 + */ + private Integer bizType; +} diff --git a/src/main/java/com/soft/vo/ProductStockProportionVo.java b/src/main/java/com/soft/vo/ProductStockProportionVo.java new file mode 100644 index 0000000..87c6aa4 --- /dev/null +++ b/src/main/java/com/soft/vo/ProductStockProportionVo.java @@ -0,0 +1,17 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class ProductStockProportionVo { + + @ApiModelProperty(value = "商品名") + private String productName; + + @ApiModelProperty(value = "库存数") + private String stock; + + @ApiModelProperty(value = "库存占比(百分比形式)") + private String proportion; +} diff --git a/src/main/java/com/soft/vo/ProductVo.java b/src/main/java/com/soft/vo/ProductVo.java new file mode 100644 index 0000000..cfdaf3a --- /dev/null +++ b/src/main/java/com/soft/vo/ProductVo.java @@ -0,0 +1,104 @@ +package com.soft.vo; + +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +public class ProductVo { + + /** + * ID + */ + private String id; + + /** + * 编号 + */ + private String code; + + /** + * 名称 + */ + private String name; + + /** + * 简称 + */ + private String shortName; + + /** + * SKU + */ + private String skuCode; + + /** + * 简码 + */ + private String externalCode; + + /** + * 分类ID + */ + private String categoryId; + + /** + * 品牌ID + */ + private String brandId; + + /** + * 进项税率(%) + */ + private BigDecimal taxRate; + + /** + * 销项税率(%) + */ + private BigDecimal saleTaxRate; + + /** + * 规格 + */ + private String spec; + + /** + * 单位 + */ + private String unit; + + /** + * 重量(kg) + */ + private BigDecimal weight; + + /** + * 体积(cm3) + */ + private BigDecimal volume; + + /** + * 状态 + */ + private Boolean available; + + private String createById; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private String updateById; + + private Date updateTime; + + /** + * 库存数量 + */ + private Integer stockNum; + + +} diff --git a/src/main/java/com/soft/vo/PurchaseOrderChartVo.java b/src/main/java/com/soft/vo/PurchaseOrderChartVo.java new file mode 100644 index 0000000..cb7b22c --- /dev/null +++ b/src/main/java/com/soft/vo/PurchaseOrderChartVo.java @@ -0,0 +1,23 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class PurchaseOrderChartVo { + + private List list; + + private String chartType; + + private String msg; + + @ApiModelProperty(value = "横轴:供应商名称") + private List xAxisData; + + @ApiModelProperty(value = "纵轴:订单金额") + private List yAxisData; +} diff --git a/src/main/java/com/soft/vo/PurchaseOrderVo.java b/src/main/java/com/soft/vo/PurchaseOrderVo.java new file mode 100644 index 0000000..c3d08c9 --- /dev/null +++ b/src/main/java/com/soft/vo/PurchaseOrderVo.java @@ -0,0 +1,129 @@ +package com.soft.vo; + +import com.soft.entitys.voice.PurchaseOrderDetail; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +@Data +public class PurchaseOrderVo { + + private String id; + + /** + * 单号 + */ + private String code; + + /** + * 仓库ID + */ + private String scId; + + /** + * 供应商ID + */ + private String supplierId; + + + /** + * 供应商 + */ + private String supplierName; + + /** + * 采购员ID + */ + private String purchaserId; + + /** + * 预计到货日期 + */ + private Date expectArriveDate; + + /** + * 采购数量 + */ + private Integer totalNum; + + /** + * 赠品数量 + */ + private Integer totalGiftNum; + + /** + * 采购金额 + */ + private BigDecimal totalAmount; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + + private String createById; + + /** + * 创建人 新增时赋值 + */ + + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + + private Date createTime; + + /** + * 修改人 新增和修改时赋值 + */ + + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + + private Date updateTime; + + /** + * 审核人 + */ + private String approveBy; + + /** + * 审核时间 + */ + private Date approveTime; + + + + /** + * 拒绝原因 + */ + private String refuseReason; + + /** + * 关联订单号 + */ + private String linkNumber; + + + @ApiModelProperty(value = "详情") + private List purchaseOrderDetailList; + +} diff --git a/src/main/java/com/soft/vo/QueryProductInventoryVo.java b/src/main/java/com/soft/vo/QueryProductInventoryVo.java new file mode 100644 index 0000000..bde48e5 --- /dev/null +++ b/src/main/java/com/soft/vo/QueryProductInventoryVo.java @@ -0,0 +1,16 @@ +package com.soft.vo; + +import com.soft.utils.PieChartData; +import lombok.Data; + +import java.util.List; + +@Data +public class QueryProductInventoryVo { + + private String msg; + + private String chartType; + + private List pieChartData; // 饼图数据列表 +} diff --git a/src/main/java/com/soft/vo/SaleOrderChartVo.java b/src/main/java/com/soft/vo/SaleOrderChartVo.java new file mode 100644 index 0000000..9577d5e --- /dev/null +++ b/src/main/java/com/soft/vo/SaleOrderChartVo.java @@ -0,0 +1,23 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class SaleOrderChartVo { + + private List list; + + private String chartType; + + private String msg; + + @ApiModelProperty(value = "横轴:客户名称") + private List xAxisData; + + @ApiModelProperty(value = "纵轴:订单金额") + private List yAxisData; +} diff --git a/src/main/java/com/soft/vo/SaleOrderCurrentYearAmountVo.java b/src/main/java/com/soft/vo/SaleOrderCurrentYearAmountVo.java new file mode 100644 index 0000000..406956e --- /dev/null +++ b/src/main/java/com/soft/vo/SaleOrderCurrentYearAmountVo.java @@ -0,0 +1,28 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class SaleOrderCurrentYearAmountVo { + + @ApiModelProperty("年度累计销售额") + private BigDecimal currentYearAmount; + @ApiModelProperty("年度销售数量") + private String saleCount; + @ApiModelProperty("年度销售成本") + private BigDecimal totalPurchasePrice; + @ApiModelProperty("毛利率(百分比格式)") + private String grossMarginPercent; + + @ApiModelProperty("销售额同比增长率") + private String amountGrowthPercent; + @ApiModelProperty("销售数量同比增长率") + private String saleCountGrowthPercent; + @ApiModelProperty("销售成本同比增长率") + private String purchasePriceGrowthPercent; + @ApiModelProperty("毛利率同比增长率") + private String grossMarginGrowthPercent; +} diff --git a/src/main/java/com/soft/vo/SaleOrderGrossMarginVo.java b/src/main/java/com/soft/vo/SaleOrderGrossMarginVo.java new file mode 100644 index 0000000..8dfcdfd --- /dev/null +++ b/src/main/java/com/soft/vo/SaleOrderGrossMarginVo.java @@ -0,0 +1,20 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class SaleOrderGrossMarginVo { + + private String chartType; + + @ApiModelProperty(value = "横轴:月份") + private List xAxisData; //最近12个月 + + @ApiModelProperty(value = "毛利") + private List saleAmounts; // 每个月的毛利 + +} diff --git a/src/main/java/com/soft/vo/SaleOrderLastYearProfitVo.java b/src/main/java/com/soft/vo/SaleOrderLastYearProfitVo.java new file mode 100644 index 0000000..39b98f8 --- /dev/null +++ b/src/main/java/com/soft/vo/SaleOrderLastYearProfitVo.java @@ -0,0 +1,21 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class SaleOrderLastYearProfitVo { + + private String chartType; + + @ApiModelProperty(value = "横轴:月份") + private List xAxisData; //去年月份 + + @ApiModelProperty(value = "毛利") + private List saleAmounts; // 去年每个月的毛利 + + +} diff --git a/src/main/java/com/soft/vo/SaleOrderTotalProfitVo.java b/src/main/java/com/soft/vo/SaleOrderTotalProfitVo.java new file mode 100644 index 0000000..37bf38e --- /dev/null +++ b/src/main/java/com/soft/vo/SaleOrderTotalProfitVo.java @@ -0,0 +1,31 @@ +package com.soft.vo; + +import com.soft.utils.PieChartData; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class SaleOrderTotalProfitVo { + + @ApiModelProperty(value = "利润总和") + private BigDecimal totalProfit; + + @ApiModelProperty(value = "成本") + private BigDecimal cost; + + @ApiModelProperty(value = "营收") + private BigDecimal revenue; + + private String chartType; + + private String msg; + + private List pieChartData; // 饼图数据列表 + + // private List marginChartData; + + +} diff --git a/src/main/java/com/soft/vo/SaleOrderVo.java b/src/main/java/com/soft/vo/SaleOrderVo.java new file mode 100644 index 0000000..fc3ee9c --- /dev/null +++ b/src/main/java/com/soft/vo/SaleOrderVo.java @@ -0,0 +1,155 @@ +package com.soft.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.soft.entitys.voice.SaleOrderDetail; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +@Data +public class SaleOrderVo { + + private String id; + + /** + * 单号 + */ + private String code; + + /** + * 仓库ID + */ + private String scId; + + /** + * 客户ID + */ + private String customerId; + + /** + * 销售员ID + */ + private String salerId; + + /** + * 销售员 + */ + private String salerName; + + /** + * 销售数量 + */ + private Integer totalNum; + + /** + * 赠品数量 + */ + private Integer totalGiftNum; + + /** + * 销售金额 + */ + private BigDecimal totalAmount; + + /** + * 备注 + */ + private String description; + + + private String createById; + + /** + * 创建人 新增时赋值 + */ + + private String createBy; + + + private Date createTime; + + /** + * 修改人 新增和修改时赋值 + */ + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + + private Date updateTime; + + /** + * 审核人 + */ + private String approveBy; + + /** + * 审核时间 + */ + private Date approveTime; + + /** + * 拒绝原因 + */ + private String refuseReason; + + /** + * 本单利润 + */ + private BigDecimal thisOrderProfit; + + /** + * 客户费用 + */ + private BigDecimal customMoney; + + /** + * 采购价 + */ + private BigDecimal purchaseDecimal; + + /** + * 采购总价 + */ + private BigDecimal totalPurchasePrice; + + /** + * 运费 + */ + private BigDecimal shippingFee; + + /** + * 是否租赁订单 + */ + private Integer isLease; + + + private Integer purchaseStatus; + + /** + * 租赁起始日期 + */ + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date leaseStartTime; + + /** + * 租赁结束日期 + */ + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date leaseEndTime; + + @ApiModelProperty(value = "详情") + private List saleOrderDetailList; +} diff --git a/src/main/java/com/soft/vo/SaleOutSheetChartVo.java b/src/main/java/com/soft/vo/SaleOutSheetChartVo.java new file mode 100644 index 0000000..9a7fc56 --- /dev/null +++ b/src/main/java/com/soft/vo/SaleOutSheetChartVo.java @@ -0,0 +1,15 @@ +package com.soft.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class SaleOutSheetChartVo { + + private List list; + + private String chartType; + + private String msg; +} diff --git a/src/main/java/com/soft/vo/SaleOutSheetVo.java b/src/main/java/com/soft/vo/SaleOutSheetVo.java new file mode 100644 index 0000000..5820398 --- /dev/null +++ b/src/main/java/com/soft/vo/SaleOutSheetVo.java @@ -0,0 +1,109 @@ +package com.soft.vo; + +import com.soft.entitys.voice.SaleOutSheetDetail; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +@Data +public class SaleOutSheetVo { + + /** + * ID + */ + private String id; + + /** + * 单号 + */ + private String code; + + /** + * 仓库ID + */ + private String scId; + + /** + * 客户ID + */ + private String customerId; + + /** + * 销售员ID + */ + private String salerId; + + /** + * 付款日期 + */ + private Date paymentDate; + + /** + * 销售单ID + */ + private String saleOrderId; + + /** + * 商品数量 + */ + private Integer totalNum; + + /** + * 赠品数量 + */ + private Integer totalGiftNum; + + /** + * 出库金额 + */ + private BigDecimal totalAmount; + + /** + * 备注 + */ + private String description; + + + private String createById; + + + private String createBy; + + + private Date createTime; + + + private String updateBy; + + + private String updateById; + + + private Date updateTime; + + /** + * 审核人 + */ + private String approveBy; + + /** + * 审核时间 + */ + private Date approveTime; + + /** + * 拒绝原因 + */ + private String refuseReason; + + /** + * 结算状态 + */ + private Integer settleStatus; + + @ApiModelProperty(value = "详情") + private List saleOutSheetDetailList; +} diff --git a/src/main/java/com/soft/vo/SaleSalerRankVo.java b/src/main/java/com/soft/vo/SaleSalerRankVo.java new file mode 100644 index 0000000..d9da1f5 --- /dev/null +++ b/src/main/java/com/soft/vo/SaleSalerRankVo.java @@ -0,0 +1,22 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class SaleSalerRankVo { + + + @ApiModelProperty(value = "销售人员") + private String salerName; + + @ApiModelProperty(value = "销售金额") + private BigDecimal saleAmount; + + public SaleSalerRankVo(String salerName, BigDecimal saleAmount) { + this.salerName=salerName; + this.saleAmount=saleAmount; + } +} diff --git a/src/main/java/com/soft/vo/SaleSalerWeekRankVo.java b/src/main/java/com/soft/vo/SaleSalerWeekRankVo.java new file mode 100644 index 0000000..306f8c3 --- /dev/null +++ b/src/main/java/com/soft/vo/SaleSalerWeekRankVo.java @@ -0,0 +1,21 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class SaleSalerWeekRankVo { + + @ApiModelProperty(value = "销售人员") + private String salerName; + + @ApiModelProperty(value = "销售金额") + private BigDecimal saleAmount; + + public SaleSalerWeekRankVo(String salerName, BigDecimal saleAmount) { + this.salerName=salerName; + this.saleAmount=saleAmount; + } +} diff --git a/src/main/java/com/soft/vo/SettleCheckAccountsPayableVo.java b/src/main/java/com/soft/vo/SettleCheckAccountsPayableVo.java new file mode 100644 index 0000000..b81e495 --- /dev/null +++ b/src/main/java/com/soft/vo/SettleCheckAccountsPayableVo.java @@ -0,0 +1,15 @@ +package com.soft.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class SettleCheckAccountsPayableVo { + + private BigDecimal totalAmount; + + private String chartType; + + private String msg; +} diff --git a/src/main/java/com/soft/vo/SettleSheetPaymentOfFeesVo.java b/src/main/java/com/soft/vo/SettleSheetPaymentOfFeesVo.java new file mode 100644 index 0000000..e5811b0 --- /dev/null +++ b/src/main/java/com/soft/vo/SettleSheetPaymentOfFeesVo.java @@ -0,0 +1,15 @@ +package com.soft.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class SettleSheetPaymentOfFeesVo { + + private BigDecimal totalAmount; + + private String chartType; + + private String msg; +} diff --git a/src/main/java/com/soft/vo/TodaysPurchaseOrderReturnChartVo.java b/src/main/java/com/soft/vo/TodaysPurchaseOrderReturnChartVo.java new file mode 100644 index 0000000..5bd036c --- /dev/null +++ b/src/main/java/com/soft/vo/TodaysPurchaseOrderReturnChartVo.java @@ -0,0 +1,24 @@ +package com.soft.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class TodaysPurchaseOrderReturnChartVo { + + + private List list; + + private String chartType; + + private String msg; + + @ApiModelProperty(value = "横轴:供应商名称") + private List xAxisData; + + @ApiModelProperty(value = "纵轴:订单金额") + private List yAxisData; +} diff --git a/src/main/java/com/soft/vo/TodaysPurchaseOrderReturnVo.java b/src/main/java/com/soft/vo/TodaysPurchaseOrderReturnVo.java new file mode 100644 index 0000000..49d2079 --- /dev/null +++ b/src/main/java/com/soft/vo/TodaysPurchaseOrderReturnVo.java @@ -0,0 +1,118 @@ +package com.soft.vo; + +import com.soft.entitys.voice.PurchaseOrderDetail; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +@Data +public class TodaysPurchaseOrderReturnVo { + + /** + * ID + */ + private String id; + + /** + * 单号 + */ + private String code; + + /** + * 仓库ID + */ + private String scId; + + /** + * 供应商ID + */ + private String supplierId; + + /** + * 采购员ID + */ + private String purchaserId; + + /** + * 付款日期 + */ + private Date paymentDate; + + /** + * 收货单ID + */ + private String receiveSheetId; + + /** + * 商品数量 + */ + private Integer totalNum; + + /** + * 赠品数量 + */ + private Integer totalGiftNum; + + /** + * 退货金额 + */ + private BigDecimal totalAmount; + + /** + * 备注 + */ + private String description; + + /** + * 创建人ID 新增时赋值 + */ + private String createById; + + /** + * 创建人 新增时赋值 + */ + private String createBy; + + /** + * 创建时间 新增时赋值 + */ + private Date createTime; + + /** + * 修改人 新增和修改时赋值 + */ + private String updateBy; + + /** + * 修改人ID 新增和修改时赋值 + */ + private String updateById; + + /** + * 修改时间 新增和修改时赋值 + */ + private Date updateTime; + + /** + * 审核人 + */ + private String approveBy; + + /** + * 审核时间 + */ + private Date approveTime; + + + /** + * 拒绝原因 + */ + private String refuseReason; + + @ApiModelProperty(value = "详情") + private List purchaseOrderDetailList; + +} diff --git a/src/main/java/com/soft/vo/page/PageVo.java b/src/main/java/com/soft/vo/page/PageVo.java new file mode 100644 index 0000000..53a3d4a --- /dev/null +++ b/src/main/java/com/soft/vo/page/PageVo.java @@ -0,0 +1,82 @@ +package com.soft.vo.page; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +public abstract class PageVo implements Serializable { + private static final long serialVersionUID = 1L; + @ApiModelProperty( + value = "当前页码", + required = true + ) + private Integer pageIndex; + @ApiModelProperty( + value = "每页条数", + required = true + ) + private Integer pageSize; + + public PageVo() { + } + + public Integer getPageIndex() { + return this.pageIndex; + } + + public Integer getPageSize() { + return this.pageSize; + } + + public void setPageIndex(Integer pageIndex) { + this.pageIndex = pageIndex; + } + + public void setPageSize(Integer pageSize) { + this.pageSize = pageSize; + } + + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (!(o instanceof PageVo)) { + return false; + } else { + PageVo other = (PageVo)o; + if (!other.canEqual(this)) { + return false; + } else { + Object this$pageIndex = this.getPageIndex(); + Object other$pageIndex = other.getPageIndex(); + if (this$pageIndex == null) { + if (other$pageIndex != null) { + return false; + } + } else if (!this$pageIndex.equals(other$pageIndex)) { + return false; + } + + Object this$pageSize = this.getPageSize(); + Object other$pageSize = other.getPageSize(); + if (this$pageSize == null) { + if (other$pageSize != null) { + return false; + } + } else if (!this$pageSize.equals(other$pageSize)) { + return false; + } + + return true; + } + } + } + + protected boolean canEqual(Object other) { + return other instanceof PageVo; + } + + public String toString() { + return "PageVo(pageIndex=" + this.getPageIndex() + ", pageSize=" + this.getPageSize() + ")"; + } +} + diff --git a/src/main/java/com/soft/vo/sale/QuerySaleOrderVo.java b/src/main/java/com/soft/vo/sale/QuerySaleOrderVo.java new file mode 100644 index 0000000..5dd7396 --- /dev/null +++ b/src/main/java/com/soft/vo/sale/QuerySaleOrderVo.java @@ -0,0 +1,20 @@ +package com.soft.vo.sale; + +import com.soft.vo.page.PageVo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +@Data +@EqualsAndHashCode(callSuper = false) +public class QuerySaleOrderVo extends PageVo { + + private static final long serialVersionUID = 1L; + /** + * 状态 + */ + @ApiModelProperty("订单审核状态(0-待审核,3-审核通过,6-审核拒绝)") + private Integer status; +} + diff --git a/src/main/resources/IKAnalyzer.cfg.xml b/src/main/resources/IKAnalyzer.cfg.xml new file mode 100644 index 0000000..787bf87 --- /dev/null +++ b/src/main/resources/IKAnalyzer.cfg.xml @@ -0,0 +1,9 @@ + + + IK Analyzer 扩展配置 + + ext.dic; + + + + \ No newline at end of file diff --git a/src/main/resources/application-pro.yml b/src/main/resources/application-pro.yml new file mode 100644 index 0000000..116650a --- /dev/null +++ b/src/main/resources/application-pro.yml @@ -0,0 +1,49 @@ +server: + port: 8088 + servlet: + context-path: /soft + + +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://114.67.216.129:3306/voice?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useAffectedRows=true&serverTimezone=Asia/Shanghai + username: root + password: xinan123 +# url: jdbc:mysql://114.67.216.129:3306/voice?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useAffectedRows=true&serverTimezone=Asia/Shanghai +# username: root +# password: xinan123 + redis: + host: 127.0.0.1 + port: 6379 + password: + jedis: + pool: + max-idle: 300 + max-wait: -1 + min-idle: 20 + max-active: 500 + database: 4 + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + +mybatis-plus: + mapper-locations: classpath:mapper/*.xml + type-aliases-package: com.soft.entitys + global-config: + db-config: + logic-delete-value: 0 + logic-not-delete-value: 1 + id-type: auto + +logging: + level: + com: + soft: + mapper: debug #开启mybatis日志 + + + diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml new file mode 100644 index 0000000..e33aaf7 --- /dev/null +++ b/src/main/resources/application-test.yml @@ -0,0 +1,52 @@ +server: + port: 8088 + servlet: + context-path: /soft + + +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://127.0.0.1:3306/xingyun?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useAffectedRows=true&serverTimezone=Asia/Shanghai + username: root + password: root +# url: jdbc:mysql://114.67.216.129:3306/voice?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useAffectedRows=true&serverTimezone=Asia/Shanghai +# username: root +# password: xinan123 + redis: + host: 127.0.0.1 + port: 6379 + password: 123456 + jedis: + pool: + max-idle: 300 + max-wait: -1 + min-idle: 20 + max-active: 500 + database: 4 + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + +mybatis-plus: + mapper-locations: classpath:mapper/*.xml + type-aliases-package: com.soft.entitys + global-config: + db-config: + logic-delete-value: 0 + logic-not-delete-value: 1 + id-type: auto + +logging: + level: + com: + soft: + mapper: debug #开启mybatis日志 + + + + + + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..00714d3 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + profiles: + active: pro + + security: + user: + name: ${SWAGGER_USER:admin} + password: ${SWAGGER_PASSWORD:123456} \ No newline at end of file diff --git a/src/main/resources/ext.dic b/src/main/resources/ext.dic new file mode 100644 index 0000000..2cbf901 --- /dev/null +++ b/src/main/resources/ext.dic @@ -0,0 +1,4 @@ +鸭 +鸡 +鱼 +提 diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..7904d1c --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,95 @@ + + + ${APP_NAME} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + ${CONSOLE_LOG_PATTERN} + UTF-8 + + + + + + ${LOG_FILE}/${APP_NAME}.log + + + ${CONSOLE_LOG_PATTERN_NO_COLOR} + UTF-8 + + + + ${LOG_FILE}/${APP_NAME}.%d{yyyy-MM-dd}.%i.log + + ${LOG_FILE_MAX_HISTORY} + + ${LOG_FILE_MAX_SIZE} + + + + INFO + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/mapper/AgentMapper.xml b/src/main/resources/mapper/AgentMapper.xml new file mode 100644 index 0000000..e7be844 --- /dev/null +++ b/src/main/resources/mapper/AgentMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + diff --git a/src/main/resources/mapper/CategoryMapper.xml b/src/main/resources/mapper/CategoryMapper.xml new file mode 100644 index 0000000..2b887c4 --- /dev/null +++ b/src/main/resources/mapper/CategoryMapper.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/src/main/resources/mapper/CustomerMapper.xml b/src/main/resources/mapper/CustomerMapper.xml new file mode 100644 index 0000000..b7d7e9a --- /dev/null +++ b/src/main/resources/mapper/CustomerMapper.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/src/main/resources/mapper/DemandMapper.xml b/src/main/resources/mapper/DemandMapper.xml new file mode 100644 index 0000000..a250353 --- /dev/null +++ b/src/main/resources/mapper/DemandMapper.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/main/resources/mapper/OrderChartMapper.xml b/src/main/resources/mapper/OrderChartMapper.xml new file mode 100644 index 0000000..b0283eb --- /dev/null +++ b/src/main/resources/mapper/OrderChartMapper.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/OrderPayTypeMapper.xml b/src/main/resources/mapper/OrderPayTypeMapper.xml new file mode 100644 index 0000000..b235b8f --- /dev/null +++ b/src/main/resources/mapper/OrderPayTypeMapper.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/ProductMapper.xml b/src/main/resources/mapper/ProductMapper.xml new file mode 100644 index 0000000..14dc44b --- /dev/null +++ b/src/main/resources/mapper/ProductMapper.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + diff --git a/src/main/resources/mapper/ProductStockLogMapper.xml b/src/main/resources/mapper/ProductStockLogMapper.xml new file mode 100644 index 0000000..d627c14 --- /dev/null +++ b/src/main/resources/mapper/ProductStockLogMapper.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/main/resources/mapper/ProductStockMapper.xml b/src/main/resources/mapper/ProductStockMapper.xml new file mode 100644 index 0000000..81282f9 --- /dev/null +++ b/src/main/resources/mapper/ProductStockMapper.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/src/main/resources/mapper/PurchaseOrderDetailMapper.xml b/src/main/resources/mapper/PurchaseOrderDetailMapper.xml new file mode 100644 index 0000000..e9d934f --- /dev/null +++ b/src/main/resources/mapper/PurchaseOrderDetailMapper.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/src/main/resources/mapper/PurchaseOrderMapper.xml b/src/main/resources/mapper/PurchaseOrderMapper.xml new file mode 100644 index 0000000..2fb59fe --- /dev/null +++ b/src/main/resources/mapper/PurchaseOrderMapper.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/mapper/PurchaseReturnDetailMapper.xml b/src/main/resources/mapper/PurchaseReturnDetailMapper.xml new file mode 100644 index 0000000..aee1944 --- /dev/null +++ b/src/main/resources/mapper/PurchaseReturnDetailMapper.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/src/main/resources/mapper/PurchaseReturnMapper.xml b/src/main/resources/mapper/PurchaseReturnMapper.xml new file mode 100644 index 0000000..326f5f5 --- /dev/null +++ b/src/main/resources/mapper/PurchaseReturnMapper.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/src/main/resources/mapper/SaleOrderDetailBundleMapper.xml b/src/main/resources/mapper/SaleOrderDetailBundleMapper.xml new file mode 100644 index 0000000..c0f6555 --- /dev/null +++ b/src/main/resources/mapper/SaleOrderDetailBundleMapper.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/SaleOrderDetailMapper.xml b/src/main/resources/mapper/SaleOrderDetailMapper.xml new file mode 100644 index 0000000..f80d891 --- /dev/null +++ b/src/main/resources/mapper/SaleOrderDetailMapper.xml @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/src/main/resources/mapper/SaleOrderMapper.xml b/src/main/resources/mapper/SaleOrderMapper.xml new file mode 100644 index 0000000..faaa517 --- /dev/null +++ b/src/main/resources/mapper/SaleOrderMapper.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPDATE tbl_sale_order + SET + approve_by = #{sysUserId}, + approve_time = #{now} + WHERE + id = #{id} + AND status IN + + #{status} + + + + + diff --git a/src/main/resources/mapper/SaleOutSheetDetailMapper.xml b/src/main/resources/mapper/SaleOutSheetDetailMapper.xml new file mode 100644 index 0000000..00816d6 --- /dev/null +++ b/src/main/resources/mapper/SaleOutSheetDetailMapper.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/src/main/resources/mapper/SaleOutSheetMapper.xml b/src/main/resources/mapper/SaleOutSheetMapper.xml new file mode 100644 index 0000000..b1838af --- /dev/null +++ b/src/main/resources/mapper/SaleOutSheetMapper.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/main/resources/mapper/SettleCheckSheetDetailMapper.xml b/src/main/resources/mapper/SettleCheckSheetDetailMapper.xml new file mode 100644 index 0000000..58334c0 --- /dev/null +++ b/src/main/resources/mapper/SettleCheckSheetDetailMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/resources/mapper/SettleCheckSheetMapper.xml b/src/main/resources/mapper/SettleCheckSheetMapper.xml new file mode 100644 index 0000000..bff77b8 --- /dev/null +++ b/src/main/resources/mapper/SettleCheckSheetMapper.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/main/resources/mapper/SettleSheetDetailMapper.xml b/src/main/resources/mapper/SettleSheetDetailMapper.xml new file mode 100644 index 0000000..59c606a --- /dev/null +++ b/src/main/resources/mapper/SettleSheetDetailMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/resources/mapper/SettleSheetMapper.xml b/src/main/resources/mapper/SettleSheetMapper.xml new file mode 100644 index 0000000..2e8595f --- /dev/null +++ b/src/main/resources/mapper/SettleSheetMapper.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/src/main/resources/mapper/StoreCenterMapper.xml b/src/main/resources/mapper/StoreCenterMapper.xml new file mode 100644 index 0000000..2ae5f63 --- /dev/null +++ b/src/main/resources/mapper/StoreCenterMapper.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/src/main/resources/mapper/SupplierMapper.xml b/src/main/resources/mapper/SupplierMapper.xml new file mode 100644 index 0000000..78f7198 --- /dev/null +++ b/src/main/resources/mapper/SupplierMapper.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/src/main/resources/mapper/SysMenuMapper.xml b/src/main/resources/mapper/SysMenuMapper.xml new file mode 100644 index 0000000..59b6d02 --- /dev/null +++ b/src/main/resources/mapper/SysMenuMapper.xml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/SysRoleMenuMapper.xml b/src/main/resources/mapper/SysRoleMenuMapper.xml new file mode 100644 index 0000000..6fdb0f4 --- /dev/null +++ b/src/main/resources/mapper/SysRoleMenuMapper.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/SysUserMapper.xml b/src/main/resources/mapper/SysUserMapper.xml new file mode 100644 index 0000000..301834a --- /dev/null +++ b/src/main/resources/mapper/SysUserMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + diff --git a/src/main/resources/mapper/SysUserRoleMapper.xml b/src/main/resources/mapper/SysUserRoleMapper.xml new file mode 100644 index 0000000..10cebb7 --- /dev/null +++ b/src/main/resources/mapper/SysUserRoleMapper.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/UserMapper.xml b/src/main/resources/mapper/UserMapper.xml new file mode 100644 index 0000000..83f084b --- /dev/null +++ b/src/main/resources/mapper/UserMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + diff --git a/src/test/java/com/soft/Test.java b/src/test/java/com/soft/Test.java new file mode 100644 index 0000000..a00dce2 --- /dev/null +++ b/src/test/java/com/soft/Test.java @@ -0,0 +1,10 @@ +package com.soft; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Test { + + +}