From 9fc6e0f00b7f795e7843e8613f161f84d4a1d528 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Fri, 9 Dec 2022 13:43:15 +0800 Subject: [PATCH 01/59] =?UTF-8?q?refactor:=20springdoc=20=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=20springfox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-dependencies/pom.xml | 35 +++--- yudao-framework/yudao-common/pom.xml | 10 +- .../framework/common/pojo/PageParam.java | 9 +- .../framework/common/pojo/PageResult.java | 10 +- .../core/annotations/OperateLog.java | 4 +- .../operatelog/core/aop/OperateLogAspect.java | 50 ++++---- .../yudao-spring-boot-starter-web/pom.xml | 17 +-- .../config/YudaoSwaggerAutoConfiguration.java | 119 +++++------------- ...ngFoxHandlerProviderBeanPostProcessor.java | 86 ++++++------- .../admin/definition/BpmFormController.java | 24 ++-- .../admin/definition/BpmModelController.java | 30 ++--- .../BpmProcessDefinitionController.java | 16 +-- .../BpmTaskAssignRuleController.java | 22 ++-- .../definition/BpmUserGroupController.java | 24 ++-- .../definition/vo/form/BpmFormBaseVO.java | 9 +- .../vo/form/BpmFormCreateReqVO.java | 9 +- .../definition/vo/form/BpmFormPageReqVO.java | 7 +- .../definition/vo/form/BpmFormRespVO.java | 14 +-- .../vo/form/BpmFormSimpleRespVO.java | 9 +- .../vo/form/BpmFormUpdateReqVO.java | 11 +- .../vo/group/BpmUserGroupBaseVO.java | 11 +- .../vo/group/BpmUserGroupCreateReqVO.java | 5 +- .../vo/group/BpmUserGroupPageReqVO.java | 11 +- .../vo/group/BpmUserGroupRespVO.java | 9 +- .../vo/group/BpmUserGroupSimpleRespVO.java | 9 +- .../vo/group/BpmUserGroupUpdateReqVO.java | 7 +- .../vo/model/BpmModeImportReqVO.java | 7 +- .../definition/vo/model/BpmModelBaseVO.java | 23 ++-- .../vo/model/BpmModelCreateReqVO.java | 11 +- .../vo/model/BpmModelPageItemRespVO.java | 21 ++-- .../vo/model/BpmModelPageReqVO.java | 11 +- .../definition/vo/model/BpmModelRespVO.java | 11 +- .../vo/model/BpmModelUpdateReqVO.java | 27 ++-- .../vo/model/BpmModelUpdateStateReqVO.java | 9 +- .../BpmProcessDefinitionListReqVO.java | 7 +- .../BpmProcessDefinitionPageItemRespVO.java | 9 +- .../BpmProcessDefinitionPageReqVO.java | 7 +- .../process/BpmProcessDefinitionRespVO.java | 37 +++--- .../vo/rule/BpmTaskAssignRuleBaseVO.java | 7 +- .../vo/rule/BpmTaskAssignRuleCreateReqVO.java | 9 +- .../vo/rule/BpmTaskAssignRuleRespVO.java | 15 ++- .../vo/rule/BpmTaskAssignRuleUpdateReqVO.java | 7 +- .../admin/oa/BpmOALeaveController.java | 16 +-- .../admin/oa/vo/BpmOALeaveBaseVO.java | 11 +- .../admin/oa/vo/BpmOALeaveCreateReqVO.java | 5 +- .../admin/oa/vo/BpmOALeavePageReqVO.java | 13 +- .../admin/oa/vo/BpmOALeaveRespVO.java | 13 +- .../admin/task/BpmActivityController.java | 14 +-- .../task/BpmProcessInstanceController.java | 18 +-- .../admin/task/BpmTaskController.java | 22 ++-- .../task/vo/activity/BpmActivityRespVO.java | 15 ++- .../BpmProcessInstanceCancelReqVO.java | 9 +- .../BpmProcessInstanceCreateReqVO.java | 9 +- .../BpmProcessInstanceMyPageReqVO.java | 17 ++- .../BpmProcessInstancePageItemRespVO.java | 27 ++-- .../vo/instance/BpmProcessInstanceRespVO.java | 59 +++++---- .../task/vo/task/BpmTaskApproveReqVO.java | 9 +- .../vo/task/BpmTaskDonePageItemRespVO.java | 13 +- .../task/vo/task/BpmTaskDonePageReqVO.java | 11 +- .../task/vo/task/BpmTaskRejectReqVO.java | 9 +- .../admin/task/vo/task/BpmTaskRespVO.java | 17 ++- .../vo/task/BpmTaskTodoPageItemRespVO.java | 27 ++-- .../task/vo/task/BpmTaskTodoPageReqVO.java | 11 +- .../vo/task/BpmTaskUpdateAssigneeReqVO.java | 9 +- .../admin/codegen/CodegenController.java | 46 +++---- .../codegen/vo/CodegenCreateListReqVO.java | 9 +- .../admin/codegen/vo/CodegenDetailRespVO.java | 9 +- .../codegen/vo/CodegenPreviewRespVO.java | 9 +- .../admin/codegen/vo/CodegenUpdateReqVO.java | 13 +- .../vo/column/CodegenColumnBaseVO.java | 39 +++--- .../vo/column/CodegenColumnRespVO.java | 9 +- .../codegen/vo/table/CodegenTableBaseVO.java | 25 ++-- .../vo/table/CodegenTablePageReqVO.java | 11 +- .../codegen/vo/table/CodegenTableRespVO.java | 13 +- .../codegen/vo/table/DatabaseTableRespVO.java | 9 +- .../admin/config/ConfigController.java | 28 ++--- .../admin/config/vo/ConfigBaseVO.java | 13 +- .../admin/config/vo/ConfigCreateReqVO.java | 7 +- .../admin/config/vo/ConfigExportReqVO.java | 13 +- .../admin/config/vo/ConfigPageReqVO.java | 13 +- .../admin/config/vo/ConfigRespVO.java | 13 +- .../admin/config/vo/ConfigUpdateReqVO.java | 7 +- .../admin/db/DataSourceConfigController.java | 22 ++-- .../admin/db/DatabaseDocController.java | 23 ++-- .../admin/db/vo/DataSourceConfigBaseVO.java | 10 +- .../db/vo/DataSourceConfigCreateReqVO.java | 8 +- .../admin/db/vo/DataSourceConfigRespVO.java | 9 +- .../db/vo/DataSourceConfigUpdateReqVO.java | 10 +- .../admin/file/FileConfigController.java | 26 ++-- .../controller/admin/file/FileController.java | 20 +-- .../file/vo/config/FileConfigBaseVO.java | 7 +- .../file/vo/config/FileConfigCreateReqVO.java | 9 +- .../file/vo/config/FileConfigPageReqVO.java | 11 +- .../file/vo/config/FileConfigRespVO.java | 15 ++- .../file/vo/config/FileConfigUpdateReqVO.java | 9 +- .../admin/file/vo/file/FilePageReqVO.java | 11 +- .../admin/file/vo/file/FileRespVO.java | 21 ++-- .../admin/file/vo/file/FileUploadReqVO.java | 9 +- .../controller/admin/job/JobController.java | 50 ++++---- .../admin/job/JobLogController.java | 20 +-- .../admin/job/vo/job/JobBaseVO.java | 15 ++- .../admin/job/vo/job/JobCreateReqVO.java | 7 +- .../admin/job/vo/job/JobExportReqVO.java | 11 +- .../admin/job/vo/job/JobPageReqVO.java | 11 +- .../admin/job/vo/job/JobRespVO.java | 13 +- .../admin/job/vo/job/JobUpdateReqVO.java | 7 +- .../admin/job/vo/log/JobLogBaseVO.java | 21 ++-- .../admin/job/vo/log/JobLogExportReqVO.java | 15 ++- .../admin/job/vo/log/JobLogPageReqVO.java | 15 ++- .../admin/job/vo/log/JobLogRespVO.java | 9 +- .../admin/logger/ApiAccessLogController.java | 10 +- .../admin/logger/ApiErrorLogController.java | 22 ++-- .../vo/apiaccesslog/ApiAccessLogBaseVO.java | 31 +++-- .../apiaccesslog/ApiAccessLogExportReqVO.java | 19 ++- .../apiaccesslog/ApiAccessLogPageReqVO.java | 19 ++- .../vo/apiaccesslog/ApiAccessLogRespVO.java | 9 +- .../vo/apierrorlog/ApiErrorLogBaseVO.java | 41 +++--- .../apierrorlog/ApiErrorLogExportReqVO.java | 17 ++- .../vo/apierrorlog/ApiErrorLogPageReqVO.java | 17 ++- .../vo/apierrorlog/ApiErrorLogRespVO.java | 13 +- .../admin/redis/RedisController.java | 28 ++--- .../admin/redis/vo/RedisKeyDefineRespVO.java | 17 ++- .../admin/redis/vo/RedisKeyValueRespVO.java | 9 +- .../admin/redis/vo/RedisMonitorRespVO.java | 19 ++- .../admin/test/TestDemoController.java | 28 ++--- .../admin/test/vo/TestDemoBaseVO.java | 14 +-- .../admin/test/vo/TestDemoCreateReqVO.java | 5 +- .../admin/test/vo/TestDemoExportReqVO.java | 17 ++- .../admin/test/vo/TestDemoPageReqVO.java | 17 ++- .../admin/test/vo/TestDemoRespVO.java | 9 +- .../admin/test/vo/TestDemoUpdateReqVO.java | 7 +- .../config/SecurityConfiguration.java | 4 +- .../codegen/java/controller/controller.vm | 22 ++-- .../codegen/java/controller/vo/_column.vm | 2 +- .../codegen/java/controller/vo/createReqVO.vm | 2 +- .../codegen/java/controller/vo/exportReqVO.vm | 6 +- .../codegen/java/controller/vo/pageReqVO.vm | 6 +- .../codegen/java/controller/vo/respVO.vm | 4 +- .../codegen/java/controller/vo/updateReqVO.vm | 2 +- .../admin/brand/ProductBrandController.java | 24 ++-- .../admin/brand/vo/ProductBrandBaseVO.java | 13 +- .../brand/vo/ProductBrandCreateReqVO.java | 5 +- .../admin/brand/vo/ProductBrandListReqVO.java | 7 +- .../admin/brand/vo/ProductBrandPageReqVO.java | 11 +- .../admin/brand/vo/ProductBrandRespVO.java | 9 +- .../brand/vo/ProductBrandUpdateReqVO.java | 7 +- .../category/ProductCategoryController.java | 22 ++-- .../category/vo/ProductCategoryBaseVO.java | 15 ++- .../vo/ProductCategoryCreateReqVO.java | 5 +- .../category/vo/ProductCategoryListReqVO.java | 7 +- .../category/vo/ProductCategoryRespVO.java | 9 +- .../vo/ProductCategoryUpdateReqVO.java | 7 +- .../property/ProductPropertyController.java | 26 ++-- .../ProductPropertyValueController.java | 22 ++-- .../vo/ProductPropertyViewRespVO.java | 13 +- .../ProductPropertyAndValueRespVO.java | 9 +- .../vo/property/ProductPropertyBaseVO.java | 9 +- .../property/ProductPropertyCreateReqVO.java | 5 +- .../vo/property/ProductPropertyListReqVO.java | 9 +- .../vo/property/ProductPropertyPageReqVO.java | 11 +- .../vo/property/ProductPropertyRespVO.java | 9 +- .../property/ProductPropertyUpdateReqVO.java | 9 +- .../vo/value/ProductPropertyValueBaseVO.java | 11 +- .../ProductPropertyValueCreateReqVO.java | 5 +- .../value/ProductPropertyValuePageReqVO.java | 11 +- .../vo/value/ProductPropertyValueRespVO.java | 9 +- .../ProductPropertyValueUpdateReqVO.java | 7 +- .../admin/sku/ProductSkuController.java | 8 +- .../admin/sku/vo/ProductSkuBaseVO.java | 31 +++-- .../sku/vo/ProductSkuCreateOrUpdateReqVO.java | 7 +- .../admin/sku/vo/ProductSkuOptionRespVO.java | 17 ++- .../admin/sku/vo/ProductSkuRespVO.java | 9 +- .../admin/spu/ProductSpuController.java | 32 ++--- .../admin/spu/vo/ProductSpuBaseVO.java | 40 +++--- .../admin/spu/vo/ProductSpuCreateReqVO.java | 4 +- .../admin/spu/vo/ProductSpuDetailRespVO.java | 21 ++-- .../admin/spu/vo/ProductSpuPageReqVO.java | 25 ++-- .../admin/spu/vo/ProductSpuRespVO.java | 9 +- .../admin/spu/vo/ProductSpuSimpleRespVO.java | 13 +- .../admin/spu/vo/ProductSpuUpdateReqVO.java | 7 +- .../app/category/AppCategoryController.java | 8 +- .../app/category/vo/AppCategoryRespVO.java | 13 +- .../app/spu/AppProductSpuController.java | 10 +- .../app/spu/vo/AppSpuPageReqVO.java | 7 +- .../app/spu/vo/AppSpuPageRespVO.java | 27 ++-- .../controller/app/spu/vo/AppSpuRespVO.java | 4 +- .../admin/banner/BannerController.java | 22 ++-- .../admin/banner/vo/BannerBaseVO.java | 14 +-- .../admin/banner/vo/BannerCreateReqVO.java | 5 +- .../admin/banner/vo/BannerPageReqVO.java | 11 +- .../admin/banner/vo/BannerRespVO.java | 9 +- .../admin/banner/vo/BannerUpdateReqVO.java | 7 +- .../admin/coupon/CouponController.java | 18 +-- .../coupon/CouponTemplateController.java | 24 ++-- .../admin/coupon/vo/coupon/CouponBaseVO.java | 34 ++--- .../vo/coupon/CouponPageItemRespVO.java | 7 +- .../coupon/vo/coupon/CouponPageReqVO.java | 13 +- .../admin/coupon/vo/coupon/CouponRespVO.java | 9 +- .../vo/template/CouponTemplateBaseVO.java | 34 ++--- .../template/CouponTemplateCreateReqVO.java | 5 +- .../vo/template/CouponTemplatePageReqVO.java | 13 +- .../vo/template/CouponTemplateRespVO.java | 15 ++- .../template/CouponTemplateUpdateReqVO.java | 7 +- .../CouponTemplateUpdateStatusReqVO.java | 9 +- .../discount/DiscountActivityController.java | 26 ++-- .../discount/vo/DiscountActivityBaseVO.java | 23 ++-- .../vo/DiscountActivityCreateReqVO.java | 5 +- .../vo/DiscountActivityDetailRespVO.java | 5 +- .../vo/DiscountActivityPageReqVO.java | 11 +- .../discount/vo/DiscountActivityRespVO.java | 11 +- .../vo/DiscountActivityUpdateReqVO.java | 7 +- .../reward/RewardActivityController.java | 26 ++-- .../admin/reward/vo/RewardActivityBaseVO.java | 31 +++-- .../reward/vo/RewardActivityCreateReqVO.java | 5 +- .../reward/vo/RewardActivityPageReqVO.java | 9 +- .../admin/reward/vo/RewardActivityRespVO.java | 11 +- .../reward/vo/RewardActivityUpdateReqVO.java | 7 +- .../app/AppMarketTestController.java | 8 +- .../app/banner/AppBannerController.java | 8 +- .../AppProductPropertyValueDetailRespVO.java | 13 +- .../app/base/sku/AppProductSkuBaseRespVO.java | 10 +- .../app/base/spu/AppProductSpuBaseRespVO.java | 9 +- .../app/cart/TradeCartController.java | 22 ++-- .../app/cart/vo/AppTradeCartDetailRespVO.java | 49 ++++---- .../vo/AppTradeCartItemAddCountReqVO.java | 9 +- .../vo/AppTradeCartItemUpdateCountReqVO.java | 9 +- .../AppTradeCartItemUpdateSelectedReqVO.java | 9 +- .../app/order/AppTradeOrderController.java | 18 +-- .../order/vo/AppTradeOrderCreateReqVO.java | 19 ++- .../vo/AppTradeOrderGetCreateInfoRespVO.java | 15 ++- .../app/order/vo/TradeOrderItemRespVO.java | 43 ++++--- .../app/order/vo/TradeOrderPageReqVO.java | 7 +- .../app/order/vo/TradeOrderRespVO.java | 55 ++++---- .../yudao-module-member-biz/pom.xml | 5 + .../app/address/AppAddressController.java | 24 ++-- .../app/address/vo/AppAddressBaseVO.java | 15 ++- .../app/address/vo/AppAddressCreateReqVO.java | 7 +- .../app/address/vo/AppAddressRespVO.java | 9 +- .../app/address/vo/AppAddressUpdateReqVO.java | 8 +- .../app/auth/AppAuthController.java | 38 +++--- .../app/auth/vo/AppAuthCheckCodeReqVO.java | 11 +- .../app/auth/vo/AppAuthLoginReqVO.java | 15 ++- .../app/auth/vo/AppAuthLoginRespVO.java | 13 +- .../auth/vo/AppAuthResetPasswordReqVO.java | 11 +- .../app/auth/vo/AppAuthSmsLoginReqVO.java | 15 ++- .../app/auth/vo/AppAuthSmsSendReqVO.java | 9 +- .../app/auth/vo/AppAuthSocialLoginReqVO.java | 11 +- .../auth/vo/AppAuthUpdatePasswordReqVO.java | 9 +- .../vo/AppAuthWeixinMiniAppLoginReqVO.java | 9 +- .../app/social/AppSocialUserController.java | 10 +- .../app/social/vo/AppSocialUserBindReqVO.java | 11 +- .../social/vo/AppSocialUserUnbindReqVO.java | 9 +- .../app/user/AppUserController.java | 14 +-- .../app/user/vo/AppUserInfoRespVO.java | 11 +- .../app/user/vo/AppUserUpdateMobileReqVO.java | 13 +- .../app/weixin/AppWxMpController.java | 10 +- .../admin/merchant/PayAppController.java | 34 ++--- .../admin/merchant/PayChannelController.java | 48 +++---- .../admin/merchant/PayMerchantController.java | 34 ++--- .../admin/merchant/vo/app/PayAppBaseVO.java | 15 ++- .../merchant/vo/app/PayAppCreateReqVO.java | 5 +- .../merchant/vo/app/PayAppExportReqVO.java | 19 ++- .../merchant/vo/app/PayAppPageItemRespVO.java | 17 ++- .../merchant/vo/app/PayAppPageReqVO.java | 19 ++- .../admin/merchant/vo/app/PayAppRespVO.java | 9 +- .../merchant/vo/app/PayAppUpdateReqVO.java | 7 +- .../vo/app/PayAppUpdateStatusReqVO.java | 9 +- .../merchant/vo/channel/PayChannelBaseVO.java | 15 ++- .../vo/channel/PayChannelCreateReqVO.java | 7 +- .../vo/channel/PayChannelExportReqVO.java | 21 ++-- .../vo/channel/PayChannelPageReqVO.java | 21 ++-- .../merchant/vo/channel/PayChannelRespVO.java | 11 +- .../vo/channel/PayChannelUpdateReqVO.java | 9 +- .../vo/merchant/PayMerchantBaseVO.java | 11 +- .../vo/merchant/PayMerchantCreateReqVO.java | 5 +- .../vo/merchant/PayMerchantExportReqVO.java | 17 ++- .../vo/merchant/PayMerchantPageReqVO.java | 17 ++- .../vo/merchant/PayMerchantRespVO.java | 11 +- .../vo/merchant/PayMerchantUpdateReqVO.java | 7 +- .../PayMerchantUpdateStatusReqVO.java | 9 +- .../admin/order/PayOrderController.java | 16 +-- .../admin/order/vo/PayOrderBaseVO.java | 49 ++++---- .../admin/order/vo/PayOrderDetailsRespVO.java | 21 ++-- .../admin/order/vo/PayOrderExportReqVO.java | 53 ++++---- .../order/vo/PayOrderPageItemRespVO.java | 17 ++- .../admin/order/vo/PayOrderPageReqVO.java | 53 ++++---- .../admin/order/vo/PayOrderRespVO.java | 9 +- .../admin/refund/PayRefundController.java | 16 +-- .../admin/refund/vo/PayRefundBaseVO.java | 51 ++++---- .../admin/refund/vo/PayRefundCreateReqVO.java | 5 +- .../refund/vo/PayRefundDetailsRespVO.java | 17 ++- .../admin/refund/vo/PayRefundExportReqVO.java | 55 ++++---- .../refund/vo/PayRefundPageItemRespVO.java | 15 ++- .../admin/refund/vo/PayRefundPageReqVO.java | 55 ++++---- .../admin/refund/vo/PayRefundRespVO.java | 9 +- .../admin/refund/vo/PayRefundUpdateReqVO.java | 7 +- .../app/order/AppPayOrderController.java | 14 +-- .../app/order/vo/AppPayOrderSubmitReqVO.java | 11 +- .../app/order/vo/AppPayOrderSubmitRespVO.java | 4 +- .../app/refund/AppPayRefundController.java | 8 +- .../app/refund/vo/AppPayRefundReqVO.java | 13 +- .../app/refund/vo/AppPayRefundRespVO.java | 7 +- .../notify/vo/PayNotifyOrderReqVO.java | 9 +- .../notify/vo/PayRefundOrderReqVO.java | 11 +- .../yudao-module-system-biz/pom.xml | 5 + .../controller/admin/auth/AuthController.java | 36 +++--- .../admin/auth/vo/AuthLoginReqVO.java | 19 ++- .../admin/auth/vo/AuthLoginRespVO.java | 13 +- .../admin/auth/vo/AuthMenuRespVO.java | 21 ++-- .../auth/vo/AuthPermissionInfoRespVO.java | 19 ++- .../admin/auth/vo/AuthSmsLoginReqVO.java | 9 +- .../admin/auth/vo/AuthSmsSendReqVO.java | 9 +- .../admin/auth/vo/AuthSocialLoginReqVO.java | 11 +- .../admin/captcha/CaptchaController.java | 10 +- .../controller/admin/dept/DeptController.java | 24 ++-- .../controller/admin/dept/PostController.java | 24 ++-- .../admin/dept/vo/dept/DeptBaseVO.java | 17 ++- .../admin/dept/vo/dept/DeptCreateReqVO.java | 5 +- .../admin/dept/vo/dept/DeptListReqVO.java | 9 +- .../admin/dept/vo/dept/DeptRespVO.java | 11 +- .../admin/dept/vo/dept/DeptSimpleRespVO.java | 11 +- .../admin/dept/vo/dept/DeptUpdateReqVO.java | 7 +- .../admin/dept/vo/post/PostBaseVO.java | 13 +- .../admin/dept/vo/post/PostCreateReqVO.java | 4 +- .../admin/dept/vo/post/PostExportReqVO.java | 11 +- .../admin/dept/vo/post/PostListReqVO.java | 9 +- .../admin/dept/vo/post/PostPageReqVO.java | 11 +- .../admin/dept/vo/post/PostRespVO.java | 9 +- .../admin/dept/vo/post/PostSimpleRespVO.java | 9 +- .../admin/dept/vo/post/PostUpdateReqVO.java | 7 +- .../admin/dict/DictDataController.java | 26 ++-- .../admin/dict/DictTypeController.java | 26 ++-- .../admin/dict/vo/data/DictDataBaseVO.java | 18 +-- .../dict/vo/data/DictDataCreateReqVO.java | 4 +- .../dict/vo/data/DictDataExportReqVO.java | 11 +- .../admin/dict/vo/data/DictDataPageReqVO.java | 11 +- .../admin/dict/vo/data/DictDataRespVO.java | 9 +- .../dict/vo/data/DictDataSimpleRespVO.java | 15 ++- .../dict/vo/data/DictDataUpdateReqVO.java | 7 +- .../admin/dict/vo/type/DictTypeBaseVO.java | 8 +- .../dict/vo/type/DictTypeCreateReqVO.java | 7 +- .../dict/vo/type/DictTypeExportReqVO.java | 13 +- .../admin/dict/vo/type/DictTypePageReqVO.java | 13 +- .../admin/dict/vo/type/DictTypeRespVO.java | 11 +- .../dict/vo/type/DictTypeSimpleRespVO.java | 11 +- .../dict/vo/type/DictTypeUpdateReqVO.java | 7 +- .../admin/errorcode/ErrorCodeController.java | 24 ++-- .../admin/errorcode/vo/ErrorCodeBaseVO.java | 10 +- .../errorcode/vo/ErrorCodeCreateReqVO.java | 4 +- .../errorcode/vo/ErrorCodeExportReqVO.java | 15 ++- .../errorcode/vo/ErrorCodePageReqVO.java | 15 ++- .../admin/errorcode/vo/ErrorCodeRespVO.java | 11 +- .../errorcode/vo/ErrorCodeUpdateReqVO.java | 7 +- .../admin/logger/LoginLogController.java | 10 +- .../admin/logger/OperateLogController.java | 10 +- .../logger/vo/loginlog/LoginLogBaseVO.java | 14 +-- .../vo/loginlog/LoginLogExportReqVO.java | 13 +- .../logger/vo/loginlog/LoginLogPageReqVO.java | 13 +- .../logger/vo/loginlog/LoginLogRespVO.java | 13 +- .../vo/operatelog/OperateLogBaseVO.java | 38 +++--- .../vo/operatelog/OperateLogExportReqVO.java | 15 ++- .../vo/operatelog/OperateLogPageReqVO.java | 15 ++- .../vo/operatelog/OperateLogRespVO.java | 9 +- .../admin/notice/NoticeController.java | 23 ++-- .../admin/notice/vo/NoticeBaseVO.java | 10 +- .../admin/notice/vo/NoticeCreateReqVO.java | 4 +- .../admin/notice/vo/NoticePageReqVO.java | 9 +- .../admin/notice/vo/NoticeRespVO.java | 9 +- .../admin/notice/vo/NoticeUpdateReqVO.java | 7 +- .../admin/oauth2/OAuth2ClientController.java | 22 ++-- .../admin/oauth2/OAuth2OpenController.java | 58 ++++----- .../admin/oauth2/OAuth2TokenController.java | 14 +-- .../admin/oauth2/OAuth2UserController.java | 10 +- .../oauth2/vo/client/OAuth2ClientBaseVO.java | 32 ++--- .../vo/client/OAuth2ClientCreateReqVO.java | 4 +- .../vo/client/OAuth2ClientPageReqVO.java | 8 +- .../oauth2/vo/client/OAuth2ClientRespVO.java | 9 +- .../vo/client/OAuth2ClientUpdateReqVO.java | 7 +- .../vo/open/OAuth2OpenAccessTokenRespVO.java | 15 ++- .../open/OAuth2OpenAuthorizeInfoRespVO.java | 11 +- .../vo/open/OAuth2OpenCheckTokenRespVO.java | 19 ++- .../vo/token/OAuth2AccessTokenPageReqVO.java | 11 +- .../vo/token/OAuth2AccessTokenRespVO.java | 21 ++-- .../oauth2/vo/user/OAuth2UserInfoRespVO.java | 31 +++-- .../oauth2/vo/user/OAuth2UserUpdateReqVO.java | 13 +- .../admin/permission/MenuController.java | 22 ++-- .../permission/PermissionController.java | 22 ++-- .../admin/permission/RoleController.java | 24 ++-- .../admin/permission/vo/menu/MenuBaseVO.java | 24 ++-- .../permission/vo/menu/MenuCreateReqVO.java | 4 +- .../permission/vo/menu/MenuListReqVO.java | 9 +- .../admin/permission/vo/menu/MenuRespVO.java | 11 +- .../permission/vo/menu/MenuSimpleRespVO.java | 13 +- .../permission/vo/menu/MenuUpdateReqVO.java | 7 +- .../PermissionAssignRoleDataScopeReqVO.java | 11 +- .../PermissionAssignRoleMenuReqVO.java | 9 +- .../PermissionAssignUserRoleReqVO.java | 9 +- .../admin/permission/vo/role/RoleBaseVO.java | 10 +- .../permission/vo/role/RoleCreateReqVO.java | 4 +- .../permission/vo/role/RoleExportReqVO.java | 13 +- .../permission/vo/role/RolePageReqVO.java | 13 +- .../admin/permission/vo/role/RoleRespVO.java | 17 ++- .../permission/vo/role/RoleSimpleRespVO.java | 9 +- .../permission/vo/role/RoleUpdateReqVO.java | 7 +- .../vo/role/RoleUpdateStatusReqVO.java | 9 +- .../SensitiveWordController.java | 28 ++--- .../sensitiveword/vo/SensitiveWordBaseVO.java | 10 +- .../vo/SensitiveWordCreateReqVO.java | 4 +- .../vo/SensitiveWordExportReqVO.java | 13 +- .../vo/SensitiveWordPageReqVO.java | 13 +- .../sensitiveword/vo/SensitiveWordRespVO.java | 9 +- .../vo/SensitiveWordUpdateReqVO.java | 7 +- .../admin/sms/SmsCallbackController.java | 10 +- .../admin/sms/SmsChannelController.java | 24 ++-- .../admin/sms/SmsLogController.java | 10 +- .../admin/sms/SmsTemplateController.java | 26 ++-- .../sms/vo/channel/SmsChannelBaseVO.java | 15 ++- .../sms/vo/channel/SmsChannelCreateReqVO.java | 7 +- .../sms/vo/channel/SmsChannelPageReqVO.java | 11 +- .../sms/vo/channel/SmsChannelRespVO.java | 11 +- .../vo/channel/SmsChannelSimpleRespVO.java | 11 +- .../sms/vo/channel/SmsChannelUpdateReqVO.java | 7 +- .../admin/sms/vo/log/SmsLogExportReqVO.java | 19 ++- .../admin/sms/vo/log/SmsLogPageReqVO.java | 19 ++- .../admin/sms/vo/log/SmsLogRespVO.java | 55 ++++---- .../sms/vo/template/SmsTemplateBaseVO.java | 19 ++- .../vo/template/SmsTemplateCreateReqVO.java | 5 +- .../vo/template/SmsTemplateExportReqVO.java | 19 ++- .../sms/vo/template/SmsTemplatePageReqVO.java | 19 ++- .../sms/vo/template/SmsTemplateRespVO.java | 13 +- .../sms/vo/template/SmsTemplateSendReqVO.java | 11 +- .../vo/template/SmsTemplateUpdateReqVO.java | 7 +- .../admin/socail/SocialUserController.java | 10 +- .../admin/socail/vo/SocialUserBindReqVO.java | 11 +- .../socail/vo/SocialUserUnbindReqVO.java | 9 +- .../admin/tenant/TenantController.java | 28 ++--- .../admin/tenant/TenantPackageController.java | 24 ++-- .../vo/packages/TenantPackageBaseVO.java | 10 +- .../vo/packages/TenantPackageCreateReqVO.java | 4 +- .../vo/packages/TenantPackagePageReqVO.java | 13 +- .../vo/packages/TenantPackageRespVO.java | 9 +- .../packages/TenantPackageSimpleRespVO.java | 9 +- .../vo/packages/TenantPackageUpdateReqVO.java | 7 +- .../admin/tenant/vo/tenant/TenantBaseVO.java | 20 ++- .../tenant/vo/tenant/TenantCreateReqVO.java | 8 +- .../tenant/vo/tenant/TenantExportReqVO.java | 15 ++- .../tenant/vo/tenant/TenantPageReqVO.java | 15 ++- .../admin/tenant/vo/tenant/TenantRespVO.java | 8 +- .../tenant/vo/tenant/TenantUpdateReqVO.java | 6 +- .../controller/admin/user/UserController.java | 42 +++---- .../admin/user/UserProfileController.java | 14 +-- .../user/vo/profile/UserProfileRespVO.java | 39 +++--- .../UserProfileUpdatePasswordReqVO.java | 9 +- .../vo/profile/UserProfileUpdateReqVO.java | 16 ++- .../admin/user/vo/user/UserBaseVO.java | 20 +-- .../admin/user/vo/user/UserCreateReqVO.java | 8 +- .../admin/user/vo/user/UserExportReqVO.java | 15 ++- .../admin/user/vo/user/UserImportRespVO.java | 11 +- .../user/vo/user/UserPageItemRespVO.java | 11 +- .../admin/user/vo/user/UserPageReqVO.java | 15 ++- .../admin/user/vo/user/UserRespVO.java | 15 ++- .../admin/user/vo/user/UserSimpleRespVO.java | 9 +- .../user/vo/user/UserUpdatePasswordReqVO.java | 9 +- .../admin/user/vo/user/UserUpdateReqVO.java | 7 +- .../user/vo/user/UserUpdateStatusReqVO.java | 9 +- yudao-server/pom.xml | 20 +-- .../app/AppShopOrderController.java | 12 +- .../app/vo/AppShopOrderCreateRespVO.java | 9 +- .../src/views/infra/swagger/index.vue | 2 +- 469 files changed, 3317 insertions(+), 3721 deletions(-) diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index be7229232..6390fefef 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -18,8 +18,8 @@ 2.7.6 + 1.6.13 3.0.3 - 1.6.8 2.5 1.2.15 @@ -158,28 +158,21 @@ - com.github.xiaoymin - knife4j-spring-boot-starter - ${knife4j.version} - - - mapstruct - org.mapstruct - - - guava - com.google.guava - - - swagger-annotations - io.swagger - - + org.springdoc + springdoc-openapi-webmvc-core + ${springdoc.version} + - io.swagger - swagger-annotations - ${swagger-annotations.version} + org.springdoc + springdoc-openapi-javadoc + ${springdoc.version} + + + + org.springdoc + springdoc-openapi-security + ${springdoc.version} diff --git a/yudao-framework/yudao-common/pom.xml b/yudao-framework/yudao-common/pom.xml index 2ad12ad87..699fa9528 100644 --- a/yudao-framework/yudao-common/pom.xml +++ b/yudao-framework/yudao-common/pom.xml @@ -59,9 +59,13 @@ - io.swagger - swagger-annotations - provided + org.springdoc + springdoc-openapi-webmvc-core + + + + org.springdoc + springdoc-openapi-javadoc diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java index 80029703b..3cb1fc3ad 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.framework.common.pojo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.Min; @@ -9,19 +8,19 @@ import javax.validation.constraints.Max; import javax.validation.constraints.NotNull; import java.io.Serializable; -@ApiModel("分页参数") +@Schema(title="分页参数") @Data public class PageParam implements Serializable { private static final Integer PAGE_NO = 1; private static final Integer PAGE_SIZE = 10; - @ApiModelProperty(value = "页码,从 1 开始", required = true,example = "1") + @Schema(title = "页码,从 1 开始", required = true,example = "1") @NotNull(message = "页码不能为空") @Min(value = 1, message = "页码最小值为 1") private Integer pageNo = PAGE_NO; - @ApiModelProperty(value = "每页条数,最大值为 100", required = true, example = "10") + @Schema(title = "每页条数,最大值为 100", required = true, example = "10") @NotNull(message = "每页条数不能为空") @Min(value = 1, message = "每页条数最小值为 1") @Max(value = 100, message = "每页条数最大值为 100") diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java index dbdeb85ba..655dea180 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java @@ -1,21 +1,19 @@ package cn.iocoder.yudao.framework.common.pojo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; import java.util.ArrayList; import java.util.List; -@ApiModel("分页结果") +@Schema(title = "分页结果") @Data public final class PageResult implements Serializable { - @ApiModelProperty(value = "数据", required = true) + @Schema(title = "数据", required = true) private List list; - @ApiModelProperty(value = "总量", required = true) + @Schema(title = "总量", required = true) private Long total; public PageResult() { diff --git a/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/annotations/OperateLog.java b/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/annotations/OperateLog.java index 2f9ecaf8f..c9a117cb4 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/annotations/OperateLog.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/annotations/OperateLog.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.framework.operatelog.core.annotations; import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/aop/OperateLogAspect.java b/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/aop/OperateLogAspect.java index 75819cbe1..2576a0531 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/aop/OperateLogAspect.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-operatelog/src/main/java/cn/iocoder/yudao/framework/operatelog/core/aop/OperateLogAspect.java @@ -15,8 +15,8 @@ import cn.iocoder.yudao.framework.operatelog.core.service.OperateLog; import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import com.google.common.collect.Maps; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -71,15 +71,15 @@ public class OperateLogAspect { @Resource private OperateLogFrameworkService operateLogFrameworkService; - @Around("@annotation(apiOperation)") - public Object around(ProceedingJoinPoint joinPoint, ApiOperation apiOperation) throws Throwable { + @Around("@annotation(operation)") + public Object around(ProceedingJoinPoint joinPoint, Operation operation) throws Throwable { // 可能也添加了 @ApiOperation 注解 cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog = getMethodAnnotation(joinPoint, cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog.class); - return around0(joinPoint, operateLog, apiOperation); + return around0(joinPoint, operateLog, operation); } - @Around("!@annotation(io.swagger.annotations.ApiOperation) && @annotation(operateLog)") + @Around("!@annotation(io.swagger.v3.oas.annotations.Operation) && @annotation(operateLog)") // 兼容处理,只添加 @OperateLog 注解的情况 public Object around(ProceedingJoinPoint joinPoint, cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog) throws Throwable { @@ -88,7 +88,7 @@ public class OperateLogAspect { private Object around0(ProceedingJoinPoint joinPoint, cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog, - ApiOperation apiOperation) throws Throwable { + Operation operation) throws Throwable { // 目前,只有管理员,才记录操作日志!所以非管理员,直接调用,不进行记录 Integer userType = WebFrameworkUtils.getLoginUserType(); if (!Objects.equals(userType, UserTypeEnum.ADMIN.getValue())) { @@ -101,10 +101,10 @@ public class OperateLogAspect { // 执行原有方法 Object result = joinPoint.proceed(); // 记录正常执行时的操作日志 - this.log(joinPoint, operateLog, apiOperation, startTime, result, null); + this.log(joinPoint, operateLog, operation, startTime, result, null); return result; } catch (Throwable exception) { - this.log(joinPoint, operateLog, apiOperation, startTime, null, exception); + this.log(joinPoint, operateLog, operation, startTime, null, exception); throw exception; } finally { clearThreadLocal(); @@ -129,7 +129,7 @@ public class OperateLogAspect { private void log(ProceedingJoinPoint joinPoint, cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog, - ApiOperation apiOperation, + Operation operation, LocalDateTime startTime, Object result, Throwable exception) { try { // 判断不记录的情况 @@ -137,16 +137,16 @@ public class OperateLogAspect { return; } // 真正记录操作日志 - this.log0(joinPoint, operateLog, apiOperation, startTime, result, exception); + this.log0(joinPoint, operateLog, operation, startTime, result, exception); } catch (Throwable ex) { log.error("[log][记录操作日志时,发生异常,其中参数是 joinPoint({}) operateLog({}) apiOperation({}) result({}) exception({}) ]", - joinPoint, operateLog, apiOperation, result, exception, ex); + joinPoint, operateLog, operation, result, exception, ex); } } private void log0(ProceedingJoinPoint joinPoint, cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog, - ApiOperation apiOperation, + Operation operation, LocalDateTime startTime, Object result, Throwable exception) { OperateLog operateLogObj = new OperateLog(); // 补全通用字段 @@ -155,7 +155,7 @@ public class OperateLogAspect { // 补充用户信息 fillUserFields(operateLogObj); // 补全模块信息 - fillModuleFields(operateLogObj, joinPoint, operateLog, apiOperation); + fillModuleFields(operateLogObj, joinPoint, operateLog, operation); // 补全请求信息 fillRequestFields(operateLogObj); // 补全方法信息 @@ -173,21 +173,21 @@ public class OperateLogAspect { private static void fillModuleFields(OperateLog operateLogObj, ProceedingJoinPoint joinPoint, cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog operateLog, - ApiOperation apiOperation) { + Operation operation) { // module 属性 if (operateLog != null) { operateLogObj.setModule(operateLog.module()); } if (StrUtil.isEmpty(operateLogObj.getModule())) { - Api api = getClassAnnotation(joinPoint, Api.class); - if (api != null) { - // 优先读取 @API 的 name 属性 - if (StrUtil.isNotEmpty(api.value())) { - operateLogObj.setModule(api.value()); + Tag tag = getClassAnnotation(joinPoint, Tag.class); + if (tag != null) { + // 优先读取 @Tag 的 name 属性 + if (StrUtil.isNotEmpty(tag.name())) { + operateLogObj.setModule(tag.name()); } - // 没有的话,读取 @API 的 tags 属性 - if (StrUtil.isEmpty(operateLogObj.getModule()) && ArrayUtil.isNotEmpty(api.tags())) { - operateLogObj.setModule(api.tags()[0]); + // 没有的话,读取 @API 的 description 属性 + if (StrUtil.isEmpty(operateLogObj.getModule()) && ArrayUtil.isNotEmpty(tag.description())) { + operateLogObj.setModule(tag.description()); } } } @@ -195,8 +195,8 @@ public class OperateLogAspect { if (operateLog != null) { operateLogObj.setName(operateLog.name()); } - if (StrUtil.isEmpty(operateLogObj.getName()) && apiOperation != null) { - operateLogObj.setName(apiOperation.value()); + if (StrUtil.isEmpty(operateLogObj.getName()) && operation != null) { + operateLogObj.setName(operation.description()); } // type 属性 if (operateLog != null && ArrayUtil.isNotEmpty(operateLog.type())) { diff --git a/yudao-framework/yudao-spring-boot-starter-web/pom.xml b/yudao-framework/yudao-spring-boot-starter-web/pom.xml index 8662584e3..437503a40 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-web/pom.xml @@ -34,17 +34,18 @@ - com.github.xiaoymin - knife4j-spring-boot-starter - - - io.swagger - swagger-annotations + org.springdoc + springdoc-openapi-webmvc-core - org.springframework.boot - spring-boot-starter-validation + org.springdoc + springdoc-openapi-javadoc + + + + org.springdoc + springdoc-openapi-security diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index 240f0f284..01fcb6ed2 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -1,119 +1,60 @@ package cn.iocoder.yudao.framework.swagger.config; -import cn.iocoder.yudao.framework.swagger.core.SpringFoxHandlerProviderBeanPostProcessor; -import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.ExternalDocumentation; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springdoc.core.GroupedOpenApi; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpHeaders; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.ExampleBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestParameterBuilder; -import springfox.documentation.service.*; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -import java.util.Collections; -import java.util.List; - -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; -import static springfox.documentation.builders.RequestHandlerSelectors.basePackage; /** - * Swagger2 自动配置类 + * Swagger3 自动配置类 * * @author 芋道源码 */ @AutoConfiguration -@EnableSwagger2 -@EnableKnife4j -@ConditionalOnClass({Docket.class, ApiInfoBuilder.class}) +@ConditionalOnClass({OpenAPI.class}) // 允许使用 swagger.enable=false 禁用 Swagger @ConditionalOnProperty(prefix = "yudao.swagger", value = "enable", matchIfMissing = true) @EnableConfigurationProperties(SwaggerProperties.class) public class YudaoSwaggerAutoConfiguration { @Bean - public SpringFoxHandlerProviderBeanPostProcessor springFoxHandlerProviderBeanPostProcessor() { - return new SpringFoxHandlerProviderBeanPostProcessor(); + public OpenAPI createRestApi(SwaggerProperties properties) { + return new OpenAPI() + .info(new Info().title(properties.getTitle()) + .description(properties.getDescription()) + .version(properties.getVersion()) + .license(new License().name("MIT").url("https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE"))) + .externalDocs(new ExternalDocumentation() + .description(properties.getDescription()) + .url("https://gitee.com/zhijiantianya/ruoyi-vue-pro")); + } @Bean - public Docket createRestApi(SwaggerProperties properties) { - // 创建 Docket 对象 - return new Docket(DocumentationType.SWAGGER_2) - // ① 用来创建该 API 的基本信息,展示在文档的页面中(自定义展示的信息) - .apiInfo(apiInfo(properties)) - // ② 设置扫描指定 package 包下的 - .select() - .apis(basePackage(properties.getBasePackage())) -// .apis(basePackage("cn.iocoder.yudao.module.system")) // 可用于 swagger 无法展示时使用 - .paths(PathSelectors.any()) - .build() - // ③ 安全上下文(认证) - .securitySchemes(securitySchemes()) - .securityContexts(securityContexts()) - // ④ 全局参数(多租户 header) - .globalRequestParameters(globalRequestParameters()); - } - - // ========== apiInfo ========== - - /** - * API 摘要信息 - */ - private static ApiInfo apiInfo(SwaggerProperties properties) { - return new ApiInfoBuilder() - .title(properties.getTitle()) - .description(properties.getDescription()) - .contact(new Contact(properties.getAuthor(), null, null)) - .version(properties.getVersion()) + public GroupedOpenApi publicApi() { + return GroupedOpenApi.builder() + .group("app") + .pathsToMatch("/app/**") .build(); } - // ========== securitySchemes ========== - - /** - * 安全模式,这里配置通过请求头 Authorization 传递 token 参数 - */ - private static List securitySchemes() { - return Collections.singletonList(new ApiKey(HttpHeaders.AUTHORIZATION, "Authorization", "header")); + @Bean + public GroupedOpenApi adminApi() { + return GroupedOpenApi.builder() + .group("admin") + .pathsToMatch("/admin/**") + .build(); } - /** - * 安全上下文 - * - * @see #securitySchemes() - * @see #authorizationScopes() - */ - private static List securityContexts() { - return Collections.singletonList(SecurityContext.builder() - .securityReferences(securityReferences()) - // 通过 PathSelectors.regex("^(?!auth).*$"),排除包含 "auth" 的接口不需要使用securitySchemes - .operationSelector(o -> o.requestMappingPattern().matches("^(?!auth).*$")) - .build()); - } - - private static List securityReferences() { - return Collections.singletonList(new SecurityReference(HttpHeaders.AUTHORIZATION, authorizationScopes())); - } - - private static AuthorizationScope[] authorizationScopes() { - return new AuthorizationScope[]{new AuthorizationScope("global", "accessEverything")}; - } - - // ========== globalRequestParameters ========== - - private static List globalRequestParameters() { - RequestParameterBuilder tenantParameter = new RequestParameterBuilder() - .name(HEADER_TENANT_ID).description("租户编号") - .in(ParameterType.HEADER).example(new ExampleBuilder().value(1L).build()); - return Collections.singletonList(tenantParameter.build()); - } } diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java index c9d178ac8..4eea3cc36 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java @@ -1,43 +1,43 @@ -package cn.iocoder.yudao.framework.swagger.core; - -import cn.hutool.core.util.ReflectUtil; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; -import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider; -import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; - -import java.util.List; - -/** - * 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题 - * 该问题对应的 issue 为 https://github.com/springfox/springfox/issues/3462 - * - * @author 芋道源码 - */ -public class SpringFoxHandlerProviderBeanPostProcessor implements BeanPostProcessor { - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { - customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); - } - return bean; - } - - private void customizeSpringfoxHandlerMappings(List mappings) { - // 移除,只保留 patternParser - List copy = CollectionUtils.filterList(mappings, mapping -> mapping.getPatternParser() == null); - // 添加到 mappings 中 - mappings.clear(); - mappings.addAll(copy); - } - - @SuppressWarnings("unchecked") - private List getHandlerMappings(Object bean) { - return (List) - ReflectUtil.getFieldValue(bean, "handlerMappings"); - } - -} +//package cn.iocoder.yudao.framework.swagger.core; +// +//import cn.hutool.core.util.ReflectUtil; +//import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +//import org.springframework.beans.BeansException; +//import org.springframework.beans.factory.config.BeanPostProcessor; +//import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; +//import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider; +//import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; +// +//import java.util.List; +// +///** +// * 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题 +// * 该问题对应的 issue 为 https://github.com/springfox/springfox/issues/3462 +// * +// * @author 芋道源码 +// */ +//public class SpringFoxHandlerProviderBeanPostProcessor implements BeanPostProcessor { +// +// @Override +// public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { +// if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { +// customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); +// } +// return bean; +// } +// +// private void customizeSpringfoxHandlerMappings(List mappings) { +// // 移除,只保留 patternParser +// List copy = CollectionUtils.filterList(mappings, mapping -> mapping.getPatternParser() == null); +// // 添加到 mappings 中 +// mappings.clear(); +// mappings.addAll(copy); +// } +// +// @SuppressWarnings("unchecked") +// private List getHandlerMappings(Object bean) { +// return (List) +// ReflectUtil.getFieldValue(bean, "handlerMappings"); +// } +// +//} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmFormController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmFormController.java index 217067f31..e5b6f2ceb 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmFormController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmFormController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO; import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 动态表单") +@Tag(name = "管理后台 - 动态表单") @RestController @RequestMapping("/bpm/form") @Validated @@ -29,14 +29,14 @@ public class BpmFormController { private BpmFormService formService; @PostMapping("/create") - @ApiOperation("创建动态表单") + @Operation(summary = "创建动态表单") @PreAuthorize("@ss.hasPermission('bpm:form:create')") public CommonResult createForm(@Valid @RequestBody BpmFormCreateReqVO createReqVO) { return success(formService.createForm(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新动态表单") + @Operation(summary = "更新动态表单") @PreAuthorize("@ss.hasPermission('bpm:form:update')") public CommonResult updateForm(@Valid @RequestBody BpmFormUpdateReqVO updateReqVO) { formService.updateForm(updateReqVO); @@ -44,8 +44,8 @@ public class BpmFormController { } @DeleteMapping("/delete") - @ApiOperation("删除动态表单") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除动态表单") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('bpm:form:delete')") public CommonResult deleteForm(@RequestParam("id") Long id) { formService.deleteForm(id); @@ -53,8 +53,8 @@ public class BpmFormController { } @GetMapping("/get") - @ApiOperation("获得动态表单") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得动态表单") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('bpm:form:query')") public CommonResult getForm(@RequestParam("id") Long id) { BpmFormDO form = formService.getForm(id); @@ -62,14 +62,14 @@ public class BpmFormController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获得动态表单的精简列表", notes = "用于表单下拉框") + @Operation(summary = "获得动态表单的精简列表", description = "用于表单下拉框") public CommonResult> getSimpleForms() { List list = formService.getFormList(); return success(BpmFormConvert.INSTANCE.convertList2(list)); } @GetMapping("/page") - @ApiOperation("获得动态表单分页") + @Operation(summary = "获得动态表单分页") @PreAuthorize("@ss.hasPermission('bpm:form:query')") public CommonResult> getFormPage(@Valid BpmFormPageReqVO pageVO) { PageResult pageResult = formService.getFormPage(pageVO); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java index 3dd0a0a4d..9156c4255 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.framework.common.util.io.IoUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*; import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert; import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import java.io.IOException; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 流程模型") +@Tag(name = "管理后台 - 流程模型") @RestController @RequestMapping("/bpm/model") @Validated @@ -30,14 +30,14 @@ public class BpmModelController { private BpmModelService modelService; @GetMapping("/page") - @ApiOperation(value = "获得模型分页") + @Operation(summary = "获得模型分页") public CommonResult> getModelPage(BpmModelPageReqVO pageVO) { return success(modelService.getModelPage(pageVO)); } @GetMapping("/get") - @ApiOperation("获得模型") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) + @Operation(summary = "获得模型") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('bpm:model:query')") public CommonResult getModel(@RequestParam("id") String id) { BpmModelRespVO model = modelService.getModel(id); @@ -45,14 +45,14 @@ public class BpmModelController { } @PostMapping("/create") - @ApiOperation(value = "新建模型") + @Operation(summary = "新建模型") @PreAuthorize("@ss.hasPermission('bpm:model:create')") public CommonResult createModel(@Valid @RequestBody BpmModelCreateReqVO createRetVO) { return success(modelService.createModel(createRetVO, null)); } @PutMapping("/update") - @ApiOperation(value = "修改模型") + @Operation(summary = "修改模型") @PreAuthorize("@ss.hasPermission('bpm:model:update')") public CommonResult updateModel(@Valid @RequestBody BpmModelUpdateReqVO modelVO) { modelService.updateModel(modelVO); @@ -60,7 +60,7 @@ public class BpmModelController { } @PostMapping("/import") - @ApiOperation(value = "导入模型") + @Operation(summary = "导入模型") @PreAuthorize("@ss.hasPermission('bpm:model:import')") public CommonResult importModel(@Valid BpmModeImportReqVO importReqVO) throws IOException { BpmModelCreateReqVO createReqVO = BpmModelConvert.INSTANCE.convert(importReqVO); @@ -70,8 +70,8 @@ public class BpmModelController { } @PostMapping("/deploy") - @ApiOperation(value = "部署模型") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) + @Operation(summary = "部署模型") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('bpm:model:deploy')") public CommonResult deployModel(@RequestParam("id") String id) { modelService.deployModel(id); @@ -79,7 +79,7 @@ public class BpmModelController { } @PutMapping("/update-state") - @ApiOperation(value = "修改模型的状态", notes = "实际更新的部署的流程定义的状态") + @Operation(summary = "修改模型的状态", description = "实际更新的部署的流程定义的状态") @PreAuthorize("@ss.hasPermission('bpm:model:update')") public CommonResult updateModelState(@Valid @RequestBody BpmModelUpdateStateReqVO reqVO) { modelService.updateModelState(reqVO.getId(), reqVO.getState()); @@ -87,8 +87,8 @@ public class BpmModelController { } @DeleteMapping("/delete") - @ApiOperation("删除模型") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) + @Operation(summary = "删除模型") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('bpm:model:delete')") public CommonResult deleteModel(@RequestParam("id") String id) { modelService.deleteModel(id); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java index ebcaad05b..e77e0bd6d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java @@ -7,9 +7,9 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmPro import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -23,7 +23,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 流程定义") +@Tag(name = "管理后台 - 流程定义") @RestController @RequestMapping("/bpm/process-definition") @Validated @@ -33,7 +33,7 @@ public class BpmProcessDefinitionController { private BpmProcessDefinitionService bpmDefinitionService; @GetMapping("/page") - @ApiOperation(value = "获得流程定义分页") + @Operation(summary = "获得流程定义分页") @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')") public CommonResult> getProcessDefinitionPage( BpmProcessDefinitionPageReqVO pageReqVO) { @@ -41,7 +41,7 @@ public class BpmProcessDefinitionController { } @GetMapping ("/list") - @ApiOperation(value = "获得流程定义列表") + @Operation(summary = "获得流程定义列表") @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')") public CommonResult> getProcessDefinitionList( BpmProcessDefinitionListReqVO listReqVO) { @@ -49,8 +49,8 @@ public class BpmProcessDefinitionController { } @GetMapping ("/get-bpmn-xml") - @ApiOperation(value = "获得流程定义的 BPMN XML") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = String.class) + @Operation(summary = "获得流程定义的 BPMN XML") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')") public CommonResult getProcessDefinitionBpmnXML(@RequestParam("id") String id) { String bpmnXML = bpmDefinitionService.getProcessDefinitionBpmnXML(id); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java index 3e946707a..d730626a6 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmTaskAssignRuleController.java @@ -5,10 +5,10 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAs import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 任务分配规则") +@Tag(name = "管理后台 - 任务分配规则") @RestController @RequestMapping("/bpm/task-assign-rule") @Validated @@ -29,10 +29,10 @@ public class BpmTaskAssignRuleController { private BpmTaskAssignRuleService taskAssignRuleService; @GetMapping("/list") - @ApiOperation(value = "获得任务分配规则列表") - @ApiImplicitParams({ - @ApiImplicitParam(name = "modelId", value = "模型编号", example = "1024", dataTypeClass = String.class), - @ApiImplicitParam(name = "processDefinitionId", value = "流程定义的编号", example = "2048", dataTypeClass = String.class) + @Operation(summary = "获得任务分配规则列表") + @Parameters({ + @Parameter(name = "modelId", description = "模型编号", example = "1024"), + @Parameter(name = "processDefinitionId", description = "流程定义的编号", example = "2048") }) @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:query')") public CommonResult> getTaskAssignRuleList( @@ -42,14 +42,14 @@ public class BpmTaskAssignRuleController { } @PostMapping("/create") - @ApiOperation(value = "创建任务分配规则") + @Operation(summary = "创建任务分配规则") @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:create')") public CommonResult createTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleCreateReqVO reqVO) { return success(taskAssignRuleService.createTaskAssignRule(reqVO)); } @PutMapping("/update") - @ApiOperation(value = "更新任务分配规则") + @Operation(summary = "更新任务分配规则") @PreAuthorize("@ss.hasPermission('bpm:task-assign-rule:update')") public CommonResult updateTaskAssignRule(@Valid @RequestBody BpmTaskAssignRuleUpdateReqVO reqVO) { taskAssignRuleService.updateTaskAssignRule(reqVO); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmUserGroupController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmUserGroupController.java index 4267f0902..5e7a54b85 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmUserGroupController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmUserGroupController.java @@ -10,9 +10,9 @@ import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -23,7 +23,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 用户组") +@Tag(name = "管理后台 - 用户组") @RestController @RequestMapping("/bpm/user-group") @Validated @@ -33,14 +33,14 @@ public class BpmUserGroupController { private BpmUserGroupService userGroupService; @PostMapping("/create") - @ApiOperation("创建用户组") + @Operation(summary = "创建用户组") @PreAuthorize("@ss.hasPermission('bpm:user-group:create')") public CommonResult createUserGroup(@Valid @RequestBody BpmUserGroupCreateReqVO createReqVO) { return success(userGroupService.createUserGroup(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新用户组") + @Operation(summary = "更新用户组") @PreAuthorize("@ss.hasPermission('bpm:user-group:update')") public CommonResult updateUserGroup(@Valid @RequestBody BpmUserGroupUpdateReqVO updateReqVO) { userGroupService.updateUserGroup(updateReqVO); @@ -48,8 +48,8 @@ public class BpmUserGroupController { } @DeleteMapping("/delete") - @ApiOperation("删除用户组") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除用户组") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('bpm:user-group:delete')") public CommonResult deleteUserGroup(@RequestParam("id") Long id) { userGroupService.deleteUserGroup(id); @@ -57,8 +57,8 @@ public class BpmUserGroupController { } @GetMapping("/get") - @ApiOperation("获得用户组") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得用户组") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('bpm:user-group:query')") public CommonResult getUserGroup(@RequestParam("id") Long id) { BpmUserGroupDO userGroup = userGroupService.getUserGroup(id); @@ -66,7 +66,7 @@ public class BpmUserGroupController { } @GetMapping("/page") - @ApiOperation("获得用户组分页") + @Operation(summary = "获得用户组分页") @PreAuthorize("@ss.hasPermission('bpm:user-group:query')") public CommonResult> getUserGroupPage(@Valid BpmUserGroupPageReqVO pageVO) { PageResult pageResult = userGroupService.getUserGroupPage(pageVO); @@ -74,7 +74,7 @@ public class BpmUserGroupController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获取用户组精简信息列表", notes = "只包含被开启的用户组,主要用于前端的下拉选项") + @Operation(summary = "获取用户组精简信息列表", description = "只包含被开启的用户组,主要用于前端的下拉选项") public CommonResult> getSimpleUserGroups() { // 获用户门列表,只要开启状态的 List list = userGroupService.getUserGroupListByStatus(CommonStatusEnum.ENABLE.getStatus()); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java index 11fee5c00..3345adb52 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; /** @@ -11,15 +10,15 @@ import javax.validation.constraints.*; @Data public class BpmFormBaseVO { - @ApiModelProperty(value = "表单名称", required = true, example = "芋道") + @Schema(title = "表单名称", required = true, example = "芋道") @NotNull(message = "表单名称不能为空") private String name; - @ApiModelProperty(value = "表单状态", required = true, notes = "参见 CommonStatusEnum 枚举", example = "1") + @Schema(title = "表单状态", required = true, description = "参见 CommonStatusEnum 枚举", example = "1") @NotNull(message = "表单状态不能为空") private Integer status; - @ApiModelProperty(value = "备注", example = "我是备注") + @Schema(title = "备注", example = "我是备注") private String remark; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java index d9a628125..ce3410ced 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel("管理后台 - 动态表单创建 Request VO") +@Schema(title = "管理后台 - 动态表单创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmFormCreateReqVO extends BpmFormBaseVO { - @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串") + @Schema(title = "表单的配置", required = true, description = "JSON 字符串") @NotNull(message = "表单的配置不能为空") private String conf; - @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组") + @Schema(title = "表单项的数组", required = true, description = "JSON 字符串的数组") @NotNull(message = "表单项的数组不能为空") private List fields; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java index a8097c437..87adc3f63 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 动态表单分页 Request VO") +@Schema(title = "管理后台 - 动态表单分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmFormPageReqVO extends PageParam { - @ApiModelProperty(value = "表单名称", example = "芋道") + @Schema(title = "表单名称", example = "芋道") private String name; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java index e49f09879..b93b66012 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java @@ -1,7 +1,5 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -10,24 +8,24 @@ import javax.validation.constraints.NotNull; import java.time.LocalDateTime; import java.util.List; -@ApiModel("管理后台 - 动态表单 Response VO") +@Schema(title = "管理后台 - 动态表单 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmFormRespVO extends BpmFormBaseVO { - @ApiModelProperty(value = "表单编号", required = true, example = "1024") + @Schema(title = "表单编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串") + @Schema(title = "表单的配置", required = true, description = "JSON 字符串") @NotNull(message = "表单的配置不能为空") private String conf; - @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组") + @Schema(title = "表单项的数组", required = true, description = "JSON 字符串的数组") @NotNull(message = "表单项的数组不能为空") private List fields; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java index 3a6b3c093..9764a9835 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("管理后台 - 流程表单精简 Response VO") +@Schema(title = "管理后台 - 流程表单精简 Response VO") @Data public class BpmFormSimpleRespVO { - @ApiModelProperty(value = "表单编号", required = true, example = "1024") + @Schema(title = "表单编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "表单名称", required = true, example = "芋道") + @Schema(title = "表单名称", required = true, example = "芋道") private String name; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java index 55b997679..641e57617 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java @@ -1,25 +1,24 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; import java.util.List; -@ApiModel("管理后台 - 动态表单更新 Request VO") +@Schema(title = "管理后台 - 动态表单更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmFormUpdateReqVO extends BpmFormBaseVO { - @ApiModelProperty(value = "表单编号", required = true, example = "1024") + @Schema(title = "表单编号", required = true, example = "1024") @NotNull(message = "表单编号不能为空") private Long id; - @ApiModelProperty(value = "表单的配置", required = true, notes = "JSON 字符串") + @Schema(title = "表单的配置", required = true, description = "JSON 字符串") @NotNull(message = "表单的配置不能为空") private String conf; - @ApiModelProperty(value = "表单项的数组", required = true, notes = "JSON 字符串的数组") + @Schema(title = "表单项的数组", required = true, description = "JSON 字符串的数组") @NotNull(message = "表单项的数组不能为空") private List fields; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java index e0dfe568e..b82f6d1d5 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; /** @@ -12,19 +11,19 @@ import javax.validation.constraints.*; @Data public class BpmUserGroupBaseVO { - @ApiModelProperty(value = "组名", required = true, example = "芋道") + @Schema(title = "组名", required = true, example = "芋道") @NotNull(message = "组名不能为空") private String name; - @ApiModelProperty(value = "描述", required = true, example = "芋道源码") + @Schema(title = "描述", required = true, example = "芋道源码") @NotNull(message = "描述不能为空") private String description; - @ApiModelProperty(value = "成员编号数组", required = true, example = "1,2,3") + @Schema(title = "成员编号数组", required = true, example = "1,2,3") @NotNull(message = "成员编号数组不能为空") private Set memberUserIds; - @ApiModelProperty(value = "状态", required = true, example = "1") + @Schema(title = "状态", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java index 48b44d38b..7509746a7 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 用户组创建 Request VO") +@Schema(title = "管理后台 - 用户组创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java index 2608607bf..c5d417131 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.util.date.DateUtils; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -11,20 +10,20 @@ import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; -@ApiModel("管理后台 - 用户组分页 Request VO") +@Schema(title = "管理后台 - 用户组分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmUserGroupPageReqVO extends PageParam { - @ApiModelProperty(value = "组名", example = "芋道") + @Schema(title = "组名", example = "芋道") private String name; - @ApiModelProperty(value = "状态", example = "1") + @Schema(title = "状态", example = "1") private Integer status; @DateTimeFormat(pattern = DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java index b3d4693f3..e7399d228 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 用户组 Response VO") +@Schema(title = "管理后台 - 用户组 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmUserGroupRespVO extends BpmUserGroupBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java index 0b47f447e..785e9e571 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel("管理后台 - 用户组精简信息 Response VO") +@Schema(title = "管理后台 - 用户组精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class BpmUserGroupSimpleRespVO { - @ApiModelProperty(value = "用户组编号", required = true, example = "1024") + @Schema(title = "用户组编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "用户组名字", required = true, example = "芋道") + @Schema(title = "用户组名字", required = true, example = "芋道") private String name; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java index 14aa25c5b..88846644f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java @@ -1,16 +1,15 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 用户组更新 Request VO") +@Schema(title = "管理后台 - 用户组更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmUserGroupUpdateReqVO extends BpmUserGroupBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java index 7240ba15c..79771bfcb 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,13 +8,13 @@ import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotNull; -@ApiModel(value = "管理后台 - 流程模型的导入 Request VO", description = "相比流程模型的新建来说,只是多了一个 bpmnFile 文件") +@Schema(title = "管理后台 - 流程模型的导入 Request VO", description = "相比流程模型的新建来说,只是多了一个 bpmnFile 文件") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmModeImportReqVO extends BpmModelCreateReqVO { - @ApiModelProperty(value = "BPMN 文件", required = true) + @Schema(title = "BPMN 文件", required = true) @NotNull(message = "BPMN 文件不能为空") private MultipartFile bpmnFile; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java index 542a177e4..639967286 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -12,30 +11,30 @@ import javax.validation.constraints.NotEmpty; @Data public class BpmModelBaseVO { - @ApiModelProperty(value = "流程标识", required = true, example = "process_yudao") + @Schema(title = "流程标识", required = true, example = "process_yudao") @NotEmpty(message = "流程标识不能为空") private String key; - @ApiModelProperty(value = "流程名称", required = true, example = "芋道") + @Schema(title = "流程名称", required = true, example = "芋道") @NotEmpty(message = "流程名称不能为空") private String name; - @ApiModelProperty(value = "流程描述", example = "我是描述") + @Schema(title = "流程描述", example = "我是描述") private String description; - @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1") + @Schema(title = "流程分类", description = "参见 bpm_model_category 数据字典", example = "1") @NotEmpty(message = "流程分类不能为空") private String category; - @ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1") + @Schema(title = "表单类型", description = "参见 bpm_model_form_type 数据字典", example = "1") private Integer formType; - @ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "表单编号", example = "1024", description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private Long formId; - @ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", - notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", + description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private String formCustomCreatePath; - @ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", - notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", + description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private String formCustomViewPath; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java index c85ef3ae4..d100b744f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 流程模型的创建 Request VO") +@Schema(title = "管理后台 - 流程模型的创建 Request VO") @Data public class BpmModelCreateReqVO { - @ApiModelProperty(value = "流程标识", required = true, example = "process_yudao") + @Schema(title = "流程标识", required = true, example = "process_yudao") @NotEmpty(message = "流程标识不能为空") private String key; - @ApiModelProperty(value = "流程名称", required = true, example = "芋道") + @Schema(title = "流程名称", required = true, example = "芋道") @NotEmpty(message = "流程名称不能为空") private String name; - @ApiModelProperty(value = "流程描述", example = "我是描述") + @Schema(title = "流程描述", example = "我是描述") private String description; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java index 10d23892e..cfd646ebc 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 流程模型的分页的每一项 Response VO") +@Schema(title = "管理后台 - 流程模型的分页的每一项 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmModelPageItemRespVO extends BpmModelBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private String id; - @ApiModelProperty(value = "表单名字", example = "请假表单") + @Schema(title = "表单名字", example = "请假表单") private String formName; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; /** @@ -28,20 +27,20 @@ public class BpmModelPageItemRespVO extends BpmModelBaseVO { */ private ProcessDefinition processDefinition; - @ApiModel("流程定义") + @Schema(title = "流程定义") @Data public static class ProcessDefinition { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private String id; - @ApiModelProperty(value = "版本", required = true, example = "1") + @Schema(title = "版本", required = true, example = "1") private Integer version; - @ApiModelProperty(value = "部署时间", required = true) + @Schema(title = "部署时间", required = true) private LocalDateTime deploymentTime; - @ApiModelProperty(value = "中断状态", required = true, example = "1", notes = "参见 SuspensionState 枚举") + @Schema(title = "中断状态", required = true, example = "1", description = "参见 SuspensionState 枚举") private Integer suspensionState; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java index 945da139c..ce2f4ae1c 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 流程模型分页 Request VO") +@Schema(title = "管理后台 - 流程模型分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmModelPageReqVO extends PageParam { - @ApiModelProperty(value = "标识", example = "process1641042089407", notes = "精准匹配") + @Schema(title = "标识", example = "process1641042089407", description = "精准匹配") private String key; - @ApiModelProperty(value = "名字", example = "芋道", notes = "模糊匹配") + @Schema(title = "名字", example = "芋道", description = "模糊匹配") private String name; - @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1") + @Schema(title = "流程分类", description = "参见 bpm_model_category 数据字典", example = "1") private String category; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java index 571850ff0..f8e520078 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 流程模型的创建 Request VO") +@Schema(title = "管理后台 - 流程模型的创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmModelRespVO extends BpmModelBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private String id; - @ApiModelProperty(value = "BPMN XML", required = true) + @Schema(title = "BPMN XML", required = true) private String bpmnXml; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java index 972aa31bb..b480d0b1f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java @@ -1,40 +1,39 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 流程模型的更新 Request VO") +@Schema(title = "管理后台 - 流程模型的更新 Request VO") @Data public class BpmModelUpdateReqVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") @NotEmpty(message = "编号不能为空") private String id; - @ApiModelProperty(value = "流程名称", example = "芋道") + @Schema(title = "流程名称", example = "芋道") private String name; - @ApiModelProperty(value = "流程描述", example = "我是描述") + @Schema(title = "流程描述", example = "我是描述") private String description; - @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1") + @Schema(title = "流程分类", description = "参见 bpm_model_category 数据字典", example = "1") private String category; - @ApiModelProperty(value = "BPMN XML", required = true) + @Schema(title = "BPMN XML", required = true) private String bpmnXml; - @ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1") + @Schema(title = "表单类型", description = "参见 bpm_model_form_type 数据字典", example = "1") private Integer formType; - @ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "表单编号", example = "1024", description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private Long formId; - @ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", - notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", + description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private String formCustomCreatePath; - @ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", - notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", + description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private String formCustomViewPath; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java index 9cfcebbdc..d07b3b249 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 流程模型更新状态 Request VO") +@Schema(title = "管理后台 - 流程模型更新状态 Request VO") @Data public class BpmModelUpdateStateReqVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private String id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SuspensionState 枚举") + @Schema(title = "状态", required = true, example = "1", description = "见 SuspensionState 枚举") @NotNull(message = "状态不能为空") private Integer state; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java index 5e45b8bde..664d3b27b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 流程定义列表 Request VO") +@Schema(title = "管理后台 - 流程定义列表 Request VO") @Data @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class BpmProcessDefinitionListReqVO extends PageParam { - @ApiModelProperty(value = "中断状态", example = "1", notes = "参见 SuspensionState 枚举") + @Schema(title = "中断状态", example = "1", description = "参见 SuspensionState 枚举") private Integer suspensionState; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java index 1952e95a7..5bf9bf42a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 流程定义的分页的每一项 Response VO") +@Schema(title = "管理后台 - 流程定义的分页的每一项 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmProcessDefinitionPageItemRespVO extends BpmProcessDefinitionRespVO { - @ApiModelProperty(value = "表单名字", example = "请假表单") + @Schema(title = "表单名字", example = "请假表单") private String formName; - @ApiModelProperty(value = "部署时间", required = true) + @Schema(title = "部署时间", required = true) private LocalDateTime deploymentTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java index a9657e9a2..0b92700e3 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 流程定义分页 Request VO") +@Schema(title = "管理后台 - 流程定义分页 Request VO") @Data @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class BpmProcessDefinitionPageReqVO extends PageParam { - @ApiModelProperty(value = "标识", example = "process1641042089407", notes = "精准匹配") + @Schema(title = "标识", example = "process1641042089407", description = "精准匹配") private String key; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java index 6f8fd4e5b..f4c540f2d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java @@ -1,52 +1,51 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel("管理后台 - 流程定义 Response VO") +@Schema(title = "管理后台 - 流程定义 Response VO") @Data public class BpmProcessDefinitionRespVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private String id; - @ApiModelProperty(value = "版本", required = true, example = "1") + @Schema(title = "版本", required = true, example = "1") private Integer version; - @ApiModelProperty(value = "流程名称", required = true, example = "芋道") + @Schema(title = "流程名称", required = true, example = "芋道") @NotEmpty(message = "流程名称不能为空") private String name; - @ApiModelProperty(value = "流程描述", example = "我是描述") + @Schema(title = "流程描述", example = "我是描述") private String description; - @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1") + @Schema(title = "流程分类", description = "参见 bpm_model_category 数据字典", example = "1") @NotEmpty(message = "流程分类不能为空") private String category; - @ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1") + @Schema(title = "表单类型", description = "参见 bpm_model_form_type 数据字典", example = "1") private Integer formType; - @ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "表单编号", example = "1024", description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private Long formId; - @ApiModelProperty(value = "表单的配置", required = true, - notes = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "表单的配置", required = true, + description = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private String formConf; - @ApiModelProperty(value = "表单项的数组", required = true, - notes = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "表单项的数组", required = true, + description = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private List formFields; - @ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", - notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", + description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private String formCustomCreatePath; - @ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", - notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", + description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private String formCustomViewPath; - @ApiModelProperty(value = "中断状态", required = true, example = "1", notes = "参见 SuspensionState 枚举") + @Schema(title = "中断状态", required = true, example = "1", description = "参见 SuspensionState 枚举") private Integer suspensionState; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java index bcb9fc0f0..8ec779bad 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -14,11 +13,11 @@ import java.util.Set; @Data public class BpmTaskAssignRuleBaseVO { - @ApiModelProperty(value = "规则类型", required = true, example = "bpm_task_assign_rule_type") + @Schema(title = "规则类型", required = true, example = "bpm_task_assign_rule_type") @NotNull(message = "规则类型不能为空") private Integer type; - @ApiModelProperty(value = "规则值数组", required = true, example = "1,2,3") + @Schema(title = "规则值数组", required = true, example = "1,2,3") @NotNull(message = "规则值数组不能为空") private Set options; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java index cbbc108c0..b1cc63c18 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java @@ -1,24 +1,23 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 流程任务分配规则的创建 Request VO") +@Schema(title = "管理后台 - 流程任务分配规则的创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskAssignRuleCreateReqVO extends BpmTaskAssignRuleBaseVO { - @ApiModelProperty(value = "流程模型的编号", required = true, example = "1024") + @Schema(title = "流程模型的编号", required = true, example = "1024") @NotEmpty(message = "流程模型的编号不能为空") private String modelId; - @ApiModelProperty(value = "流程任务定义的编号", required = true, example = "2048") + @Schema(title = "流程任务定义的编号", required = true, example = "2048") @NotEmpty(message = "流程任务定义的编号不能为空") private String taskDefinitionKey; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java index c0786e52b..630952e14 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java @@ -1,29 +1,28 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 流程任务分配规则的 Response VO") +@Schema(title = "管理后台 - 流程任务分配规则的 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskAssignRuleRespVO extends BpmTaskAssignRuleBaseVO { - @ApiModelProperty(value = "任务分配规则的编号", required = true, example = "1024") + @Schema(title = "任务分配规则的编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "流程模型的编号", required = true, example = "2048") + @Schema(title = "流程模型的编号", required = true, example = "2048") private String modelId; - @ApiModelProperty(value = "流程定义的编号", required = true, example = "4096") + @Schema(title = "流程定义的编号", required = true, example = "4096") private String processDefinitionId; - @ApiModelProperty(value = "流程任务定义的编号", required = true, example = "2048") + @Schema(title = "流程任务定义的编号", required = true, example = "2048") private String taskDefinitionKey; - @ApiModelProperty(value = "流程任务定义的名字", required = true, example = "关注芋道") + @Schema(title = "流程任务定义的名字", required = true, example = "关注芋道") private String taskDefinitionName; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java index 8f1c12701..bb6f44374 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 流程任务分配规则的更新 Request VO") +@Schema(title = "管理后台 - 流程任务分配规则的更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskAssignRuleUpdateReqVO extends BpmTaskAssignRuleBaseVO { - @ApiModelProperty(value = "任务分配规则的编号", required = true, example = "1024") + @Schema(title = "任务分配规则的编号", required = true, example = "1024") @NotNull(message = "任务分配规则的编号不能为空") private Long id; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java index dd66580d3..770d465b6 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/BpmOALeaveController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -27,7 +27,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti * @author jason * @author 芋道源码 */ -@Api(tags = "管理后台 - OA 请假申请") +@Tag(name = "管理后台 - OA 请假申请") @RestController @RequestMapping("/bpm/oa/leave") @Validated @@ -38,15 +38,15 @@ public class BpmOALeaveController { @PostMapping("/create") @PreAuthorize("@ss.hasPermission('bpm:oa-leave:create')") - @ApiOperation("创建请求申请") + @Operation(summary = "创建请求申请") public CommonResult createLeave(@Valid @RequestBody BpmOALeaveCreateReqVO createReqVO) { return success(leaveService.createLeave(getLoginUserId(), createReqVO)); } @GetMapping("/get") @PreAuthorize("@ss.hasPermission('bpm:oa-leave:query')") - @ApiOperation("获得请假申请") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得请假申请") + @Parameter(name = "id", description = "编号", required = true, example = "1024") public CommonResult getLeave(@RequestParam("id") Long id) { BpmOALeaveDO leave = leaveService.getLeave(id); return success(BpmOALeaveConvert.INSTANCE.convert(leave)); @@ -54,7 +54,7 @@ public class BpmOALeaveController { @GetMapping("/page") @PreAuthorize("@ss.hasPermission('bpm:oa-leave:query')") - @ApiOperation("获得请假申请分页") + @Operation(summary = "获得请假申请分页") public CommonResult> getLeavePage(@Valid BpmOALeavePageReqVO pageVO) { PageResult pageResult = leaveService.getLeavePage(getLoginUserId(), pageVO); return success(BpmOALeaveConvert.INSTANCE.convertPage(pageResult)); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java index b8b38c6f2..9d883af85 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; import javax.validation.constraints.*; import org.springframework.format.annotation.DateTimeFormat; @@ -15,19 +14,19 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class BpmOALeaveBaseVO { - @ApiModelProperty(value = "请假的开始时间", required = true) + @Schema(title = "请假的开始时间", required = true) @NotNull(message = "开始时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; - @ApiModelProperty(value = "请假的结束时间", required = true) + @Schema(title = "请假的结束时间", required = true) @NotNull(message = "结束时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; - @ApiModelProperty(value = "请假类型", required = true, example = "1", notes = "参见 bpm_oa_type 枚举") + @Schema(title = "请假类型", required = true, example = "1", description = "参见 bpm_oa_type 枚举") private Integer type; - @ApiModelProperty(value = "原因", required = true, example = "阅读芋道源码") + @Schema(title = "原因", required = true, example = "阅读芋道源码") private String reason; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java index 8ccb6807f..e1d7d082b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java @@ -1,13 +1,12 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo; - -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.AssertTrue; -@ApiModel("管理后台 - 请假申请创建 Request VO") +@Schema(title = "管理后台 - 请假申请创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java index 38dc5148f..4341bd974 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java @@ -1,30 +1,29 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 请假申请分页 Request VO") +@Schema(title = "管理后台 - 请假申请分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmOALeavePageReqVO extends PageParam { - @ApiModelProperty(value = "状态", example = "1", notes = "参见 bpm_process_instance_result 枚举") + @Schema(title = "状态", example = "1", description = "参见 bpm_process_instance_result 枚举") private Integer result; - @ApiModelProperty(value = "请假类型", example = "1", notes = "参见 bpm_oa_type") + @Schema(title = "请假类型", example = "1", description = "参见 bpm_oa_type") private Integer type; - @ApiModelProperty(value = "原因", example = "阅读芋道源码", notes = "模糊匹配") + @Schema(title = "原因", example = "阅读芋道源码", description = "模糊匹配") private String reason; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "申请时间") + @Schema(title = "申请时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java index 42b3ec66c..a30c41676 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.oa.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import org.springframework.format.annotation.DateTimeFormat; import javax.validation.constraints.NotNull; @@ -9,24 +8,24 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 请假申请 Response VO") +@Schema(title = "管理后台 - 请假申请 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmOALeaveRespVO extends BpmOALeaveBaseVO { - @ApiModelProperty(value = "请假表单主键", required = true, example = "1024") + @Schema(title = "请假表单主键", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 bpm_process_instance_result 枚举") + @Schema(title = "状态", required = true, example = "1", description = "参见 bpm_process_instance_result 枚举") private Integer result; - @ApiModelProperty(value = "申请时间", required = true) + @Schema(title = "申请时间", required = true) @NotNull(message = "申请时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime createTime; - @ApiModelProperty(value = "流程id") + @Schema(title = "流程id") private String processInstanceId; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java index 24d89cd36..44d0373f1 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmActivityController.java @@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; import cn.iocoder.yudao.module.bpm.service.task.BpmActivityService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -18,7 +18,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 流程活动实例") +@Tag(name = "管理后台 - 流程活动实例") @RestController @RequestMapping("/bpm/activity") @Validated @@ -28,9 +28,9 @@ public class BpmActivityController { private BpmActivityService activityService; @GetMapping("/list") - @ApiOperation(value = "生成指定流程实例的高亮流程图", - notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成") - @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class) + @Operation(summary = "生成指定流程实例的高亮流程图", + description = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成") + @Parameter(name = "processInstanceId", description = "流程实例的编号", required = true) @PreAuthorize("@ss.hasPermission('bpm:task:query')") public CommonResult> getActivityList( @RequestParam("processInstanceId") String processInstanceId) { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java index 31abf7de1..b8e8971f2 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java @@ -4,9 +4,9 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -17,7 +17,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Api(tags = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请” +@Tag(name = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请” @RestController @RequestMapping("/bpm/process-instance") @Validated @@ -27,7 +27,7 @@ public class BpmProcessInstanceController { private BpmProcessInstanceService processInstanceService; @GetMapping("/my-page") - @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用") + @Operation(summary = "获得我的实例分页列表", description = "在【我的流程】菜单中,进行调用") @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") public CommonResult> getMyProcessInstancePage( @Valid BpmProcessInstanceMyPageReqVO pageReqVO) { @@ -35,22 +35,22 @@ public class BpmProcessInstanceController { } @PostMapping("/create") - @ApiOperation("新建流程实例") + @Operation(summary = "新建流程实例") @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") public CommonResult createProcessInstance(@Valid @RequestBody BpmProcessInstanceCreateReqVO createReqVO) { return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO)); } @GetMapping("/get") - @ApiOperation(value = "获得指定流程实例", notes = "在【流程详细】界面中,进行调用") - @ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class) + @Operation(summary = "获得指定流程实例", description = "在【流程详细】界面中,进行调用") + @Parameter(name = "id", description = "流程实例的编号", required = true) @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") public CommonResult getProcessInstance(@RequestParam("id") String id) { return success(processInstanceService.getProcessInstanceVO(id)); } @DeleteMapping("/cancel") - @ApiOperation(value = "取消流程实例", notes = "撤回发起的流程") + @Operation(summary = "取消流程实例", description = "撤回发起的流程") @PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')") public CommonResult cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) { processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java index eaa991f55..885b03143 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java @@ -4,9 +4,9 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*; import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId; -@Api(tags = "管理后台 - 流程任务实例") +@Tag(name = "管理后台 - 流程任务实例") @RestController @RequestMapping("/bpm/task") @Validated @@ -29,22 +29,22 @@ public class BpmTaskController { private BpmTaskService taskService; @GetMapping("todo-page") - @ApiOperation("获取 Todo 待办任务分页") + @Operation(summary = "获取 Todo 待办任务分页") @PreAuthorize("@ss.hasPermission('bpm:task:query')") public CommonResult> getTodoTaskPage(@Valid BpmTaskTodoPageReqVO pageVO) { return success(taskService.getTodoTaskPage(getLoginUserId(), pageVO)); } @GetMapping("done-page") - @ApiOperation("获取 Done 已办任务分页") + @Operation(summary = "获取 Done 已办任务分页") @PreAuthorize("@ss.hasPermission('bpm:task:query')") public CommonResult> getDoneTaskPage(@Valid BpmTaskDonePageReqVO pageVO) { return success(taskService.getDoneTaskPage(getLoginUserId(), pageVO)); } @GetMapping("/list-by-process-instance-id") - @ApiOperation(value = "获得指定流程实例的任务列表", notes = "包括完成的、未完成的") - @ApiImplicitParam(name = "processInstanceId", value = "流程实例的编号", required = true, dataTypeClass = String.class) + @Operation(summary = "获得指定流程实例的任务列表", description = "包括完成的、未完成的") + @Parameter(name = "processInstanceId", description = "流程实例的编号", required = true) @PreAuthorize("@ss.hasPermission('bpm:task:query')") public CommonResult> getTaskListByProcessInstanceId( @RequestParam("processInstanceId") String processInstanceId) { @@ -52,7 +52,7 @@ public class BpmTaskController { } @PutMapping("/approve") - @ApiOperation("通过任务") + @Operation(summary = "通过任务") @PreAuthorize("@ss.hasPermission('bpm:task:update')") public CommonResult approveTask(@Valid @RequestBody BpmTaskApproveReqVO reqVO) { taskService.approveTask(getLoginUserId(), reqVO); @@ -60,7 +60,7 @@ public class BpmTaskController { } @PutMapping("/reject") - @ApiOperation("不通过任务") + @Operation(summary = "不通过任务") @PreAuthorize("@ss.hasPermission('bpm:task:update')") public CommonResult rejectTask(@Valid @RequestBody BpmTaskRejectReqVO reqVO) { taskService.rejectTask(getLoginUserId(), reqVO); @@ -68,7 +68,7 @@ public class BpmTaskController { } @PutMapping("/update-assignee") - @ApiOperation(value = "更新任务的负责人", notes = "用于【流程详情】的【转派】按钮") + @Operation(summary = "更新任务的负责人", description = "用于【流程详情】的【转派】按钮") @PreAuthorize("@ss.hasPermission('bpm:task:update')") public CommonResult updateTaskAssignee(@Valid @RequestBody BpmTaskUpdateAssigneeReqVO reqVO) { taskService.updateTaskAssignee(getLoginUserId(), reqVO); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java index 7f183f50c..997b8bce0 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; -@ApiModel("管理后台 - 流程活动的 Response VO") +@Schema(title = "管理后台 - 流程活动的 Response VO") @Data public class BpmActivityRespVO { - @ApiModelProperty(value = "流程活动的标识", required = true, example = "1024") + @Schema(title = "流程活动的标识", required = true, example = "1024") private String key; - @ApiModelProperty(value = "流程活动的类型", required = true, example = "StartEvent") + @Schema(title = "流程活动的类型", required = true, example = "StartEvent") private String type; - @ApiModelProperty(value = "流程活动的开始时间", required = true) + @Schema(title = "流程活动的开始时间", required = true) private LocalDateTime startTime; - @ApiModelProperty(value = "流程活动的结束时间", required = true) + @Schema(title = "流程活动的结束时间", required = true) private LocalDateTime endTime; - @ApiModelProperty(value = "关联的流程任务的编号", example = "2048", notes = "关联的流程任务,只有 UserTask 等类型才有") + @Schema(title = "关联的流程任务的编号", example = "2048", description = "关联的流程任务,只有 UserTask 等类型才有") private String taskId; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java index 928f187e7..3a2ea654c 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.Map; -@ApiModel("管理后台 - 流程实例的取消 Request VO") +@Schema(title = "管理后台 - 流程实例的取消 Request VO") @Data public class BpmProcessInstanceCancelReqVO { - @ApiModelProperty(value = "流程实例的编号", required = true, example = "1024") + @Schema(title = "流程实例的编号", required = true, example = "1024") @NotEmpty(message = "流程实例的编号不能为空") private String id; - @ApiModelProperty(value = "取消原因", required = true, example = "不请假了!") + @Schema(title = "取消原因", required = true, example = "不请假了!") @NotEmpty(message = "取消原因不能为空") private String reason; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java index 2085253d3..588de54fd 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; import java.util.Map; -@ApiModel("管理后台 - 流程实例的创建 Request VO") +@Schema(title = "管理后台 - 流程实例的创建 Request VO") @Data public class BpmProcessInstanceCreateReqVO { - @ApiModelProperty(value = "流程定义的编号", required = true, example = "1024") + @Schema(title = "流程定义的编号", required = true, example = "1024") @NotEmpty(message = "流程定义编号不能为空") private String processDefinitionId; - @ApiModelProperty(value = "变量实例") + @Schema(title = "变量实例") private Map variables; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java index e52d45f44..111c73b5d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,28 +11,28 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 流程实例的分页 Item Response VO") +@Schema(title = "管理后台 - 流程实例的分页 Item Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmProcessInstanceMyPageReqVO extends PageParam { - @ApiModelProperty(value = "流程名称", example = "芋道") + @Schema(title = "流程名称", example = "芋道") private String name; - @ApiModelProperty(value = "流程定义的编号", example = "2048") + @Schema(title = "流程定义的编号", example = "2048") private String processDefinitionId; - @ApiModelProperty(value = "流程实例的状态", notes = "参见 bpm_process_instance_status", example = "1") + @Schema(title = "流程实例的状态", description = "参见 bpm_process_instance_status", example = "1") private Integer status; - @ApiModelProperty(value = "流程实例的结果", notes = "参见 bpm_process_instance_result", example = "2") + @Schema(title = "流程实例的结果", description = "参见 bpm_process_instance_result", example = "2") private Integer result; - @ApiModelProperty(value = "流程分类", notes = "参见 bpm_model_category 数据字典", example = "1") + @Schema(title = "流程分类", description = "参见 bpm_model_category 数据字典", example = "1") private String category; - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java index 0d2534b53..c367eaf5a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java @@ -1,38 +1,37 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; import java.util.List; -@ApiModel("管理后台 - 流程实例的分页 Item Response VO") +@Schema(title = "管理后台 - 流程实例的分页 Item Response VO") @Data public class BpmProcessInstancePageItemRespVO { - @ApiModelProperty(value = "流程实例的编号", required = true, example = "1024") + @Schema(title = "流程实例的编号", required = true, example = "1024") private String id; - @ApiModelProperty(value = "流程名称", required = true, example = "芋道") + @Schema(title = "流程名称", required = true, example = "芋道") private String name; - @ApiModelProperty(value = "流程定义的编号", required = true, example = "2048") + @Schema(title = "流程定义的编号", required = true, example = "2048") private String processDefinitionId; - @ApiModelProperty(value = "流程分类", required = true, notes = "参见 bpm_model_category 数据字典", example = "1") + @Schema(title = "流程分类", required = true, description = "参见 bpm_model_category 数据字典", example = "1") private String category; - @ApiModelProperty(value = "流程实例的状态", required = true, notes = "参见 bpm_process_instance_status", example = "1") + @Schema(title = "流程实例的状态", required = true, description = "参见 bpm_process_instance_status", example = "1") private Integer status; - @ApiModelProperty(value = "流程实例的结果", required = true, notes = "参见 bpm_process_instance_result", example = "2") + @Schema(title = "流程实例的结果", required = true, description = "参见 bpm_process_instance_result", example = "2") private Integer result; - @ApiModelProperty(value = "提交时间", required = true) + @Schema(title = "提交时间", required = true) private LocalDateTime createTime; - @ApiModelProperty(value = "结束时间", required = true) + @Schema(title = "结束时间", required = true) private LocalDateTime endTime; /** @@ -40,14 +39,14 @@ public class BpmProcessInstancePageItemRespVO { */ private List tasks; - @ApiModel("流程任务") + @Schema(title = "流程任务") @Data public static class Task { - @ApiModelProperty(value = "流程任务的编号", required = true, example = "1024") + @Schema(title = "流程任务的编号", required = true, example = "1024") private String id; - @ApiModelProperty(value = "任务名称", required = true, example = "芋道") + @Schema(title = "任务名称", required = true, example = "芋道") private String name; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java index 58374dae2..8d02aec71 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java @@ -1,42 +1,41 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; import java.util.List; import java.util.Map; -@ApiModel("管理后台 - 流程实例的 Response VO") +@Schema(title = "管理后台 - 流程实例的 Response VO") @Data public class BpmProcessInstanceRespVO { - @ApiModelProperty(value = "流程实例的编号", required = true, example = "1024") + @Schema(title = "流程实例的编号", required = true, example = "1024") private String id; - @ApiModelProperty(value = "流程名称", required = true, example = "芋道") + @Schema(title = "流程名称", required = true, example = "芋道") private String name; - @ApiModelProperty(value = "流程分类", required = true, notes = "参见 bpm_model_category 数据字典", example = "1") + @Schema(title = "流程分类", required = true, description = "参见 bpm_model_category 数据字典", example = "1") private String category; - @ApiModelProperty(value = "流程实例的状态", required = true, notes = "参见 bpm_process_instance_status", example = "1") + @Schema(title = "流程实例的状态", required = true, description = "参见 bpm_process_instance_status", example = "1") private Integer status; - @ApiModelProperty(value = "流程实例的结果", required = true, notes = "参见 bpm_process_instance_result", example = "2") + @Schema(title = "流程实例的结果", required = true, description = "参见 bpm_process_instance_result", example = "2") private Integer result; - @ApiModelProperty(value = "提交时间", required = true) + @Schema(title = "提交时间", required = true) private LocalDateTime createTime; - @ApiModelProperty(value = "结束时间", required = true) + @Schema(title = "结束时间", required = true) private LocalDateTime endTime; - @ApiModelProperty(value = "提交的表单值", required = true) + @Schema(title = "提交的表单值", required = true) private Map formVariables; - @ApiModelProperty(value = "业务的唯一标识", example = "1", notes = "例如说,请假申请的编号") + @Schema(title = "业务的唯一标识", example = "1", description = "例如说,请假申请的编号") private String businessKey; /** @@ -49,47 +48,47 @@ public class BpmProcessInstanceRespVO { */ private ProcessDefinition processDefinition; - @ApiModel("用户信息") + @Schema(title = "用户信息") @Data public static class User { - @ApiModelProperty(value = "用户编号", required = true, example = "1") + @Schema(title = "用户编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") + @Schema(title = "用户昵称", required = true, example = "芋艿") private String nickname; - @ApiModelProperty(value = "部门编号", required = true, example = "1") + @Schema(title = "部门编号", required = true, example = "1") private Long deptId; - @ApiModelProperty(value = "部门名称", required = true, example = "研发部") + @Schema(title = "部门名称", required = true, example = "研发部") private String deptName; } - @ApiModel("流程定义信息") + @Schema(title = "流程定义信息") @Data public static class ProcessDefinition { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private String id; - @ApiModelProperty(value = "表单类型", notes = "参见 bpm_model_form_type 数据字典", example = "1") + @Schema(title = "表单类型", description = "参见 bpm_model_form_type 数据字典", example = "1") private Integer formType; - @ApiModelProperty(value = "表单编号", example = "1024", notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "表单编号", example = "1024", description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private Long formId; - @ApiModelProperty(value = "表单的配置", required = true, - notes = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "表单的配置", required = true, + description = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private String formConf; - @ApiModelProperty(value = "表单项的数组", required = true, - notes = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "表单项的数组", required = true, + description = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private List formFields; - @ApiModelProperty(value = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", - notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", + description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private String formCustomCreatePath; - @ApiModelProperty(value = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", - notes = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(title = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", + description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") private String formCustomViewPath; - @ApiModelProperty(value = "BPMN XML", required = true) + @Schema(title = "BPMN XML", required = true) private String bpmnXml; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java index 1b6a69066..5e023f2c1 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 通过流程任务的 Request VO") +@Schema(title = "管理后台 - 通过流程任务的 Request VO") @Data public class BpmTaskApproveReqVO { - @ApiModelProperty(value = "任务编号", required = true, example = "1024") + @Schema(title = "任务编号", required = true, example = "1024") @NotEmpty(message = "任务编号不能为空") private String id; - @ApiModelProperty(value = "审批意见", required = true, example = "不错不错!") + @Schema(title = "审批意见", required = true, example = "不错不错!") @NotEmpty(message = "审批意见不能为空") private String reason; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java index a9bb93f9e..a77fb1002 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java @@ -1,27 +1,26 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 流程任务的 Done 已完成的分页项 Response VO") +@Schema(title = "管理后台 - 流程任务的 Done 已完成的分页项 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskDonePageItemRespVO extends BpmTaskTodoPageItemRespVO { - @ApiModelProperty(value = "结束时间", required = true) + @Schema(title = "结束时间", required = true) private LocalDateTime endTime; - @ApiModelProperty(value = "持续时间", required = true, example = "1000") + @Schema(title = "持续时间", required = true, example = "1000") private Long durationInMillis; - @ApiModelProperty(value = "任务结果", required = true, notes = "参见 bpm_process_instance_result", example = "2") + @Schema(title = "任务结果", required = true, description = "参见 bpm_process_instance_result", example = "2") private Integer result; - @ApiModelProperty(value = "审批建议", required = true, example = "不请假了!") + @Schema(title = "审批建议", required = true, example = "不请假了!") private String reason; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java index a347d58fe..fa152186c 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 流程任务的 Done 已办的分页 Request VO") +@Schema(title = "管理后台 - 流程任务的 Done 已办的分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskDonePageReqVO extends PageParam { - @ApiModelProperty(value = "流程任务名", example = "芋道") + @Schema(title = "流程任务名", example = "芋道") private String name; - @ApiModelProperty(value = "开始的创建收间") + @Schema(title = "开始的创建收间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime beginCreateTime; - @ApiModelProperty(value = "结束的创建时间") + @Schema(title = "结束的创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endCreateTime; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java index 596a82f77..1b7d0d34f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 不通过流程任务的 Request VO") +@Schema(title = "管理后台 - 不通过流程任务的 Request VO") @Data public class BpmTaskRejectReqVO { - @ApiModelProperty(value = "任务编号", required = true, example = "1024") + @Schema(title = "任务编号", required = true, example = "1024") @NotEmpty(message = "任务编号不能为空") private String id; - @ApiModelProperty(value = "审批意见", required = true, example = "不错不错!") + @Schema(title = "审批意见", required = true, example = "不错不错!") @NotEmpty(message = "审批意见不能为空") private String reason; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java index 1f7d2c7fa..df1e10764 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 流程任务的 Response VO") +@Schema(title = "管理后台 - 流程任务的 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO { - @ApiModelProperty(value = "任务定义的标识", required = true, example = "user-001") + @Schema(title = "任务定义的标识", required = true, example = "user-001") private String definitionKey; /** @@ -20,18 +19,18 @@ public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO { */ private User assigneeUser; - @ApiModel("用户信息") + @Schema(title = "用户信息") @Data public static class User { - @ApiModelProperty(value = "用户编号", required = true, example = "1") + @Schema(title = "用户编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") + @Schema(title = "用户昵称", required = true, example = "芋艿") private String nickname; - @ApiModelProperty(value = "部门编号", required = true, example = "1") + @Schema(title = "部门编号", required = true, example = "1") private Long deptId; - @ApiModelProperty(value = "部门名称", required = true, example = "研发部") + @Schema(title = "部门名称", required = true, example = "研发部") private String deptName; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java index 5c2cbf26a..dbcdb7c14 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java @@ -1,28 +1,27 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; -@ApiModel("管理后台 - 流程任务的 Running 进行中的分页项 Response VO") +@Schema(title = "管理后台 - 流程任务的 Running 进行中的分页项 Response VO") @Data public class BpmTaskTodoPageItemRespVO { - @ApiModelProperty(value = "任务编号", required = true, example = "1024") + @Schema(title = "任务编号", required = true, example = "1024") private String id; - @ApiModelProperty(value = "任务名字", required = true, example = "芋道") + @Schema(title = "任务名字", required = true, example = "芋道") private String name; - @ApiModelProperty(value = "接收时间", required = true) + @Schema(title = "接收时间", required = true) private LocalDateTime claimTime; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; - @ApiModelProperty(value = "激活状态", required = true, example = "1", notes = "参见 SuspensionState 枚举") + @Schema(title = "激活状态", required = true, example = "1", description = "参见 SuspensionState 枚举") private Integer suspensionState; /** @@ -31,22 +30,22 @@ public class BpmTaskTodoPageItemRespVO { private ProcessInstance processInstance; @Data - @ApiModel("流程实例") + @Schema(title = "流程实例") public static class ProcessInstance { - @ApiModelProperty(value = "流程实例编号", required = true, example = "1024") + @Schema(title = "流程实例编号", required = true, example = "1024") private String id; - @ApiModelProperty(value = "流程实例名称", required = true, example = "芋道") + @Schema(title = "流程实例名称", required = true, example = "芋道") private String name; - @ApiModelProperty(value = "发起人的用户编号", required = true, example = "1024") + @Schema(title = "发起人的用户编号", required = true, example = "1024") private Long startUserId; - @ApiModelProperty(value = "发起人的用户昵称", required = true, example = "芋艿") + @Schema(title = "发起人的用户昵称", required = true, example = "芋艿") private String startUserNickname; - @ApiModelProperty(value = "流程定义的编号", required = true, example = "2048") + @Schema(title = "流程定义的编号", required = true, example = "2048") private String processDefinitionId; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java index 9d2ad18c2..d4994e272 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 流程任务的 TODO 待办的分页 Request VO") +@Schema(title = "管理后台 - 流程任务的 TODO 待办的分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskTodoPageReqVO extends PageParam { - @ApiModelProperty(value = "流程任务名", example = "芋道") + @Schema(title = "流程任务名", example = "芋道") private String name; - @ApiModelProperty(value = "开始的创建收间") + @Schema(title = "开始的创建收间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime beginCreateTime; - @ApiModelProperty(value = "结束的创建时间") + @Schema(title = "结束的创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endCreateTime; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java index 0dd0ffed4..0bd364043 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -10,15 +9,15 @@ import net.bytebuddy.implementation.bind.annotation.Empty; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 流程任务的更新负责人的 Request VO") +@Schema(title = "管理后台 - 流程任务的更新负责人的 Request VO") @Data public class BpmTaskUpdateAssigneeReqVO { - @ApiModelProperty(value = "任务编号", required = true, example = "1024") + @Schema(title = "任务编号", required = true, example = "1024") @NotEmpty(message = "任务编号不能为空") private String id; - @ApiModelProperty(value = "新审批人的用户编号", required = true, example = "2048") + @Schema(title = "新审批人的用户编号", required = true, example = "2048") @NotNull(message = "新审批人的用户编号不能为空") private Long assigneeUserId; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java index 9a0013b93..76e5b6a83 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java @@ -16,10 +16,10 @@ import cn.iocoder.yudao.module.infra.convert.codegen.CodegenConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO; import cn.iocoder.yudao.module.infra.service.codegen.CodegenService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -36,7 +36,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Api(tags = "管理后台 - 代码生成器") +@Tag(name = "管理后台 - 代码生成器") @RestController @RequestMapping("/infra/codegen") @Validated @@ -46,11 +46,11 @@ public class CodegenController { private CodegenService codegenService; @GetMapping("/db/table/list") - @ApiOperation(value = "获得数据库自带的表定义列表", notes = "会过滤掉已经导入 Codegen 的表") - @ApiImplicitParams({ - @ApiImplicitParam(name = "dataSourceConfigId", value = "数据源配置的编号", required = true, example = "1", dataTypeClass = Long.class), - @ApiImplicitParam(name = "name", value = "表名,模糊匹配", example = "yudao", dataTypeClass = String.class), - @ApiImplicitParam(name = "comment", value = "描述,模糊匹配", example = "芋道", dataTypeClass = String.class) + @Operation(summary = "获得数据库自带的表定义列表", description = "会过滤掉已经导入 Codegen 的表") + @Parameters({ + @Parameter(name = "dataSourceConfigId", description = "数据源配置的编号", required = true, example = "1"), + @Parameter(name = "name", description = "表名,模糊匹配", example = "yudao"), + @Parameter(name = "comment", description = "描述,模糊匹配", example = "芋道") }) @PreAuthorize("@ss.hasPermission('infra:codegen:query')") public CommonResult> getDatabaseTableList( @@ -61,7 +61,7 @@ public class CodegenController { } @GetMapping("/table/page") - @ApiOperation("获得表定义分页") + @Operation(summary = "获得表定义分页") @PreAuthorize("@ss.hasPermission('infra:codegen:query')") public CommonResult> getCodeGenTablePage(@Valid CodegenTablePageReqVO pageReqVO) { PageResult pageResult = codegenService.getCodegenTablePage(pageReqVO); @@ -69,8 +69,8 @@ public class CodegenController { } @GetMapping("/detail") - @ApiOperation("获得表和字段的明细") - @ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得表和字段的明细") + @Parameter(name = "tableId", description = "表编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:codegen:query')") public CommonResult getCodegenDetail(@RequestParam("tableId") Long tableId) { CodegenTableDO table = codegenService.getCodegenTablePage(tableId); @@ -79,14 +79,14 @@ public class CodegenController { return success(CodegenConvert.INSTANCE.convert(table, columns)); } - @ApiOperation("基于数据库的表结构,创建代码生成器的表和字段定义") + @Operation(summary = "基于数据库的表结构,创建代码生成器的表和字段定义") @PostMapping("/create-list") @PreAuthorize("@ss.hasPermission('infra:codegen:create')") public CommonResult> createCodegenList(@Valid @RequestBody CodegenCreateListReqVO reqVO) { return success(codegenService.createCodegenList(getLoginUserId(), reqVO)); } - @ApiOperation("更新数据库的表和字段定义") + @Operation(summary = "更新数据库的表和字段定义") @PutMapping("/update") @PreAuthorize("@ss.hasPermission('infra:codegen:update')") public CommonResult updateCodegen(@Valid @RequestBody CodegenUpdateReqVO updateReqVO) { @@ -94,36 +94,36 @@ public class CodegenController { return success(true); } - @ApiOperation("基于数据库的表结构,同步数据库的表和字段定义") + @Operation(summary = "基于数据库的表结构,同步数据库的表和字段定义") @PutMapping("/sync-from-db") - @ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class) + @Parameter(name = "tableId", description = "表编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:codegen:update')") public CommonResult syncCodegenFromDB(@RequestParam("tableId") Long tableId) { codegenService.syncCodegenFromDB(tableId); return success(true); } - @ApiOperation("删除数据库的表和字段定义") + @Operation(summary = "删除数据库的表和字段定义") @DeleteMapping("/delete") - @ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class) + @Parameter(name = "tableId", description = "表编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:codegen:delete')") public CommonResult deleteCodegen(@RequestParam("tableId") Long tableId) { codegenService.deleteCodegen(tableId); return success(true); } - @ApiOperation("预览生成代码") + @Operation(summary = "预览生成代码") @GetMapping("/preview") - @ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class) + @Parameter(name = "tableId", description = "表编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:codegen:preview')") public CommonResult> previewCodegen(@RequestParam("tableId") Long tableId) { Map codes = codegenService.generationCodes(tableId); return success(CodegenConvert.INSTANCE.convert(codes)); } - @ApiOperation("下载生成代码") + @Operation(summary = "下载生成代码") @GetMapping("/download") - @ApiImplicitParam(name = "tableId", value = "表编号", required = true, example = "1024", dataTypeClass = Long.class) + @Parameter(name = "tableId", description = "表编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:codegen:download')") public void downloadCodegen(@RequestParam("tableId") Long tableId, HttpServletResponse response) throws IOException { diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenCreateListReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenCreateListReqVO.java index 965c5d2b9..c2a1497df 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenCreateListReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenCreateListReqVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel("管理后台 - 基于数据库的表结构,创建代码生成器的表和字段定义 Request VO") +@Schema(title = "管理后台 - 基于数据库的表结构,创建代码生成器的表和字段定义 Request VO") @Data public class CodegenCreateListReqVO { - @ApiModelProperty(value = "数据源配置的编号", required = true, example = "1") + @Schema(title = "数据源配置的编号", required = true, example = "1") @NotNull(message = "数据源配置的编号不能为空") private Long dataSourceConfigId; - @ApiModelProperty(value = "表名数组", required = true, example = "[1, 2, 3]") + @Schema(title = "表名数组", required = true, example = "[1, 2, 3]") @NotNull(message = "表名数组不能为空") private List tableNames; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenDetailRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenDetailRespVO.java index ad9c86812..3b8e13e94 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenDetailRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenDetailRespVO.java @@ -2,20 +2,19 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column.CodegenColumnRespVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableRespVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; -@ApiModel("管理后台 - 代码生成表和字段的明细 Response VO") +@Schema(title = "管理后台 - 代码生成表和字段的明细 Response VO") @Data public class CodegenDetailRespVO { - @ApiModelProperty("表定义") + @Schema(name = "表定义") private CodegenTableRespVO table; - @ApiModelProperty("字段定义") + @Schema(name = "字段定义") private List columns; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenPreviewRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenPreviewRespVO.java index 662a2350c..597d4de8f 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenPreviewRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenPreviewRespVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel(value = "管理后台 - 代码生成预览 Response VO", description ="注意,每个文件都是一个该对象") +@Schema(title = "管理后台 - 代码生成预览 Response VO", description ="注意,每个文件都是一个该对象") @Data public class CodegenPreviewRespVO { - @ApiModelProperty(value = "文件路径", required = true, example = "java/cn/iocoder/yudao/adminserver/modules/system/controller/test/SysTestDemoController.java") + @Schema(title = "文件路径", required = true, example = "java/cn/iocoder/yudao/adminserver/modules/system/controller/test/SysTestDemoController.java") private String filePath; - @ApiModelProperty(value = "代码", required = true, example = "Hello World") + @Schema(title = "代码", required = true, example = "Hello World") private String code; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenUpdateReqVO.java index 2423da077..8ccde1284 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenUpdateReqVO.java @@ -4,8 +4,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column.CodegenColumnBaseVO; import cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table.CodegenTableBaseVO; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -15,7 +14,7 @@ import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel("管理后台 - 代码生成表和字段的修改 Request VO") +@Schema(title = "管理后台 - 代码生成表和字段的修改 Request VO") @Data public class CodegenUpdateReqVO { @@ -27,14 +26,14 @@ public class CodegenUpdateReqVO { @NotNull(message = "字段定义不能为空") private List columns; - @ApiModel("更新表定义") + @Schema(title = "更新表定义") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @Valid public static class Table extends CodegenTableBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1") + @Schema(title = "编号", required = true, example = "1") private Long id; @AssertTrue(message = "上级菜单不能为空") @@ -46,13 +45,13 @@ public class CodegenUpdateReqVO { } - @ApiModel("更新表定义") + @Schema(title = "更新表定义") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public static class Column extends CodegenColumnBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1") + @Schema(title = "编号", required = true, example = "1") private Long id; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnBaseVO.java index 770255185..f9a3a668b 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -12,73 +11,73 @@ import javax.validation.constraints.NotNull; @Data public class CodegenColumnBaseVO { - @ApiModelProperty(value = "表编号", required = true, example = "1") + @Schema(title = "表编号", required = true, example = "1") @NotNull(message = "表编号不能为空") private Long tableId; - @ApiModelProperty(value = "字段名", required = true, example = "user_age") + @Schema(title = "字段名", required = true, example = "user_age") @NotNull(message = "字段名不能为空") private String columnName; - @ApiModelProperty(value = "字段类型", required = true, example = "int(11)") + @Schema(title = "字段类型", required = true, example = "int(11)") @NotNull(message = "字段类型不能为空") private String dataType; - @ApiModelProperty(value = "字段描述", required = true, example = "年龄") + @Schema(title = "字段描述", required = true, example = "年龄") @NotNull(message = "字段描述不能为空") private String columnComment; - @ApiModelProperty(value = "是否允许为空", required = true, example = "true") + @Schema(title = "是否允许为空", required = true, example = "true") @NotNull(message = "是否允许为空不能为空") private Boolean nullable; - @ApiModelProperty(value = "是否主键", required = true, example = "false") + @Schema(title = "是否主键", required = true, example = "false") @NotNull(message = "是否主键不能为空") private Boolean primaryKey; - @ApiModelProperty(value = "是否自增", required = true, example = "true") + @Schema(title = "是否自增", required = true, example = "true") @NotNull(message = "是否自增不能为空") private String autoIncrement; - @ApiModelProperty(value = "排序", required = true, example = "10") + @Schema(title = "排序", required = true, example = "10") @NotNull(message = "排序不能为空") private Integer ordinalPosition; - @ApiModelProperty(value = "Java 属性类型", required = true, example = "userAge") + @Schema(title = "Java 属性类型", required = true, example = "userAge") @NotNull(message = "Java 属性类型不能为空") private String javaType; - @ApiModelProperty(value = "Java 属性名", required = true, example = "Integer") + @Schema(title = "Java 属性名", required = true, example = "Integer") @NotNull(message = "Java 属性名不能为空") private String javaField; - @ApiModelProperty(value = "字典类型", example = "sys_gender") + @Schema(title = "字典类型", example = "sys_gender") private String dictType; - @ApiModelProperty(value = "数据示例", example = "1024") + @Schema(title = "数据示例", example = "1024") private String example; - @ApiModelProperty(value = "是否为 Create 创建操作的字段", required = true, example = "true") + @Schema(title = "是否为 Create 创建操作的字段", required = true, example = "true") @NotNull(message = "是否为 Create 创建操作的字段不能为空") private Boolean createOperation; - @ApiModelProperty(value = "是否为 Update 更新操作的字段", required = true, example = "false") + @Schema(title = "是否为 Update 更新操作的字段", required = true, example = "false") @NotNull(message = "是否为 Update 更新操作的字段不能为空") private Boolean updateOperation; - @ApiModelProperty(value = "是否为 List 查询操作的字段", required = true, example = "true") + @Schema(title = "是否为 List 查询操作的字段", required = true, example = "true") @NotNull(message = "是否为 List 查询操作的字段不能为空") private Boolean listOperation; - @ApiModelProperty(value = "List 查询操作的条件类型", required = true, example = "LIKE", notes = "参见 CodegenColumnListConditionEnum 枚举") + @Schema(title = "List 查询操作的条件类型", required = true, example = "LIKE", description = "参见 CodegenColumnListConditionEnum 枚举") @NotNull(message = "List 查询操作的条件类型不能为空") private String listOperationCondition; - @ApiModelProperty(value = "是否为 List 查询操作的返回字段", required = true, example = "true") + @Schema(title = "是否为 List 查询操作的返回字段", required = true, example = "true") @NotNull(message = "是否为 List 查询操作的返回字段不能为空") private Boolean listOperationResult; - @ApiModelProperty(value = "显示类型", required = true, example = "input") + @Schema(title = "显示类型", required = true, example = "input") @NotNull(message = "显示类型不能为空") private String htmlType; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnRespVO.java index 125b71801..c5abfa1e1 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.column; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 代码生成字段定义 Response VO") +@Schema(title = "管理后台 - 代码生成字段定义 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CodegenColumnRespVO extends CodegenColumnBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1") + @Schema(title = "编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableBaseVO.java index ad69de7dd..01cb907f4 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -12,46 +11,46 @@ import javax.validation.constraints.NotNull; @Data public class CodegenTableBaseVO { - @ApiModelProperty(value = "生成场景", required = true, example = "1", notes = "参见 CodegenSceneEnum 枚举") + @Schema(title = "生成场景", required = true, example = "1", description = "参见 CodegenSceneEnum 枚举") @NotNull(message = "导入类型不能为空") private Integer scene; - @ApiModelProperty(value = "表名称", required = true, example = "yudao") + @Schema(title = "表名称", required = true, example = "yudao") @NotNull(message = "表名称不能为空") private String tableName; - @ApiModelProperty(value = "表描述", required = true, example = "芋道") + @Schema(title = "表描述", required = true, example = "芋道") @NotNull(message = "表描述不能为空") private String tableComment; - @ApiModelProperty(value = "备注", example = "我是备注") + @Schema(title = "备注", example = "我是备注") private String remark; - @ApiModelProperty(value = "模块名", required = true, example = "system") + @Schema(title = "模块名", required = true, example = "system") @NotNull(message = "模块名不能为空") private String moduleName; - @ApiModelProperty(value = "业务名", required = true, example = "codegen") + @Schema(title = "业务名", required = true, example = "codegen") @NotNull(message = "业务名不能为空") private String businessName; - @ApiModelProperty(value = "类名称", required = true, example = "CodegenTable") + @Schema(title = "类名称", required = true, example = "CodegenTable") @NotNull(message = "类名称不能为空") private String className; - @ApiModelProperty(value = "类描述", required = true, example = "代码生成器的表定义") + @Schema(title = "类描述", required = true, example = "代码生成器的表定义") @NotNull(message = "类描述不能为空") private String classComment; - @ApiModelProperty(value = "作者", required = true, example = "芋道源码") + @Schema(title = "作者", required = true, example = "芋道源码") @NotNull(message = "作者不能为空") private String author; - @ApiModelProperty(value = "模板类型", required = true, example = "1", notes = "参见 CodegenTemplateTypeEnum 枚举") + @Schema(title = "模板类型", required = true, example = "1", description = "参见 CodegenTemplateTypeEnum 枚举") @NotNull(message = "模板类型不能为空") private Integer templateType; - @ApiModelProperty(value = "父菜单编号", example = "1024") + @Schema(title = "父菜单编号", example = "1024") private Long parentMenuId; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTablePageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTablePageReqVO.java index 7a8ff7f31..648869d7b 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTablePageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTablePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,19 +11,19 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 表定义分页 Request VO") +@Schema(title = "管理后台 - 表定义分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CodegenTablePageReqVO extends PageParam { - @ApiModelProperty(value = "表名称", example = "yudao", notes = "模糊匹配") + @Schema(title = "表名称", example = "yudao", description = "模糊匹配") private String tableName; - @ApiModelProperty(value = "表描述", example = "芋道", notes = "模糊匹配") + @Schema(title = "表描述", example = "芋道", description = "模糊匹配") private String tableComment; - @ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableRespVO.java index 7ef96b9a8..4703fa4ae 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableRespVO.java @@ -1,29 +1,28 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 代码生成表定义 Response VO") +@Schema(title = "管理后台 - 代码生成表定义 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CodegenTableRespVO extends CodegenTableBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1") + @Schema(title = "编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "主键编号", required = true, example = "1024") + @Schema(title = "主键编号", required = true, example = "1024") private Integer dataSourceConfigId; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; - @ApiModelProperty(value = "更新时间", required = true) + @Schema(title = "更新时间", required = true) private LocalDateTime updateTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/DatabaseTableRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/DatabaseTableRespVO.java index 1423d119e..e2541666e 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/DatabaseTableRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/DatabaseTableRespVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("管理后台 - 数据库的表定义 Response VO") +@Schema(title = "管理后台 - 数据库的表定义 Response VO") @Data public class DatabaseTableRespVO { - @ApiModelProperty(value = "表名称", required = true, example = "yuanma") + @Schema(title = "表名称", required = true, example = "yuanma") private String name; - @ApiModelProperty(value = "表描述", required = true, example = "芋道源码") + @Schema(title = "表描述", required = true, example = "芋道源码") private String comment; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java index 726a10498..cfd1ece7b 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java @@ -10,9 +10,9 @@ import cn.iocoder.yudao.module.infra.convert.config.ConfigConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO; import cn.iocoder.yudao.module.infra.service.config.ConfigService; import cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -26,7 +26,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 参数配置") +@Tag(name = "管理后台 - 参数配置") @RestController @RequestMapping("/infra/config") @Validated @@ -36,14 +36,14 @@ public class ConfigController { private ConfigService configService; @PostMapping("/create") - @ApiOperation("创建参数配置") + @Operation(summary = "创建参数配置") @PreAuthorize("@ss.hasPermission('infra:config:create')") public CommonResult createConfig(@Valid @RequestBody ConfigCreateReqVO reqVO) { return success(configService.createConfig(reqVO)); } @PutMapping("/update") - @ApiOperation("修改参数配置") + @Operation(summary = "修改参数配置") @PreAuthorize("@ss.hasPermission('infra:config:update')") public CommonResult updateConfig(@Valid @RequestBody ConfigUpdateReqVO reqVO) { configService.updateConfig(reqVO); @@ -51,8 +51,8 @@ public class ConfigController { } @DeleteMapping("/delete") - @ApiOperation("删除参数配置") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除参数配置") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:config:delete')") public CommonResult deleteConfig(@RequestParam("id") Long id) { configService.deleteConfig(id); @@ -60,16 +60,16 @@ public class ConfigController { } @GetMapping(value = "/get") - @ApiOperation("获得参数配置") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得参数配置") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:config:query')") public CommonResult getConfig(@RequestParam("id") Long id) { return success(ConfigConvert.INSTANCE.convert(configService.getConfig(id))); } @GetMapping(value = "/get-value-by-key") - @ApiOperation(value = "根据参数键名查询参数值", notes = "不可见的配置,不允许返回给前端") - @ApiImplicitParam(name = "key", value = "参数键", required = true, example = "yunai.biz.username", dataTypeClass = String.class) + @Operation(summary = "根据参数键名查询参数值", description = "不可见的配置,不允许返回给前端") + @Parameter(name = "key", description = "参数键", required = true, example = "yunai.biz.username") public CommonResult getConfigKey(@RequestParam("key") String key) { ConfigDO config = configService.getConfigByKey(key); if (config == null) { @@ -82,7 +82,7 @@ public class ConfigController { } @GetMapping("/page") - @ApiOperation("获取参数配置分页") + @Operation(summary = "获取参数配置分页") @PreAuthorize("@ss.hasPermission('infra:config:query')") public CommonResult> getConfigPage(@Valid ConfigPageReqVO reqVO) { PageResult page = configService.getConfigPage(reqVO); @@ -90,7 +90,7 @@ public class ConfigController { } @GetMapping("/export") - @ApiOperation("导出参数配置") + @Operation(summary = "导出参数配置") @PreAuthorize("@ss.hasPermission('infra:config:export')") @OperateLog(type = EXPORT) public void exportSysConfig(@Valid ConfigExportReqVO reqVO, diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigBaseVO.java index 774b0ac81..acd680290 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.infra.controller.admin.config.vo; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -15,26 +14,26 @@ import javax.validation.constraints.Size; @Data public class ConfigBaseVO { - @ApiModelProperty(value = "参数分组", required = true, example = "biz") + @Schema(title = "参数分组", required = true, example = "biz") @NotEmpty(message = "参数分组不能为空") @Size(max = 50, message = "参数名称不能超过50个字符") private String category; - @ApiModelProperty(value = "参数名称", required = true, example = "数据库名") + @Schema(title = "参数名称", required = true, example = "数据库名") @NotBlank(message = "参数名称不能为空") @Size(max = 100, message = "参数名称不能超过100个字符") private String name; - @ApiModelProperty(value = "参数键值", required = true, example = "1024") + @Schema(title = "参数键值", required = true, example = "1024") @NotBlank(message = "参数键值不能为空") @Size(max = 500, message = "参数键值长度不能超过500个字符") private String value; - @ApiModelProperty(value = "是否敏感", required = true, example = "true") + @Schema(title = "是否敏感", required = true, example = "true") @NotNull(message = "是否敏感不能为空") private Boolean visible; - @ApiModelProperty(value = "备注", example = "备注一下很帅气!") + @Schema(title = "备注", example = "备注一下很帅气!") private String remark; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigCreateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigCreateReqVO.java index 7a2118ae1..d9d369b20 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigCreateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigCreateReqVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.infra.controller.admin.config.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; -@ApiModel("管理后台 - 参数配置创建 Request VO") +@Schema(title = "管理后台 - 参数配置创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class ConfigCreateReqVO extends ConfigBaseVO { - @ApiModelProperty(value = "参数键名", required = true, example = "yunai.db.username") + @Schema(title = "参数键名", required = true, example = "yunai.db.username") @NotBlank(message = "参数键名长度不能为空") @Size(max = 100, message = "参数键名长度不能超过100个字符") private String key; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigExportReqVO.java index 7c679e2d1..6bcf83a86 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.config.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,20 +8,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 参数配置导出 Request VO") +@Schema(title = "管理后台 - 参数配置导出 Request VO") @Data public class ConfigExportReqVO { - @ApiModelProperty(value = "参数名称", example = "模糊匹配") + @Schema(title = "参数名称", example = "模糊匹配") private String name; - @ApiModelProperty(value = "参数键名", example = "yunai.db.username", notes = "模糊匹配") + @Schema(title = "参数键名", example = "yunai.db.username", description = "模糊匹配") private String key; - @ApiModelProperty(value = "参数类型", example = "1", notes = "参见 SysConfigTypeEnum 枚举") + @Schema(title = "参数类型", example = "1", description = "参见 SysConfigTypeEnum 枚举") private Integer type; - @ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigPageReqVO.java index 5ca206d46..34d9e5d88 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.infra.controller.admin.config.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,22 +11,22 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 参数配置分页 Request VO") +@Schema(title = "管理后台 - 参数配置分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ConfigPageReqVO extends PageParam { - @ApiModelProperty(value = "数据源名称", example = "模糊匹配") + @Schema(title = "数据源名称", example = "模糊匹配") private String name; - @ApiModelProperty(value = "参数键名", example = "yunai.db.username", notes = "模糊匹配") + @Schema(title = "参数键名", example = "yunai.db.username", description = "模糊匹配") private String key; - @ApiModelProperty(value = "参数类型", example = "1", notes = "参见 SysConfigTypeEnum 枚举") + @Schema(title = "参数类型", example = "1", description = "参见 SysConfigTypeEnum 枚举") private Integer type; - @ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigRespVO.java index 0c952eecb..e9746f9a4 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.config.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -9,23 +8,23 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import java.time.LocalDateTime; -@ApiModel("管理后台 - 参数配置信息 Response VO") +@Schema(title = "管理后台 - 参数配置信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) public class ConfigRespVO extends ConfigBaseVO { - @ApiModelProperty(value = "参数配置序号", required = true, example = "1024") + @Schema(title = "参数配置序号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "参数键名", required = true, example = "yunai.db.username") + @Schema(title = "参数键名", required = true, example = "yunai.db.username") @NotBlank(message = "参数键名长度不能为空") @Size(max = 100, message = "参数键名长度不能超过100个字符") private String key; - @ApiModelProperty(value = "参数类型", required = true, example = "1", notes = "参见 SysConfigTypeEnum 枚举") + @Schema(title = "参数类型", required = true, example = "1", description = "参见 SysConfigTypeEnum 枚举") private Integer type; - @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + @Schema(title = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigUpdateReqVO.java index 2335d6169..175f8a4dc 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.infra.controller.admin.config.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 参数配置创建 Request VO") +@Schema(title = "管理后台 - 参数配置创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ConfigUpdateReqVO extends ConfigBaseVO { - @ApiModelProperty(value = "参数配置序号", required = true, example = "1024") + @Schema(title = "参数配置序号", required = true, example = "1024") @NotNull(message = "参数配置编号不能为空") private Long id; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DataSourceConfigController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DataSourceConfigController.java index 6b535ae98..366f382d7 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DataSourceConfigController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DataSourceConfigController.java @@ -7,9 +7,9 @@ import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigUpda import cn.iocoder.yudao.module.infra.convert.db.DataSourceConfigConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO; import cn.iocoder.yudao.module.infra.service.db.DataSourceConfigService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 数据源配置") +@Tag(name = "管理后台 - 数据源配置") @RestController @RequestMapping("/infra/data-source-config") @Validated @@ -30,14 +30,14 @@ public class DataSourceConfigController { private DataSourceConfigService dataSourceConfigService; @PostMapping("/create") - @ApiOperation("创建数据源配置") + @Operation(summary = "创建数据源配置") @PreAuthorize("@ss.hasPermission('infra:data-source-config:create')") public CommonResult createDataSourceConfig(@Valid @RequestBody DataSourceConfigCreateReqVO createReqVO) { return success(dataSourceConfigService.createDataSourceConfig(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新数据源配置") + @Operation(summary = "更新数据源配置") @PreAuthorize("@ss.hasPermission('infra:data-source-config:update')") public CommonResult updateDataSourceConfig(@Valid @RequestBody DataSourceConfigUpdateReqVO updateReqVO) { dataSourceConfigService.updateDataSourceConfig(updateReqVO); @@ -45,8 +45,8 @@ public class DataSourceConfigController { } @DeleteMapping("/delete") - @ApiOperation("删除数据源配置") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除数据源配置") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('infra:data-source-config:delete')") public CommonResult deleteDataSourceConfig(@RequestParam("id") Long id) { dataSourceConfigService.deleteDataSourceConfig(id); @@ -54,8 +54,8 @@ public class DataSourceConfigController { } @GetMapping("/get") - @ApiOperation("获得数据源配置") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得数据源配置") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:data-source-config:query')") public CommonResult getDataSourceConfig(@RequestParam("id") Long id) { DataSourceConfigDO dataSourceConfig = dataSourceConfigService.getDataSourceConfig(id); @@ -63,7 +63,7 @@ public class DataSourceConfigController { } @GetMapping("/list") - @ApiOperation("获得数据源配置列表") + @Operation(summary = "获得数据源配置列表") @PreAuthorize("@ss.hasPermission('infra:data-source-config:query')") public CommonResult> getDataSourceConfigList() { List list = dataSourceConfigService.getDataSourceConfigList(); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DatabaseDocController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DatabaseDocController.java index eb35d4555..6e05844de 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DatabaseDocController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DatabaseDocController.java @@ -13,9 +13,9 @@ import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourcePrope import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -27,7 +27,7 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; -@Api(tags = "管理后台 - 数据库文档") +@Tag(name = "管理后台 - 数据库文档") @RestController @RequestMapping("/infra/db-doc") public class DatabaseDocController { @@ -42,27 +42,24 @@ public class DatabaseDocController { private static final String DOC_DESCRIPTION = "文档描述"; @GetMapping("/export-html") - @ApiOperation("导出 html 格式的数据文档") - @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", - dataTypeClass = Boolean.class) + @Operation(summary = "导出 html 格式的数据文档") + @Parameter(name = "deleteFile", description = "是否删除在服务器本地生成的数据库文档", example = "true") public void exportHtml(@RequestParam(defaultValue = "true") Boolean deleteFile, HttpServletResponse response) throws IOException { doExportFile(EngineFileType.HTML, deleteFile, response); } @GetMapping("/export-word") - @ApiOperation("导出 word 格式的数据文档") - @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", - dataTypeClass = Boolean.class) + @Operation(summary = "导出 word 格式的数据文档") + @Parameter(name = "deleteFile", description = "是否删除在服务器本地生成的数据库文档", example = "true") public void exportWord(@RequestParam(defaultValue = "true") Boolean deleteFile, HttpServletResponse response) throws IOException { doExportFile(EngineFileType.WORD, deleteFile, response); } @GetMapping("/export-markdown") - @ApiOperation("导出 markdown 格式的数据文档") - @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", - dataTypeClass = Boolean.class) + @Operation(summary = "导出 markdown 格式的数据文档") + @Parameter(name = "deleteFile", description = "是否删除在服务器本地生成的数据库文档", example = "true") public void exportMarkdown(@RequestParam(defaultValue = "true") Boolean deleteFile, HttpServletResponse response) throws IOException { doExportFile(EngineFileType.MD, deleteFile, response); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigBaseVO.java index dbf25b75c..53230df01 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigBaseVO.java @@ -1,8 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.db.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import java.util.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; /** @@ -12,15 +10,15 @@ import javax.validation.constraints.*; @Data public class DataSourceConfigBaseVO { - @ApiModelProperty(value = "数据源名称", required = true, example = "test") + @Schema(title = "数据源名称", required = true, example = "test") @NotNull(message = "数据源名称不能为空") private String name; - @ApiModelProperty(value = "数据源连接", required = true, example = "jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro") + @Schema(title = "数据源连接", required = true, example = "jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro") @NotNull(message = "数据源连接不能为空") private String url; - @ApiModelProperty(value = "用户名", required = true, example = "root") + @Schema(title = "用户名", required = true, example = "root") @NotNull(message = "用户名不能为空") private String username; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigCreateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigCreateReqVO.java index 13085f9b1..9f244c817 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigCreateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigCreateReqVO.java @@ -1,17 +1,15 @@ package cn.iocoder.yudao.module.infra.controller.admin.db.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import java.util.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 数据源配置创建 Request VO") +@Schema(title = "管理后台 - 数据源配置创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DataSourceConfigCreateReqVO extends DataSourceConfigBaseVO { - @ApiModelProperty(value = "密码", required = true, example = "123456") + @Schema(title = "密码", required = true, example = "123456") @NotNull(message = "密码不能为空") private String password; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java index dea918764..2f3b02faf 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.infra.controller.admin.db.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 数据源配置 Response VO") +@Schema(title = "管理后台 - 数据源配置 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DataSourceConfigRespVO extends DataSourceConfigBaseVO { - @ApiModelProperty(value = "主键编号", required = true, example = "1024") + @Schema(title = "主键编号", required = true, example = "1024") private Integer id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigUpdateReqVO.java index 134f3e9df..019ed0a20 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigUpdateReqVO.java @@ -1,21 +1,19 @@ package cn.iocoder.yudao.module.infra.controller.admin.db.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import java.util.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 数据源配置更新 Request VO") +@Schema(title = "管理后台 - 数据源配置更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DataSourceConfigUpdateReqVO extends DataSourceConfigBaseVO { - @ApiModelProperty(value = "主键编号", required = true, example = "1024") + @Schema(title = "主键编号", required = true, example = "1024") @NotNull(message = "主键编号不能为空") private Long id; - @ApiModelProperty(value = "密码", required = true, example = "123456") + @Schema(title = "密码", required = true, example = "123456") @NotNull(message = "密码不能为空") private String password; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileConfigController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileConfigController.java index 8c355d627..1fbae0931 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileConfigController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileConfigController.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigU import cn.iocoder.yudao.module.infra.convert.file.FileConfigConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO; import cn.iocoder.yudao.module.infra.service.file.FileConfigService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -21,7 +21,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 文件配置") +@Tag(name = "管理后台 - 文件配置") @RestController @RequestMapping("/infra/file-config") @Validated @@ -31,14 +31,14 @@ public class FileConfigController { private FileConfigService fileConfigService; @PostMapping("/create") - @ApiOperation("创建文件配置") + @Operation(summary = "创建文件配置") @PreAuthorize("@ss.hasPermission('infra:file-config:create')") public CommonResult createFileConfig(@Valid @RequestBody FileConfigCreateReqVO createReqVO) { return success(fileConfigService.createFileConfig(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新文件配置") + @Operation(summary = "更新文件配置") @PreAuthorize("@ss.hasPermission('infra:file-config:update')") public CommonResult updateFileConfig(@Valid @RequestBody FileConfigUpdateReqVO updateReqVO) { fileConfigService.updateFileConfig(updateReqVO); @@ -46,7 +46,7 @@ public class FileConfigController { } @PutMapping("/update-master") - @ApiOperation("更新文件配置为 Master") + @Operation(summary = "更新文件配置为 Master") @PreAuthorize("@ss.hasPermission('infra:file-config:update')") public CommonResult updateFileConfigMaster(@RequestParam("id") Long id) { fileConfigService.updateFileConfigMaster(id); @@ -54,8 +54,8 @@ public class FileConfigController { } @DeleteMapping("/delete") - @ApiOperation("删除文件配置") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除文件配置") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('infra:file-config:delete')") public CommonResult deleteFileConfig(@RequestParam("id") Long id) { fileConfigService.deleteFileConfig(id); @@ -63,8 +63,8 @@ public class FileConfigController { } @GetMapping("/get") - @ApiOperation("获得文件配置") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得文件配置") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:file-config:query')") public CommonResult getFileConfig(@RequestParam("id") Long id) { FileConfigDO fileConfig = fileConfigService.getFileConfig(id); @@ -72,7 +72,7 @@ public class FileConfigController { } @GetMapping("/page") - @ApiOperation("获得文件配置分页") + @Operation(summary = "获得文件配置分页") @PreAuthorize("@ss.hasPermission('infra:file-config:query')") public CommonResult> getFileConfigPage(@Valid FileConfigPageReqVO pageVO) { PageResult pageResult = fileConfigService.getFileConfigPage(pageVO); @@ -80,7 +80,7 @@ public class FileConfigController { } @GetMapping("/test") - @ApiOperation("测试文件配置是否正确") + @Operation(summary = "测试文件配置是否正确") @PreAuthorize("@ss.hasPermission('infra:file-config:query')") public CommonResult testFileConfig(@RequestParam("id") Long id) throws Exception { String url = fileConfigService.testFileConfig(id); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java index 3719bc31b..acb9360b5 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java @@ -12,9 +12,9 @@ import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileUploadReq import cn.iocoder.yudao.module.infra.convert.file.FileConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; import cn.iocoder.yudao.module.infra.service.file.FileService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -30,7 +30,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 文件存储") +@Tag(name = "管理后台 - 文件存储") @RestController @RequestMapping("/infra/file") @Validated @@ -41,7 +41,7 @@ public class FileController { private FileService fileService; @PostMapping("/upload") - @ApiOperation("上传文件") + @Operation(summary = "上传文件") @OperateLog(logArgs = false) // 上传文件,没有记录操作日志的必要 public CommonResult uploadFile(FileUploadReqVO uploadReqVO) throws Exception { MultipartFile file = uploadReqVO.getFile(); @@ -50,8 +50,8 @@ public class FileController { } @DeleteMapping("/delete") - @ApiOperation("删除文件") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除文件") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('infra:file:delete')") public CommonResult deleteFile(@RequestParam("id") Long id) throws Exception { fileService.deleteFile(id); @@ -60,8 +60,8 @@ public class FileController { @GetMapping("/{configId}/get/**") @PermitAll - @ApiOperation("下载文件") - @ApiImplicitParam(name = "configId", value = "配置编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "下载文件") + @Parameter(name = "configId", description = "配置编号", required = true) public void getFileContent(HttpServletRequest request, HttpServletResponse response, @PathVariable("configId") Long configId) throws Exception { @@ -82,7 +82,7 @@ public class FileController { } @GetMapping("/page") - @ApiOperation("获得文件分页") + @Operation(summary = "获得文件分页") @PreAuthorize("@ss.hasPermission('infra:file:query')") public CommonResult> getFilePage(@Valid FilePageReqVO pageVO) { PageResult pageResult = fileService.getFilePage(pageVO); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigBaseVO.java index 09faa645b..c9a1f9e4d 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.infra.controller.admin.file.vo.config; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -12,11 +11,11 @@ import javax.validation.constraints.NotNull; @Data public class FileConfigBaseVO { - @ApiModelProperty(value = "配置名", required = true, example = "S3 - 阿里云") + @Schema(title = "配置名", required = true, example = "S3 - 阿里云") @NotNull(message = "配置名不能为空") private String name; - @ApiModelProperty(value = "备注", example = "我是备注") + @Schema(title = "备注", example = "我是备注") private String remark; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigCreateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigCreateReqVO.java index 876757920..10602bfd9 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigCreateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigCreateReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.file.vo.config; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,17 +8,17 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.util.Map; -@ApiModel("管理后台 - 文件配置创建 Request VO") +@Schema(title = "管理后台 - 文件配置创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class FileConfigCreateReqVO extends FileConfigBaseVO { - @ApiModelProperty(value = "存储器", required = true, example = "1", notes = "参见 FileStorageEnum 枚举类") + @Schema(title = "存储器", required = true, example = "1", description = "参见 FileStorageEnum 枚举类") @NotNull(message = "存储器不能为空") private Integer storage; - @ApiModelProperty(value = "存储配置", required = true, notes = "配置是动态参数,所以使用 Map 接收") + @Schema(title = "存储配置", required = true, description = "配置是动态参数,所以使用 Map 接收") @NotNull(message = "存储配置不能为空") private Map config; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigPageReqVO.java index 07104cba5..a8888f788 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.infra.controller.admin.file.vo.config; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 文件配置分页 Request VO") +@Schema(title = "管理后台 - 文件配置分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class FileConfigPageReqVO extends PageParam { - @ApiModelProperty(value = "配置名", example = "S3 - 阿里云") + @Schema(title = "配置名", example = "S3 - 阿里云") private String name; - @ApiModelProperty(value = "存储器", example = "1") + @Schema(title = "存储器", example = "1") private Integer storage; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigRespVO.java index c2341e486..25f1ebec3 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigRespVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.infra.controller.admin.file.vo.config; import cn.iocoder.yudao.framework.file.core.client.FileClientConfig; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -10,27 +9,27 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@ApiModel("管理后台 - 文件配置 Response VO") +@Schema(title = "管理后台 - 文件配置 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class FileConfigRespVO extends FileConfigBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1") + @Schema(title = "编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "存储器", required = true, example = "1", notes = "参见 FileStorageEnum 枚举类") + @Schema(title = "存储器", required = true, example = "1", description = "参见 FileStorageEnum 枚举类") @NotNull(message = "存储器不能为空") private Integer storage; - @ApiModelProperty(value = "是否为主配置", required = true, example = "true") + @Schema(title = "是否为主配置", required = true, example = "true") @NotNull(message = "是否为主配置不能为空") private Boolean master; - @ApiModelProperty(value = "存储配置", required = true) + @Schema(title = "存储配置", required = true) private FileClientConfig config; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigUpdateReqVO.java index 45f8f751a..079c67dc8 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigUpdateReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.file.vo.config; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,17 +8,17 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.util.Map; -@ApiModel("管理后台 - 文件配置更新 Request VO") +@Schema(title = "管理后台 - 文件配置更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class FileConfigUpdateReqVO extends FileConfigBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1") + @Schema(title = "编号", required = true, example = "1") @NotNull(message = "编号不能为空") private Long id; - @ApiModelProperty(value = "存储配置", required = true, notes = "配置是动态参数,所以使用 Map 接收") + @Schema(title = "存储配置", required = true, description = "配置是动态参数,所以使用 Map 接收") @NotNull(message = "存储配置不能为空") private Map config; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java index 0f44f4fc7..823a65bd5 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.infra.controller.admin.file.vo.file; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 文件分页 Request VO") +@Schema(title = "管理后台 - 文件分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class FilePageReqVO extends PageParam { - @ApiModelProperty(value = "文件路径", example = "yudao", notes = "模糊匹配") + @Schema(title = "文件路径", example = "yudao", description = "模糊匹配") private String path; - @ApiModelProperty(value = "文件类型", example = "application/octet-stream", notes = "模糊匹配") + @Schema(title = "文件类型", example = "application/octet-stream", description = "模糊匹配") private String type; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java index 4d5cecc7a..beccb8ccd 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java @@ -1,37 +1,36 @@ package cn.iocoder.yudao.module.infra.controller.admin.file.vo.file; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; -@ApiModel(value = "管理后台 - 文件 Response VO", description = "不返回 content 字段,太大") +@Schema(title = "管理后台 - 文件 Response VO", description = "不返回 content 字段,太大") @Data public class FileRespVO { - @ApiModelProperty(value = "文件编号", required = true, example = "1024") + @Schema(title = "文件编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "配置编号", required = true, example = "11") + @Schema(title = "配置编号", required = true, example = "11") private Long configId; - @ApiModelProperty(value = "文件路径", required = true, example = "yudao.jpg") + @Schema(title = "文件路径", required = true, example = "yudao.jpg") private String path; - @ApiModelProperty(value = "原文件名", required = true, example = "yudao.jpg") + @Schema(title = "原文件名", required = true, example = "yudao.jpg") private String name; - @ApiModelProperty(value = "文件 URL", required = true, example = "https://www.iocoder.cn/yudao.jpg") + @Schema(title = "文件 URL", required = true, example = "https://www.iocoder.cn/yudao.jpg") private String url; - @ApiModelProperty(value = "文件MIME类型", example = "application/octet-stream") + @Schema(title = "文件MIME类型", example = "application/octet-stream") private String type; - @ApiModelProperty(value = "文件大小", example = "2048", required = true) + @Schema(title = "文件大小", example = "2048", required = true) private Integer size; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileUploadReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileUploadReqVO.java index 74e00a75a..06b54a34d 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileUploadReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileUploadReqVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.infra.controller.admin.file.vo.file; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotNull; -@ApiModel(value = "管理后台 - 上传文件 Request VO") +@Schema(title = "管理后台 - 上传文件 Request VO") @Data public class FileUploadReqVO { - @ApiModelProperty(value = "文件附件", required = true) + @Schema(title = "文件附件", required = true) @NotNull(message = "文件附件不能为空") private MultipartFile file; - @ApiModelProperty(value = "文件附件", example = "yudaoyuanma.png") + @Schema(title = "文件附件", example = "yudaoyuanma.png") private String path; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.java index e3fd84eda..2574db968 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.java @@ -9,10 +9,10 @@ import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.*; import cn.iocoder.yudao.module.infra.convert.job.JobConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO; import cn.iocoder.yudao.module.infra.service.job.JobService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.Operation; import org.quartz.SchedulerException; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; @@ -30,7 +30,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 定时任务") +@Tag(name = "管理后台 - 定时任务") @RestController @RequestMapping("/infra/job") @Validated @@ -40,7 +40,7 @@ public class JobController { private JobService jobService; @PostMapping("/create") - @ApiOperation("创建定时任务") + @Operation(summary = "创建定时任务") @PreAuthorize("@ss.hasPermission('infra:job:create')") public CommonResult createJob(@Valid @RequestBody JobCreateReqVO createReqVO) throws SchedulerException { @@ -48,7 +48,7 @@ public class JobController { } @PutMapping("/update") - @ApiOperation("更新定时任务") + @Operation(summary = "更新定时任务") @PreAuthorize("@ss.hasPermission('infra:job:update')") public CommonResult updateJob(@Valid @RequestBody JobUpdateReqVO updateReqVO) throws SchedulerException { @@ -57,10 +57,10 @@ public class JobController { } @PutMapping("/update-status") - @ApiOperation("更新定时任务的状态") - @ApiImplicitParams({ - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class), - @ApiImplicitParam(name = "status", value = "状态", required = true, example = "1", dataTypeClass = Integer.class), + @Operation(summary = "更新定时任务的状态") + @Parameters({ + @Parameter(name = "id", description = "编号", required = true, example = "1024"), + @Parameter(name = "status", description = "状态", required = true, example = "1"), }) @PreAuthorize("@ss.hasPermission('infra:job:update')") public CommonResult updateJobStatus(@RequestParam(value = "id") Long id, @RequestParam("status") Integer status) @@ -70,8 +70,8 @@ public class JobController { } @DeleteMapping("/delete") - @ApiOperation("删除定时任务") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除定时任务") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:job:delete')") public CommonResult deleteJob(@RequestParam("id") Long id) throws SchedulerException { @@ -80,8 +80,8 @@ public class JobController { } @PutMapping("/trigger") - @ApiOperation("触发定时任务") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "触发定时任务") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:job:trigger')") public CommonResult triggerJob(@RequestParam("id") Long id) throws SchedulerException { jobService.triggerJob(id); @@ -89,8 +89,8 @@ public class JobController { } @GetMapping("/get") - @ApiOperation("获得定时任务") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得定时任务") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:job:query')") public CommonResult getJob(@RequestParam("id") Long id) { JobDO job = jobService.getJob(id); @@ -98,8 +98,8 @@ public class JobController { } @GetMapping("/list") - @ApiOperation("获得定时任务列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, dataTypeClass = List.class) + @Operation(summary = "获得定时任务列表") + @Parameter(name = "ids", description = "编号列表", required = true) @PreAuthorize("@ss.hasPermission('infra:job:query')") public CommonResult> getJobList(@RequestParam("ids") Collection ids) { List list = jobService.getJobList(ids); @@ -107,7 +107,7 @@ public class JobController { } @GetMapping("/page") - @ApiOperation("获得定时任务分页") + @Operation(summary = "获得定时任务分页") @PreAuthorize("@ss.hasPermission('infra:job:query')") public CommonResult> getJobPage(@Valid JobPageReqVO pageVO) { PageResult pageResult = jobService.getJobPage(pageVO); @@ -115,7 +115,7 @@ public class JobController { } @GetMapping("/export-excel") - @ApiOperation("导出定时任务 Excel") + @Operation(summary = "导出定时任务 Excel") @PreAuthorize("@ss.hasPermission('infra:job:export')") @OperateLog(type = EXPORT) public void exportJobExcel(@Valid JobExportReqVO exportReqVO, @@ -127,10 +127,10 @@ public class JobController { } @GetMapping("/get_next_times") - @ApiOperation("获得定时任务的下 n 次执行时间") - @ApiImplicitParams({ - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class), - @ApiImplicitParam(name = "count", value = "数量", example = "5", dataTypeClass = Long.class) + @Operation(summary = "获得定时任务的下 n 次执行时间") + @Parameters({ + @Parameter(name = "id", description = "编号", required = true, example = "1024"), + @Parameter(name = "count", description = "数量", example = "5") }) @PreAuthorize("@ss.hasPermission('infra:job:query')") public CommonResult> getJobNextTimes(@RequestParam("id") Long id, diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobLogController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobLogController.java index 40de986cf..24f1f44b7 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobLogController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobLogController.java @@ -11,9 +11,9 @@ import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogRespVO; import cn.iocoder.yudao.module.infra.convert.job.JobLogConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO; import cn.iocoder.yudao.module.infra.service.job.JobLogService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -31,7 +31,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 定时任务日志") +@Tag(name = "管理后台 - 定时任务日志") @RestController @RequestMapping("/infra/job-log") @Validated @@ -41,8 +41,8 @@ public class JobLogController { private JobLogService jobLogService; @GetMapping("/get") - @ApiOperation("获得定时任务日志") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得定时任务日志") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:job:query')") public CommonResult getJobLog(@RequestParam("id") Long id) { JobLogDO jobLog = jobLogService.getJobLog(id); @@ -50,8 +50,8 @@ public class JobLogController { } @GetMapping("/list") - @ApiOperation("获得定时任务日志列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) + @Operation(summary = "获得定时任务日志列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") @PreAuthorize("@ss.hasPermission('infra:job:query')") public CommonResult> getJobLogList(@RequestParam("ids") Collection ids) { List list = jobLogService.getJobLogList(ids); @@ -59,7 +59,7 @@ public class JobLogController { } @GetMapping("/page") - @ApiOperation("获得定时任务日志分页") + @Operation(summary = "获得定时任务日志分页") @PreAuthorize("@ss.hasPermission('infra:job:query')") public CommonResult> getJobLogPage(@Valid JobLogPageReqVO pageVO) { PageResult pageResult = jobLogService.getJobLogPage(pageVO); @@ -67,7 +67,7 @@ public class JobLogController { } @GetMapping("/export-excel") - @ApiOperation("导出定时任务日志 Excel") + @Operation(summary = "导出定时任务日志 Excel") @PreAuthorize("@ss.hasPermission('infra:job:export')") @OperateLog(type = EXPORT) public void exportJobLogExcel(@Valid JobLogExportReqVO exportReqVO, diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobBaseVO.java index db3fcac1d..9cbecd604 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -12,26 +11,26 @@ import javax.validation.constraints.NotNull; @Data public class JobBaseVO { - @ApiModelProperty(value = "任务名称", required = true, example = "测试任务") + @Schema(title = "任务名称", required = true, example = "测试任务") @NotNull(message = "任务名称不能为空") private String name; - @ApiModelProperty(value = "处理器的参数", example = "yudao") + @Schema(title = "处理器的参数", example = "yudao") private String handlerParam; - @ApiModelProperty(value = "CRON 表达式", required = true, example = "0/10 * * * * ? *") + @Schema(title = "CRON 表达式", required = true, example = "0/10 * * * * ? *") @NotNull(message = "CRON 表达式不能为空") private String cronExpression; - @ApiModelProperty(value = "重试次数", required = true, example = "3") + @Schema(title = "重试次数", required = true, example = "3") @NotNull(message = "重试次数不能为空") private Integer retryCount; - @ApiModelProperty(value = "重试间隔", required = true, example = "1000") + @Schema(title = "重试间隔", required = true, example = "1000") @NotNull(message = "重试间隔不能为空") private Integer retryInterval; - @ApiModelProperty(value = "监控超时时间", example = "1000") + @Schema(title = "监控超时时间", example = "1000") private Integer monitorTimeout; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobCreateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobCreateReqVO.java index 0e9f45741..f4cd23a53 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobCreateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobCreateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 定时任务创建 Request VO") +@Schema(title = "管理后台 - 定时任务创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobCreateReqVO extends JobBaseVO { - @ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") + @Schema(title = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") @NotNull(message = "处理器的名字不能为空") private String handlerName; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobExportReqVO.java index ec393a604..530d8fc99 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobExportReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel(value = "管理后台 - 定时任务 Excel 导出 Request VO", description = "参数和 JobPageReqVO 是一致的") +@Schema(title = "管理后台 - 定时任务 Excel 导出 Request VO", description = "参数和 JobPageReqVO 是一致的") @Data public class JobExportReqVO { - @ApiModelProperty(value = "任务名称", example = "测试任务", notes = "模糊匹配") + @Schema(title = "任务名称", example = "测试任务", description = "模糊匹配") private String name; - @ApiModelProperty(value = "任务状态", example = "1", notes = "参见 JobStatusEnum 枚举") + @Schema(title = "任务状态", example = "1", description = "参见 JobStatusEnum 枚举") private Integer status; - @ApiModelProperty(value = "处理器的名字", example = "UserSessionTimeoutJob", notes = "模糊匹配") + @Schema(title = "处理器的名字", example = "UserSessionTimeoutJob", description = "模糊匹配") private String handlerName; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobPageReqVO.java index 02d3a7e2b..860a14546 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobPageReqVO.java @@ -1,25 +1,24 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 定时任务分页 Request VO") +@Schema(title = "管理后台 - 定时任务分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobPageReqVO extends PageParam { - @ApiModelProperty(value = "任务名称", example = "测试任务", notes = "模糊匹配") + @Schema(title = "任务名称", example = "测试任务", description = "模糊匹配") private String name; - @ApiModelProperty(value = "任务状态", example = "1", notes = "参见 JobStatusEnum 枚举") + @Schema(title = "任务状态", example = "1", description = "参见 JobStatusEnum 枚举") private Integer status; - @ApiModelProperty(value = "处理器的名字", example = "sysUserSessionTimeoutJob", notes = "模糊匹配") + @Schema(title = "处理器的名字", example = "sysUserSessionTimeoutJob", description = "模糊匹配") private String handlerName; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobRespVO.java index 26d7f8d73..fc0c4cc97 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,23 +8,23 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@ApiModel("管理后台 - 定时任务 Response VO") +@Schema(title = "管理后台 - 定时任务 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobRespVO extends JobBaseVO { - @ApiModelProperty(value = "任务编号", required = true, example = "1024") + @Schema(title = "任务编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "任务状态", required = true, example = "1") + @Schema(title = "任务状态", required = true, example = "1") private Integer status; - @ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") + @Schema(title = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") @NotNull(message = "处理器的名字不能为空") private String handlerName; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobUpdateReqVO.java index f26cd226c..013522be1 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 定时任务更新 Request VO") +@Schema(title = "管理后台 - 定时任务更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobUpdateReqVO extends JobBaseVO { - @ApiModelProperty(value = "任务编号", required = true, example = "1024") + @Schema(title = "任务编号", required = true, example = "1024") @NotNull(message = "任务编号不能为空") private Long id; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogBaseVO.java index 591c7a699..03863815f 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.log; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -16,38 +15,38 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class JobLogBaseVO { - @ApiModelProperty(value = "任务编号", required = true, example = "1024") + @Schema(title = "任务编号", required = true, example = "1024") @NotNull(message = "任务编号不能为空") private Long jobId; - @ApiModelProperty(value = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") + @Schema(title = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") @NotNull(message = "处理器的名字不能为空") private String handlerName; - @ApiModelProperty(value = "处理器的参数", example = "yudao") + @Schema(title = "处理器的参数", example = "yudao") private String handlerParam; - @ApiModelProperty(value = "第几次执行", required = true, example = "1") + @Schema(title = "第几次执行", required = true, example = "1") @NotNull(message = "第几次执行不能为空") private Integer executeIndex; - @ApiModelProperty(value = "开始执行时间", required = true) + @Schema(title = "开始执行时间", required = true) @NotNull(message = "开始执行时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime beginTime; - @ApiModelProperty(value = "结束执行时间") + @Schema(title = "结束执行时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; - @ApiModelProperty(value = "执行时长", example = "123") + @Schema(title = "执行时长", example = "123") private Integer duration; - @ApiModelProperty(value = "任务状态", required = true, example = "1", notes = "参见 JobLogStatusEnum 枚举") + @Schema(title = "任务状态", required = true, example = "1", description = "参见 JobLogStatusEnum 枚举") @NotNull(message = "任务状态不能为空") private Integer status; - @ApiModelProperty(value = "结果数据", example = "执行成功") + @Schema(title = "结果数据", example = "执行成功") private String result; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogExportReqVO.java index 62824739f..8a4c468a4 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.log; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,25 +8,25 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 定时任务 Excel 导出 Request VO", description = "参数和 JobLogPageReqVO 是一致的") +@Schema(title = "管理后台 - 定时任务 Excel 导出 Request VO", description = "参数和 JobLogPageReqVO 是一致的") @Data public class JobLogExportReqVO { - @ApiModelProperty(value = "任务编号", example = "10") + @Schema(title = "任务编号", example = "10") private Long jobId; - @ApiModelProperty(value = "处理器的名字", notes = "模糊匹配") + @Schema(title = "处理器的名字", description = "模糊匹配") private String handlerName; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始执行时间") + @Schema(title = "开始执行时间") private LocalDateTime beginTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束执行时间") + @Schema(title = "结束执行时间") private LocalDateTime endTime; - @ApiModelProperty(value = "任务状态", notes = "参见 JobLogStatusEnum 枚举") + @Schema(title = "任务状态", description = "参见 JobLogStatusEnum 枚举") private Integer status; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogPageReqVO.java index 6a71c4d3e..6be08ce52 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.log; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,27 +11,27 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 定时任务日志分页 Request VO") +@Schema(title = "管理后台 - 定时任务日志分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobLogPageReqVO extends PageParam { - @ApiModelProperty(value = "任务编号", example = "10") + @Schema(title = "任务编号", example = "10") private Long jobId; - @ApiModelProperty(value = "处理器的名字", notes = "模糊匹配") + @Schema(title = "处理器的名字", description = "模糊匹配") private String handlerName; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始执行时间") + @Schema(title = "开始执行时间") private LocalDateTime beginTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束执行时间") + @Schema(title = "结束执行时间") private LocalDateTime endTime; - @ApiModelProperty(value = "任务状态", notes = "参见 JobLogStatusEnum 枚举") + @Schema(title = "任务状态", description = "参见 JobLogStatusEnum 枚举") private Integer status; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogRespVO.java index 611c87b58..e0412950b 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.log; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 定时任务日志 Response VO") +@Schema(title = "管理后台 - 定时任务日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobLogRespVO extends JobLogBaseVO { - @ApiModelProperty(value = "日志编号", required = true, example = "1024") + @Schema(title = "日志编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/ApiAccessLogController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/ApiAccessLogController.java index 5046ea5af..641e1c23b 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/ApiAccessLogController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/ApiAccessLogController.java @@ -11,8 +11,8 @@ import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.Api import cn.iocoder.yudao.module.infra.convert.logger.ApiAccessLogConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO; import cn.iocoder.yudao.module.infra.service.logger.ApiAccessLogService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -28,7 +28,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - API 访问日志") +@Tag(name = "管理后台 - API 访问日志") @RestController @RequestMapping("/infra/api-access-log") @Validated @@ -38,7 +38,7 @@ public class ApiAccessLogController { private ApiAccessLogService apiAccessLogService; @GetMapping("/page") - @ApiOperation("获得API 访问日志分页") + @Operation(summary = "获得API 访问日志分页") @PreAuthorize("@ss.hasPermission('infra:api-access-log:query')") public CommonResult> getApiAccessLogPage(@Valid ApiAccessLogPageReqVO pageVO) { PageResult pageResult = apiAccessLogService.getApiAccessLogPage(pageVO); @@ -46,7 +46,7 @@ public class ApiAccessLogController { } @GetMapping("/export-excel") - @ApiOperation("导出API 访问日志 Excel") + @Operation(summary = "导出API 访问日志 Excel") @PreAuthorize("@ss.hasPermission('infra:api-access-log:export')") @OperateLog(type = EXPORT) public void exportApiAccessLogExcel(@Valid ApiAccessLogExportReqVO exportReqVO, diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/ApiErrorLogController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/ApiErrorLogController.java index d592836b2..191bd94d0 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/ApiErrorLogController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/ApiErrorLogController.java @@ -11,10 +11,10 @@ import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiE import cn.iocoder.yudao.module.infra.convert.logger.ApiErrorLogConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO; import cn.iocoder.yudao.module.infra.service.logger.ApiErrorLogService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -29,7 +29,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Api(tags = "管理后台 - API 错误日志") +@Tag(name = "管理后台 - API 错误日志") @RestController @RequestMapping("/infra/api-error-log") @Validated @@ -39,10 +39,10 @@ public class ApiErrorLogController { private ApiErrorLogService apiErrorLogService; @PutMapping("/update-status") - @ApiOperation("更新 API 错误日志的状态") - @ApiImplicitParams({ - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class), - @ApiImplicitParam(name = "processStatus", value = "处理状态", required = true, example = "1", dataTypeClass = Integer.class) + @Operation(summary = "更新 API 错误日志的状态") + @Parameters({ + @Parameter(name = "id", description = "编号", required = true, example = "1024"), + @Parameter(name = "processStatus", description = "处理状态", required = true, example = "1") }) @PreAuthorize("@ss.hasPermission('infra:api-error-log:update-status')") public CommonResult updateApiErrorLogProcess(@RequestParam("id") Long id, @@ -52,7 +52,7 @@ public class ApiErrorLogController { } @GetMapping("/page") - @ApiOperation("获得 API 错误日志分页") + @Operation(summary = "获得 API 错误日志分页") @PreAuthorize("@ss.hasPermission('infra:api-error-log:query')") public CommonResult> getApiErrorLogPage(@Valid ApiErrorLogPageReqVO pageVO) { PageResult pageResult = apiErrorLogService.getApiErrorLogPage(pageVO); @@ -60,7 +60,7 @@ public class ApiErrorLogController { } @GetMapping("/export-excel") - @ApiOperation("导出 API 错误日志 Excel") + @Operation(summary = "导出 API 错误日志 Excel") @PreAuthorize("@ss.hasPermission('infra:api-error-log:export')") @OperateLog(type = EXPORT) public void exportApiErrorLogExcel(@Valid ApiErrorLogExportReqVO exportReqVO, diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogBaseVO.java index 077f26133..e819c3d81 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -16,60 +15,60 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class ApiAccessLogBaseVO { - @ApiModelProperty(value = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002") + @Schema(title = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002") @NotNull(message = "链路追踪编号不能为空") private String traceId; - @ApiModelProperty(value = "用户编号", required = true, example = "666") + @Schema(title = "用户编号", required = true, example = "666") @NotNull(message = "用户编号不能为空") private Long userId; - @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举") + @Schema(title = "用户类型", required = true, example = "2", description = "参见 UserTypeEnum 枚举") @NotNull(message = "用户类型不能为空") private Integer userType; - @ApiModelProperty(value = "应用名", required = true, example = "dashboard") + @Schema(title = "应用名", required = true, example = "dashboard") @NotNull(message = "应用名不能为空") private String applicationName; - @ApiModelProperty(value = "请求方法名", required = true, example = "GET") + @Schema(title = "请求方法名", required = true, example = "GET") @NotNull(message = "请求方法名不能为空") private String requestMethod; - @ApiModelProperty(value = "请求地址", required = true, example = "/xxx/yyy") + @Schema(title = "请求地址", required = true, example = "/xxx/yyy") @NotNull(message = "请求地址不能为空") private String requestUrl; - @ApiModelProperty(value = "请求参数") + @Schema(title = "请求参数") private String requestParams; - @ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1") + @Schema(title = "用户 IP", required = true, example = "127.0.0.1") @NotNull(message = "用户 IP不能为空") private String userIp; - @ApiModelProperty(value = "浏览器 UA", required = true, example = "Mozilla/5.0") + @Schema(title = "浏览器 UA", required = true, example = "Mozilla/5.0") @NotNull(message = "浏览器 UA不能为空") private String userAgent; - @ApiModelProperty(value = "开始请求时间", required = true) + @Schema(title = "开始请求时间", required = true) @NotNull(message = "开始请求时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime beginTime; - @ApiModelProperty(value = "结束请求时间", required = true) + @Schema(title = "结束请求时间", required = true) @NotNull(message = "结束请求时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; - @ApiModelProperty(value = "执行时长", required = true, example = "100") + @Schema(title = "执行时长", required = true, example = "100") @NotNull(message = "执行时长不能为空") private Integer duration; - @ApiModelProperty(value = "结果码", required = true, example = "0") + @Schema(title = "结果码", required = true, example = "0") @NotNull(message = "结果码不能为空") private Integer resultCode; - @ApiModelProperty(value = "结果提示", example = "芋道源码,牛逼!") + @Schema(title = "结果提示", example = "芋道源码,牛逼!") private String resultMsg; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogExportReqVO.java index 228ac3c86..70cd57afe 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,30 +8,30 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - API 访问日志 Excel 导出 Request VO", description = "参数和 ApiAccessLogPageReqVO 是一致的") +@Schema(title = "管理后台 - API 访问日志 Excel 导出 Request VO", description = "参数和 ApiAccessLogPageReqVO 是一致的") @Data public class ApiAccessLogExportReqVO { - @ApiModelProperty(value = "用户编号", example = "666") + @Schema(title = "用户编号", example = "666") private Long userId; - @ApiModelProperty(value = "用户类型", example = "2") + @Schema(title = "用户类型", example = "2") private Integer userType; - @ApiModelProperty(value = "应用名", example = "dashboard") + @Schema(title = "应用名", example = "dashboard") private String applicationName; - @ApiModelProperty(value = "请求地址", example = "/xxx/yyy", notes = "模糊匹配") + @Schema(title = "请求地址", example = "/xxx/yyy", description = "模糊匹配") private String requestUrl; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始请求时间") + @Schema(title = "开始请求时间") private LocalDateTime[] beginTime; - @ApiModelProperty(value = "执行时长", example = "100", notes = "大于等于,单位:毫秒") + @Schema(title = "执行时长", example = "100", description = "大于等于,单位:毫秒") private Integer duration; - @ApiModelProperty(value = "结果码", example = "0") + @Schema(title = "结果码", example = "0") private Integer resultCode; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogPageReqVO.java index 62b4eeea8..ca1074450 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,32 +11,32 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - API 访问日志分页 Request VO") +@Schema(title = "管理后台 - API 访问日志分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ApiAccessLogPageReqVO extends PageParam { - @ApiModelProperty(value = "用户编号", example = "666") + @Schema(title = "用户编号", example = "666") private Long userId; - @ApiModelProperty(value = "用户类型", example = "2") + @Schema(title = "用户类型", example = "2") private Integer userType; - @ApiModelProperty(value = "应用名", example = "dashboard") + @Schema(title = "应用名", example = "dashboard") private String applicationName; - @ApiModelProperty(value = "请求地址", example = "/xxx/yyy", notes = "模糊匹配") + @Schema(title = "请求地址", example = "/xxx/yyy", description = "模糊匹配") private String requestUrl; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始请求时间") + @Schema(title = "开始请求时间") private LocalDateTime[] beginTime; - @ApiModelProperty(value = "执行时长", example = "100", notes = "大于等于,单位:毫秒") + @Schema(title = "执行时长", example = "100", description = "大于等于,单位:毫秒") private Integer duration; - @ApiModelProperty(value = "结果码", example = "0") + @Schema(title = "结果码", example = "0") private Integer resultCode; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogRespVO.java index 2a6125d38..9ab73751e 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - API 访问日志 Response VO") +@Schema(title = "管理后台 - API 访问日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ApiAccessLogRespVO extends ApiAccessLogBaseVO { - @ApiModelProperty(value = "日志主键", required = true, example = "1024") + @Schema(title = "日志主键", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogBaseVO.java index ad0b44368..c05b0f2e7 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -16,80 +15,80 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class ApiErrorLogBaseVO { - @ApiModelProperty(value = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002") + @Schema(title = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002") @NotNull(message = "链路追踪编号不能为空") private String traceId; - @ApiModelProperty(value = "用户编号", required = true, example = "666") + @Schema(title = "用户编号", required = true, example = "666") @NotNull(message = "用户编号不能为空") private Integer userId; - @ApiModelProperty(value = "用户类型", required = true, example = "1") + @Schema(title = "用户类型", required = true, example = "1") @NotNull(message = "用户类型不能为空") private Integer userType; - @ApiModelProperty(value = "应用名", required = true, example = "dashboard") + @Schema(title = "应用名", required = true, example = "dashboard") @NotNull(message = "应用名不能为空") private String applicationName; - @ApiModelProperty(value = "请求方法名", required = true, example = "GET") + @Schema(title = "请求方法名", required = true, example = "GET") @NotNull(message = "请求方法名不能为空") private String requestMethod; - @ApiModelProperty(value = "请求地址", required = true, example = "/xx/yy") + @Schema(title = "请求地址", required = true, example = "/xx/yy") @NotNull(message = "请求地址不能为空") private String requestUrl; - @ApiModelProperty(value = "请求参数", required = true) + @Schema(title = "请求参数", required = true) @NotNull(message = "请求参数不能为空") private String requestParams; - @ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1") + @Schema(title = "用户 IP", required = true, example = "127.0.0.1") @NotNull(message = "用户 IP不能为空") private String userIp; - @ApiModelProperty(value = "浏览器 UA", required = true, example = "Mozilla/5.0") + @Schema(title = "浏览器 UA", required = true, example = "Mozilla/5.0") @NotNull(message = "浏览器 UA不能为空") private String userAgent; - @ApiModelProperty(value = "异常发生时间", required = true) + @Schema(title = "异常发生时间", required = true) @NotNull(message = "异常发生时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime exceptionTime; - @ApiModelProperty(value = "异常名", required = true) + @Schema(title = "异常名", required = true) @NotNull(message = "异常名不能为空") private String exceptionName; - @ApiModelProperty(value = "异常导致的消息", required = true) + @Schema(title = "异常导致的消息", required = true) @NotNull(message = "异常导致的消息不能为空") private String exceptionMessage; - @ApiModelProperty(value = "异常导致的根消息", required = true) + @Schema(title = "异常导致的根消息", required = true) @NotNull(message = "异常导致的根消息不能为空") private String exceptionRootCauseMessage; - @ApiModelProperty(value = "异常的栈轨迹", required = true) + @Schema(title = "异常的栈轨迹", required = true) @NotNull(message = "异常的栈轨迹不能为空") private String exceptionStackTrace; - @ApiModelProperty(value = "异常发生的类全名", required = true) + @Schema(title = "异常发生的类全名", required = true) @NotNull(message = "异常发生的类全名不能为空") private String exceptionClassName; - @ApiModelProperty(value = "异常发生的类文件", required = true) + @Schema(title = "异常发生的类文件", required = true) @NotNull(message = "异常发生的类文件不能为空") private String exceptionFileName; - @ApiModelProperty(value = "异常发生的方法名", required = true) + @Schema(title = "异常发生的方法名", required = true) @NotNull(message = "异常发生的方法名不能为空") private String exceptionMethodName; - @ApiModelProperty(value = "异常发生的方法所在行", required = true) + @Schema(title = "异常发生的方法所在行", required = true) @NotNull(message = "异常发生的方法所在行不能为空") private Integer exceptionLineNumber; - @ApiModelProperty(value = "处理状态", required = true, example = "0") + @Schema(title = "处理状态", required = true, example = "0") @NotNull(message = "处理状态不能为空") private Integer processStatus; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogExportReqVO.java index e2c241138..a5b1698ce 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,27 +8,27 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - API 错误日志 Excel 导出 Request VO", description = "参数和 ApiErrorLogPageReqVO 是一致的") +@Schema(title = "管理后台 - API 错误日志 Excel 导出 Request VO", description = "参数和 ApiErrorLogPageReqVO 是一致的") @Data public class ApiErrorLogExportReqVO { - @ApiModelProperty(value = "用户编号", example = "666") + @Schema(title = "用户编号", example = "666") private Long userId; - @ApiModelProperty(value = "用户类型", example = "1") + @Schema(title = "用户类型", example = "1") private Integer userType; - @ApiModelProperty(value = "应用名", example = "dashboard") + @Schema(title = "应用名", example = "dashboard") private String applicationName; - @ApiModelProperty(value = "请求地址", example = "/xx/yy") + @Schema(title = "请求地址", example = "/xx/yy") private String requestUrl; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "异常发生时间") + @Schema(title = "异常发生时间") private LocalDateTime[] exceptionTime; - @ApiModelProperty(value = "处理状态", example = "0") + @Schema(title = "处理状态", example = "0") private Integer processStatus; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogPageReqVO.java index 56496325d..eb759c680 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,29 +11,29 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - API 错误日志分页 Request VO") +@Schema(title = "管理后台 - API 错误日志分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ApiErrorLogPageReqVO extends PageParam { - @ApiModelProperty(value = "用户编号", example = "666") + @Schema(title = "用户编号", example = "666") private Long userId; - @ApiModelProperty(value = "用户类型", example = "1") + @Schema(title = "用户类型", example = "1") private Integer userType; - @ApiModelProperty(value = "应用名", example = "dashboard") + @Schema(title = "应用名", example = "dashboard") private String applicationName; - @ApiModelProperty(value = "请求地址", example = "/xx/yy") + @Schema(title = "请求地址", example = "/xx/yy") private String requestUrl; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "异常发生时间") + @Schema(title = "异常发生时间") private LocalDateTime[] exceptionTime; - @ApiModelProperty(value = "处理状态", example = "0") + @Schema(title = "处理状态", example = "0") private Integer processStatus; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogRespVO.java index c108b548c..d0a93f2a9 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogRespVO.java @@ -1,29 +1,28 @@ package cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - API 错误日志 Response VO") +@Schema(title = "管理后台 - API 错误日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ApiErrorLogRespVO extends ApiErrorLogBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private Integer id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; - @ApiModelProperty(value = "处理时间", required = true) + @Schema(title = "处理时间", required = true) private LocalDateTime processTime; - @ApiModelProperty(value = "处理用户编号", example = "233") + @Schema(title = "处理用户编号", example = "233") private Integer processUserId; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/RedisController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/RedisController.java index 3e66b3348..c82b21cda 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/RedisController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/RedisController.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyDefineRes import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyValueRespVO; import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO; import cn.iocoder.yudao.module.infra.convert.redis.RedisConvert; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.data.redis.connection.RedisServerCommands; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.RedisCallback; @@ -25,7 +25,7 @@ import java.util.*; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - Redis 监控") +@Tag(name = "管理后台 - Redis 监控") @RestController @RequestMapping("/infra/redis") public class RedisController { @@ -34,7 +34,7 @@ public class RedisController { private StringRedisTemplate stringRedisTemplate; @GetMapping("/get-monitor-info") - @ApiOperation("获得 Redis 监控信息") + @Operation(summary = "获得 Redis 监控信息") @PreAuthorize("@ss.hasPermission('infra:redis:get-monitor-info')") public CommonResult getRedisMonitorInfo() { // 获得 Redis 统计信息 @@ -48,7 +48,7 @@ public class RedisController { } @GetMapping("/get-key-define-list") - @ApiOperation("获得 Redis Key 模板列表") + @Operation(summary = "获得 Redis Key 模板列表") @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") public CommonResult> getKeyDefineList() { List keyDefines = RedisKeyRegistry.list(); @@ -56,8 +56,8 @@ public class RedisController { } @GetMapping("/get-key-list") - @ApiOperation("获得 Redis keys 键名列表") - @ApiImplicitParam(name = "keyTemplate", value = "Redis Key 定义", example = "true", dataTypeClass = String.class) + @Operation(summary = "获得 Redis keys 键名列表") + @Parameter(name = "keyTemplate", description = "Redis Key 定义", example = "true") @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") public CommonResult> getKeyDefineList(@RequestParam("keyTemplate") String keyTemplate) { return success(getKeyDefineList0(keyTemplate)); @@ -80,8 +80,8 @@ public class RedisController { } @GetMapping("/get-key-value") - @ApiOperation("获得 Redis key 内容") - @ApiImplicitParam(name = "key", value = "Redis Key", example = "oauth2_access_token:233", dataTypeClass = String.class) + @Operation(summary = "获得 Redis key 内容") + @Parameter(name = "key", description = "Redis Key", example = "oauth2_access_token:233") @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") public CommonResult getKeyValue(@RequestParam("key") String key) { String value = stringRedisTemplate.opsForValue().get(key); @@ -89,8 +89,8 @@ public class RedisController { } @DeleteMapping("/delete-key") - @ApiOperation("删除 Redis Key") - @ApiImplicitParam(name = "key", value = "Redis Key", example = "oauth2_access_token:233", dataTypeClass = String.class) + @Operation(summary = "删除 Redis Key") + @Parameter(name = "key", description = "Redis Key", example = "oauth2_access_token:233") @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") public CommonResult deleteKey(@RequestParam("key") String key) { stringRedisTemplate.delete(key); @@ -98,8 +98,8 @@ public class RedisController { } @DeleteMapping("/delete-keys") - @ApiOperation("删除 Redis Key 根据模板") - @ApiImplicitParam(name = "keyTemplate", value = "Redis Key 定义", example = "true", dataTypeClass = String.class) + @Operation(summary = "删除 Redis Key 根据模板") + @Parameter(name = "keyTemplate", description = "Redis Key 定义", example = "true") @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") public CommonResult deleteKeys(@RequestParam("keyTemplate") String keyTemplate) { Set keys = getKeyDefineList0(keyTemplate); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyDefineRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyDefineRespVO.java index 4c1b5acd8..c2b7836a8 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyDefineRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyDefineRespVO.java @@ -1,36 +1,35 @@ package cn.iocoder.yudao.module.infra.controller.admin.redis.vo; import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import java.time.Duration; -@ApiModel("管理后台 - Redis Key 信息 Response VO") +@Schema(title = "管理后台 - Redis Key 信息 Response VO") @Data @Builder @AllArgsConstructor public class RedisKeyDefineRespVO { - @ApiModelProperty(value = "Key 模板", required = true, example = "login_user:%s") + @Schema(title = "Key 模板", required = true, example = "login_user:%s") private String keyTemplate; - @ApiModelProperty(value = "Key 类型的枚举", required = true, example = "String") + @Schema(title = "Key 类型的枚举", required = true, example = "String") private RedisKeyDefine.KeyTypeEnum keyType; - @ApiModelProperty(value = "Value 类型", required = true, example = "java.lang.String") + @Schema(title = "Value 类型", required = true, example = "java.lang.String") private Class valueType; - @ApiModelProperty(value = "超时类型", required = true, example = "1") + @Schema(title = "超时类型", required = true, example = "1") private RedisKeyDefine.TimeoutTypeEnum timeoutType; - @ApiModelProperty(value = "过期时间,单位:毫秒", required = true, example = "1024") + @Schema(title = "过期时间,单位:毫秒", required = true, example = "1024") private Duration timeout; - @ApiModelProperty(value = "备注", required = true, example = "啦啦啦啦~") + @Schema(title = "备注", required = true, example = "啦啦啦啦~") private String memo; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyValueRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyValueRespVO.java index 0f16f0640..71d4c1ec2 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyValueRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyValueRespVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.infra.controller.admin.redis.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; -@ApiModel("管理后台 - 单个 Redis Key Value Response VO") +@Schema(title = "管理后台 - 单个 Redis Key Value Response VO") @Data @AllArgsConstructor public class RedisKeyValueRespVO { - @ApiModelProperty(value = "c5f6990767804a928f4bb96ca249febf", required = true, example = "String") + @Schema(title = "c5f6990767804a928f4bb96ca249febf", required = true, example = "String") private String key; - @ApiModelProperty(required = true, example = "String") + @Schema(required = true, example = "String") private String value; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisMonitorRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisMonitorRespVO.java index 73b0cfc9f..42b8419ea 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisMonitorRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisMonitorRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.redis.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,34 +8,34 @@ import lombok.Data; import java.util.List; import java.util.Properties; -@ApiModel("管理后台 - Redis 监控信息 Response VO") +@Schema(title = "管理后台 - Redis 监控信息 Response VO") @Data @Builder @AllArgsConstructor public class RedisMonitorRespVO { - @ApiModelProperty(value = "Redis info 指令结果", required = true, notes = "具体字段,查看 Redis 文档") + @Schema(title = "Redis info 指令结果", required = true, description = "具体字段,查看 Redis 文档") private Properties info; - @ApiModelProperty(value = "Redis key 数量", required = true, example = "1024") + @Schema(title = "Redis key 数量", required = true, example = "1024") private Long dbSize; - @ApiModelProperty(value = "CommandStat 数组", required = true) + @Schema(title = "CommandStat 数组", required = true) private List commandStats; - @ApiModel("Redis 命令统计结果") + @Schema(title = "Redis 命令统计结果") @Data @Builder @AllArgsConstructor public static class CommandStat { - @ApiModelProperty(value = "Redis 命令", required = true, example = "get") + @Schema(title = "Redis 命令", required = true, example = "get") private String command; - @ApiModelProperty(value = "调用次数", required = true, example = "1024") + @Schema(title = "调用次数", required = true, example = "1024") private Long calls; - @ApiModelProperty(value = "消耗 CPU 秒数", required = true, example = "666") + @Schema(title = "消耗 CPU 秒数", required = true, example = "666") private Long usec; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/TestDemoController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/TestDemoController.java index a534b7daf..b64b49178 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/TestDemoController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/TestDemoController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.module.infra.controller.admin.test.vo.*; import cn.iocoder.yudao.module.infra.convert.test.TestDemoConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.test.TestDemoDO; import cn.iocoder.yudao.module.infra.service.test.TestDemoService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -25,7 +25,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 字典类型") +@Tag(name = "管理后台 - 字典类型") @RestController @RequestMapping("/infra/test-demo") @Validated @@ -35,14 +35,14 @@ public class TestDemoController { private TestDemoService testDemoService; @PostMapping("/create") - @ApiOperation("创建字典类型") + @Operation(summary = "创建字典类型") @PreAuthorize("@ss.hasPermission('infra:test-demo:create')") public CommonResult createTestDemo(@Valid @RequestBody TestDemoCreateReqVO createReqVO) { return success(testDemoService.createTestDemo(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新字典类型") + @Operation(summary = "更新字典类型") @PreAuthorize("@ss.hasPermission('infra:test-demo:update')") public CommonResult updateTestDemo(@Valid @RequestBody TestDemoUpdateReqVO updateReqVO) { testDemoService.updateTestDemo(updateReqVO); @@ -50,8 +50,8 @@ public class TestDemoController { } @DeleteMapping("/delete") - @ApiOperation("删除字典类型") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除字典类型") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('infra:test-demo:delete')") public CommonResult deleteTestDemo(@RequestParam("id") Long id) { testDemoService.deleteTestDemo(id); @@ -59,8 +59,8 @@ public class TestDemoController { } @GetMapping("/get") - @ApiOperation("获得字典类型") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得字典类型") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('infra:test-demo:query')") public CommonResult getTestDemo(@RequestParam("id") Long id) { TestDemoDO testDemo = testDemoService.getTestDemo(id); @@ -68,8 +68,8 @@ public class TestDemoController { } @GetMapping("/list") - @ApiOperation("获得字典类型列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) + @Operation(summary = "获得字典类型列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") @PreAuthorize("@ss.hasPermission('infra:test-demo:query')") public CommonResult> getTestDemoList(@RequestParam("ids") Collection ids) { List list = testDemoService.getTestDemoList(ids); @@ -77,14 +77,14 @@ public class TestDemoController { } @GetMapping("/page") - @ApiOperation("获得字典类型分页") + @Operation(summary = "获得字典类型分页") @PreAuthorize("@ss.hasPermission('infra:test-demo:query')") public CommonResult> getTestDemoPage(@Valid TestDemoPageReqVO pageVO) { PageResult pageResult = testDemoService.getTestDemoPage(pageVO); return success(TestDemoConvert.INSTANCE.convertPage(pageResult)); } @GetMapping("/export-excel") - @ApiOperation("导出字典类型 Excel") + @Operation(summary = "导出字典类型 Excel") @PreAuthorize("@ss.hasPermission('infra:test-demo:export')") @OperateLog(type = EXPORT) public void exportTestDemoExcel(@Valid TestDemoExportReqVO exportReqVO, HttpServletResponse response) throws IOException { diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoBaseVO.java index 1f657938e..5f78f48f7 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoBaseVO.java @@ -1,8 +1,6 @@ package cn.iocoder.yudao.module.infra.controller.admin.test.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import java.util.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; /** @@ -12,23 +10,23 @@ import javax.validation.constraints.*; @Data public class TestDemoBaseVO { - @ApiModelProperty(value = "名字", required = true) + @Schema(title = "名字", required = true) @NotNull(message = "名字不能为空") private String name; - @ApiModelProperty(value = "状态", required = true) + @Schema(title = "状态", required = true) @NotNull(message = "状态不能为空") private Integer status; - @ApiModelProperty(value = "类型", required = true) + @Schema(title = "类型", required = true) @NotNull(message = "类型不能为空") private Integer type; - @ApiModelProperty(value = "分类", required = true) + @Schema(title = "分类", required = true) @NotNull(message = "分类不能为空") private Integer category; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoCreateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoCreateReqVO.java index d932daac6..f2b2786e5 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoCreateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoCreateReqVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.infra.controller.admin.test.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 字典类型创建 Request VO") +@Schema(title = "管理后台 - 字典类型创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoExportReqVO.java index 8c386d4c1..e12d753d4 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoExportReqVO.java @@ -1,34 +1,33 @@ package cn.iocoder.yudao.module.infra.controller.admin.test.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 字典类型 Excel 导出 Request VO", description = "参数和 TestDemoPageReqVO 是一致的") +@Schema(title = "管理后台 - 字典类型 Excel 导出 Request VO", description = "参数和 TestDemoPageReqVO 是一致的") @Data public class TestDemoExportReqVO { - @ApiModelProperty(value = "名字") + @Schema(title = "名字") private String name; - @ApiModelProperty(value = "状态") + @Schema(title = "状态") private Integer status; - @ApiModelProperty(value = "类型") + @Schema(title = "类型") private Integer type; - @ApiModelProperty(value = "分类") + @Schema(title = "分类") private Integer category; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoPageReqVO.java index 56b14c3d4..6881e17e2 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoPageReqVO.java @@ -1,37 +1,36 @@ package cn.iocoder.yudao.module.infra.controller.admin.test.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 字典类型分页 Request VO") +@Schema(title = "管理后台 - 字典类型分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TestDemoPageReqVO extends PageParam { - @ApiModelProperty(value = "名字") + @Schema(title = "名字") private String name; - @ApiModelProperty(value = "状态") + @Schema(title = "状态") private Integer status; - @ApiModelProperty(value = "类型") + @Schema(title = "类型") private Integer type; - @ApiModelProperty(value = "分类") + @Schema(title = "分类") private Integer category; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoRespVO.java index 4b38ee401..95af5b4b4 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoRespVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.infra.controller.admin.test.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 字典类型 Response VO") +@Schema(title = "管理后台 - 字典类型 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TestDemoRespVO extends TestDemoBaseVO { - @ApiModelProperty(value = "编号", required = true) + @Schema(title = "编号", required = true) private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoUpdateReqVO.java index 59d56b4da..7c8315381 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoUpdateReqVO.java @@ -1,16 +1,15 @@ package cn.iocoder.yudao.module.infra.controller.admin.test.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 字典类型更新 Request VO") +@Schema(title = "管理后台 - 字典类型更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TestDemoUpdateReqVO extends TestDemoBaseVO { - @ApiModelProperty(value = "编号", required = true) + @Schema(title = "编号", required = true) @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java index c99cc1a8d..01b5714ba 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java @@ -23,7 +23,9 @@ public class SecurityConfiguration { @Override public void customize(ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry) { // Swagger 接口文档 - registry.antMatchers("/swagger-ui.html").anonymous() + registry.antMatchers("/v3/api-docs/**").permitAll() + .antMatchers("/swagger-ui.html").permitAll() + .antMatchers("/swagger-ui/**").permitAll() .antMatchers("/swagger-resources/**").anonymous() .antMatchers("/webjars/**").anonymous() .antMatchers("/*/api-docs").anonymous(); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm index 5b0546777..0296df771 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm @@ -27,7 +27,7 @@ import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.business import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert; import ${basePackage}.module.${table.moduleName}.service.${table.businessName}.${table.className}Service; -@Api(tags = "${sceneEnum.name} - ${table.classComment}") +@Tag(name = "${sceneEnum.name} - ${table.classComment}") @RestController ##二级的 businessName 暂时不算在 HTTP 路径上,可以根据需要写 @RequestMapping("/${table.moduleName}/${simpleClassName_strikeCase}") @@ -38,7 +38,7 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { private ${table.className}Service ${classNameVar}Service; @PostMapping("/create") - @ApiOperation("创建${table.classComment}") + @Operation(summary = "创建${table.classComment}") #if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")#end public CommonResult<${primaryColumn.javaType}> create${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) { @@ -46,7 +46,7 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { } @PutMapping("/update") - @ApiOperation("更新${table.classComment}") + @Operation(summary = "更新${table.classComment}") #if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")#end public CommonResult update${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) { @@ -55,8 +55,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { } @DeleteMapping("/delete") - @ApiOperation("删除${table.classComment}") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = ${primaryColumn.javaType}.class) + @Operation(summary = "删除${table.classComment}") + @Parameter(name = "id", description = "编号", required = true) #if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")#end public CommonResult delete${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) { @@ -65,8 +65,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { } @GetMapping("/get") - @ApiOperation("获得${table.classComment}") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = ${primaryColumn.javaType}.class) + @Operation(summary = "获得${table.classComment}") + @Parameter(name = "id", description = "编号", required = true, example = "1024") #if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end public CommonResult<${sceneEnum.prefixClass}${table.className}RespVO> get${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) { @@ -75,8 +75,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { } @GetMapping("/list") - @ApiOperation("获得${table.classComment}列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) + @Operation(summary = "获得${table.classComment}列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") #if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end public CommonResult> get${simpleClassName}List(@RequestParam("ids") Collection<${primaryColumn.javaType}> ids) { @@ -85,7 +85,7 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { } @GetMapping("/page") - @ApiOperation("获得${table.classComment}分页") + @Operation(summary = "获得${table.classComment}分页") #if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end public CommonResult> get${simpleClassName}Page(@Valid ${sceneEnum.prefixClass}${table.className}PageReqVO pageVO) { @@ -94,7 +94,7 @@ public class ${sceneEnum.prefixClass}${table.className}Controller { } @GetMapping("/export-excel") - @ApiOperation("导出${table.classComment} Excel") + @Operation(summary = "导出${table.classComment} Excel") #if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:export')")#end @OperateLog(type = EXPORT) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/_column.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/_column.vm index 69477d433..71c4eebf8 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/_column.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/_column.vm @@ -1,5 +1,5 @@ ## 提供给 baseVO、createVO、updateVO 生成字段 - @ApiModelProperty(value = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(title = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end) #if (!${column.nullable})## 判断 @NotEmpty 和 @NotNull 注解 #if (${field.fieldType} == 'String') @NotEmpty(message = "${column.columnComment}不能为空") diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm index bf6408c9c..315faf7fc 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm @@ -15,7 +15,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; #end #end -@ApiModel("${sceneEnum.name} - ${table.classComment}创建 Request VO") +@Schema(title = "${sceneEnum.name} - ${table.classComment}创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm index cd68dd82e..749a43e25 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm @@ -16,18 +16,18 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; #end ## 字段模板 #macro(columnTpl $prefix $prefixStr) - @ApiModelProperty(value = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(title = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end; #end -@ApiModel(value = "${sceneEnum.name} - ${table.classComment} Excel 导出 Request VO", description = "参数和 ${table.className}PageReqVO 是一致的") +@Schema(title = "${sceneEnum.name} - ${table.classComment} Excel 导出 Request VO", description = "参数和 ${table.className}PageReqVO 是一致的") @Data public class ${sceneEnum.prefixClass}${table.className}ExportReqVO { #foreach ($column in $columns) #if (${column.listOperation})##查询操作 #if (${column.listOperationCondition} == "BETWEEN")## 情况一,Between 的时候 - @ApiModelProperty(value = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(title = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private ${column.javaType}[] ${column.javaField}; #else##情况二,非 Between 的时间 diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm index f2664390a..44a5307ea 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm @@ -16,11 +16,11 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; #end ## 字段模板 #macro(columnTpl $prefix $prefixStr) - @ApiModelProperty(value = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(title = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end; #end -@ApiModel("${sceneEnum.name} - ${table.classComment}分页 Request VO") +@Schema(title = "${sceneEnum.name} - ${table.classComment}分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -29,7 +29,7 @@ public class ${sceneEnum.prefixClass}${table.className}PageReqVO extends PagePar #foreach ($column in $columns) #if (${column.listOperation})##查询操作 #if (${column.listOperationCondition} == "BETWEEN")## 情况一,Between 的时候 - @ApiModelProperty(value = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(title = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private ${column.javaType}[] ${column.javaField}; #else##情况二,非 Between 的时间 diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm index dd6e16e10..f0dd7bbf5 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm @@ -8,7 +8,7 @@ import java.time.LocalDateTime; #end import io.swagger.annotations.*; -@ApiModel("${sceneEnum.name} - ${table.classComment} Response VO") +@Schema(title = "${sceneEnum.name} - ${table.classComment} Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -16,7 +16,7 @@ public class ${sceneEnum.prefixClass}${table.className}RespVO extends ${sceneEnu #foreach ($column in $columns) #if (${column.listOperationResult} && (!${column.createOperation} || !${column.updateOperation}))##不是通用字段 - @ApiModelProperty(value = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(title = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end) private ${column.javaType} ${column.javaField}; #end diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm index 636991508..fb9b42f00 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm @@ -15,7 +15,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; #end #end -@ApiModel("${sceneEnum.name} - ${table.classComment}更新 Request VO") +@Schema(title = "${sceneEnum.name} - ${table.classComment}更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java index 2227afeaf..8427449f7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*; import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert; import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 商品品牌") +@Tag(name = "管理后台 - 商品品牌") @RestController @RequestMapping("/product/brand") @Validated @@ -30,14 +30,14 @@ public class ProductBrandController { private ProductBrandService brandService; @PostMapping("/create") - @ApiOperation("创建品牌") + @Operation(summary = "创建品牌") @PreAuthorize("@ss.hasPermission('product:brand:create')") public CommonResult createBrand(@Valid @RequestBody ProductBrandCreateReqVO createReqVO) { return success(brandService.createBrand(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新品牌") + @Operation(summary = "更新品牌") @PreAuthorize("@ss.hasPermission('product:brand:update')") public CommonResult updateBrand(@Valid @RequestBody ProductBrandUpdateReqVO updateReqVO) { brandService.updateBrand(updateReqVO); @@ -45,8 +45,8 @@ public class ProductBrandController { } @DeleteMapping("/delete") - @ApiOperation("删除品牌") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除品牌") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('product:brand:delete')") public CommonResult deleteBrand(@RequestParam("id") Long id) { brandService.deleteBrand(id); @@ -54,8 +54,8 @@ public class ProductBrandController { } @GetMapping("/get") - @ApiOperation("获得品牌") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得品牌") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:brand:query')") public CommonResult getBrand(@RequestParam("id") Long id) { ProductBrandDO brand = brandService.getBrand(id); @@ -63,7 +63,7 @@ public class ProductBrandController { } @GetMapping("/page") - @ApiOperation("获得品牌分页") + @Operation(summary = "获得品牌分页") @PreAuthorize("@ss.hasPermission('product:brand:query')") public CommonResult> getBrandPage(@Valid ProductBrandPageReqVO pageVO) { PageResult pageResult = brandService.getBrandPage(pageVO); @@ -71,7 +71,7 @@ public class ProductBrandController { } @GetMapping("/list") - @ApiOperation("获得品牌列表") + @Operation(summary = "获得品牌列表") @PreAuthorize("@ss.hasPermission('product:brand:query')") public CommonResult> getBrandList(@Valid ProductBrandListReqVO listVO) { List list = brandService.getBrandList(listVO); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java index fa5ecd2d1..f586e7415 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.controller.admin.brand.vo; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -12,22 +11,22 @@ import javax.validation.constraints.NotNull; @Data public class ProductBrandBaseVO { - @ApiModelProperty(value = "品牌名称", required = true, example = "芋道") + @Schema(title = "品牌名称", required = true, example = "芋道") @NotNull(message = "品牌名称不能为空") private String name; - @ApiModelProperty(value = "品牌图片", required = true) + @Schema(title = "品牌图片", required = true) @NotNull(message = "品牌图片不能为空") private String picUrl; - @ApiModelProperty(value = "品牌排序", required = true, example = "1") + @Schema(title = "品牌排序", required = true, example = "1") @NotNull(message = "品牌排序不能为空") private Integer sort; - @ApiModelProperty(value = "品牌描述", example = "描述") + @Schema(title = "品牌描述", example = "描述") private String description; - @ApiModelProperty(value = "状态", required = true, example = "0") + @Schema(title = "状态", required = true, example = "0") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java index 74024929f..1ea83e259 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.product.controller.admin.brand.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 商品品牌创建 Request VO") +@Schema(title = "管理后台 - 商品品牌创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java index 5367e2dfe..a1ea87ad8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java @@ -1,14 +1,13 @@ package cn.iocoder.yudao.module.product.controller.admin.brand.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel(value = "管理后台 - 商品品牌分页 Request VO") +@Schema(title = "管理后台 - 商品品牌分页 Request VO") @Data public class ProductBrandListReqVO { - @ApiModelProperty(value = "品牌名称", example = "芋道") + @Schema(title = "品牌名称", example = "芋道") private String name; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java index c5a7b0047..b19a9a711 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.product.controller.admin.brand.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 商品品牌分页 Request VO") +@Schema(title = "管理后台 - 商品品牌分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductBrandPageReqVO extends PageParam { - @ApiModelProperty(value = "品牌名称", example = "芋道") + @Schema(title = "品牌名称", example = "芋道") private String name; - @ApiModelProperty(value = "状态", example = "0", notes = "参考 CommonStatusEnum 枚举") + @Schema(title = "状态", example = "0", description = "参考 CommonStatusEnum 枚举") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java index fb4ce0954..a61cf5235 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.product.controller.admin.brand.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 品牌 Response VO") +@Schema(title = "管理后台 - 品牌 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductBrandRespVO extends ProductBrandBaseVO { - @ApiModelProperty(value = "品牌编号", required = true, example = "1") + @Schema(title = "品牌编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java index 54d610207..e86112c92 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java @@ -1,16 +1,15 @@ package cn.iocoder.yudao.module.product.controller.admin.brand.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 商品品牌更新 Request VO") +@Schema(title = "管理后台 - 商品品牌更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductBrandUpdateReqVO extends ProductBrandBaseVO { - @ApiModelProperty(value = "品牌编号", required = true, example = "1") + @Schema(title = "品牌编号", required = true, example = "1") @NotNull(message = "品牌编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java index 4144e6a57..c51498d3b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCateg import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -22,7 +22,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 商品分类") +@Tag(name = "管理后台 - 商品分类") @RestController @RequestMapping("/product/category") @Validated @@ -32,14 +32,14 @@ public class ProductCategoryController { private ProductCategoryService categoryService; @PostMapping("/create") - @ApiOperation("创建商品分类") + @Operation(summary = "创建商品分类") @PreAuthorize("@ss.hasPermission('product:category:create')") public CommonResult createCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) { return success(categoryService.createCategory(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新商品分类") + @Operation(summary = "更新商品分类") @PreAuthorize("@ss.hasPermission('product:category:update')") public CommonResult updateCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) { categoryService.updateCategory(updateReqVO); @@ -47,8 +47,8 @@ public class ProductCategoryController { } @DeleteMapping("/delete") - @ApiOperation("删除商品分类") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除商品分类") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('product:category:delete')") public CommonResult deleteCategory(@RequestParam("id") Long id) { categoryService.deleteCategory(id); @@ -56,8 +56,8 @@ public class ProductCategoryController { } @GetMapping("/get") - @ApiOperation("获得商品分类") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得商品分类") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:category:query')") public CommonResult getCategory(@RequestParam("id") Long id) { ProductCategoryDO category = categoryService.getCategory(id); @@ -65,7 +65,7 @@ public class ProductCategoryController { } @GetMapping("/list") - @ApiOperation("获得商品分类列表") + @Operation(summary = "获得商品分类列表") @PreAuthorize("@ss.hasPermission('product:category:query')") public CommonResult> getCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) { List list = categoryService.getEnableCategoryList(treeListReqVO); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java index 9b9c77a08..922ab321b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -13,25 +12,25 @@ import javax.validation.constraints.NotNull; @Data public class ProductCategoryBaseVO { - @ApiModelProperty(value = "父分类编号", required = true, example = "1") + @Schema(title = "父分类编号", required = true, example = "1") @NotNull(message = "父分类编号不能为空") private Long parentId; - @ApiModelProperty(value = "分类名称", required = true, example = "办公文具") + @Schema(title = "分类名称", required = true, example = "办公文具") @NotBlank(message = "分类名称不能为空") private String name; - @ApiModelProperty(value = "分类图片", required = true) + @Schema(title = "分类图片", required = true) @NotBlank(message = "分类图片不能为空") private String picUrl; - @ApiModelProperty(value = "分类排序", required = true, example = "1") + @Schema(title = "分类排序", required = true, example = "1") private Integer sort; - @ApiModelProperty(value = "分类描述", required = true, example = "描述") + @Schema(title = "分类描述", required = true, example = "描述") private String description; - @ApiModelProperty(value = "开启状态", required = true, example = "0") + @Schema(title = "开启状态", required = true, example = "0") @NotNull(message = "开启状态不能为空") private Integer status; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java index d35e1ad3c..32e5e6719 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 商品分类创建 Request VO") +@Schema(title = "管理后台 - 商品分类创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java index a487c16a4..3a8e83106 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java @@ -1,14 +1,13 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel(value = "管理后台 - 商品分类列表查询 Request VO") +@Schema(title = "管理后台 - 商品分类列表查询 Request VO") @Data public class ProductCategoryListReqVO { - @ApiModelProperty(value = "分类名称", example = "办公文具") + @Schema(title = "分类名称", example = "办公文具") private String name; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java index c6fdfcfe1..32298487b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 商品分类 Response VO") +@Schema(title = "管理后台 - 商品分类 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductCategoryRespVO extends ProductCategoryBaseVO { - @ApiModelProperty(value = "分类编号", required = true, example = "2") + @Schema(title = "分类编号", required = true, example = "2") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java index b0c8fe57d..1b8357f96 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java @@ -1,16 +1,15 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 商品分类更新 Request VO") +@Schema(title = "管理后台 - 商品分类更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO { - @ApiModelProperty(value = "分类编号", required = true, example = "2") + @Schema(title = "分类编号", required = true, example = "2") @NotNull(message = "分类编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java index 9a4c20c58..54ee1fbbd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java @@ -4,9 +4,9 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*; import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -18,7 +18,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 规格名称") +@Tag(name = "管理后台 - 规格名称") @RestController @RequestMapping("/product/property") @Validated @@ -28,14 +28,14 @@ public class ProductPropertyController { private ProductPropertyService productPropertyService; @PostMapping("/create") - @ApiOperation("创建规格名称") + @Operation(summary = "创建规格名称") @PreAuthorize("@ss.hasPermission('product:property:create')") public CommonResult createProperty(@Valid @RequestBody ProductPropertyCreateReqVO createReqVO) { return success(productPropertyService.createProperty(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新规格名称") + @Operation(summary = "更新规格名称") @PreAuthorize("@ss.hasPermission('product:property:update')") public CommonResult updateProperty(@Valid @RequestBody ProductPropertyUpdateReqVO updateReqVO) { productPropertyService.updateProperty(updateReqVO); @@ -43,8 +43,8 @@ public class ProductPropertyController { } @DeleteMapping("/delete") - @ApiOperation("删除规格名称") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除规格名称") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('product:property:delete')") public CommonResult deleteProperty(@RequestParam("id") Long id) { productPropertyService.deleteProperty(id); @@ -52,29 +52,29 @@ public class ProductPropertyController { } @GetMapping("/get") - @ApiOperation("获得规格名称") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得规格名称") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:property:query')") public CommonResult getProperty(@RequestParam("id") Long id) { return success(productPropertyService.getProperty(id)); } @GetMapping("/list") - @ApiOperation("获得规格名称列表") + @Operation(summary = "获得规格名称列表") @PreAuthorize("@ss.hasPermission('product:property:query')") public CommonResult> getPropertyList(@Valid ProductPropertyListReqVO listReqVO) { return success(productPropertyService.getPropertyList(listReqVO)); } @GetMapping("/page") - @ApiOperation("获得规格名称分页") + @Operation(summary = "获得规格名称分页") @PreAuthorize("@ss.hasPermission('product:property:query')") public CommonResult> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) { return success(productPropertyService.getPropertyPage(pageVO)); } @GetMapping("/listAndValue") - @ApiOperation("获得规格名称列表") + @Operation(summary = "获得规格名称列表") @PreAuthorize("@ss.hasPermission('product:property:query')") public CommonResult> getPropertyAndValueList(@Valid ProductPropertyListReqVO listReqVO) { return success(productPropertyService.getPropertyAndValueList(listReqVO)); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java index e88c91415..cdcd1f7a3 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.Produc import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 规格值名称") +@Tag(name = "管理后台 - 规格值名称") @RestController @RequestMapping("/product/property/value") @Validated @@ -30,14 +30,14 @@ public class ProductPropertyValueController { private ProductPropertyValueService productPropertyValueService; @PostMapping("/create") - @ApiOperation("创建规格名称") + @Operation(summary = "创建规格名称") @PreAuthorize("@ss.hasPermission('product:property:create')") public CommonResult createProperty(@Valid @RequestBody ProductPropertyValueCreateReqVO createReqVO) { return success(productPropertyValueService.createPropertyValue(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新规格名称") + @Operation(summary = "更新规格名称") @PreAuthorize("@ss.hasPermission('product:property:update')") public CommonResult updateProperty(@Valid @RequestBody ProductPropertyValueUpdateReqVO updateReqVO) { productPropertyValueService.updatePropertyValue(updateReqVO); @@ -45,8 +45,8 @@ public class ProductPropertyValueController { } @DeleteMapping("/delete") - @ApiOperation("删除规格名称") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除规格名称") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('product:property:delete')") public CommonResult deleteProperty(@RequestParam("id") Long id) { productPropertyValueService.deletePropertyValue(id); @@ -54,15 +54,15 @@ public class ProductPropertyValueController { } @GetMapping("/get") - @ApiOperation("获得规格名称") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得规格名称") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:property:query')") public CommonResult getProperty(@RequestParam("id") Long id) { return success(productPropertyValueService.getPropertyValue(id)); } @GetMapping("/page") - @ApiOperation("获得规格名称分页") + @Operation(summary = "获得规格名称分页") @PreAuthorize("@ss.hasPermission('product:property:query')") public CommonResult> getPropertyValuePage(@Valid ProductPropertyValuePageReqVO pageVO) { return success(productPropertyValueService.getPropertyValueListPage(pageVO)); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java index 9bdc70bd7..7ef873264 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.ToString; @@ -13,22 +12,22 @@ import java.util.List; * @CreateDate: 2022/7/5 21:29 * @Version: 1.0.0 */ -@ApiModel("管理后台 - 规格名称详情展示 Request VO") +@Schema(title = "管理后台 - 规格名称详情展示 Request VO") @Data @ToString(callSuper = true) public class ProductPropertyViewRespVO { - @ApiModelProperty(value = "规格名称id", example = "1") + @Schema(title = "规格名称id", example = "1") public Long propertyId; - @ApiModelProperty(value = "规格名称", example = "内存") + @Schema(title = "规格名称", example = "内存") public String name; - @ApiModelProperty(value = "规格属性值集合", example = "[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]") + @Schema(title = "规格属性值集合", example = "[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]") public List propertyValues; @Data - @ApiModel(value = "规格属性值元组") + @Schema(title = "规格属性值元组") public static class Tuple2 { private final long id; private final String name; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java index e7b3c352f..7c75830bb 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -10,16 +9,16 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@ApiModel("管理后台 - 规格 + 规格值 Response VO") +@Schema(title = "管理后台 - 规格 + 规格值 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyAndValueRespVO extends ProductPropertyBaseVO { - @ApiModelProperty(value = "规格的编号", required = true, example = "1024") + @Schema(title = "规格的编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java index 25fc4c01a..22f92ebb8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -13,14 +12,14 @@ import javax.validation.constraints.NotNull; @Data public class ProductPropertyBaseVO { - @ApiModelProperty(value = "规格名称", required = true, example = "颜色") + @Schema(title = "规格名称", required = true, example = "颜色") @NotBlank(message = "规格名称不能为空") private String name; - @ApiModelProperty(value = "备注", example = "颜色") + @Schema(title = "备注", example = "颜色") private String remark; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java index 8dfd58a5d..28b93d516 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java @@ -1,11 +1,10 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 规格名称创建 Request VO") +@Schema(title = "管理后台 - 规格名称创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java index 314288ffb..49b2e7a2f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.ToString; -@ApiModel("管理后台 - 规格名称 List Request VO") +@Schema(title = "管理后台 - 规格名称 List Request VO") @Data @ToString(callSuper = true) public class ProductPropertyListReqVO { - @ApiModelProperty(value = "规格名称", example = "颜色") + @Schema(title = "规格名称", example = "颜色") private String name; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") private Integer status; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java index 05a67e874..96551fd84 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 规格名称分页 Request VO") +@Schema(title = "管理后台 - 规格名称分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyPageReqVO extends PageParam { - @ApiModelProperty(value = "规格名称", example = "颜色") + @Schema(title = "规格名称", example = "颜色") private String name; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java index 75a9a5eea..fc7e03911 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 规格 + 规格值 Response VO") +@Schema(title = "管理后台 - 规格 + 规格值 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyRespVO extends ProductPropertyBaseVO { - @ApiModelProperty(value = "规格的编号", required = true, example = "1024") + @Schema(title = "规格的编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java index f4630d874..bde40c9c0 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java @@ -1,18 +1,15 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -import java.util.List; -@ApiModel("管理后台 - 规格名称更新 Request VO") +@Schema(title = "管理后台 - 规格名称更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyUpdateReqVO extends ProductPropertyBaseVO { - @ApiModelProperty(value = "主键", required = true, example = "1") + @Schema(title = "主键", required = true, example = "1") @NotNull(message = "主键不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java index 142a8e6e2..b4a526c47 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -13,19 +12,19 @@ import javax.validation.constraints.NotNull; @Data public class ProductPropertyValueBaseVO { - @ApiModelProperty(value = "规格编号", required = true, example = "1024") + @Schema(title = "规格编号", required = true, example = "1024") @NotNull(message = "规格编号不能为空") private Long propertyId; - @ApiModelProperty(value = "规格值名字", required = true, example = "红色") + @Schema(title = "规格值名字", required = true, example = "红色") @NotEmpty(message = "规格值名字不能为空") private String name; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") private Integer status; - @ApiModelProperty(value = "备注", example = "颜色") + @Schema(title = "备注", example = "颜色") private String remark; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java index f7237f9cd..6477b7091 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 规格值创建 Request VO") +@Schema(title = "管理后台 - 规格值创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java index ae77d822b..bcada5154 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -13,19 +12,19 @@ import java.util.Date; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 规格名称值分页 Request VO") +@Schema(title = "管理后台 - 规格名称值分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyValuePageReqVO extends PageParam { - @ApiModelProperty(value = "规格id", example = "1024") + @Schema(title = "规格id", example = "1024") private String propertyId; - @ApiModelProperty(value = "规格值", example = "红色") + @Schema(title = "规格值", example = "红色") private String name; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") private Integer status; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java index 501afd752..2a40e0056 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 规格值 Response VO") +@Schema(title = "管理后台 - 规格值 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyValueRespVO extends ProductPropertyValueBaseVO { - @ApiModelProperty(value = "主键", required = true, example = "10") + @Schema(title = "主键", required = true, example = "10") private Long id; - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java index 2437600a8..cb346c27c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java @@ -1,16 +1,15 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 规格值更新 Request VO") +@Schema(title = "管理后台 - 规格值更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyValueUpdateReqVO extends ProductPropertyValueBaseVO { - @ApiModelProperty(value = "主键", required = true, example = "1024") + @Schema(title = "主键", required = true, example = "1024") @NotNull(message = "主键不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java index ac9713423..6c8601782 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java @@ -9,8 +9,8 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -24,7 +24,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -@Api(tags = "管理后台 - 商品 sku") +@Tag(name = "管理后台 - 商品 sku") @RestController @RequestMapping("/product/sku") @Validated @@ -36,7 +36,7 @@ public class ProductSkuController { private ProductSpuService productSpuService; @GetMapping("/get-option-list") - @ApiOperation("获得商品 SKU 选项的列表") + @Operation(summary = "获得商品 SKU 选项的列表") // @PreAuthorize("@ss.hasPermission('product:sku:query')") public CommonResult> getSkuOptionList() { // 获得 SKU 列表 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java index 45cb447b8..8ae8c8a5a 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -16,54 +15,54 @@ import javax.validation.constraints.NotNull; @Data public class ProductSkuBaseVO { - @ApiModelProperty(value = "商品 SKU 名字", required = true, example = "芋道") + @Schema(title = "商品 SKU 名字", required = true, example = "芋道") @NotEmpty(message = "商品 SKU 名字不能为空") private String name; - @ApiModelProperty(value = "销售价格,单位:分", required = true, example = "1024", notes = "单位:分") + @Schema(title = "销售价格,单位:分", required = true, example = "1024", description = "单位:分") @NotNull(message = "销售价格,单位:分不能为空") private Integer price; - @ApiModelProperty(value = "市场价", example = "1024", notes = "单位:分") + @Schema(title = "市场价", example = "1024", description = "单位:分") private Integer marketPrice; - @ApiModelProperty(value = "成本价", example = "1024", notes = "单位:分") + @Schema(title = "成本价", example = "1024", description = "单位:分") private Integer costPrice; - @ApiModelProperty(value = "条形码", example = "haha") + @Schema(title = "条形码", example = "haha") private String barCode; - @ApiModelProperty(value = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") + @Schema(title = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") @NotNull(message = "图片地址不能为空") private String picUrl; - @ApiModelProperty(value = "SKU 状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(title = "SKU 状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") @NotNull(message = "SKU 状态不能为空") @InEnum(CommonStatusEnum.class) private Integer status; - @ApiModelProperty(value = "库存", required = true, example = "1") + @Schema(title = "库存", required = true, example = "1") @NotNull(message = "库存不能为空") private Integer stock; - @ApiModelProperty(value = "预警预存", example = "1") + @Schema(title = "预警预存", example = "1") private Integer warnStock; - @ApiModelProperty(value = "商品重量", example = "1", notes = "单位:kg 千克") + @Schema(title = "商品重量", example = "1", description = "单位:kg 千克") private Double weight; - @ApiModelProperty(value = "商品体积", example = "1024", notes = "单位:m^3 平米") + @Schema(title = "商品体积", example = "1024", description = "单位:m^3 平米") private Double volume; - @ApiModel("规格值") + @Schema(title = "规格值") @Data public static class Property { - @ApiModelProperty(value = "属性编号", required = true, example = "1") + @Schema(title = "属性编号", required = true, example = "1") @NotNull(message = "属性编号不能为空") private Long propertyId; - @ApiModelProperty(value = "属性值编号", required = true, example = "1024") + @Schema(title = "属性值编号", required = true, example = "1024") @NotNull(message = "属性值编号不能为空") private Long valueId; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java index 6d5ce024d..3648f3159 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.util.List; -@ApiModel("管理后台 - 商品 SKU 创建/更新 Request VO") +@Schema(title = "管理后台 - 商品 SKU 创建/更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO { - @ApiModelProperty(value = "商品 SKU 编号", example = "1") + @Schema(title = "商品 SKU 编号", example = "1") private Long id; /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java index 0324bdc8d..dd71d6954 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java @@ -1,31 +1,30 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel(value = "管理后台 - 商品 SKU 选项 Response VO", description = "用于前端 SELECT 选项") +@Schema(title = "管理后台 - 商品 SKU 选项 Response VO", description = "用于前端 SELECT 选项") @Data public class ProductSkuOptionRespVO { - @ApiModelProperty(value = "主键", required = true, example = "1024") + @Schema(title = "主键", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "商品 SKU 名字", example = "红色") + @Schema(title = "商品 SKU 名字", example = "红色") private String name; - @ApiModelProperty(value = "销售价格", required = true, example = "100", notes = "单位:分") + @Schema(title = "销售价格", required = true, example = "100", description = "单位:分") private String price; - @ApiModelProperty(value = "库存", required = true, example = "100") + @Schema(title = "库存", required = true, example = "100") private Integer stock; // ========== 商品 SPU 信息 ========== - @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") + @Schema(title = "商品 SPU 编号", required = true, example = "1") private Long spuId; - @ApiModelProperty(value = "商品 SPU 名字", required = true, example = "iPhone 11") + @Schema(title = "商品 SPU 名字", required = true, example = "iPhone 11") private String spuName; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java index 1ac29724b..62e4ec9cc 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,16 +8,16 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@ApiModel("管理后台 - 商品 SKU Response VO") +@Schema(title = "管理后台 - 商品 SKU Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSkuRespVO extends ProductSkuBaseVO { - @ApiModelProperty(value = "主键", required = true, example = "1024") + @Schema(title = "主键", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime createTime; /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index 155fd0265..0801da438 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 商品 SPU") +@Tag(name = "管理后台 - 商品 SPU") @RestController @RequestMapping("/product/spu") @Validated @@ -30,14 +30,14 @@ public class ProductSpuController { private ProductSpuService spuService; @PostMapping("/create") - @ApiOperation("创建商品 SPU") + @Operation(summary = "创建商品 SPU") @PreAuthorize("@ss.hasPermission('product:spu:create')") public CommonResult createProductSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) { return success(spuService.createSpu(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新商品 SPU") + @Operation(summary = "更新商品 SPU") @PreAuthorize("@ss.hasPermission('product:spu:update')") public CommonResult updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) { spuService.updateSpu(updateReqVO); @@ -45,8 +45,8 @@ public class ProductSpuController { } @DeleteMapping("/delete") - @ApiOperation("删除商品 SPU") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除商品 SPU") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('product:spu:delete')") public CommonResult deleteSpu(@RequestParam("id") Long id) { spuService.deleteSpu(id); @@ -55,16 +55,16 @@ public class ProductSpuController { // TODO 芋艿:修改接口 @GetMapping("/get/detail") - @ApiOperation("获得商品 SPU") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得商品 SPU") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:spu:query')") public CommonResult getSpuDetail(@RequestParam("id") Long id) { return success(spuService.getSpuDetail(id)); } @GetMapping("/get") - @ApiOperation("获得商品 SPU") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得商品 SPU") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:spu:query')") public CommonResult getSpu(@RequestParam("id") Long id) { return success(spuService.getSpu(id)); @@ -72,8 +72,8 @@ public class ProductSpuController { @GetMapping("/list") - @ApiOperation("获得商品 SPU 列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) + @Operation(summary = "获得商品 SPU 列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") @PreAuthorize("@ss.hasPermission('product:spu:query')") public CommonResult> getSpuList(@RequestParam("ids") Collection ids) { List list = spuService.getSpuList(ids); @@ -81,7 +81,7 @@ public class ProductSpuController { } @GetMapping("/get-simple-list") - @ApiOperation("获得商品 SPU 精简列表") + @Operation(summary = "获得商品 SPU 精简列表") @PreAuthorize("@ss.hasPermission('product:spu:query')") public CommonResult> getSpuSimpleList() { List list = spuService.getSpuList(); @@ -89,7 +89,7 @@ public class ProductSpuController { } @GetMapping("/page") - @ApiOperation("获得商品 SPU 分页") + @Operation(summary = "获得商品 SPU 分页") @PreAuthorize("@ss.hasPermission('product:spu:query')") public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { return success(spuService.getSpuPage(pageVO)); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java index 54f0986dd..fa7e2717d 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -17,75 +17,75 @@ import java.util.List; @Data public class ProductSpuBaseVO { - @ApiModelProperty(value = "商品名称", required = true, example = "芋道") + @Schema(title = "商品名称", required = true, example = "芋道") @NotEmpty(message = "商品名称不能为空") private String name; - @ApiModelProperty(value = "商品编码", example = "yudaoyuanma") + @Schema(title = "商品编码", example = "yudaoyuanma") private String code; - @ApiModelProperty(value = "促销语", example = "好吃!") + @Schema(title = "促销语", example = "好吃!") private String sellPoint; - @ApiModelProperty(value = "商品详情", required = true, example = "我是商品描述") + @Schema(title = "商品详情", required = true, example = "我是商品描述") @NotNull(message = "商品详情不能为空") private String description; - @ApiModelProperty(value = "商品分类编号", required = true, example = "1") + @Schema(title = "商品分类编号", required = true, example = "1") @NotNull(message = "商品分类编号不能为空") private Long categoryId; - @ApiModelProperty(value = "商品品牌编号", example = "1") + @Schema(title = "商品品牌编号", example = "1") private Long brandId; - @ApiModelProperty(value = "商品图片的数组", required = true) + @Schema(title = "商品图片的数组", required = true) @NotNull(message = "商品图片的数组不能为空") private List picUrls; - @ApiModelProperty(value = "商品视频", required = true) + @Schema(title = "商品视频", required = true) private String videoUrl; - @ApiModelProperty(value = "排序字段", required = true, example = "1") + @Schema(title = "排序字段", required = true, example = "1") private Integer sort; - @ApiModelProperty(value = "商品状态", required = true, example = "1", notes = "参见 ProductSpuStatusEnum 枚举类") + @Schema(title = "商品状态", required = true, example = "1", description = "参见 ProductSpuStatusEnum 枚举类") @NotNull(message = "商品状态不能为空") @InEnum(ProductSpuStatusEnum.class) private Integer status; // ========== SKU 相关字段 ========= - @ApiModelProperty(value = "规格类型", required = true, example = "1", notes = "参见 ProductSpuSpecTypeEnum 枚举类") + @Schema(title = "规格类型", required = true, example = "1", description = "参见 ProductSpuSpecTypeEnum 枚举类") @NotNull(message = "规格类型不能为空") @InEnum(ProductSpuSpecTypeEnum.class) private Integer specType; - @ApiModelProperty(value = "是否展示库存", required = true, example = "true") + @Schema(title = "是否展示库存", required = true, example = "true") @NotNull(message = "是否展示库存不能为空") private Boolean showStock; - @ApiModelProperty(value = "库存", required = true, example = "true") + @Schema(title = "库存", required = true, example = "true") private Integer totalStock; - @ApiModelProperty(value = "市场价", example = "1024") + @Schema(title = "市场价", example = "1024") private Integer marketPrice; - @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024") + @Schema(title = " 最小价格,单位使用:分", required = true, example = "1024") private Integer minPrice; - @ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024") + @Schema(title = "最大价格,单位使用:分", required = true, example = "1024") private Integer maxPrice; // ========== 统计相关字段 ========= - @ApiModelProperty(value = "商品销量", example = "1024") + @Schema(title = "商品销量", example = "1024") private Integer salesCount; - @ApiModelProperty(value = "虚拟销量", required = true, example = "1024") + @Schema(title = "虚拟销量", required = true, example = "1024") @NotNull(message = "虚拟销量不能为空") private Integer virtualSalesCount; - @ApiModelProperty(value = "点击量", example = "1024") + @Schema(title = "点击量", example = "1024") private Integer clickCount; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java index 87b0dd0b6..50aef8570 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,7 +9,7 @@ import lombok.ToString; import javax.validation.Valid; import java.util.List; -@ApiModel("管理后台 - 商品 SPU 创建 Request VO") +@Schema(title = "管理后台 - 商品 SPU 创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java index de41d1416..622d9eecd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -11,16 +10,16 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@ApiModel(value = "管理后台 - 商品 SPU 详细 Response VO", description = "包括关联的 SKU 等信息") +@Schema(title = "管理后台 - 商品 SPU 详细 Response VO", description = "包括关联的 SKU 等信息") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuDetailRespVO extends ProductSpuBaseVO { - @ApiModelProperty(value = "主键", required = true, example = "1") + @Schema(title = "主键", required = true, example = "1") private Long id; - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime createTime; /** @@ -28,7 +27,7 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO { */ private List skus; - @ApiModel(value = "管理后台 - 商品 SKU 详细 Response VO") + @Schema(title = "管理后台 - 商品 SKU 详细 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -41,25 +40,25 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO { } - @ApiModel(value = "管理后台 - 商品规格的详细 Response VO") + @Schema(title = "管理后台 - 商品规格的详细 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public static class Property extends ProductSkuBaseVO.Property { - @ApiModelProperty(value = "规格的名字", required = true, example = "颜色") + @Schema(title = "规格的名字", required = true, example = "颜色") private String propertyName; - @ApiModelProperty(value = "规格值的名字", required = true, example = "蓝色") + @Schema(title = "规格值的名字", required = true, example = "蓝色") private String valueName; } - @ApiModelProperty(value = "分类 id 数组,一直递归到一级父节点", example = "4") + @Schema(title = "分类 id 数组,一直递归到一级父节点", example = "4") private Long categoryId; // TODO @芋艿:在瞅瞅~ - @ApiModelProperty(value = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]") + @Schema(title = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]") private List productPropertyViews; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java index 8d1bbee5f..47ba5f213 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java @@ -1,46 +1,45 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 商品 SPU 分页 Request VO") +@Schema(title = "管理后台 - 商品 SPU 分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuPageReqVO extends PageParam { - @ApiModelProperty(value = "商品名称", example = "yutou") + @Schema(title = "商品名称", example = "yutou") private String name; - @ApiModelProperty(value = "商品编码", example = "yudaoyuanma") + @Schema(title = "商品编码", example = "yudaoyuanma") private String code; - @ApiModelProperty(value = "分类id", example = "1") + @Schema(title = "分类id", example = "1") private Long categoryId; - @ApiModelProperty(value = "商品品牌编号", example = "1") + @Schema(title = "商品品牌编号", example = "1") private Long brandId; - @ApiModelProperty(value = "上下架状态", example = "1", notes = "参见 ProductSpuStatusEnum 枚举值") + @Schema(title = "上下架状态", example = "1", description = "参见 ProductSpuStatusEnum 枚举值") private Integer status; - @ApiModelProperty(value = "销量最小值", example = "1") + @Schema(title = "销量最小值", example = "1") private Integer salesCountMin; - @ApiModelProperty(value = "销量最大值", example = "1024") + @Schema(title = "销量最大值", example = "1024") private Integer salesCountMax; - @ApiModelProperty(value = "市场价最小值", example = "1") + @Schema(title = "市场价最小值", example = "1") private Integer marketPriceMin; - @ApiModelProperty(value = "市场价最大值", example = "1024") + @Schema(title = "市场价最大值", example = "1024") private Integer marketPriceMax; - @ApiModelProperty(value = "是否库存告警", example = "true") + @Schema(title = "是否库存告警", example = "true") private Boolean alarmStock; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java index a8dca328b..46a1639ad 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,16 +8,16 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@ApiModel("管理后台 - 商品 SPU Response VO") +@Schema(title = "管理后台 - 商品 SPU Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuRespVO extends ProductSpuBaseVO { - @ApiModelProperty(value = "主键", required = true, example = "1") + @Schema(title = "主键", required = true, example = "1") private Long id; - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java index ea2811f8b..fe8e9a1c0 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java @@ -1,27 +1,26 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 商品 SPU 精简 Response VO") +@Schema(title = "管理后台 - 商品 SPU 精简 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuSimpleRespVO extends ProductSpuBaseVO { - @ApiModelProperty(value = "主键", required = true, example = "1") + @Schema(title = "主键", required = true, example = "1") private Long id; - @ApiModelProperty(value = "商品名称", required = true, example = "芋道") + @Schema(title = "商品名称", required = true, example = "芋道") private String name; - @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024") + @Schema(title = " 最小价格,单位使用:分", required = true, example = "1024") private Integer minPrice; - @ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024") + @Schema(title = "最大价格,单位使用:分", required = true, example = "1024") private Integer maxPrice; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java index 378a98dc6..5c988a3a2 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -11,13 +10,13 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel("管理后台 - 商品 SPU 更新 Request VO") +@Schema(title = "管理后台 - 商品 SPU 更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuUpdateReqVO extends ProductSpuBaseVO { - @ApiModelProperty(value = "商品编号", required = true, example = "1") + @Schema(title = "商品编号", required = true, example = "1") @NotNull(message = "商品编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java index fec882c48..79f066de4 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java @@ -5,8 +5,8 @@ import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRes import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -18,7 +18,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "用户 APP - 商品分类") +@Tag(name = "用户 APP - 商品分类") @RestController @RequestMapping("/product/category") @Validated @@ -28,7 +28,7 @@ public class AppCategoryController { private ProductCategoryService categoryService; @GetMapping("/list") - @ApiOperation("获得商品分类列表") + @Operation(summary = "获得商品分类列表") public CommonResult> getProductCategoryList() { List list = categoryService.getEnableCategoryList(); list.sort(Comparator.comparing(ProductCategoryDO::getSort)); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java index e46a50cd3..555677b9a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java @@ -1,28 +1,27 @@ package cn.iocoder.yudao.module.product.controller.app.category.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @Data -@ApiModel(value = "用户 APP - 商品分类 Response VO") +@Schema(title = "用户 APP - 商品分类 Response VO") public class AppCategoryRespVO { - @ApiModelProperty(value = "分类编号", required = true, example = "2") + @Schema(title = "分类编号", required = true, example = "2") private Long id; - @ApiModelProperty(value = "父分类编号", required = true, example = "1") + @Schema(title = "父分类编号", required = true, example = "1") @NotNull(message = "父分类编号不能为空") private Long parentId; - @ApiModelProperty(value = "分类名称", required = true, example = "办公文具") + @Schema(title = "分类名称", required = true, example = "办公文具") @NotBlank(message = "分类名称不能为空") private String name; - @ApiModelProperty(value = "分类图片", required = true) + @Schema(title = "分类图片", required = true) @NotBlank(message = "分类图片不能为空") private String picUrl; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index 7e0f912b4..289b89e1d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -7,8 +7,8 @@ import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO; import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuRespVO; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -20,7 +20,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "用户 APP - 商品spu") +@Tag(name = "用户 APP - 商品spu") @RestController @RequestMapping("/product/spu") @Validated @@ -30,13 +30,13 @@ public class AppProductSpuController { private ProductSpuService spuService; @GetMapping("/page") - @ApiOperation("获得商品spu分页") + @Operation(summary = "获得商品spu分页") public CommonResult> getSpuPage(@Valid AppSpuPageReqVO pageVO) { return success(spuService.getSpuPage(pageVO)); } @GetMapping("/") - @ApiOperation("获取商品 - 通过商品id") + @Operation(summary = "获取商品 - 通过商品id") public CommonResult getSpu(@RequestParam("spuId") Long spuId) { AppSpuRespVO appSpuRespVO = BeanUtil.toBean(spuService.getSpu(spuId), AppSpuRespVO.class); return success(appSpuRespVO); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java index 38ed4975e..facabfa88 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.product.controller.app.spu.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("App - 商品spu分页 Request VO") +@Schema(title = "App - 商品spu分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class AppSpuPageReqVO extends PageParam { - @ApiModelProperty(value = "分类id") + @Schema(title = "分类id") private Long categoryId; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java index c0a0f0eb8..074058cb4 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java @@ -1,52 +1,51 @@ package cn.iocoder.yudao.module.product.controller.app.spu.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel("App - 商品spu分页 Request VO") +@Schema(title = "App - 商品spu分页 Request VO") @Data public class AppSpuPageRespVO { - @ApiModelProperty(value = "主键", required = true, example = "1") + @Schema(title = "主键", required = true, example = "1") private Long id; - @ApiModelProperty(value = "商品名称") + @Schema(title = "商品名称") private String name; - @ApiModelProperty(value = "卖点", required = true) + @Schema(title = "卖点", required = true) @NotNull(message = "卖点不能为空") private String sellPoint; - @ApiModelProperty(value = "描述", required = true) + @Schema(title = "描述", required = true) @NotNull(message = "描述不能为空") private String description; - @ApiModelProperty(value = "分类id", required = true) + @Schema(title = "分类id", required = true) @NotNull(message = "分类id不能为空") private Long categoryId; - @ApiModelProperty(value = "商品主图地址,* 数组,以逗号分隔,最多上传15张", required = true) + @Schema(title = "商品主图地址,* 数组,以逗号分隔,最多上传15张", required = true) @NotNull(message = "商品主图地址,* 数组,以逗号分隔,最多上传15张不能为空") private List picUrls; - @ApiModelProperty(value = "排序字段", required = true) + @Schema(title = "排序字段", required = true) @NotNull(message = "排序字段不能为空") private Integer sort; - @ApiModelProperty(value = "点赞初始人数") + @Schema(title = "点赞初始人数") private Integer likeCount; - @ApiModelProperty(value = "价格 单位使用:分") + @Schema(title = "价格 单位使用:分") private Integer price; - @ApiModelProperty(value = "库存数量") + @Schema(title = "库存数量") private Integer quantity; - @ApiModelProperty(value = "上下架状态: 0 上架(开启) 1 下架(禁用)") + @Schema(title = "上下架状态: 0 上架(开启) 1 下架(禁用)") private Integer status; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java index b45987370..b63a78a52 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.product.controller.app.spu.vo; import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,7 +12,7 @@ import lombok.EqualsAndHashCode; * * @author LuoWenFeng */ -@ApiModel("App - 商品spu Response VO") +@Schema(title = "App - 商品spu Response VO") @Data @EqualsAndHashCode(callSuper = true) public class AppSpuRespVO extends ProductSpuRespVO { diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java index 0fbef12d5..f052a3349 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.*; import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; import cn.iocoder.yudao.module.promotion.service.banner.BannerService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -18,7 +18,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - Banner 管理") +@Tag(name = "管理后台 - Banner 管理") @RestController @RequestMapping("/market/banner") @Validated @@ -28,14 +28,14 @@ public class BannerController { private BannerService bannerService; @PostMapping("/create") - @ApiOperation("创建 Banner") + @Operation(summary = "创建 Banner") @PreAuthorize("@ss.hasPermission('market:banner:create')") public CommonResult createBanner(@Valid @RequestBody BannerCreateReqVO createReqVO) { return success(bannerService.createBanner(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新 Banner") + @Operation(summary = "更新 Banner") @PreAuthorize("@ss.hasPermission('market:banner:update')") public CommonResult updateBanner(@Valid @RequestBody BannerUpdateReqVO updateReqVO) { bannerService.updateBanner(updateReqVO); @@ -43,8 +43,8 @@ public class BannerController { } @DeleteMapping("/delete") - @ApiOperation("删除 Banner") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除 Banner") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('market:banner:delete')") public CommonResult deleteBanner(@RequestParam("id") Long id) { bannerService.deleteBanner(id); @@ -52,8 +52,8 @@ public class BannerController { } @GetMapping("/get") - @ApiOperation("获得 Banner") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得 Banner") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('market:banner:query')") public CommonResult getBanner(@RequestParam("id") Long id) { BannerDO banner = bannerService.getBanner(id); @@ -61,7 +61,7 @@ public class BannerController { } @GetMapping("/page") - @ApiOperation("获得 Banner 分页") + @Operation(summary = "获得 Banner 分页") @PreAuthorize("@ss.hasPermission('market:banner:query')") public CommonResult> getBannerPage(@Valid BannerPageReqVO pageVO) { PageResult pageResult = bannerService.getBannerPage(pageVO); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java index 3083856f5..75109ff12 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -15,28 +15,28 @@ import javax.validation.constraints.NotNull; @Data public class BannerBaseVO { - @ApiModelProperty(value = "标题", required = true) + @Schema(title = "标题", required = true) @NotNull(message = "标题不能为空") private String title; - @ApiModelProperty(value = "跳转链接", required = true) + @Schema(title = "跳转链接", required = true) @NotNull(message = "跳转链接不能为空") private String url; - @ApiModelProperty(value = "图片地址", required = true) + @Schema(title = "图片地址", required = true) @NotNull(message = "图片地址不能为空") private String picUrl; - @ApiModelProperty(value = "排序", required = true) + @Schema(title = "排序", required = true) @NotNull(message = "排序不能为空") private Integer sort; - @ApiModelProperty(value = "状态", required = true) + @Schema(title = "状态", required = true) @NotNull(message = "状态不能为空") @InEnum(CommonStatusEnum.class) private Integer status; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String memo; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java index c058fd8c2..488dc9aa3 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; - -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -8,7 +7,7 @@ import lombok.ToString; /** * @author xia */ -@ApiModel("管理后台 - Banner 创建 Request VO") +@Schema(title = "管理后台 - Banner 创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java index 5b7bd5f31..99729038e 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java @@ -3,8 +3,7 @@ package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -17,22 +16,22 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ /** * @author xia */ -@ApiModel("管理后台 - Banner 分页 Request VO") +@Schema(title = "管理后台 - Banner 分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BannerPageReqVO extends PageParam { - @ApiModelProperty(value = "标题") + @Schema(title = "标题") private String title; - @ApiModelProperty(value = "状态") + @Schema(title = "状态") @InEnum(CommonStatusEnum.class) private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java index 6b50110e8..792585c7d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.ToString; @@ -11,16 +10,16 @@ import java.time.LocalDateTime; /** * @author xia */ -@ApiModel("管理后台 - Banner Response VO") +@Schema(title = "管理后台 - Banner Response VO") @Data @ToString(callSuper = true) public class BannerRespVO extends BannerBaseVO { - @ApiModelProperty(value = "banner编号", required = true) + @Schema(title = "banner编号", required = true) @NotNull(message = "banner编号不能为空") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java index 971a87353..db4b28709 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -11,13 +10,13 @@ import javax.validation.constraints.NotNull; /** * @author xia */ -@ApiModel("管理后台 - Banner更新 Request VO") +@Schema(title = "管理后台 - Banner更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BannerUpdateReqVO extends BannerBaseVO { - @ApiModelProperty(value = "banner 编号", required = true) + @Schema(title = "banner 编号", required = true) @NotNull(message = "banner 编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java index 0a6facbc9..5f7bff151 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java @@ -11,9 +11,9 @@ import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.Coupo import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -26,7 +26,7 @@ import java.util.Set; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -@Api(tags = "管理后台 - 优惠劵") +@Tag(name = "管理后台 - 优惠劵") @RestController @RequestMapping("/promotion/coupon") @Validated @@ -38,8 +38,8 @@ public class CouponController { private MemberUserApi memberUserApi; // @GetMapping("/get") -// @ApiOperation("获得优惠劵") -// @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) +// @Operation(summary = "获得优惠劵") +// @Parameter(name = "id", description = "编号", required = true, example = "1024") // @PreAuthorize("@ss.hasPermission('promotion:coupon:query')") // public CommonResult getCoupon(@RequestParam("id") Long id) { // CouponDO coupon = couponService.getCoupon(id); @@ -47,8 +47,8 @@ public class CouponController { // } @DeleteMapping("/delete") - @ApiOperation("回收优惠劵") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "回收优惠劵") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('promotion:coupon:delete')") public CommonResult deleteCoupon(@RequestParam("id") Long id) { couponService.deleteCoupon(id); @@ -56,7 +56,7 @@ public class CouponController { } @GetMapping("/page") - @ApiOperation("获得优惠劵分页") + @Operation(summary = "获得优惠劵分页") @PreAuthorize("@ss.hasPermission('promotion:coupon:query')") public CommonResult> getCouponPage(@Valid CouponPageReqVO pageVO) { PageResult pageResult = couponService.getCouponPage(pageVO); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java index 76efd2daa..df5b16986 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.*; import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; import cn.iocoder.yudao.module.promotion.service.coupon.CouponTemplateService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -18,7 +18,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 优惠劵模板") +@Tag(name = "管理后台 - 优惠劵模板") @RestController @RequestMapping("/promotion/coupon-template") @Validated @@ -28,14 +28,14 @@ public class CouponTemplateController { private CouponTemplateService couponTemplateService; @PostMapping("/create") - @ApiOperation("创建优惠劵模板") + @Operation(summary = "创建优惠劵模板") @PreAuthorize("@ss.hasPermission('promotion:coupon-template:create')") public CommonResult createCouponTemplate(@Valid @RequestBody CouponTemplateCreateReqVO createReqVO) { return success(couponTemplateService.createCouponTemplate(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新优惠劵模板") + @Operation(summary = "更新优惠劵模板") @PreAuthorize("@ss.hasPermission('promotion:coupon-template:update')") public CommonResult updateCouponTemplate(@Valid @RequestBody CouponTemplateUpdateReqVO updateReqVO) { couponTemplateService.updateCouponTemplate(updateReqVO); @@ -43,7 +43,7 @@ public class CouponTemplateController { } @PutMapping("/update-status") - @ApiOperation("更新优惠劵模板状态") + @Operation(summary = "更新优惠劵模板状态") @PreAuthorize("@ss.hasPermission('promotion:coupon-template:update')") public CommonResult updateCouponTemplateStatus(@Valid @RequestBody CouponTemplateUpdateStatusReqVO reqVO) { couponTemplateService.updateCouponTemplateStatus(reqVO.getId(), reqVO.getStatus()); @@ -51,8 +51,8 @@ public class CouponTemplateController { } @DeleteMapping("/delete") - @ApiOperation("删除优惠劵模板") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除优惠劵模板") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('promotion:coupon-template:delete')") public CommonResult deleteCouponTemplate(@RequestParam("id") Long id) { couponTemplateService.deleteCouponTemplate(id); @@ -60,8 +60,8 @@ public class CouponTemplateController { } @GetMapping("/get") - @ApiOperation("获得优惠劵模板") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得优惠劵模板") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('promotion:coupon-template:query')") public CommonResult getCouponTemplate(@RequestParam("id") Long id) { CouponTemplateDO couponTemplate = couponTemplateService.getCouponTemplate(id); @@ -69,7 +69,7 @@ public class CouponTemplateController { } @GetMapping("/page") - @ApiOperation("获得优惠劵模板分页") + @Operation(summary = "获得优惠劵模板分页") @PreAuthorize("@ss.hasPermission('promotion:coupon-template:query')") public CommonResult> getCouponTemplatePage(@Valid CouponTemplatePageReqVO pageVO) { PageResult pageResult = couponTemplateService.getCouponTemplatePage(pageVO); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java index 269b2b2ca..90f4c7278 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; import com.fasterxml.jackson.annotation.JsonFormat; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -24,76 +24,76 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DE public class CouponBaseVO { // ========== 基本信息 BEGIN ========== - @ApiModelProperty(value = "优惠劵模板编号", required = true, example = "1024") + @Schema(title = "优惠劵模板编号", required = true, example = "1024") @NotNull(message = "优惠劵模板编号不能为空") private Integer templateId; - @ApiModelProperty(value = "优惠劵名", required = true, example = "春节送送送") + @Schema(title = "优惠劵名", required = true, example = "春节送送送") @NotNull(message = "优惠劵名不能为空") private String name; - @ApiModelProperty(value = "优惠码状态", required = true, example = "1", notes = "参见 CouponStatusEnum 枚举") + @Schema(title = "优惠码状态", required = true, example = "1", description = "参见 CouponStatusEnum 枚举") private Integer status; // ========== 基本信息 END ========== // ========== 领取情况 BEGIN ========== - @ApiModelProperty(value = "用户编号", required = true, example = "1") + @Schema(title = "用户编号", required = true, example = "1") @NotNull(message = "用户编号不能为空") private Long userId; - @ApiModelProperty(value = "领取方式", required = true, example = "1", notes = "参见 CouponTakeTypeEnum 枚举类") + @Schema(title = "领取方式", required = true, example = "1", description = "参见 CouponTakeTypeEnum 枚举类") @NotNull(message = "领取方式不能为空") private Integer takeType; // ========== 领取情况 END ========== // ========== 使用规则 BEGIN ========== - @ApiModelProperty(value = "是否设置满多少金额可用", required = true, example = "100", notes = "单位:分;0 - 不限制") + @Schema(title = "是否设置满多少金额可用", required = true, example = "100", description = "单位:分;0 - 不限制") @NotNull(message = "是否设置满多少金额可用不能为空") private Integer usePrice; - @ApiModelProperty(value = "固定日期 - 生效开始时间") + @Schema(title = "固定日期 - 生效开始时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime validStartTime; - @ApiModelProperty(value = "固定日期 - 生效结束时间") + @Schema(title = "固定日期 - 生效结束时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime validEndTime; - @ApiModelProperty(value = "商品范围", required = true, example = "1", notes = "参见 PromotionProductScopeEnum 枚举类") + @Schema(title = "商品范围", required = true, example = "1", description = "参见 PromotionProductScopeEnum 枚举类") @NotNull(message = "商品范围不能为空") @InEnum(PromotionProductScopeEnum.class) private Integer productScope; - @ApiModelProperty(value = "商品 SPU 编号的数组", example = "1,3") + @Schema(title = "商品 SPU 编号的数组", example = "1,3") private List productSpuIds; // ========== 使用规则 END ========== // ========== 使用效果 BEGIN ========== - @ApiModelProperty(value = "优惠类型", required = true, example = "1", notes = "参见 PromotionDiscountTypeEnum 枚举") + @Schema(title = "优惠类型", required = true, example = "1", description = "参见 PromotionDiscountTypeEnum 枚举") @NotNull(message = "优惠类型不能为空") @InEnum(PromotionDiscountTypeEnum.class) private Integer discountType; - @ApiModelProperty(value = "折扣百分比", example = "80", notes = "例如说,80% 为 80") + @Schema(title = "折扣百分比", example = "80", description = "例如说,80% 为 80") private Integer discountPercent; - @ApiModelProperty(value = "优惠金额", example = "10", notes = "单位:分") + @Schema(title = "优惠金额", example = "10", description = "单位:分") @Min(value = 0, message = "优惠金额需要大于等于 0") private Integer discountPrice; - @ApiModelProperty(value = "折扣上限", example = "100", notes = "单位:分,仅在 discountType 为 PERCENT 使用") + @Schema(title = "折扣上限", example = "100", description = "单位:分,仅在 discountType 为 PERCENT 使用") private Integer discountLimitPrice; // ========== 使用效果 END ========== // ========== 使用情况 BEGIN ========== - @ApiModelProperty(value = "使用订单号", example = "4096") + @Schema(title = "使用订单号", example = "4096") private Long useOrderId; - @ApiModelProperty(value = "使用时间") + @Schema(title = "使用时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime useTime; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java index 88bc364bd..7529ee62b 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 优惠劵分页的每一项 Response VO") +@Schema(title = "管理后台 - 优惠劵分页的每一项 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponPageItemRespVO extends CouponRespVO { - @ApiModelProperty(value = "用户昵称", example = "老芋艿") + @Schema(title = "用户昵称", example = "老芋艿") private String nickname; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java index 78ef1039f..ba81ca1d4 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,23 +11,23 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 优惠劵分页 Request VO") +@Schema(title = "管理后台 - 优惠劵分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponPageReqVO extends PageParam { - @ApiModelProperty(value = "优惠劵模板编号", example = "2048") + @Schema(title = "优惠劵模板编号", example = "2048") private Long templateId; - @ApiModelProperty(value = "优惠码状态", example = "1", notes = "参见 CouponStatusEnum 枚举") + @Schema(title = "优惠码状态", example = "1", description = "参见 CouponStatusEnum 枚举") private Integer status; - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; - @ApiModelProperty(value = "用户昵称", example = "芋艿", notes = "模糊匹配") + @Schema(title = "用户昵称", example = "芋艿", description = "模糊匹配") private String nickname; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java index 76e075883..8a07e28dc 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 优惠劵 Response VO") +@Schema(title = "管理后台 - 优惠劵 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponRespVO extends CouponBaseVO { - @ApiModelProperty(value = "优惠劵编号", required = true, example = "1024") + @Schema(title = "优惠劵编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java index e54a33ce0..4c69a443e 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -29,70 +29,70 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DE @Data public class CouponTemplateBaseVO { - @ApiModelProperty(value = "优惠劵名", required = true, example = "春节送送送") + @Schema(title = "优惠劵名", required = true, example = "春节送送送") @NotNull(message = "优惠劵名不能为空") private String name; - @ApiModelProperty(value = "发行总量", required = true, example = "1024", notes = "-1 - 则表示不限制发放数量") + @Schema(title = "发行总量", required = true, example = "1024", description = "-1 - 则表示不限制发放数量") @NotNull(message = "发行总量不能为空") private Integer totalCount; - @ApiModelProperty(value = "每人限领个数", required = true, example = "66", notes = "-1 - 则表示不限制") + @Schema(title = "每人限领个数", required = true, example = "66", description = "-1 - 则表示不限制") @NotNull(message = "每人限领个数不能为空") private Integer takeLimitCount; - @ApiModelProperty(value = "领取方式", required = true, example = "1", notes = "参见 CouponTakeTypeEnum 枚举类") + @Schema(title = "领取方式", required = true, example = "1", description = "参见 CouponTakeTypeEnum 枚举类") @NotNull(message = "领取方式不能为空") private Integer takeType; - @ApiModelProperty(value = "是否设置满多少金额可用", required = true, example = "100", notes = "单位:分;0 - 不限制") + @Schema(title = "是否设置满多少金额可用", required = true, example = "100", description = "单位:分;0 - 不限制") @NotNull(message = "是否设置满多少金额可用不能为空") private Integer usePrice; - @ApiModelProperty(value = "商品范围", required = true, example = "1", notes = "参见 PromotionProductScopeEnum 枚举类") + @Schema(title = "商品范围", required = true, example = "1", description = "参见 PromotionProductScopeEnum 枚举类") @NotNull(message = "商品范围不能为空") @InEnum(PromotionProductScopeEnum.class) private Integer productScope; - @ApiModelProperty(value = "商品 SPU 编号的数组", example = "1,3") + @Schema(title = "商品 SPU 编号的数组", example = "1,3") private List productSpuIds; - @ApiModelProperty(value = "生效日期类型", required = true, example = "1") + @Schema(title = "生效日期类型", required = true, example = "1") @NotNull(message = "生效日期类型不能为空") @InEnum(CouponTemplateValidityTypeEnum.class) private Integer validityType; - @ApiModelProperty(value = "固定日期 - 生效开始时间") + @Schema(title = "固定日期 - 生效开始时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime validStartTime; - @ApiModelProperty(value = "固定日期 - 生效结束时间") + @Schema(title = "固定日期 - 生效结束时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime validEndTime; - @ApiModelProperty(value = "领取日期 - 开始天数") + @Schema(title = "领取日期 - 开始天数") @Min(value = 0L, message = "开始天数必须大于 0") private Integer fixedStartTerm; - @ApiModelProperty(value = "领取日期 - 结束天数") + @Schema(title = "领取日期 - 结束天数") @Min(value = 1L, message = "开始天数必须大于 1") private Integer fixedEndTerm; - @ApiModelProperty(value = "优惠类型", required = true, example = "1", notes = "参见 PromotionDiscountTypeEnum 枚举") + @Schema(title = "优惠类型", required = true, example = "1", description = "参见 PromotionDiscountTypeEnum 枚举") @NotNull(message = "优惠类型不能为空") @InEnum(PromotionDiscountTypeEnum.class) private Integer discountType; - @ApiModelProperty(value = "折扣百分比", example = "80", notes = "例如说,80% 为 80") + @Schema(title = "折扣百分比", example = "80", description = "例如说,80% 为 80") private Integer discountPercent; - @ApiModelProperty(value = "优惠金额", example = "10", notes = "单位:分") + @Schema(title = "优惠金额", example = "10", description = "单位:分") @Min(value = 0, message = "优惠金额需要大于等于 0") private Integer discountPrice; - @ApiModelProperty(value = "折扣上限", example = "100", notes = "单位:分,仅在 discountType 为 PERCENT 使用") + @Schema(title = "折扣上限", example = "100", description = "单位:分,仅在 discountType 为 PERCENT 使用") private Integer discountLimitPrice; @AssertTrue(message = "商品 SPU 编号的数组不能为空") diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java index 91bfb0a5f..60c37ee0d 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java @@ -1,11 +1,10 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; - -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 优惠劵模板创建 Request VO") +@Schema(title = "管理后台 - 优惠劵模板创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java index 8fffe4db0..6efb227cc 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,22 +11,22 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 优惠劵模板分页 Request VO") +@Schema(title = "管理后台 - 优惠劵模板分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponTemplatePageReqVO extends PageParam { - @ApiModelProperty(value = "优惠劵名", example = "你好") + @Schema(title = "优惠劵名", example = "你好") private String name; - @ApiModelProperty(value = "状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "优惠类型", example = "1", notes = "参见 PromotionDiscountTypeEnum 枚举") + @Schema(title = "优惠类型", example = "1", description = "参见 PromotionDiscountTypeEnum 枚举") private Integer discountType; - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java index 7182733e7..d3d71696b 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java @@ -2,34 +2,33 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 优惠劵模板 Response VO") +@Schema(title = "管理后台 - 优惠劵模板 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponTemplateRespVO extends CouponTemplateBaseVO { - @ApiModelProperty(value = "模板编号", required = true, example = "1024") + @Schema(title = "模板编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1") + @Schema(title = "状态", required = true, example = "1") @InEnum(CommonStatusEnum.class) private Integer status; - @ApiModelProperty(value = "领取优惠券的数量", required = true, example = "1024") + @Schema(title = "领取优惠券的数量", required = true, example = "1024") private Integer takeCount; - @ApiModelProperty(value = "使用优惠券的次数", required = true, example = "2048") + @Schema(title = "使用优惠券的次数", required = true, example = "2048") private Integer useCount; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java index 8e5e8723a..054ddbf6a 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 优惠劵模板更新 Request VO") +@Schema(title = "管理后台 - 优惠劵模板更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponTemplateUpdateReqVO extends CouponTemplateBaseVO { - @ApiModelProperty(value = "模板编号", required = true, example = "1024") + @Schema(title = "模板编号", required = true, example = "1024") @NotNull(message = "模板编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java index 32e020637..9d6c48c41 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java @@ -2,21 +2,20 @@ package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 优惠劵模板更新状态 Request VO") +@Schema(title = "管理后台 - 优惠劵模板更新状态 Request VO") @Data public class CouponTemplateUpdateStatusReqVO { - @ApiModelProperty(value = "优惠劵模板编号", required = true, example = "1024") + @Schema(title = "优惠劵模板编号", required = true, example = "1024") @NotNull(message = "优惠劵模板编号不能为空") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") private Integer status; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java index 332a1b822..08d4dc10e 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java @@ -7,9 +7,9 @@ import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConver import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 限时折扣活动") +@Tag(name = "管理后台 - 限时折扣活动") @RestController @RequestMapping("/promotion/discount-activity") @Validated @@ -30,14 +30,14 @@ public class DiscountActivityController { private DiscountActivityService discountActivityService; @PostMapping("/create") - @ApiOperation("创建限时折扣活动") + @Operation(summary = "创建限时折扣活动") @PreAuthorize("@ss.hasPermission('promotion:discount-activity:create')") public CommonResult createDiscountActivity(@Valid @RequestBody DiscountActivityCreateReqVO createReqVO) { return success(discountActivityService.createDiscountActivity(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新限时折扣活动") + @Operation(summary = "更新限时折扣活动") @PreAuthorize("@ss.hasPermission('promotion:discount-activity:update')") public CommonResult updateDiscountActivity(@Valid @RequestBody DiscountActivityUpdateReqVO updateReqVO) { discountActivityService.updateDiscountActivity(updateReqVO); @@ -45,8 +45,8 @@ public class DiscountActivityController { } @PutMapping("/close") - @ApiOperation("关闭限时折扣活动") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "关闭限时折扣活动") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('promotion:discount-activity:close')") public CommonResult closeRewardActivity(@RequestParam("id") Long id) { discountActivityService.closeRewardActivity(id); @@ -54,8 +54,8 @@ public class DiscountActivityController { } @DeleteMapping("/delete") - @ApiOperation("删除限时折扣活动") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除限时折扣活动") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('promotion:discount-activity:delete')") public CommonResult deleteDiscountActivity(@RequestParam("id") Long id) { discountActivityService.deleteDiscountActivity(id); @@ -63,8 +63,8 @@ public class DiscountActivityController { } @GetMapping("/get") - @ApiOperation("获得限时折扣活动") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得限时折扣活动") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')") public CommonResult getDiscountActivity(@RequestParam("id") Long id) { DiscountActivityDO discountActivity = discountActivityService.getDiscountActivity(id); @@ -77,7 +77,7 @@ public class DiscountActivityController { } @GetMapping("/page") - @ApiOperation("获得限时折扣活动分页") + @Operation(summary = "获得限时折扣活动分页") @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')") public CommonResult> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) { PageResult pageResult = discountActivityService.getDiscountActivityPage(pageVO); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java index 60a65ec59..35f3da2ad 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java @@ -4,8 +4,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -23,44 +22,44 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class DiscountActivityBaseVO { - @ApiModelProperty(value = "活动标题", required = true, example = "一个标题") + @Schema(title = "活动标题", required = true, example = "一个标题") @NotNull(message = "活动标题不能为空") private String name; - @ApiModelProperty(value = "开始时间", required = true) + @Schema(title = "开始时间", required = true) @NotNull(message = "开始时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; - @ApiModelProperty(value = "结束时间", required = true) + @Schema(title = "结束时间", required = true) @NotNull(message = "结束时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; - @ApiModelProperty(value = "备注", example = "我是备注") + @Schema(title = "备注", example = "我是备注") private String remark; - @ApiModel("商品") + @Schema(title = "商品") @Data public static class Product { - @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") + @Schema(title = "商品 SPU 编号", required = true, example = "1") @NotNull(message = "商品 SPU 编号不能为空") private Long spuId; - @ApiModelProperty(value = "商品 SKU 编号", required = true, example = "1") + @Schema(title = "商品 SKU 编号", required = true, example = "1") @NotNull(message = "商品 SKU 编号不能为空") private Long skuId; - @ApiModelProperty(value = "优惠类型", required = true, example = "1", notes = "参见 PromotionDiscountTypeEnum 枚举") + @Schema(title = "优惠类型", required = true, example = "1", description = "参见 PromotionDiscountTypeEnum 枚举") @NotNull(message = "优惠类型不能为空") @InEnum(PromotionDiscountTypeEnum.class) private Integer discountType; - @ApiModelProperty(value = "折扣百分比", example = "80", notes = "例如说,80% 为 80") + @Schema(title = "折扣百分比", example = "80", description = "例如说,80% 为 80") private Integer discountPercent; - @ApiModelProperty(value = "优惠金额", example = "10", notes = "单位:分") + @Schema(title = "优惠金额", example = "10", description = "单位:分") @Min(value = 0, message = "优惠金额需要大于等于 0") private Integer discountPrice; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java index 35de6faf2..86eedc799 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; - -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,7 +8,7 @@ import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import java.util.List; -@ApiModel("管理后台 - 限时折扣活动创建 Request VO") +@Schema(title = "管理后台 - 限时折扣活动创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java index 1dfdeec18..44cc1965c 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java @@ -1,13 +1,12 @@ package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; - -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.util.List; -@ApiModel("管理后台 - 限时折扣活动的详细 Response VO") +@Schema(title = "管理后台 - 限时折扣活动的详细 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java index 0e3406f07..2c8679566 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,19 +11,19 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 限时折扣活动分页 Request VO") +@Schema(title = "管理后台 - 限时折扣活动分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DiscountActivityPageReqVO extends PageParam { - @ApiModelProperty(value = "活动标题", example = "一个标题") + @Schema(title = "活动标题", example = "一个标题") private String name; - @ApiModelProperty(value = "活动状态", example = "1") + @Schema(title = "活动状态", example = "1") private Integer status; - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java index 0422908b5..d46918edf 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,20 +8,20 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@ApiModel("管理后台 - 限时折扣活动 Response VO") +@Schema(title = "管理后台 - 限时折扣活动 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DiscountActivityRespVO extends DiscountActivityBaseVO { - @ApiModelProperty(value = "活动编号", required = true, example = "1024") + @Schema(title = "活动编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "活动状态", required = true, example = "1") + @Schema(title = "活动状态", required = true, example = "1") @NotNull(message = "活动状态不能为空") private Integer status; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java index 0f3b6e435..ff9aa27b3 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -11,13 +10,13 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel("管理后台 - 限时折扣活动更新 Request VO") +@Schema(title = "管理后台 - 限时折扣活动更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DiscountActivityUpdateReqVO extends DiscountActivityBaseVO { - @ApiModelProperty(value = "活动编号", required = true, example = "1024") + @Schema(title = "活动编号", required = true, example = "1024") @NotNull(message = "活动编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java index 043571e5e..c8c13ccf0 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivi import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -21,7 +21,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 满减送活动") +@Tag(name = "管理后台 - 满减送活动") @RestController @RequestMapping("/promotion/reward-activity") @Validated @@ -31,14 +31,14 @@ public class RewardActivityController { private RewardActivityService rewardActivityService; @PostMapping("/create") - @ApiOperation("创建满减送活动") + @Operation(summary = "创建满减送活动") @PreAuthorize("@ss.hasPermission('promotion:reward-activity:create')") public CommonResult createRewardActivity(@Valid @RequestBody RewardActivityCreateReqVO createReqVO) { return success(rewardActivityService.createRewardActivity(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新满减送活动") + @Operation(summary = "更新满减送活动") @PreAuthorize("@ss.hasPermission('promotion:reward-activity:update')") public CommonResult updateRewardActivity(@Valid @RequestBody RewardActivityUpdateReqVO updateReqVO) { rewardActivityService.updateRewardActivity(updateReqVO); @@ -46,8 +46,8 @@ public class RewardActivityController { } @PutMapping("/close") - @ApiOperation("关闭满减送活动") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "关闭满减送活动") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('promotion:reward-activity:close')") public CommonResult closeRewardActivity(@RequestParam("id") Long id) { rewardActivityService.closeRewardActivity(id); @@ -55,8 +55,8 @@ public class RewardActivityController { } @DeleteMapping("/delete") - @ApiOperation("删除满减送活动") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除满减送活动") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('promotion:reward-activity:delete')") public CommonResult deleteRewardActivity(@RequestParam("id") Long id) { rewardActivityService.deleteRewardActivity(id); @@ -64,8 +64,8 @@ public class RewardActivityController { } @GetMapping("/get") - @ApiOperation("获得满减送活动") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得满减送活动") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('promotion:reward-activity:query')") public CommonResult getRewardActivity(@RequestParam("id") Long id) { RewardActivityDO rewardActivity = rewardActivityService.getRewardActivity(id); @@ -73,7 +73,7 @@ public class RewardActivityController { } @GetMapping("/page") - @ApiOperation("获得满减送活动分页") + @Operation(summary = "获得满减送活动分页") @PreAuthorize("@ss.hasPermission('promotion:reward-activity:query')") public CommonResult> getRewardActivityPage(@Valid RewardActivityPageReqVO pageVO) { PageResult pageResult = rewardActivityService.getRewardActivityPage(pageVO); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java index ed2802124..75ab536de 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java @@ -4,8 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -26,35 +25,35 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class RewardActivityBaseVO { - @ApiModelProperty(value = "活动标题", required = true, example = "满啦满啦") + @Schema(title = "活动标题", required = true, example = "满啦满啦") @NotNull(message = "活动标题不能为空") private String name; - @ApiModelProperty(value = "开始时间", required = true) + @Schema(title = "开始时间", required = true) @NotNull(message = "开始时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; - @ApiModelProperty(value = "结束时间", required = true) + @Schema(title = "结束时间", required = true) @NotNull(message = "结束时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @Future(message = "结束时间必须大于当前时间") private LocalDateTime endTime; - @ApiModelProperty(value = "备注", example = "biubiubiu") + @Schema(title = "备注", example = "biubiubiu") private String remark; - @ApiModelProperty(value = "条件类型", required = true, example = "1") + @Schema(title = "条件类型", required = true, example = "1") @NotNull(message = "条件类型不能为空") @InEnum(value = PromotionConditionTypeEnum.class, message = "条件类型必须是 {value}") private Integer conditionType; - @ApiModelProperty(value = "商品范围", required = true, example = "1") + @Schema(title = "商品范围", required = true, example = "1") @NotNull(message = "商品范围不能为空") @InEnum(value = PromotionConditionTypeEnum.class, message = "商品范围必须是 {value}") private Integer productScope; - @ApiModelProperty(value = "商品 SPU 编号的数组", example = "1,2,3") + @Schema(title = "商品 SPU 编号的数组", example = "1,2,3") private List productSpuIds; /** @@ -63,29 +62,29 @@ public class RewardActivityBaseVO { @Valid // 校验下子对象 private List rules; - @ApiModel("优惠规则") + @Schema(title = "优惠规则") @Data public static class Rule { - @ApiModelProperty(value = "优惠门槛", required = true, example = "100", notes = "1. 满 N 元,单位:分; 2. 满 N 件") + @Schema(title = "优惠门槛", required = true, example = "100", description = "1. 满 N 元,单位:分; 2. 满 N 件") @Min(value = 1L, message = "优惠门槛必须大于等于 1") private Integer limit; - @ApiModelProperty(value = "优惠价格", required = true, example = "100", notes = "单位:分") + @Schema(title = "优惠价格", required = true, example = "100", description = "单位:分") @Min(value = 1L, message = "优惠价格必须大于等于 1") private Integer discountPrice; - @ApiModelProperty(value = "是否包邮", required = true, example = "true") + @Schema(title = "是否包邮", required = true, example = "true") private Boolean freeDelivery; - @ApiModelProperty(value = "赠送的积分", required = true, example = "100") + @Schema(title = "赠送的积分", required = true, example = "100") @Min(value = 1L, message = "赠送的积分必须大于等于 1") private Integer point; - @ApiModelProperty(value = "赠送的优惠劵编号的数组", example = "1,2,3") + @Schema(title = "赠送的优惠劵编号的数组", example = "1,2,3") private List couponIds; - @ApiModelProperty(value = "赠送的优惠卷数量的数组", example = "1,2,3") + @Schema(title = "赠送的优惠卷数量的数组", example = "1,2,3") private List couponCounts; @AssertTrue(message = "优惠劵和数量必须一一对应") diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java index 6a7251021..222a704c6 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 满减送活动创建 Request VO") +@Schema(title = "管理后台 - 满减送活动创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java index 5a8d2ba6d..980f92bfc 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; -@ApiModel("管理后台 - 满减送活动分页 Request VO") +@Schema(title = "管理后台 - 满减送活动分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class RewardActivityPageReqVO extends PageParam { - @ApiModelProperty(value = "活动标题", example = "满啦满啦") + @Schema(title = "活动标题", example = "满啦满啦") private String name; - @ApiModelProperty(value = "活动状态", example = "1") + @Schema(title = "活动状态", example = "1") private Integer status; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java index cb90e21cb..2eede11e2 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 满减送活动 Response VO") +@Schema(title = "管理后台 - 满减送活动 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class RewardActivityRespVO extends RewardActivityBaseVO { - @ApiModelProperty(value = "活动编号", required = true, example = "1024") + @Schema(title = "活动编号", required = true, example = "1024") private Integer id; - @ApiModelProperty(value = "活动状态", required = true, example = "1") + @Schema(title = "活动状态", required = true, example = "1") private Integer status; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java index 659deee3d..9580868c6 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java @@ -1,16 +1,15 @@ package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 满减送活动更新 Request VO") +@Schema(title = "管理后台 - 满减送活动更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class RewardActivityUpdateReqVO extends RewardActivityBaseVO { - @ApiModelProperty(value = "活动编号", required = true, example = "1024") + @Schema(title = "活动编号", required = true, example = "1024") @NotNull(message = "活动编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java index d6d6689ef..510889f9c 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.promotion.controller.app; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -10,14 +10,14 @@ import org.springframework.web.bind.annotation.RestController; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "用户 App - 营销") +@Tag(name = "用户 App - 营销") @RestController @RequestMapping("/market/test") @Validated public class AppMarketTestController { @GetMapping("/get") - @ApiOperation("获取 market 信息") + @Operation(summary = "获取 market 信息") public CommonResult get() { return success("true"); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java index 4edd1ed04..1a7f148ff 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java @@ -5,8 +5,8 @@ import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; import cn.iocoder.yudao.module.promotion.service.banner.BannerService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -23,7 +23,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; */ @RestController @RequestMapping("/market/banner") -@Api(tags = "用户APP- 首页Banner") +@Tag(name = "用户APP- 首页Banner") @Validated public class AppBannerController { @@ -32,7 +32,7 @@ public class AppBannerController { // TODO @xia:新建一个 AppBannerRespVO,只返回必要的字段。status 要过滤下。然后 sort 下结果 @GetMapping("/list") - @ApiOperation("获得banner列表") + @Operation(summary = "获得banner列表") @PreAuthorize("@ss.hasPermission('market:banner:query')") public CommonResult> getBannerList() { List list = bannerService.getBannerList(); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java index e116f5888..c4ec055c8 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.trade.controller.app.base.property; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("用户 App - 规格 + 规格值 Response VO") +@Schema(title = "用户 App - 规格 + 规格值 Response VO") @Data public class AppProductPropertyValueDetailRespVO { - @ApiModelProperty(value = "属性的编号", required = true, example = "1") + @Schema(title = "属性的编号", required = true, example = "1") private Long propertyId; - @ApiModelProperty(value = "属性的名称", required = true, example = "颜色") + @Schema(title = "属性的名称", required = true, example = "颜色") private String propertyName; - @ApiModelProperty(value = "属性值的编号", required = true, example = "1024") + @Schema(title = "属性值的编号", required = true, example = "1024") private Long valueId; - @ApiModelProperty(value = "属性值的名称", required = true, example = "红色") + @Schema(title = "属性值的名称", required = true, example = "红色") private String valueName; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java index ed666a9c8..5d6499517 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.trade.controller.app.base.sku; import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; @@ -14,16 +14,16 @@ import java.util.List; @Data public class AppProductSkuBaseRespVO { - @ApiModelProperty(value = "主键", required = true, example = "1024") + @Schema(title = "主键", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "商品 SKU 名字", required = true, example = "芋道") + @Schema(title = "商品 SKU 名字", required = true, example = "芋道") private String name; - @ApiModelProperty(value = "图片地址", example = "https://www.iocoder.cn/xx.png") + @Schema(title = "图片地址", example = "https://www.iocoder.cn/xx.png") private String picUrl; - @ApiModelProperty(value = "库存", required = true, example = "1") + @Schema(title = "库存", required = true, example = "1") private Integer stock; /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java index c7d9f236f..a3ebf3fe8 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.trade.controller.app.base.spu; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; @@ -13,13 +12,13 @@ import java.util.List; @Data public class AppProductSpuBaseRespVO { - @ApiModelProperty(value = "主键", required = true, example = "1024") + @Schema(title = "主键", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "商品 SPU 名字", required = true, example = "芋道") + @Schema(title = "商品 SPU 名字", required = true, example = "芋道") private String name; - @ApiModelProperty(value = "商品主图地址", example = "https://www.iocoder.cn/xx.png") + @Schema(title = "商品主图地址", example = "https://www.iocoder.cn/xx.png") private List picUrls; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java index e3688d155..96f55d9a3 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java @@ -7,9 +7,9 @@ import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddC import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO; import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; @@ -22,7 +22,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Api(tags = "用户 App - 购物车") +@Tag(name = "用户 App - 购物车") @RestController @RequestMapping("/trade/cart") @RequiredArgsConstructor @@ -34,7 +34,7 @@ public class TradeCartController { private TradeCartService cartService; @PostMapping("/add-count") - @ApiOperation("添加商品到购物车") + @Operation(summary = "添加商品到购物车") @PreAuthenticated public CommonResult addCartItemCount(@Valid @RequestBody AppTradeCartItemAddCountReqVO addCountReqVO) { cartService.addCartItemCount(getLoginUserId(), addCountReqVO); @@ -42,7 +42,7 @@ public class TradeCartController { } @PutMapping("update-count") - @ApiOperation("更新购物车商品数量") + @Operation(summary = "更新购物车商品数量") @PreAuthenticated public CommonResult updateCartItemQuantity(@Valid @RequestBody AppTradeCartItemUpdateCountReqVO updateCountReqVO) { cartService.updateCartItemCount(getLoginUserId(), updateCountReqVO); @@ -50,7 +50,7 @@ public class TradeCartController { } @PutMapping("update-selected") - @ApiOperation("更新购物车商品是否选中") + @Operation(summary = "更新购物车商品是否选中") @PreAuthenticated public CommonResult updateCartItemSelected(@Valid @RequestBody AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO) { cartService.updateCartItemSelected(getLoginUserId(), updateSelectedReqVO); @@ -59,8 +59,8 @@ public class TradeCartController { } @DeleteMapping("/delete") - @ApiOperation("删除购物车商品") - @ApiImplicitParam(name = "skuIds", value = "商品 SKU 编号的数组", required = true, example = "1024,2048", dataTypeClass = List.class) + @Operation(summary = "删除购物车商品") + @Parameter(name = "skuIds", description = "商品 SKU 编号的数组", required = true, example = "1024,2048") @PreAuthenticated public CommonResult deleteCartItem(@RequestParam("skuIds") List skuIds) { cartService.deleteCartItems(getLoginUserId(), skuIds); @@ -68,14 +68,14 @@ public class TradeCartController { } @GetMapping("get-count") - @ApiOperation("查询用户在购物车中的商品数量") + @Operation(summary = "查询用户在购物车中的商品数量") @PreAuthenticated public CommonResult getCartCount() { return success(cartService.getCartCount(getLoginUserId())); } @GetMapping("/get-detail") - @ApiOperation("查询用户的购物车的详情") + @Operation(summary = "查询用户的购物车的详情") @PreAuthenticated public CommonResult getCartDetail() { return success(cartService.getCartDetail(getLoginUserId())); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java index 5656c3d69..359917887 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java @@ -1,13 +1,12 @@ package cn.iocoder.yudao.module.trade.controller.app.cart.vo; import cn.iocoder.yudao.module.trade.controller.app.base.sku.AppProductSkuBaseRespVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; -@ApiModel(value = "用户 App - 用户的购物车明细 Response VO") +@Schema(title = "用户 App - 用户的购物车明细 Response VO") @Data public class AppTradeCartDetailRespVO { @@ -21,7 +20,7 @@ public class AppTradeCartDetailRespVO { */ private Order order; - @ApiModel(value = "商品分组", description = "多个商品,参加同一个活动,从而形成分组") + @Schema(title = "商品分组", description = "多个商品,参加同一个活动,从而形成分组") @Data public static class ItemGroup { @@ -36,7 +35,7 @@ public class AppTradeCartDetailRespVO { } - @ApiModel(value = "商品 SKU") + @Schema(title = "商品 SKU") @Data public static class Sku extends AppProductSkuBaseRespVO { @@ -47,26 +46,26 @@ public class AppTradeCartDetailRespVO { // ========== 购物车相关的字段 ========== - @ApiModelProperty(value = "商品数量", required = true, example = "1") + @Schema(title = "商品数量", required = true, example = "1") private Integer count; - @ApiModelProperty(value = "是否选中", required = true, example = "true") + @Schema(title = "是否选中", required = true, example = "true") private Boolean selected; // ========== 价格相关的字段,对应 PriceCalculateRespDTO.OrderItem 的属性 ========== // TODO 芋艿:后续可以去除一些无用的字段 - @ApiModelProperty(value = "商品原价(单)", required = true, example = "100") + @Schema(title = "商品原价(单)", required = true, example = "100") private Integer originalPrice; - @ApiModelProperty(value = "商品原价(总)", required = true, example = "200") + @Schema(title = "商品原价(总)", required = true, example = "200") private Integer totalOriginalPrice; - @ApiModelProperty(value = "商品级优惠(总)", required = true, example = "300") + @Schema(title = "商品级优惠(总)", required = true, example = "300") private Integer totalPromotionPrice; - @ApiModelProperty(value = "最终购买金额(总)", required = true, example = "400") + @Schema(title = "最终购买金额(总)", required = true, example = "400") private Integer totalPresentPrice; - @ApiModelProperty(value = "最终购买金额(单)", required = true, example = "500") + @Schema(title = "最终购买金额(单)", required = true, example = "500") private Integer presentPrice; - @ApiModelProperty(value = "应付金额(总)", required = true, example = "600") + @Schema(title = "应付金额(总)", required = true, example = "600") private Integer totalPayPrice; // ========== 营销相关的字段 ========== @@ -77,40 +76,40 @@ public class AppTradeCartDetailRespVO { } - @ApiModel(value = "订单", description = "对应 PriceCalculateRespDTO.Order 类,用于费用(合计)") + @Schema(title = "订单", description = "对应 PriceCalculateRespDTO.Order 类,用于费用(合计)") @Data public static class Order { // TODO 芋艿:后续可以去除一些无用的字段 - @ApiModelProperty(value = "商品原价(总)", required = true, example = "100") + @Schema(title = "商品原价(总)", required = true, example = "100") private Integer skuOriginalPrice; - @ApiModelProperty(value = "商品优惠(总)", required = true, example = "200") + @Schema(title = "商品优惠(总)", required = true, example = "200") private Integer skuPromotionPrice; - @ApiModelProperty(value = "订单优惠(总)", required = true, example = "300") + @Schema(title = "订单优惠(总)", required = true, example = "300") private Integer orderPromotionPrice; - @ApiModelProperty(value = "运费金额", required = true, example = "400") + @Schema(title = "运费金额", required = true, example = "400") private Integer deliveryPrice; - @ApiModelProperty(value = "应付金额(总)", required = true, example = "500") + @Schema(title = "应付金额(总)", required = true, example = "500") private Integer payPrice; } - @ApiModel(value = "营销活动", description = "对应 PriceCalculateRespDTO.Promotion 类的属性") + @Schema(title = "营销活动", description = "对应 PriceCalculateRespDTO.Promotion 类的属性") @Data public static class Promotion { - @ApiModelProperty(value = "营销编号", required = true, example = "1024", notes = "营销活动的编号、优惠劵的编号") + @Schema(title = "营销编号", required = true, example = "1024", description = "营销活动的编号、优惠劵的编号") private Long id; - @ApiModelProperty(value = "营销名字", required = true, example = "xx 活动") + @Schema(title = "营销名字", required = true, example = "xx 活动") private String name; - @ApiModelProperty(value = "营销类型", required = true, example = "1", notes = "参见 PromotionTypeEnum 枚举类") + @Schema(title = "营销类型", required = true, example = "1", description = "参见 PromotionTypeEnum 枚举类") private Integer type; // ========== 匹配情况 ========== - @ApiModelProperty(value = "是否满足优惠条件", required = true, example = "true") + @Schema(title = "是否满足优惠条件", required = true, example = "true") private Boolean meet; - @ApiModelProperty(value = "满足条件的提示", required = true, example = "圣诞价:省 150.00 元") + @Schema(title = "满足条件的提示", required = true, example = "圣诞价:省 150.00 元") private String meetTip; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java index c3103dcce..20c1e9e8b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.trade.controller.app.cart.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; -@ApiModel(value = "用户 App - 购物车添加购物项 Request VO") +@Schema(title = "用户 App - 购物车添加购物项 Request VO") @Data public class AppTradeCartItemAddCountReqVO { - @ApiModelProperty(value = "商品 SKU 编号", required = true,example = "1024") + @Schema(title = "商品 SKU 编号", required = true,example = "1024") @NotNull(message = "商品 SKU 编号不能为空") private Long skuId; - @ApiModelProperty(value = "商品数量", required = true, example = "1", notes = "注意,这是新增数量") + @Schema(title = "商品数量", required = true, example = "1", description = "注意,这是新增数量") @NotNull(message = "数量不能为空") @Min(message = "数量必须大于 0", value = 1L) private Integer count; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java index 6beb09379..3854b1bec 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.trade.controller.app.cart.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; -@ApiModel(value = "用户 App - 购物车更新数量 Request VO") +@Schema(title = "用户 App - 购物车更新数量 Request VO") @Data public class AppTradeCartItemUpdateCountReqVO { - @ApiModelProperty(value = "商品 SKU 编号", required = true, example = "1024") + @Schema(title = "商品 SKU 编号", required = true, example = "1024") @NotNull(message = "商品 SKU 编号不能为空") private Long skuId; - @ApiModelProperty(value = "商品数量", required = true, example = "1") + @Schema(title = "商品数量", required = true, example = "1") @NotNull(message = "数量不能为空") @Min(message = "数量必须大于 0", value = 1L) private Integer count; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java index cc7bf6f03..f126ed41b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.trade.controller.app.cart.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.Collection; -@ApiModel(value = "用户 App - 购物车更新是否选中 Request VO") +@Schema(title = "用户 App - 购物车更新是否选中 Request VO") @Data public class AppTradeCartItemUpdateSelectedReqVO { - @ApiModelProperty(value = "商品 SKU 编号列表", required = true, example = "1024,2048") + @Schema(title = "商品 SKU 编号列表", required = true, example = "1024,2048") @NotNull(message = "商品 SKU 编号列表不能为空") private Collection skuIds; - @ApiModelProperty(value = "是否选中", required = true, example = "true") + @Schema(title = "是否选中", required = true, example = "true") @NotNull(message = "是否选中不能为空") private Boolean selected; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index 4233867e1..1ddb602b1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -10,9 +10,9 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderGetCre import cn.iocoder.yudao.module.trade.controller.app.order.vo.TradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.TradeOrderRespVO; import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; @@ -20,7 +20,7 @@ import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; -@Api(tags = "用户 App - 交易订单") +@Tag(name = "用户 App - 交易订单") @RestController @RequestMapping("/trade/order") @RequiredArgsConstructor // TODO @LeeYan9: 先统一使用 @Resource 注入哈; 项目只有三层, 依赖注入会存在, 所以使用 @Resource; 也因此, 最好全局保持一致 @@ -31,7 +31,7 @@ public class AppTradeOrderController { private final TradeOrderService tradeOrderService; @GetMapping("/get-create-info") - @ApiOperation("基于商品,确认创建订单") + @Operation(summary = "基于商品,确认创建订单") @PreAuthenticated public CommonResult getTradeOrderCreateInfo(AppTradeOrderCreateReqVO createReqVO) { // return success(tradeOrderService.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId)); @@ -39,7 +39,7 @@ public class AppTradeOrderController { } @PostMapping("/create") - @ApiOperation("创建订单") + @Operation(summary = "创建订单") @PreAuthenticated public CommonResult createTradeOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO, HttpServletRequest servletRequest) { @@ -52,15 +52,15 @@ public class AppTradeOrderController { } @GetMapping("/get") - @ApiOperation("获得交易订单") - @ApiImplicitParam(name = "tradeOrderId", value = "交易订单编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "获得交易订单") + @Parameter(name = "tradeOrderId", description = "交易订单编号", required = true) public CommonResult getTradeOrder(@RequestParam("tradeOrderId") Integer tradeOrderId) { // return success(tradeOrderService.getTradeOrder(tradeOrderId)); return null; } @GetMapping("/page") - @ApiOperation("获得订单交易分页") + @Operation(summary = "获得订单交易分页") public CommonResult> pageTradeOrder(TradeOrderPageReqVO pageVO) { // return success(tradeOrderService.pageTradeOrder(UserSecurityContextHolder.getUserId(), pageVO)); return null; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java index 5126de4a5..99700d2e7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.Min; @@ -9,21 +8,21 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel(value = "用户 App - 交易订单创建 Request VO") +@Schema(title = "用户 App - 交易订单创建 Request VO") @Data public class AppTradeOrderCreateReqVO { - @ApiModelProperty(name = "收件地址编号", required = true, example = "1") + @Schema(name = "收件地址编号", required = true, example = "1") @NotNull(message = "收件地址不能为空") private Long addressId; - @ApiModelProperty(name = "优惠劵编号", example = "1024") + @Schema(name = "优惠劵编号", example = "1024") private Long couponId; - @ApiModelProperty(name = "备注", example = "这个是我的订单哟") + @Schema(name = "备注", example = "这个是我的订单哟") private String remark; - @ApiModelProperty(name = "是否来自购物车", required = true, example = "true", notes = "true - 来自购物车;false - 立即购买") + @Schema(name = "是否来自购物车", required = true, example = "true", description = "true - 来自购物车;false - 立即购买") @NotNull(message = "是否来自购物车不能为空") private Boolean fromCart; @@ -33,15 +32,15 @@ public class AppTradeOrderCreateReqVO { @NotEmpty(message = "必须选择购买的商品") private List items; - @ApiModel(value = "订单商品项") + @Schema(title = "订单商品项") @Data public static class Item { - @ApiModelProperty(name = "商品 SKU 编号", required = true, example = "111") + @Schema(name = "商品 SKU 编号", required = true, example = "111") @NotNull(message = "商品 SKU 编号不能为空") private Long skuId; - @ApiModelProperty(name = "商品 SKU 购买数量", required = true, example = "1024") + @Schema(name = "商品 SKU 购买数量", required = true, example = "1024") @NotNull(message = "商品 SKU 购买数量不能为空") @Min(value = 1, message = "商品 SKU 购买数量必须大于 0") private Integer count; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java index d0bf595f6..ee73df098 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java @@ -1,13 +1,12 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import java.util.List; -@ApiModel(value = "用户 App - 订单获得创建信息 Response VO") +@Schema(title = "用户 App - 订单获得创建信息 Response VO") @Data public class AppTradeOrderGetCreateInfoRespVO { @@ -25,7 +24,7 @@ public class AppTradeOrderGetCreateInfoRespVO { // */ // private List coupons; - @ApiModel(value = "商品分组", description = "多个商品,参加同一个活动,从而形成分组") + @Schema(title = "商品分组", description = "多个商品,参加同一个活动,从而形成分组") @Data public static class ItemGroup { @@ -40,12 +39,12 @@ public class AppTradeOrderGetCreateInfoRespVO { } - @ApiModel("商品 SKU") + @Schema(title = "商品 SKU") @Data public static class Sku { // SKU 自带信息 - @ApiModelProperty(value = "SKU 编号", required = true, example = "1024") + @Schema(title = "SKU 编号", required = true, example = "1024") private Integer id; /** * SPU 信息 @@ -140,12 +139,12 @@ public class AppTradeOrderGetCreateInfoRespVO { } - @ApiModel("费用(合计)") + @Schema(title = "费用(合计)") @Data @AllArgsConstructor public static class Fee { - @ApiModelProperty(value = "购买总价", required = true, example = "1024") + @Schema(title = "购买总价", required = true, example = "1024") private Integer buyPrice; /** * 优惠总价 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java index 354d8386a..a792c756e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java @@ -1,52 +1,51 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; -@ApiModel("交易订单项 Response VO") +@Schema(title = "交易订单项 Response VO") @Data public class TradeOrderItemRespVO { - @ApiModelProperty(value = "id自增长", required = true) + @Schema(title = "id自增长", required = true) private Integer id; - @ApiModelProperty(value = "订单编号", required = true) + @Schema(title = "订单编号", required = true) private Integer orderId; - @ApiModelProperty(value = "订单项状态", required = true) + @Schema(title = "订单项状态", required = true) private Integer status; - @ApiModelProperty(value = "商品 SKU 编号", required = true) + @Schema(title = "商品 SKU 编号", required = true) private Integer skuId; - @ApiModelProperty(value = "商品 SPU 编号", required = true) + @Schema(title = "商品 SPU 编号", required = true) private Integer spuId; - @ApiModelProperty(value = "商品名字", required = true) + @Schema(title = "商品名字", required = true) private String skuName; - @ApiModelProperty(value = "图片名字", required = true) + @Schema(title = "图片名字", required = true) private String skuImage; - @ApiModelProperty(value = "商品数量", required = true) + @Schema(title = "商品数量", required = true) private Integer quantity; - @ApiModelProperty(value = "原始单价,单位:分", required = true) + @Schema(title = "原始单价,单位:分", required = true) private Integer originPrice; - @ApiModelProperty(value = "购买单价,单位:分", required = true) + @Schema(title = "购买单价,单位:分", required = true) private Integer buyPrice; - @ApiModelProperty(value = "最终价格,单位:分", required = true) + @Schema(title = "最终价格,单位:分", required = true) private Integer presentPrice; - @ApiModelProperty(value = "购买总金额,单位:分", required = true) + @Schema(title = "购买总金额,单位:分", required = true) private Integer buyTotal; - @ApiModelProperty(value = "优惠总金额,单位:分", required = true) + @Schema(title = "优惠总金额,单位:分", required = true) private Integer discountTotal; - @ApiModelProperty(value = "最终总金额,单位:分", required = true) + @Schema(title = "最终总金额,单位:分", required = true) private Integer presentTotal; - @ApiModelProperty(value = "退款总金额,单位:分", required = true) + @Schema(title = "退款总金额,单位:分", required = true) private Integer refundTotal; - @ApiModelProperty(value = "物流id") + @Schema(title = "物流id") private Integer logisticsId; - @ApiModelProperty(value = "售后状态", required = true) + @Schema(title = "售后状态", required = true) private Integer afterSaleStatus; - @ApiModelProperty(value = "售后订单编号") + @Schema(title = "售后订单编号") private Integer afterSaleOrderId; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java index 5c8b6c872..23b5e9d47 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel("交易订单分页 Request VO") +@Schema(title = "交易订单分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class TradeOrderPageReqVO extends PageParam { - @ApiModelProperty(value = "订单状态", example = "1", notes = "参见 TradeOrderStatusEnum 枚举") + @Schema(title = "订单状态", example = "1", description = "参见 TradeOrderStatusEnum 枚举") private Integer orderStatus; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java index 583edbabc..c8630416d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java @@ -1,64 +1,63 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import java.time.LocalDateTime; import java.util.*; -@ApiModel("订单交易 Response VO") +@Schema(title = "订单交易 Response VO") @Data public class TradeOrderRespVO { - @ApiModelProperty(value = "订单编号", required = true) + @Schema(title = "订单编号", required = true) private Integer id; - @ApiModelProperty(value = "用户编号", required = true) + @Schema(title = "用户编号", required = true) private Integer userId; - @ApiModelProperty(value = "订单单号", required = true) + @Schema(title = "订单单号", required = true) private String orderNo; - @ApiModelProperty(value = "订单状态", required = true) + @Schema(title = "订单状态", required = true) private Integer orderStatus; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; - @ApiModelProperty(value = "订单结束时间") + @Schema(title = "订单结束时间") private LocalDateTime endTime; - @ApiModelProperty(value = "订单金额(总金额),单位:分", required = true) + @Schema(title = "订单金额(总金额),单位:分", required = true) private Integer buyPrice; - @ApiModelProperty(value = "优惠总金额,单位:分", required = true) + @Schema(title = "优惠总金额,单位:分", required = true) private Integer discountPrice; - @ApiModelProperty(value = "物流金额,单位:分", required = true) + @Schema(title = "物流金额,单位:分", required = true) private Integer logisticsPrice; - @ApiModelProperty(value = "最终金额,单位:分", required = true) + @Schema(title = "最终金额,单位:分", required = true) private Integer presentPrice; - @ApiModelProperty(value = "支付金额,单位:分", required = true) + @Schema(title = "支付金额,单位:分", required = true) private Integer payPrice; - @ApiModelProperty(value = "退款金额,单位:分", required = true) + @Schema(title = "退款金额,单位:分", required = true) private Integer refundPrice; - @ApiModelProperty(value = "付款时间") + @Schema(title = "付款时间") private LocalDateTime payTime; - @ApiModelProperty(value = "支付订单编号") + @Schema(title = "支付订单编号") private Integer payTransactionId; - @ApiModelProperty(value = "支付渠道") + @Schema(title = "支付渠道") private Integer payChannel; - @ApiModelProperty(value = "配送类型", required = true) + @Schema(title = "配送类型", required = true) private Integer deliveryType; - @ApiModelProperty(value = "发货时间") + @Schema(title = "发货时间") private LocalDateTime deliveryTime; - @ApiModelProperty(value = "收货时间") + @Schema(title = "收货时间") private LocalDateTime receiveTime; - @ApiModelProperty(value = "收件人名称", required = true) + @Schema(title = "收件人名称", required = true) private String receiverName; - @ApiModelProperty(value = "手机号", required = true) + @Schema(title = "手机号", required = true) private String receiverMobile; - @ApiModelProperty(value = "地区编码", required = true) + @Schema(title = "地区编码", required = true) private Integer receiverAreaCode; - @ApiModelProperty(value = "收件详细地址", required = true) + @Schema(title = "收件详细地址", required = true) private String receiverDetailAddress; - @ApiModelProperty(value = "售后状态", required = true) + @Schema(title = "售后状态", required = true) private Integer afterSaleStatus; - @ApiModelProperty(value = "优惠劵编号") + @Schema(title = "优惠劵编号") private Integer couponCardId; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; /** diff --git a/yudao-module-member/yudao-module-member-biz/pom.xml b/yudao-module-member/yudao-module-member-biz/pom.xml index 11780b8a0..839ac3a88 100644 --- a/yudao-module-member/yudao-module-member-biz/pom.xml +++ b/yudao-module-member/yudao-module-member-biz/pom.xml @@ -54,6 +54,11 @@ yudao-spring-boot-starter-security + + org.springframework.boot + spring-boot-starter-validation + + cn.iocoder.boot diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java index ee75982fa..bd65bddfd 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/AppAddressController.java @@ -7,9 +7,9 @@ import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdate import cn.iocoder.yudao.module.member.convert.address.AddressConvert; import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO; import cn.iocoder.yudao.module.member.service.address.AddressService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Api(tags = "用户 APP - 用户收件地址") +@Tag(name = "用户 APP - 用户收件地址") @RestController @RequestMapping("/member/address") @Validated @@ -30,43 +30,43 @@ public class AppAddressController { private AddressService addressService; @PostMapping("/create") - @ApiOperation("创建用户收件地址") + @Operation(summary = "创建用户收件地址") public CommonResult createAddress(@Valid @RequestBody AppAddressCreateReqVO createReqVO) { return success(addressService.createAddress(getLoginUserId(), createReqVO)); } @PutMapping("/update") - @ApiOperation("更新用户收件地址") + @Operation(summary = "更新用户收件地址") public CommonResult updateAddress(@Valid @RequestBody AppAddressUpdateReqVO updateReqVO) { addressService.updateAddress(getLoginUserId(), updateReqVO); return success(true); } @DeleteMapping("/delete") - @ApiOperation("删除用户收件地址") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除用户收件地址") + @Parameter(name = "id", description = "编号", required = true) public CommonResult deleteAddress(@RequestParam("id") Long id) { addressService.deleteAddress(getLoginUserId(), id); return success(true); } @GetMapping("/get") - @ApiOperation("获得用户收件地址") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得用户收件地址") + @Parameter(name = "id", description = "编号", required = true, example = "1024") public CommonResult getAddress(@RequestParam("id") Long id) { AddressDO address = addressService.getAddress(getLoginUserId(), id); return success(AddressConvert.INSTANCE.convert(address)); } @GetMapping("/get-default") - @ApiOperation("获得默认的用户收件地址") + @Operation(summary = "获得默认的用户收件地址") public CommonResult getDefaultUserAddress() { AddressDO address = addressService.getDefaultUserAddress(getLoginUserId()); return success(AddressConvert.INSTANCE.convert(address)); } @GetMapping("/list") - @ApiOperation("获得用户收件地址列表") + @Operation(summary = "获得用户收件地址列表") public CommonResult> getAddressList() { List list = addressService.getAddressList(getLoginUserId()); return success(AddressConvert.INSTANCE.convertList(list)); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java index 8cfbac7d2..e82f78ea3 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.member.controller.app.address.vo; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -13,27 +12,27 @@ import javax.validation.constraints.NotNull; @Data public class AppAddressBaseVO { - @ApiModelProperty(value = "收件人名称", required = true) + @Schema(title = "收件人名称", required = true) @NotNull(message = "收件人名称不能为空") private String name; - @ApiModelProperty(value = "手机号", required = true) + @Schema(title = "手机号", required = true) @NotNull(message = "手机号不能为空") private String mobile; - @ApiModelProperty(value = "地区编号", required = true) + @Schema(title = "地区编号", required = true) @NotNull(message = "地区编号不能为空") private Long areaId; - @ApiModelProperty(value = "邮编", required = true) + @Schema(title = "邮编", required = true) @NotEmpty(message = "邮编不能为空") private String postCode; - @ApiModelProperty(value = "收件详细地址", required = true) + @Schema(title = "收件详细地址", required = true) @NotNull(message = "收件详细地址不能为空") private String detailAddress; - @ApiModelProperty(value = "是否默认地址", required = true) + @Schema(title = "是否默认地址", required = true) @NotNull(message = "是否默认地址不能为空") private Boolean defaulted; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressCreateReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressCreateReqVO.java index 31fd89fa3..deaa7da87 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressCreateReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressCreateReqVO.java @@ -1,11 +1,8 @@ package cn.iocoder.yudao.module.member.controller.app.address.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; -@ApiModel("用户 APP - 用户收件地址创建 Request VO") +@Schema(title = "用户 APP - 用户收件地址创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java index 0ba231e9f..0acc49b7b 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.member.controller.app.address.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; -@ApiModel("用户 APP - 用户收件地址 Response VO") +@Schema(title = "用户 APP - 用户收件地址 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class AppAddressRespVO extends AppAddressBaseVO { - @ApiModelProperty(value = "编号", required = true) + @Schema(title = "编号", required = true) private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java index b4100c76a..c93d1dbc2 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java @@ -1,17 +1,15 @@ package cn.iocoder.yudao.module.member.controller.app.address.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import java.util.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("用户 APP - 用户收件地址更新 Request VO") +@Schema(title = "用户 APP - 用户收件地址更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class AppAddressUpdateReqVO extends AppAddressBaseVO { - @ApiModelProperty(value = "编号", required = true) + @Schema(title = "编号", required = true) @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java index fadd20733..0a9f69bc9 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java @@ -8,10 +8,10 @@ import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; import cn.iocoder.yudao.module.member.service.auth.MemberAuthService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -24,7 +24,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Api(tags = "用户 APP - 认证") +@Tag(name = "用户 APP - 认证") @RestController @RequestMapping("/member/auth") @Validated @@ -38,14 +38,14 @@ public class AppAuthController { private SecurityProperties securityProperties; @PostMapping("/login") - @ApiOperation("使用手机 + 密码登录") + @Operation(summary = "使用手机 + 密码登录") public CommonResult login(@RequestBody @Valid AppAuthLoginReqVO reqVO) { return success(authService.login(reqVO)); } @PostMapping("/logout") @PermitAll - @ApiOperation("登出系统") + @Operation(summary = "登出系统") public CommonResult logout(HttpServletRequest request) { String token = SecurityFrameworkUtils.obtainAuthorization(request, securityProperties.getTokenHeader()); if (StrUtil.isNotBlank(token)) { @@ -55,8 +55,8 @@ public class AppAuthController { } @PostMapping("/refresh-token") - @ApiOperation("刷新令牌") - @ApiImplicitParam(name = "refreshToken", value = "刷新令牌", required = true, dataTypeClass = String.class) + @Operation(summary = "刷新令牌") + @Parameter(name = "refreshToken", description = "刷新令牌", required = true) @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult refreshToken(@RequestParam("refreshToken") String refreshToken) { return success(authService.refreshToken(refreshToken)); @@ -65,20 +65,20 @@ public class AppAuthController { // ========== 短信登录相关 ========== @PostMapping("/sms-login") - @ApiOperation("使用手机 + 验证码登录") + @Operation(summary = "使用手机 + 验证码登录") public CommonResult smsLogin(@RequestBody @Valid AppAuthSmsLoginReqVO reqVO) { return success(authService.smsLogin(reqVO)); } @PostMapping("/send-sms-code") - @ApiOperation(value = "发送手机验证码") + @Operation(summary = "发送手机验证码") public CommonResult sendSmsCode(@RequestBody @Valid AppAuthSmsSendReqVO reqVO) { authService.sendSmsCode(getLoginUserId(), reqVO); return success(true); } @PostMapping("/reset-password") - @ApiOperation(value = "重置密码", notes = "用户忘记密码时使用") + @Operation(summary = "重置密码", description = "用户忘记密码时使用") @PreAuthenticated public CommonResult resetPassword(@RequestBody @Valid AppAuthResetPasswordReqVO reqVO) { authService.resetPassword(reqVO); @@ -86,7 +86,7 @@ public class AppAuthController { } @PostMapping("/update-password") - @ApiOperation(value = "修改用户密码",notes = "用户修改密码时使用") + @Operation(summary = "修改用户密码",description = "用户修改密码时使用") @PreAuthenticated public CommonResult updatePassword(@RequestBody @Valid AppAuthUpdatePasswordReqVO reqVO) { authService.updatePassword(getLoginUserId(), reqVO); @@ -96,10 +96,10 @@ public class AppAuthController { // ========== 社交登录相关 ========== @GetMapping("/social-auth-redirect") - @ApiOperation("社交授权的跳转") - @ApiImplicitParams({ - @ApiImplicitParam(name = "type", value = "社交类型", required = true, dataTypeClass = Integer.class), - @ApiImplicitParam(name = "redirectUri", value = "回调路径", dataTypeClass = String.class) + @Operation(summary = "社交授权的跳转") + @Parameters({ + @Parameter(name = "type", description = "社交类型", required = true), + @Parameter(name = "redirectUri", description = "回调路径") }) public CommonResult socialAuthRedirect(@RequestParam("type") Integer type, @RequestParam("redirectUri") String redirectUri) { @@ -107,13 +107,13 @@ public class AppAuthController { } @PostMapping("/social-login") - @ApiOperation(value = "社交快捷登录,使用 code 授权码", notes = "适合未登录的用户,但是社交账号已绑定用户") + @Operation(summary = "社交快捷登录,使用 code 授权码", description = "适合未登录的用户,但是社交账号已绑定用户") public CommonResult socialLogin(@RequestBody @Valid AppAuthSocialLoginReqVO reqVO) { return success(authService.socialLogin(reqVO)); } @PostMapping("/weixin-mini-app-login") - @ApiOperation("微信小程序的一键登录") + @Operation(summary = "微信小程序的一键登录") public CommonResult weixinMiniAppLogin(@RequestBody @Valid AppAuthWeixinMiniAppLoginReqVO reqVO) { return success(authService.weixinMiniAppLogin(reqVO)); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java index dd050147e..8cdd0fcd6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java @@ -3,8 +3,7 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.Mobile; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -16,25 +15,25 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; // TODO 芋艿:code review 相关逻辑 -@ApiModel("用户 APP - 校验验证码 Request VO") +@Schema(title = "用户 APP - 校验验证码 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthCheckCodeReqVO { - @ApiModelProperty(value = "手机号", example = "15601691234") + @Schema(title = "手机号", example = "15601691234") @NotBlank(message = "手机号不能为空") @Mobile private String mobile; - @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @Schema(title = "手机验证码", required = true, example = "1024") @NotBlank(message = "手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") private String code; - @ApiModelProperty(value = "发送场景", example = "1", notes = "对应 SmsSceneEnum 枚举") + @Schema(title = "发送场景", example = "1", description = "对应 SmsSceneEnum 枚举") @NotNull(message = "发送场景不能为空") @InEnum(SmsSceneEnum.class) private Integer scene; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java index d8fe3940f..9c347b990 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java @@ -4,8 +4,7 @@ import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.Mobile; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -15,33 +14,33 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotEmpty; -@ApiModel(value = "用户 APP - 手机 + 密码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") +@Schema(title = "用户 APP - 手机 + 密码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthLoginReqVO { - @ApiModelProperty(value = "手机号", required = true, example = "15601691300") + @Schema(title = "手机号", required = true, example = "15601691300") @NotEmpty(message = "手机号不能为空") @Mobile private String mobile; - @ApiModelProperty(value = "密码", required = true, example = "buzhidao") + @Schema(title = "密码", required = true, example = "buzhidao") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; // ========== 绑定社交登录时,需要传递如下参数 ========== - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") @InEnum(SocialTypeEnum.class) private Integer socialType; - @ApiModelProperty(value = "授权码", required = true, example = "1024") + @Schema(title = "授权码", required = true, example = "1024") private String socialCode; - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") private String socialState; @AssertTrue(message = "授权码不能为空") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java index ebd1ea35c..734c01591 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,23 +8,23 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@ApiModel("用户 APP - 登录 Response VO") +@Schema(title = "用户 APP - 登录 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthLoginRespVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1024") + @Schema(title = "用户编号", required = true, example = "1024") private Long userId; - @ApiModelProperty(value = "访问令牌", required = true, example = "happy") + @Schema(title = "访问令牌", required = true, example = "happy") private String accessToken; - @ApiModelProperty(value = "刷新令牌", required = true, example = "nice") + @Schema(title = "刷新令牌", required = true, example = "nice") private String refreshToken; - @ApiModelProperty(value = "过期时间", required = true) + @Schema(title = "过期时间", required = true) private LocalDateTime expiresTime; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java index a6d6ebea4..0be071a84 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; import cn.iocoder.yudao.framework.common.validation.Mobile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -14,25 +13,25 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; // TODO 芋艿:code review 相关逻辑 -@ApiModel("用户 APP - 重置密码 Request VO") +@Schema(title = "用户 APP - 重置密码 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthResetPasswordReqVO { - @ApiModelProperty(value = "新密码", required = true, example = "buzhidao") + @Schema(title = "新密码", required = true, example = "buzhidao") @NotEmpty(message = "新密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; - @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @Schema(title = "手机验证码", required = true, example = "1024") @NotEmpty(message = "手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") private String code; - @ApiModelProperty(value = "手机号",required = true,example = "15878962356") + @Schema(title = "手机号",required = true,example = "15878962356") @NotBlank(message = "手机号不能为空") @Mobile private String mobile; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java index dd6de5d59..256a59452 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java @@ -4,8 +4,7 @@ import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.Mobile; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -16,19 +15,19 @@ import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; -@ApiModel(value = "用户 APP - 手机 + 验证码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") +@Schema(title = "用户 APP - 手机 + 验证码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthSmsLoginReqVO { - @ApiModelProperty(value = "手机号", required = true, example = "15601691300") + @Schema(title = "手机号", required = true, example = "15601691300") @NotEmpty(message = "手机号不能为空") @Mobile private String mobile; - @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @Schema(title = "手机验证码", required = true, example = "1024") @NotEmpty(message = "手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") @@ -36,14 +35,14 @@ public class AppAuthSmsLoginReqVO { // ========== 绑定社交登录时,需要传递如下参数 ========== - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") @InEnum(SocialTypeEnum.class) private Integer socialType; - @ApiModelProperty(value = "授权码", required = true, example = "1024") + @Schema(title = "授权码", required = true, example = "1024") private String socialCode; - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") private String socialState; @AssertTrue(message = "授权码不能为空") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsSendReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsSendReqVO.java index cd051f8c3..aaf4e30c7 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsSendReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsSendReqVO.java @@ -3,23 +3,22 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.Mobile; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.experimental.Accessors; import javax.validation.constraints.NotNull; -@ApiModel("用户 APP - 发送手机验证码 Request VO") +@Schema(title = "用户 APP - 发送手机验证码 Request VO") @Data @Accessors(chain = true) public class AppAuthSmsSendReqVO { - @ApiModelProperty(value = "手机号", example = "15601691234") + @Schema(title = "手机号", example = "15601691234") @Mobile private String mobile; - @ApiModelProperty(value = "发送场景", example = "1", notes = "对应 SmsSceneEnum 枚举") + @Schema(title = "发送场景", example = "1", description = "对应 SmsSceneEnum 枚举") @NotNull(message = "发送场景不能为空") @InEnum(SmsSceneEnum.class) private Integer scene; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java index 7a5856d67..237017962 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,23 +11,23 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("用户 APP - 社交快捷登录 Request VO,使用 code 授权码") +@Schema(title = "用户 APP - 社交快捷登录 Request VO,使用 code 授权码") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthSocialLoginReqVO { - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @ApiModelProperty(value = "授权码", required = true, example = "1024") + @Schema(title = "授权码", required = true, example = "1024") @NotEmpty(message = "授权码不能为空") private String code; - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") @NotEmpty(message = "state 不能为空") private String state; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java index 9addb1046..d1926c9bb 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,19 +11,19 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; // TODO 芋艿:code review 相关逻辑 -@ApiModel("用户 APP - 修改密码 Request VO") +@Schema(title = "用户 APP - 修改密码 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthUpdatePasswordReqVO { - @ApiModelProperty(value = "用户旧密码", required = true, example = "123456") + @Schema(title = "用户旧密码", required = true, example = "123456") @NotBlank(message = "旧密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String oldPassword; - @ApiModelProperty(value = "新密码", required = true, example = "buzhidao") + @Schema(title = "新密码", required = true, example = "buzhidao") @NotEmpty(message = "新密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java index bd34085b2..5245507a6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,18 +8,18 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; -@ApiModel("用户 APP - 微信小程序手机登录 Request VO") +@Schema(title = "用户 APP - 微信小程序手机登录 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthWeixinMiniAppLoginReqVO { - @ApiModelProperty(value = "手机 code", required = true, example = "hello", notes = "小程序通过 wx.getPhoneNumber 方法获得") + @Schema(title = "手机 code", required = true, example = "hello", description = "小程序通过 wx.getPhoneNumber 方法获得") @NotEmpty(message = "手机 code 不能为空") private String phoneCode; - @ApiModelProperty(value = "登录 code", required = true, example = "word", notes = "小程序通过 wx.login 方法获得") + @Schema(title = "登录 code", required = true, example = "word", description = "小程序通过 wx.login 方法获得") @NotEmpty(message = "登录 code 不能为空") private String loginCode; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/AppSocialUserController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/AppSocialUserController.java index d5dac93e6..fb22a4224 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/AppSocialUserController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/AppSocialUserController.java @@ -6,8 +6,8 @@ import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserBind import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserUnbindReqVO; import cn.iocoder.yudao.module.member.convert.social.SocialUserConvert; import cn.iocoder.yudao.module.system.api.social.SocialUserApi; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -16,7 +16,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Api(tags = "用户 App - 社交用户") +@Tag(name = "用户 App - 社交用户") @RestController @RequestMapping("/system/social-user") @Validated @@ -26,14 +26,14 @@ public class AppSocialUserController { private SocialUserApi socialUserApi; @PostMapping("/bind") - @ApiOperation("社交绑定,使用 code 授权码") + @Operation(summary = "社交绑定,使用 code 授权码") public CommonResult socialBind(@RequestBody @Valid AppSocialUserBindReqVO reqVO) { socialUserApi.bindSocialUser(SocialUserConvert.INSTANCE.convert(getLoginUserId(), UserTypeEnum.MEMBER.getValue(), reqVO)); return CommonResult.success(true); } @DeleteMapping("/unbind") - @ApiOperation("取消社交绑定") + @Operation(summary = "取消社交绑定") public CommonResult socialUnbind(@RequestBody AppSocialUserUnbindReqVO reqVO) { socialUserApi.unbindSocialUser(SocialUserConvert.INSTANCE.convert(getLoginUserId(), UserTypeEnum.MEMBER.getValue(), reqVO)); return CommonResult.success(true); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserBindReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserBindReqVO.java index f3fcd0bb0..d1fde4e56 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserBindReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserBindReqVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.social.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,23 +11,23 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("用户 APP - 社交绑定 Request VO,使用 code 授权码") +@Schema(title = "用户 APP - 社交绑定 Request VO,使用 code 授权码") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppSocialUserBindReqVO { - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @ApiModelProperty(value = "授权码", required = true, example = "1024") + @Schema(title = "授权码", required = true, example = "1024") @NotEmpty(message = "授权码不能为空") private String code; - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") @NotEmpty(message = "state 不能为空") private String state; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserUnbindReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserUnbindReqVO.java index 195238adc..5783983fe 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserUnbindReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserUnbindReqVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.social.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,19 +11,19 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("用户 APP - 取消社交绑定 Request VO") +@Schema(title = "用户 APP - 取消社交绑定 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppSocialUserUnbindReqVO { - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @ApiModelProperty(value = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") + @Schema(title = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") @NotEmpty(message = "社交用户的 openid 不能为空") private String openid; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java index 4eec2893f..95b1a227a 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppUserController.java @@ -7,8 +7,8 @@ import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobile import cn.iocoder.yudao.module.member.convert.user.UserConvert; import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; import cn.iocoder.yudao.module.member.service.user.MemberUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -22,7 +22,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_IS_EMPTY; -@Api(tags = "用户 APP - 用户个人中心") +@Tag(name = "用户 APP - 用户个人中心") @RestController @RequestMapping("/member/user") @Validated @@ -33,7 +33,7 @@ public class AppUserController { private MemberUserService userService; @PutMapping("/update-nickname") - @ApiOperation("修改用户昵称") + @Operation(summary = "修改用户昵称") @PreAuthenticated public CommonResult updateUserNickname(@RequestParam("nickname") String nickname) { userService.updateUserNickname(getLoginUserId(), nickname); @@ -41,7 +41,7 @@ public class AppUserController { } @PostMapping("/update-avatar") - @ApiOperation("修改用户头像") + @Operation(summary = "修改用户头像") @PreAuthenticated public CommonResult updateUserAvatar(@RequestParam("avatarFile") MultipartFile file) throws Exception { if (file.isEmpty()) { @@ -52,7 +52,7 @@ public class AppUserController { } @GetMapping("/get") - @ApiOperation("获得基本信息") + @Operation(summary = "获得基本信息") @PreAuthenticated public CommonResult getUserInfo() { MemberUserDO user = userService.getUser(getLoginUserId()); @@ -60,7 +60,7 @@ public class AppUserController { } @PostMapping("/update-mobile") - @ApiOperation(value = "修改用户手机") + @Operation(summary = "修改用户手机") @PreAuthenticated public CommonResult updateMobile(@RequestBody @Valid AppUserUpdateMobileReqVO reqVO) { userService.updateUserMobile(getLoginUserId(), reqVO); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java index 0a79b0886..7b09af358 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.member.controller.app.user.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel("用户 APP - 用户个人信息 Response VO") +@Schema(title = "用户 APP - 用户个人信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class AppUserInfoRespVO { - @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") + @Schema(title = "用户昵称", required = true, example = "芋艿") private String nickname; - @ApiModelProperty(value = "用户头像", required = true, example = "/infra/file/get/35a12e57-4297-4faa-bf7d-7ed2f211c952") + @Schema(title = "用户头像", required = true, example = "/infra/file/get/35a12e57-4297-4faa-bf7d-7ed2f211c952") private String avatar; - @ApiModelProperty(value = "用户手机号", required = true, example = "15601691300") + @Schema(title = "用户手机号", required = true, example = "15601691300") private String mobile; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java index 1ab6e7c84..e3c9021b1 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.member.controller.app.user.vo; import cn.iocoder.yudao.framework.common.validation.Mobile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -13,26 +12,26 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; -@ApiModel("用户 APP - 修改手机 Request VO") +@Schema(title = "用户 APP - 修改手机 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppUserUpdateMobileReqVO { - @ApiModelProperty(value = "手机验证码", required = true, example = "1024") + @Schema(title = "手机验证码", required = true, example = "1024") @NotEmpty(message = "手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") private String code; - @ApiModelProperty(value = "手机号",required = true,example = "15823654487") + @Schema(title = "手机号",required = true,example = "15823654487") @NotBlank(message = "手机号不能为空") @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") @Mobile private String mobile; - @ApiModelProperty(value = "原手机验证码", required = true, example = "1024") + @Schema(title = "原手机验证码", required = true, example = "1024") @NotEmpty(message = "原手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") @@ -40,7 +39,7 @@ public class AppUserUpdateMobileReqVO { // TODO @芋艿:oldMobile 应该不用传递 - @ApiModelProperty(value = "原手机号",required = true,example = "15823654487") + @Schema(title = "原手机号",required = true,example = "15823654487") @NotBlank(message = "手机号不能为空") @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") @Mobile diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/weixin/AppWxMpController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/weixin/AppWxMpController.java index 5b33d44e6..7a2413ee3 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/weixin/AppWxMpController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/weixin/AppWxMpController.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.member.controller.app.weixin; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.error.WxErrorException; @@ -17,7 +17,7 @@ import javax.annotation.Resource; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "微信公众号") +@Tag(name = "微信公众号") @RestController @RequestMapping("/member/wx-mp") @Validated @@ -28,8 +28,8 @@ public class AppWxMpController { private WxMpService mpService; @PostMapping("/create-jsapi-signature") - @ApiOperation(value = "创建微信 JS SDK 初始化所需的签名", - notes = "参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档") + @Operation(summary = "创建微信 JS SDK 初始化所需的签名", + description = "参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档") public CommonResult createJsapiSignature(@RequestParam("url") String url) throws WxErrorException { return success(mpService.createJsapiSignature(url)); } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayAppController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayAppController.java index 47cc3a4db..4d746cf89 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayAppController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayAppController.java @@ -15,9 +15,9 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; import cn.iocoder.yudao.module.pay.service.merchant.PayAppService; import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService; import cn.iocoder.yudao.module.pay.service.merchant.PayMerchantService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; @@ -33,7 +33,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; @Slf4j -@Api(tags = "管理后台 - 支付应用信息") +@Tag(name = "管理后台 - 支付应用信息") @RestController @RequestMapping("/pay/app") @Validated @@ -47,14 +47,14 @@ public class PayAppController { private PayMerchantService merchantService; @PostMapping("/create") - @ApiOperation("创建支付应用信息") + @Operation(summary = "创建支付应用信息") @PreAuthorize("@ss.hasPermission('pay:app:create')") public CommonResult createApp(@Valid @RequestBody PayAppCreateReqVO createReqVO) { return success(appService.createApp(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新支付应用信息") + @Operation(summary = "更新支付应用信息") @PreAuthorize("@ss.hasPermission('pay:app:update')") public CommonResult updateApp(@Valid @RequestBody PayAppUpdateReqVO updateReqVO) { appService.updateApp(updateReqVO); @@ -62,7 +62,7 @@ public class PayAppController { } @PutMapping("/update-status") - @ApiOperation("更新支付应用状态") + @Operation(summary = "更新支付应用状态") @PreAuthorize("@ss.hasPermission('pay:app:update')") public CommonResult updateAppStatus(@Valid @RequestBody PayAppUpdateStatusReqVO updateReqVO) { appService.updateAppStatus(updateReqVO.getId(), updateReqVO.getStatus()); @@ -70,8 +70,8 @@ public class PayAppController { } @DeleteMapping("/delete") - @ApiOperation("删除支付应用信息") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除支付应用信息") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('pay:app:delete')") public CommonResult deleteApp(@RequestParam("id") Long id) { appService.deleteApp(id); @@ -79,8 +79,8 @@ public class PayAppController { } @GetMapping("/get") - @ApiOperation("获得支付应用信息") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得支付应用信息") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('pay:app:query')") public CommonResult getApp(@RequestParam("id") Long id) { PayAppDO app = appService.getApp(id); @@ -88,8 +88,8 @@ public class PayAppController { } @GetMapping("/list") - @ApiOperation("获得支付应用信息列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) + @Operation(summary = "获得支付应用信息列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") @PreAuthorize("@ss.hasPermission('pay:app:query')") public CommonResult> getAppList(@RequestParam("ids") Collection ids) { List list = appService.getAppList(ids); @@ -97,7 +97,7 @@ public class PayAppController { } @GetMapping("/page") - @ApiOperation("获得支付应用信息分页") + @Operation(summary = "获得支付应用信息分页") @PreAuthorize("@ss.hasPermission('pay:app:query')") public CommonResult> getAppPage(@Valid PayAppPageReqVO pageVO) { // 得到应用分页列表 @@ -140,7 +140,7 @@ public class PayAppController { } @GetMapping("/export-excel") - @ApiOperation("导出支付应用信息 Excel") + @Operation(summary = "导出支付应用信息 Excel") @PreAuthorize("@ss.hasPermission('pay:app:export')") @OperateLog(type = EXPORT) public void exportAppExcel(@Valid PayAppExportReqVO exportReqVO, @@ -152,8 +152,8 @@ public class PayAppController { } @GetMapping("/list-merchant-id") - @ApiOperation("根据商户 ID 查询支付应用信息") - @ApiImplicitParam(name = "merchantId", value = "商户ID", required = true, example = "1", dataTypeClass = Long.class) + @Operation(summary = "根据商户 ID 查询支付应用信息") + @Parameter(name = "merchantId", description = "商户ID", required = true, example = "1") @PreAuthorize("@ss.hasPermission('pay:merchant:query')") public CommonResult> getMerchantListByName(@RequestParam Long merchantId) { List appListDO = appService.getListByMerchantId(merchantId); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayChannelController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayChannelController.java index 82d3a354e..6ef6f5712 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayChannelController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayChannelController.java @@ -8,10 +8,10 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -26,7 +26,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 支付渠道") +@Tag(name = "管理后台 - 支付渠道") @RestController @RequestMapping("/pay/channel") @Validated @@ -36,14 +36,14 @@ public class PayChannelController { private PayChannelService channelService; @PostMapping("/create") - @ApiOperation("创建支付渠道 ") + @Operation(summary = "创建支付渠道 ") @PreAuthorize("@ss.hasPermission('pay:channel:create')") public CommonResult createChannel(@Valid @RequestBody PayChannelCreateReqVO createReqVO) { return success(channelService.createChannel(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新支付渠道 ") + @Operation(summary = "更新支付渠道 ") @PreAuthorize("@ss.hasPermission('pay:channel:update')") public CommonResult updateChannel(@Valid @RequestBody PayChannelUpdateReqVO updateReqVO) { channelService.updateChannel(updateReqVO); @@ -51,8 +51,8 @@ public class PayChannelController { } @DeleteMapping("/delete") - @ApiOperation("删除支付渠道 ") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除支付渠道 ") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('pay:channel:delete')") public CommonResult deleteChannel(@RequestParam("id") Long id) { channelService.deleteChannel(id); @@ -60,8 +60,8 @@ public class PayChannelController { } @GetMapping("/get") - @ApiOperation("获得支付渠道 ") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得支付渠道 ") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('pay:channel:query')") public CommonResult getChannel(@RequestParam("id") Long id) { PayChannelDO channel = channelService.getChannel(id); @@ -69,9 +69,9 @@ public class PayChannelController { } @GetMapping("/list") - @ApiOperation("获得支付渠道列表") - @ApiImplicitParam(name = "ids", value = "编号列表", - required = true, example = "1024,2048", dataTypeClass = List.class) + @Operation(summary = "获得支付渠道列表") + @Parameter(name = "ids", description = "编号列表", + required = true, example = "1024,2048") @PreAuthorize("@ss.hasPermission('pay:channel:query')") public CommonResult> getChannelList(@RequestParam("ids") Collection ids) { List list = channelService.getChannelList(ids); @@ -79,7 +79,7 @@ public class PayChannelController { } @GetMapping("/page") - @ApiOperation("获得支付渠道分页") + @Operation(summary = "获得支付渠道分页") @PreAuthorize("@ss.hasPermission('pay:channel:query')") public CommonResult> getChannelPage(@Valid PayChannelPageReqVO pageVO) { PageResult pageResult = channelService.getChannelPage(pageVO); @@ -87,7 +87,7 @@ public class PayChannelController { } @GetMapping("/export-excel") - @ApiOperation("导出支付渠道Excel") + @Operation(summary = "导出支付渠道Excel") @PreAuthorize("@ss.hasPermission('pay:channel:export')") @OperateLog(type = EXPORT) public void exportChannelExcel(@Valid PayChannelExportReqVO exportReqVO, @@ -99,14 +99,14 @@ public class PayChannelController { } @GetMapping("/get-channel") - @ApiOperation("根据条件查询微信支付渠道") - @ApiImplicitParams({ - @ApiImplicitParam(name = "merchantId", value = "商户编号", - required = true, example = "1", dataTypeClass = Long.class), - @ApiImplicitParam(name = "appId", value = "应用编号", - required = true, example = "1", dataTypeClass = Long.class), - @ApiImplicitParam(name = "code", value = "支付渠道编码", - required = true, example = "wx_pub", dataTypeClass = String.class) + @Operation(summary = "根据条件查询微信支付渠道") + @Parameters({ + @Parameter(name = "merchantId", description = "商户编号", + required = true, example = "1"), + @Parameter(name = "appId", description = "应用编号", + required = true, example = "1"), + @Parameter(name = "code", description = "支付渠道编码", + required = true, example = "wx_pub") }) @PreAuthorize("@ss.hasPermission('pay:channel:query')") public CommonResult getChannel( diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayMerchantController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayMerchantController.java index 19bdfc86d..2af7fa528 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayMerchantController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayMerchantController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -25,7 +25,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "支付商户信息") +@Tag(name = "支付商户信息") @RestController @RequestMapping("/pay/merchant") @Validated @@ -35,14 +35,14 @@ public class PayMerchantController { private PayMerchantService merchantService; @PostMapping("/create") - @ApiOperation("创建支付商户信息") + @Operation(summary = "创建支付商户信息") @PreAuthorize("@ss.hasPermission('pay:merchant:create')") public CommonResult createMerchant(@Valid @RequestBody PayMerchantCreateReqVO createReqVO) { return success(merchantService.createMerchant(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新支付商户信息") + @Operation(summary = "更新支付商户信息") @PreAuthorize("@ss.hasPermission('pay:merchant:update')") public CommonResult updateMerchant(@Valid @RequestBody PayMerchantUpdateReqVO updateReqVO) { merchantService.updateMerchant(updateReqVO); @@ -50,7 +50,7 @@ public class PayMerchantController { } @PutMapping("/update-status") - @ApiOperation("修改支付商户状态") + @Operation(summary = "修改支付商户状态") @PreAuthorize("@ss.hasPermission('pay:merchant:update')") public CommonResult updateMerchantStatus(@Valid @RequestBody PayMerchantUpdateStatusReqVO reqVO) { merchantService.updateMerchantStatus(reqVO.getId(), reqVO.getStatus()); @@ -58,8 +58,8 @@ public class PayMerchantController { } @DeleteMapping("/delete") - @ApiOperation("删除支付商户信息") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除支付商户信息") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('pay:merchant:delete')") public CommonResult deleteMerchant(@RequestParam("id") Long id) { merchantService.deleteMerchant(id); @@ -67,8 +67,8 @@ public class PayMerchantController { } @GetMapping("/get") - @ApiOperation("获得支付商户信息") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得支付商户信息") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('pay:merchant:query')") public CommonResult getMerchant(@RequestParam("id") Long id) { PayMerchantDO merchant = merchantService.getMerchant(id); @@ -76,8 +76,8 @@ public class PayMerchantController { } @GetMapping("/list-by-name") - @ApiOperation("根据商户名称获得支付商户信息列表") - @ApiImplicitParam(name = "name", value = "商户名称", example = "芋道", dataTypeClass = String.class) + @Operation(summary = "根据商户名称获得支付商户信息列表") + @Parameter(name = "name", description = "商户名称", example = "芋道") @PreAuthorize("@ss.hasPermission('pay:merchant:query')") public CommonResult> getMerchantListByName(@RequestParam(required = false) String name) { List merchantListDO = merchantService.getMerchantListByName(name); @@ -85,8 +85,8 @@ public class PayMerchantController { } @GetMapping("/list") - @ApiOperation("获得支付商户信息列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) + @Operation(summary = "获得支付商户信息列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") @PreAuthorize("@ss.hasPermission('pay:merchant:query')") public CommonResult> getMerchantList(@RequestParam("ids") Collection ids) { List list = merchantService.getMerchantList(ids); @@ -94,7 +94,7 @@ public class PayMerchantController { } @GetMapping("/page") - @ApiOperation("获得支付商户信息分页") + @Operation(summary = "获得支付商户信息分页") @PreAuthorize("@ss.hasPermission('pay:merchant:query')") public CommonResult> getMerchantPage(@Valid PayMerchantPageReqVO pageVO) { PageResult pageResult = merchantService.getMerchantPage(pageVO); @@ -102,7 +102,7 @@ public class PayMerchantController { } @GetMapping("/export-excel") - @ApiOperation("导出支付商户信息 Excel") + @Operation(summary = "导出支付商户信息 Excel") @PreAuthorize("@ss.hasPermission('pay:merchant:export')") @OperateLog(type = EXPORT) public void exportMerchantExcel(@Valid PayMerchantExportReqVO exportReqVO, diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java index 795b3c643..5ddbce516 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; /** @@ -11,26 +10,26 @@ import javax.validation.constraints.*; @Data public class PayAppBaseVO { - @ApiModelProperty(value = "应用名", required = true) + @Schema(title = "应用名", required = true) @NotNull(message = "应用名不能为空") private String name; - @ApiModelProperty(value = "开启状态", required = true) + @Schema(title = "开启状态", required = true) @NotNull(message = "开启状态不能为空") private Integer status; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; - @ApiModelProperty(value = "支付结果的回调地址", required = true) + @Schema(title = "支付结果的回调地址", required = true) @NotNull(message = "支付结果的回调地址不能为空") private String payNotifyUrl; - @ApiModelProperty(value = "退款结果的回调地址", required = true) + @Schema(title = "退款结果的回调地址", required = true) @NotNull(message = "退款结果的回调地址不能为空") private String refundNotifyUrl; - @ApiModelProperty(value = "商户编号", required = true) + @Schema(title = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long merchantId; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java index a66a71963..4c1086390 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 支付应用信息创建 Request VO") +@Schema(title = "管理后台 - 支付应用信息创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java index 3ea1f3e2e..f4cc07f40 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java @@ -1,37 +1,36 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 支付应用信息 Excel 导出 Request VO", description = "参数和 PayAppPageReqVO 是一致的") +@Schema(title = "管理后台 - 支付应用信息 Excel 导出 Request VO", description = "参数和 PayAppPageReqVO 是一致的") @Data public class PayAppExportReqVO { - @ApiModelProperty(value = "应用名") + @Schema(title = "应用名") private String name; - @ApiModelProperty(value = "开启状态") + @Schema(title = "开启状态") private Integer status; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; - @ApiModelProperty(value = "支付结果的回调地址") + @Schema(title = "支付结果的回调地址") private String payNotifyUrl; - @ApiModelProperty(value = "退款结果的回调地址") + @Schema(title = "退款结果的回调地址") private String refundNotifyUrl; - @ApiModelProperty(value = "商户名称") + @Schema(title = "商户名称") private String merchantName; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java index f0e06b0d0..214d87ee8 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,16 +8,16 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.Set; -@ApiModel(value = "管理后台 - 支付应用信息分页查询 Response VO", description = "相比于支付信息,还会多出应用渠道的开关信息") +@Schema(title = "管理后台 - 支付应用信息分页查询 Response VO", description = "相比于支付信息,还会多出应用渠道的开关信息") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayAppPageItemRespVO extends PayAppBaseVO { - @ApiModelProperty(value = "应用编号", required = true) + @Schema(title = "应用编号", required = true) private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; /** @@ -26,19 +25,19 @@ public class PayAppPageItemRespVO extends PayAppBaseVO { */ private PayMerchant payMerchant; - @ApiModel("商户") + @Schema(title = "商户") @Data public static class PayMerchant { - @ApiModelProperty(value = "商户编号", required = true, example = "1") + @Schema(title = "商户编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "商户名称", required = true, example = "研发部") + @Schema(title = "商户名称", required = true, example = "研发部") private String name; } - @ApiModelProperty(value = "渠道编码集合", required = true, example = "alipay_pc,alipay_wap...") + @Schema(title = "渠道编码集合", required = true, example = "alipay_pc,alipay_wap...") private Set channelCodes; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java index c743a8822..04312cb1b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java @@ -1,40 +1,39 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 支付应用信息分页 Request VO") +@Schema(title = "管理后台 - 支付应用信息分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayAppPageReqVO extends PageParam { - @ApiModelProperty(value = "应用名") + @Schema(title = "应用名") private String name; - @ApiModelProperty(value = "开启状态") + @Schema(title = "开启状态") private Integer status; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; - @ApiModelProperty(value = "支付结果的回调地址") + @Schema(title = "支付结果的回调地址") private String payNotifyUrl; - @ApiModelProperty(value = "退款结果的回调地址") + @Schema(title = "退款结果的回调地址") private String refundNotifyUrl; - @ApiModelProperty(value = "商户名称") + @Schema(title = "商户名称") private String merchantName; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java index 17d4961a1..c5fc4fb77 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 支付应用信息 Response VO") +@Schema(title = "管理后台 - 支付应用信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayAppRespVO extends PayAppBaseVO { - @ApiModelProperty(value = "应用编号", required = true) + @Schema(title = "应用编号", required = true) private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java index 9bdd04254..e55e86efb 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java @@ -1,16 +1,15 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 支付应用信息更新 Request VO") +@Schema(title = "管理后台 - 支付应用信息更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayAppUpdateReqVO extends PayAppBaseVO { - @ApiModelProperty(value = "应用编号", required = true) + @Schema(title = "应用编号", required = true) @NotNull(message = "应用编号不能为空") private Long id; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java index 2ccce684c..c5d257829 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 应用更新状态 Request VO") +@Schema(title = "管理后台 - 应用更新状态 Request VO") @Data public class PayAppUpdateStatusReqVO { - @ApiModelProperty(value = "商户编号", required = true, example = "1024") + @Schema(title = "商户编号", required = true, example = "1024") @NotNull(message = "商户编号不能为空") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "见 SysCommonStatusEnum 枚举") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java index 8b9f53490..3ff9f69b9 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; /** @@ -11,26 +10,26 @@ import javax.validation.constraints.*; @Data public class PayChannelBaseVO { - @ApiModelProperty(value = "渠道编码", required = true) + @Schema(title = "渠道编码", required = true) @NotNull(message = "渠道编码不能为空") private String code; - @ApiModelProperty(value = "开启状态", required = true) + @Schema(title = "开启状态", required = true) @NotNull(message = "开启状态不能为空") private Integer status; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; - @ApiModelProperty(value = "渠道费率,单位:百分比", required = true) + @Schema(title = "渠道费率,单位:百分比", required = true) @NotNull(message = "渠道费率,单位:百分比不能为空") private Double feeRate; - @ApiModelProperty(value = "商户编号", required = true) + @Schema(title = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long merchantId; - @ApiModelProperty(value = "应用编号", required = true) + @Schema(title = "应用编号", required = true) @NotNull(message = "应用编号不能为空") private Long appId; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java index 5852f9bb1..f2bda63fa 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotBlank; -@ApiModel("管理后台 - 支付渠道 创建 Request VO") +@Schema(title = "管理后台 - 支付渠道 创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayChannelCreateReqVO extends PayChannelBaseVO { - @ApiModelProperty(value = "渠道配置的 json 字符串") + @Schema(title = "渠道配置的 json 字符串") @NotBlank(message = "渠道配置不能为空") private String config; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java index 263d1b8e9..091afc14e 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java @@ -1,40 +1,39 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 支付渠道 Excel 导出 Request VO", description = "参数和 PayChannelPageReqVO 是一致的") +@Schema(title = "管理后台 - 支付渠道 Excel 导出 Request VO", description = "参数和 PayChannelPageReqVO 是一致的") @Data public class PayChannelExportReqVO { - @ApiModelProperty(value = "渠道编码") + @Schema(title = "渠道编码") private String code; - @ApiModelProperty(value = "开启状态") + @Schema(title = "开启状态") private Integer status; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; - @ApiModelProperty(value = "渠道费率,单位:百分比") + @Schema(title = "渠道费率,单位:百分比") private Double feeRate; - @ApiModelProperty(value = "商户编号") + @Schema(title = "商户编号") private Long merchantId; - @ApiModelProperty(value = "应用编号") + @Schema(title = "应用编号") private Long appId; - @ApiModelProperty(value = "支付渠道配置") + @Schema(title = "支付渠道配置") private String config; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java index 4d8e7729c..dd30097c5 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java @@ -1,43 +1,42 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 支付渠道 分页 Request VO") +@Schema(title = "管理后台 - 支付渠道 分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayChannelPageReqVO extends PageParam { - @ApiModelProperty(value = "渠道编码") + @Schema(title = "渠道编码") private String code; - @ApiModelProperty(value = "开启状态") + @Schema(title = "开启状态") private Integer status; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; - @ApiModelProperty(value = "渠道费率,单位:百分比") + @Schema(title = "渠道费率,单位:百分比") private Double feeRate; - @ApiModelProperty(value = "商户编号") + @Schema(title = "商户编号") private Long merchantId; - @ApiModelProperty(value = "应用编号") + @Schema(title = "应用编号") private Long appId; - @ApiModelProperty(value = "支付渠道配置") + @Schema(title = "支付渠道配置") private String config; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java index e3e53d3f9..92c8f5714 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 支付渠道 Response VO") +@Schema(title = "管理后台 - 支付渠道 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayChannelRespVO extends PayChannelBaseVO { - @ApiModelProperty(value = "商户编号", required = true) + @Schema(title = "商户编号", required = true) private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; - @ApiModelProperty(value = "配置", required = true) + @Schema(title = "配置", required = true) private String config; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java index c216de9ae..94c322270 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 支付渠道 更新 Request VO") +@Schema(title = "管理后台 - 支付渠道 更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayChannelUpdateReqVO extends PayChannelBaseVO { - @ApiModelProperty(value = "商户编号", required = true) + @Schema(title = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long id; - @ApiModelProperty(value = "渠道配置的json字符串") + @Schema(title = "渠道配置的json字符串") @NotBlank(message = "渠道配置不能为空") private String config; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java index 1052fdd03..71f8d0e61 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -12,19 +11,19 @@ import javax.validation.constraints.NotNull; @Data public class PayMerchantBaseVO { - @ApiModelProperty(value = "商户全称", required = true) + @Schema(title = "商户全称", required = true) @NotNull(message = "商户全称不能为空") private String name; - @ApiModelProperty(value = "商户简称", required = true) + @Schema(title = "商户简称", required = true) @NotNull(message = "商户简称不能为空") private String shortName; - @ApiModelProperty(value = "开启状态", required = true) + @Schema(title = "开启状态", required = true) @NotNull(message = "开启状态不能为空") private Integer status; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java index 018db180b..a61f728ab 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 支付商户信息创建 Request VO") +@Schema(title = "管理后台 - 支付商户信息创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java index 6a41d3afc..1a04a077d 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java @@ -1,34 +1,33 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 支付商户信息 Excel 导出 Request VO", description = "参数和 PayMerchantPageReqVO 是一致的") +@Schema(title = "管理后台 - 支付商户信息 Excel 导出 Request VO", description = "参数和 PayMerchantPageReqVO 是一致的") @Data public class PayMerchantExportReqVO { - @ApiModelProperty(value = "商户号") + @Schema(title = "商户号") private String no; - @ApiModelProperty(value = "商户全称") + @Schema(title = "商户全称") private String name; - @ApiModelProperty(value = "商户简称") + @Schema(title = "商户简称") private String shortName; - @ApiModelProperty(value = "开启状态") + @Schema(title = "开启状态") private Integer status; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java index 756299f5f..ec01270a5 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java @@ -1,37 +1,36 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 支付商户信息分页 Request VO") +@Schema(title = "管理后台 - 支付商户信息分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayMerchantPageReqVO extends PageParam { - @ApiModelProperty(value = "商户号") + @Schema(title = "商户号") private String no; - @ApiModelProperty(value = "商户全称") + @Schema(title = "商户全称") private String name; - @ApiModelProperty(value = "商户简称") + @Schema(title = "商户简称") private String shortName; - @ApiModelProperty(value = "开启状态") + @Schema(title = "开启状态") private Integer status; - @ApiModelProperty(value = "备注") + @Schema(title = "备注") private String remark; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java index f4003b7a4..54561c116 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 支付商户信息 Response VO") +@Schema(title = "管理后台 - 支付商户信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayMerchantRespVO extends PayMerchantBaseVO { - @ApiModelProperty(value = "商户编号", required = true) + @Schema(title = "商户编号", required = true) private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; - @ApiModelProperty(value = "商户号", required = true, example = "M233666999") + @Schema(title = "商户号", required = true, example = "M233666999") private String no; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java index d270a3d84..f6c509764 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java @@ -1,16 +1,15 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 支付商户信息更新 Request VO") +@Schema(title = "管理后台 - 支付商户信息更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayMerchantUpdateReqVO extends PayMerchantBaseVO { - @ApiModelProperty(value = "商户编号", required = true) + @Schema(title = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long id; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java index 39e26b8b7..6fa637e7e 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 商户更新状态 Request VO") +@Schema(title = "管理后台 - 商户更新状态 Request VO") @Data public class PayMerchantUpdateStatusReqVO { - @ApiModelProperty(value = "商户编号", required = true, example = "1024") + @Schema(title = "商户编号", required = true, example = "1024") @NotNull(message = "商户编号不能为空") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "见 SysCommonStatusEnum 枚举") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java index 2219204c4..1be5e379e 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java @@ -18,9 +18,9 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -39,7 +39,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 支付订单") +@Tag(name = "管理后台 - 支付订单") @RestController @RequestMapping("/pay/order") @Validated @@ -55,8 +55,8 @@ public class PayOrderController { private PayAppService appService; @GetMapping("/get") - @ApiOperation("获得支付订单") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得支付订单") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('pay:order:query')") public CommonResult getOrder(@RequestParam("id") Long id) { PayOrderDO order = orderService.getOrder(id); @@ -83,7 +83,7 @@ public class PayOrderController { } @GetMapping("/page") - @ApiOperation("获得支付订单分页") + @Operation(summary = "获得支付订单分页") @PreAuthorize("@ss.hasPermission('pay:order:query')") public CommonResult> getOrderPage(@Valid PayOrderPageReqVO pageVO) { PageResult pageResult = orderService.getOrderPage(pageVO); @@ -114,7 +114,7 @@ public class PayOrderController { } @GetMapping("/export-excel") - @ApiOperation("导出支付订单Excel") + @Operation(summary = "导出支付订单Excel") @PreAuthorize("@ss.hasPermission('pay:order:export')") @OperateLog(type = EXPORT) public void exportOrderExcel(@Valid PayOrderExportReqVO exportReqVO, diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java index 6928ca3c8..ebf07630f 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.pay.controller.admin.order.vo; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -18,90 +17,90 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class PayOrderBaseVO { - @ApiModelProperty(value = "商户编号", required = true) + @Schema(title = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long merchantId; - @ApiModelProperty(value = "应用编号", required = true) + @Schema(title = "应用编号", required = true) @NotNull(message = "应用编号不能为空") private Long appId; - @ApiModelProperty(value = "渠道编号") + @Schema(title = "渠道编号") private Long channelId; - @ApiModelProperty(value = "渠道编码") + @Schema(title = "渠道编码") private String channelCode; - @ApiModelProperty(value = "商户订单编号", required = true) + @Schema(title = "商户订单编号", required = true) @NotNull(message = "商户订单编号不能为空") private String merchantOrderId; - @ApiModelProperty(value = "商品标题", required = true) + @Schema(title = "商品标题", required = true) @NotNull(message = "商品标题不能为空") private String subject; - @ApiModelProperty(value = "商品描述", required = true) + @Schema(title = "商品描述", required = true) @NotNull(message = "商品描述不能为空") private String body; - @ApiModelProperty(value = "异步通知地址", required = true) + @Schema(title = "异步通知地址", required = true) @NotNull(message = "异步通知地址不能为空") private String notifyUrl; - @ApiModelProperty(value = "通知商户支付结果的回调状态", required = true) + @Schema(title = "通知商户支付结果的回调状态", required = true) @NotNull(message = "通知商户支付结果的回调状态不能为空") private Integer notifyStatus; - @ApiModelProperty(value = "支付金额,单位:分", required = true) + @Schema(title = "支付金额,单位:分", required = true) @NotNull(message = "支付金额,单位:分不能为空") private Long amount; - @ApiModelProperty(value = "渠道手续费,单位:百分比") + @Schema(title = "渠道手续费,单位:百分比") private Double channelFeeRate; - @ApiModelProperty(value = "渠道手续金额,单位:分") + @Schema(title = "渠道手续金额,单位:分") private Long channelFeeAmount; - @ApiModelProperty(value = "支付状态", required = true) + @Schema(title = "支付状态", required = true) @NotNull(message = "支付状态不能为空") private Integer status; - @ApiModelProperty(value = "用户 IP", required = true) + @Schema(title = "用户 IP", required = true) @NotNull(message = "用户 IP不能为空") private String userIp; - @ApiModelProperty(value = "订单失效时间", required = true) + @Schema(title = "订单失效时间", required = true) @NotNull(message = "订单失效时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime expireTime; - @ApiModelProperty(value = "订单支付成功时间") + @Schema(title = "订单支付成功时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime successTime; - @ApiModelProperty(value = "订单支付通知时间") + @Schema(title = "订单支付通知时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime notifyTime; - @ApiModelProperty(value = "支付成功的订单拓展单编号") + @Schema(title = "支付成功的订单拓展单编号") private Long successExtensionId; - @ApiModelProperty(value = "退款状态", required = true) + @Schema(title = "退款状态", required = true) @NotNull(message = "退款状态不能为空") private Integer refundStatus; - @ApiModelProperty(value = "退款次数", required = true) + @Schema(title = "退款次数", required = true) @NotNull(message = "退款次数不能为空") private Integer refundTimes; - @ApiModelProperty(value = "退款总金额,单位:分", required = true) + @Schema(title = "退款总金额,单位:分", required = true) @NotNull(message = "退款总金额,单位:分不能为空") private Long refundAmount; - @ApiModelProperty(value = "渠道用户编号") + @Schema(title = "渠道用户编号") private String channelUserId; - @ApiModelProperty(value = "渠道订单号") + @Schema(title = "渠道订单号") private String channelOrderNo; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java index 8c35a0f8f..25ec3c9dc 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java @@ -1,32 +1,31 @@ package cn.iocoder.yudao.module.pay.controller.admin.order.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 支付订单详细信息 Response VO") +@Schema(title = "管理后台 - 支付订单详细信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayOrderDetailsRespVO extends PayOrderBaseVO { - @ApiModelProperty(value = "支付订单编号") + @Schema(title = "支付订单编号") private Long id; - @ApiModelProperty(value = "商户名称") + @Schema(title = "商户名称") private String merchantName; - @ApiModelProperty(value = "应用名称") + @Schema(title = "应用名称") private String appName; - @ApiModelProperty(value = "渠道编号名称") + @Schema(title = "渠道编号名称") private String channelCodeName; - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime createTime; /** @@ -35,13 +34,13 @@ public class PayOrderDetailsRespVO extends PayOrderBaseVO { private PayOrderExtension payOrderExtension; @Data - @ApiModel("支付订单扩展") + @Schema(title = "支付订单扩展") public static class PayOrderExtension { - @ApiModelProperty(value = "支付订单号") + @Schema(title = "支付订单号") private String no; - @ApiModelProperty(value = "支付异步通知的内容") + @Schema(title = "支付异步通知的内容") private String channelNotifyData; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java index 955b5787e..cb08e04d4 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.controller.admin.order.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,84 +8,84 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 支付订单 Excel 导出 Request VO", description = "参数和 PayOrderPageReqVO 是一致的") +@Schema(title = "管理后台 - 支付订单 Excel 导出 Request VO", description = "参数和 PayOrderPageReqVO 是一致的") @Data public class PayOrderExportReqVO { - @ApiModelProperty(value = "商户编号") + @Schema(title = "商户编号") private Long merchantId; - @ApiModelProperty(value = "应用编号") + @Schema(title = "应用编号") private Long appId; - @ApiModelProperty(value = "渠道编号") + @Schema(title = "渠道编号") private Long channelId; - @ApiModelProperty(value = "渠道编码") + @Schema(title = "渠道编码") private String channelCode; - @ApiModelProperty(value = "商户订单编号") + @Schema(title = "商户订单编号") private String merchantOrderId; - @ApiModelProperty(value = "商品标题") + @Schema(title = "商品标题") private String subject; - @ApiModelProperty(value = "商品描述") + @Schema(title = "商品描述") private String body; - @ApiModelProperty(value = "异步通知地址") + @Schema(title = "异步通知地址") private String notifyUrl; - @ApiModelProperty(value = "通知商户支付结果的回调状态") + @Schema(title = "通知商户支付结果的回调状态") private Integer notifyStatus; - @ApiModelProperty(value = "支付金额,单位:分") + @Schema(title = "支付金额,单位:分") private Long amount; - @ApiModelProperty(value = "渠道手续费,单位:百分比") + @Schema(title = "渠道手续费,单位:百分比") private Double channelFeeRate; - @ApiModelProperty(value = "渠道手续金额,单位:分") + @Schema(title = "渠道手续金额,单位:分") private Long channelFeeAmount; - @ApiModelProperty(value = "支付状态") + @Schema(title = "支付状态") private Integer status; - @ApiModelProperty(value = "用户 IP") + @Schema(title = "用户 IP") private String userIp; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "订单失效时间") + @Schema(title = "订单失效时间") private LocalDateTime[] expireTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始订单支付成功时间") + @Schema(title = "开始订单支付成功时间") private LocalDateTime[] successTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始订单支付通知时间") + @Schema(title = "开始订单支付通知时间") private LocalDateTime[] notifyTime; - @ApiModelProperty(value = "支付成功的订单拓展单编号") + @Schema(title = "支付成功的订单拓展单编号") private Long successExtensionId; - @ApiModelProperty(value = "退款状态") + @Schema(title = "退款状态") private Integer refundStatus; - @ApiModelProperty(value = "退款次数") + @Schema(title = "退款次数") private Integer refundTimes; - @ApiModelProperty(value = "退款总金额,单位:分") + @Schema(title = "退款总金额,单位:分") private Long refundAmount; - @ApiModelProperty(value = "渠道用户编号") + @Schema(title = "渠道用户编号") private String channelUserId; - @ApiModelProperty(value = "渠道订单号") + @Schema(title = "渠道订单号") private String channelOrderNo; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java index ec1e405a7..795d2f804 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java @@ -1,35 +1,34 @@ package cn.iocoder.yudao.module.pay.controller.admin.order.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 支付订单分页 Request VO") +@Schema(title = "管理后台 - 支付订单分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayOrderPageItemRespVO extends PayOrderBaseVO { - @ApiModelProperty(value = "支付订单编号", required = true) + @Schema(title = "支付订单编号", required = true) private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; - @ApiModelProperty(value = "商户名称") + @Schema(title = "商户名称") private String merchantName; - @ApiModelProperty(value = "应用名称") + @Schema(title = "应用名称") private String appName; - @ApiModelProperty(value = "渠道名称") + @Schema(title = "渠道名称") private String channelCodeName; - @ApiModelProperty(value = "支付订单号") + @Schema(title = "支付订单号") private String no; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java index 2ae90322a..61d0ab250 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.pay.controller.admin.order.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,86 +11,86 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 支付订单分页 Request VO") +@Schema(title = "管理后台 - 支付订单分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayOrderPageReqVO extends PageParam { - @ApiModelProperty(value = "商户编号") + @Schema(title = "商户编号") private Long merchantId; - @ApiModelProperty(value = "应用编号") + @Schema(title = "应用编号") private Long appId; - @ApiModelProperty(value = "渠道编号") + @Schema(title = "渠道编号") private Long channelId; - @ApiModelProperty(value = "渠道编码") + @Schema(title = "渠道编码") private String channelCode; - @ApiModelProperty(value = "商户订单编号") + @Schema(title = "商户订单编号") private String merchantOrderId; - @ApiModelProperty(value = "商品标题") + @Schema(title = "商品标题") private String subject; - @ApiModelProperty(value = "商品描述") + @Schema(title = "商品描述") private String body; - @ApiModelProperty(value = "异步通知地址") + @Schema(title = "异步通知地址") private String notifyUrl; - @ApiModelProperty(value = "通知商户支付结果的回调状态") + @Schema(title = "通知商户支付结果的回调状态") private Integer notifyStatus; - @ApiModelProperty(value = "支付金额,单位:分") + @Schema(title = "支付金额,单位:分") private Long amount; - @ApiModelProperty(value = "渠道手续费,单位:百分比") + @Schema(title = "渠道手续费,单位:百分比") private Double channelFeeRate; - @ApiModelProperty(value = "渠道手续金额,单位:分") + @Schema(title = "渠道手续金额,单位:分") private Long channelFeeAmount; - @ApiModelProperty(value = "支付状态") + @Schema(title = "支付状态") private Integer status; - @ApiModelProperty(value = "用户 IP") + @Schema(title = "用户 IP") private String userIp; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "订单失效时间") + @Schema(title = "订单失效时间") private LocalDateTime[] expireTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "订单支付成功时间") + @Schema(title = "订单支付成功时间") private LocalDateTime[] successTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "订单支付通知时间") + @Schema(title = "订单支付通知时间") private LocalDateTime[] notifyTime; - @ApiModelProperty(value = "支付成功的订单拓展单编号") + @Schema(title = "支付成功的订单拓展单编号") private Long successExtensionId; - @ApiModelProperty(value = "退款状态") + @Schema(title = "退款状态") private Integer refundStatus; - @ApiModelProperty(value = "退款次数") + @Schema(title = "退款次数") private Integer refundTimes; - @ApiModelProperty(value = "退款总金额,单位:分") + @Schema(title = "退款总金额,单位:分") private Long refundAmount; - @ApiModelProperty(value = "渠道用户编号") + @Schema(title = "渠道用户编号") private String channelUserId; - @ApiModelProperty(value = "渠道订单号") + @Schema(title = "渠道订单号") private String channelOrderNo; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java index a22c1d709..09c71e055 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.pay.controller.admin.order.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 支付订单 Response VO") +@Schema(title = "管理后台 - 支付订单 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayOrderRespVO extends PayOrderBaseVO { - @ApiModelProperty(value = "支付订单编号", required = true) + @Schema(title = "支付订单编号", required = true) private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java index 58cb24fa3..e16e51115 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java @@ -18,9 +18,9 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -39,7 +39,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 退款订单") +@Tag(name = "管理后台 - 退款订单") @RestController @RequestMapping("/pay/refund") @Validated @@ -55,8 +55,8 @@ public class PayRefundController { private PayOrderService orderService; @GetMapping("/get") - @ApiOperation("获得退款订单") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得退款订单") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('pay:refund:query')") public CommonResult getRefund(@RequestParam("id") Long id) { PayRefundDO refund = refundService.getRefund(id); @@ -79,7 +79,7 @@ public class PayRefundController { } @GetMapping("/page") - @ApiOperation("获得退款订单分页") + @Operation(summary = "获得退款订单分页") @PreAuthorize("@ss.hasPermission('pay:refund:query')") public CommonResult> getRefundPage(@Valid PayRefundPageReqVO pageVO) { PageResult pageResult = refundService.getRefundPage(pageVO); @@ -111,7 +111,7 @@ public class PayRefundController { } @GetMapping("/export-excel") - @ApiOperation("导出退款订单 Excel") + @Operation(summary = "导出退款订单 Excel") @PreAuthorize("@ss.hasPermission('pay:refund:export')") @OperateLog(type = EXPORT) public void exportRefundExcel(@Valid PayRefundExportReqVO exportReqVO, diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java index f79780683..5df3ffa06 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -16,94 +15,94 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class PayRefundBaseVO { - @ApiModelProperty(value = "商户编号", required = true) + @Schema(title = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long merchantId; - @ApiModelProperty(value = "应用编号", required = true) + @Schema(title = "应用编号", required = true) @NotNull(message = "应用编号不能为空") private Long appId; - @ApiModelProperty(value = "渠道编号", required = true) + @Schema(title = "渠道编号", required = true) @NotNull(message = "渠道编号不能为空") private Long channelId; - @ApiModelProperty(value = "渠道编码", required = true) + @Schema(title = "渠道编码", required = true) @NotNull(message = "渠道编码不能为空") private String channelCode; - @ApiModelProperty(value = "支付订单编号 pay_order 表id", required = true) + @Schema(title = "支付订单编号 pay_order 表id", required = true) @NotNull(message = "支付订单编号 pay_order 表id不能为空") private Long orderId; - @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段", required = true) + @Schema(title = "交易订单号 pay_extension 表no 字段", required = true) @NotNull(message = "交易订单号 pay_extension 表no 字段不能为空") private String tradeNo; - @ApiModelProperty(value = "商户订单编号(商户系统生成)", required = true) + @Schema(title = "商户订单编号(商户系统生成)", required = true) @NotNull(message = "商户订单编号(商户系统生成)不能为空") private String merchantOrderId; - @ApiModelProperty(value = "商户退款订单号(商户系统生成)", required = true) + @Schema(title = "商户退款订单号(商户系统生成)", required = true) @NotNull(message = "商户退款订单号(商户系统生成)不能为空") private String merchantRefundNo; - @ApiModelProperty(value = "异步通知商户地址", required = true) + @Schema(title = "异步通知商户地址", required = true) @NotNull(message = "异步通知商户地址不能为空") private String notifyUrl; - @ApiModelProperty(value = "通知商户退款结果的回调状态", required = true) + @Schema(title = "通知商户退款结果的回调状态", required = true) @NotNull(message = "通知商户退款结果的回调状态不能为空") private Integer notifyStatus; - @ApiModelProperty(value = "退款状态", required = true) + @Schema(title = "退款状态", required = true) @NotNull(message = "退款状态不能为空") private Integer status; - @ApiModelProperty(value = "退款类型(部分退款,全部退款)", required = true) + @Schema(title = "退款类型(部分退款,全部退款)", required = true) @NotNull(message = "退款类型(部分退款,全部退款)不能为空") private Integer type; - @ApiModelProperty(value = "支付金额,单位分", required = true) + @Schema(title = "支付金额,单位分", required = true) @NotNull(message = "支付金额,单位分不能为空") private Long payAmount; - @ApiModelProperty(value = "退款金额,单位分", required = true) + @Schema(title = "退款金额,单位分", required = true) @NotNull(message = "退款金额,单位分不能为空") private Long refundAmount; - @ApiModelProperty(value = "退款原因", required = true) + @Schema(title = "退款原因", required = true) @NotNull(message = "退款原因不能为空") private String reason; - @ApiModelProperty(value = "用户 IP") + @Schema(title = "用户 IP") private String userIp; - @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应", required = true) + @Schema(title = "渠道订单号,pay_order 中的channel_order_no 对应", required = true) @NotNull(message = "渠道订单号,pay_order 中的channel_order_no 对应不能为空") private String channelOrderNo; - @ApiModelProperty(value = "渠道退款单号,渠道返回") + @Schema(title = "渠道退款单号,渠道返回") private String channelRefundNo; - @ApiModelProperty(value = "渠道调用报错时,错误码") + @Schema(title = "渠道调用报错时,错误码") private String channelErrorCode; - @ApiModelProperty(value = "渠道调用报错时,错误信息") + @Schema(title = "渠道调用报错时,错误信息") private String channelErrorMsg; - @ApiModelProperty(value = "支付渠道的额外参数") + @Schema(title = "支付渠道的额外参数") private String channelExtras; - @ApiModelProperty(value = "退款失效时间") + @Schema(title = "退款失效时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime expireTime; - @ApiModelProperty(value = "退款成功时间") + @Schema(title = "退款成功时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime successTime; - @ApiModelProperty(value = "退款通知时间") + @Schema(title = "退款通知时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime notifyTime; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java index cc09111ef..7f100464e 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 退款订单创建 Request VO") +@Schema(title = "管理后台 - 退款订单创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java index dcabd031d..9ad9fbd20 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,31 +8,31 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@ApiModel("管理后台 - 退款订单详情 Response VO") +@Schema(title = "管理后台 - 退款订单详情 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayRefundDetailsRespVO extends PayRefundBaseVO { - @ApiModelProperty(value = "支付退款编号", required = true) + @Schema(title = "支付退款编号", required = true) private Long id; - @ApiModelProperty(value = "商户名称") + @Schema(title = "商户名称") private String merchantName; - @ApiModelProperty(value = "应用名称") + @Schema(title = "应用名称") private String appName; - @ApiModelProperty(value = "渠道编号名称") + @Schema(title = "渠道编号名称") private String channelCodeName; @NotNull(message = "商品标题不能为空") private String subject; - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime createTime; - @ApiModelProperty(value = "更新时间") + @Schema(title = "更新时间") private LocalDateTime updateTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java index b39f82dd3..bb1a25f91 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,87 +8,87 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 退款订单 Excel 导出 Request VO", description = "参数和 PayRefundPageReqVO 是一致的") +@Schema(title = "管理后台 - 退款订单 Excel 导出 Request VO", description = "参数和 PayRefundPageReqVO 是一致的") @Data public class PayRefundExportReqVO { - @ApiModelProperty(value = "商户编号") + @Schema(title = "商户编号") private Long merchantId; - @ApiModelProperty(value = "应用编号") + @Schema(title = "应用编号") private Long appId; - @ApiModelProperty(value = "渠道编号") + @Schema(title = "渠道编号") private Long channelId; - @ApiModelProperty(value = "渠道编码") + @Schema(title = "渠道编码") private String channelCode; - @ApiModelProperty(value = "支付订单编号 pay_order 表id") + @Schema(title = "支付订单编号 pay_order 表id") private Long orderId; - @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段") + @Schema(title = "交易订单号 pay_extension 表no 字段") private String tradeNo; - @ApiModelProperty(value = "商户订单编号(商户系统生成)") + @Schema(title = "商户订单编号(商户系统生成)") private String merchantOrderId; - @ApiModelProperty(value = "商户退款订单号(商户系统生成)") + @Schema(title = "商户退款订单号(商户系统生成)") private String merchantRefundNo; - @ApiModelProperty(value = "异步通知商户地址") + @Schema(title = "异步通知商户地址") private String notifyUrl; - @ApiModelProperty(value = "通知商户退款结果的回调状态") + @Schema(title = "通知商户退款结果的回调状态") private Integer notifyStatus; - @ApiModelProperty(value = "退款状态") + @Schema(title = "退款状态") private Integer status; - @ApiModelProperty(value = "退款类型(部分退款,全部退款)") + @Schema(title = "退款类型(部分退款,全部退款)") private Integer type; - @ApiModelProperty(value = "支付金额,单位分") + @Schema(title = "支付金额,单位分") private Long payAmount; - @ApiModelProperty(value = "退款金额,单位分") + @Schema(title = "退款金额,单位分") private Long refundAmount; - @ApiModelProperty(value = "退款原因") + @Schema(title = "退款原因") private String reason; - @ApiModelProperty(value = "用户 IP") + @Schema(title = "用户 IP") private String userIp; - @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应") + @Schema(title = "渠道订单号,pay_order 中的channel_order_no 对应") private String channelOrderNo; - @ApiModelProperty(value = "渠道退款单号,渠道返回") + @Schema(title = "渠道退款单号,渠道返回") private String channelRefundNo; - @ApiModelProperty(value = "渠道调用报错时,错误码") + @Schema(title = "渠道调用报错时,错误码") private String channelErrorCode; - @ApiModelProperty(value = "渠道调用报错时,错误信息") + @Schema(title = "渠道调用报错时,错误信息") private String channelErrorMsg; - @ApiModelProperty(value = "支付渠道的额外参数") + @Schema(title = "支付渠道的额外参数") private String channelExtras; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "退款失效时间") + @Schema(title = "退款失效时间") private LocalDateTime[] expireTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "退款成功时间") + @Schema(title = "退款成功时间") private LocalDateTime[] successTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "退款通知时间") + @Schema(title = "退款通知时间") private LocalDateTime[] notifyTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java index b57a34c06..192a11c44 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java @@ -1,32 +1,31 @@ package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 退款订单分页查询 Response VO") +@Schema(title = "管理后台 - 退款订单分页查询 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayRefundPageItemRespVO extends PayRefundBaseVO { - @ApiModelProperty(value = "支付订单编号", required = true) + @Schema(title = "支付订单编号", required = true) private Long id; - @ApiModelProperty(value = "商户名称") + @Schema(title = "商户名称") private String merchantName; - @ApiModelProperty(value = "应用名称") + @Schema(title = "应用名称") private String appName; - @ApiModelProperty(value = "渠道名称") + @Schema(title = "渠道名称") private String channelCodeName; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java index 141e2a77f..c126cfe0f 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,89 +11,89 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 退款订单分页 Request VO") +@Schema(title = "管理后台 - 退款订单分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayRefundPageReqVO extends PageParam { - @ApiModelProperty(value = "商户编号") + @Schema(title = "商户编号") private Long merchantId; - @ApiModelProperty(value = "应用编号") + @Schema(title = "应用编号") private Long appId; - @ApiModelProperty(value = "渠道编号") + @Schema(title = "渠道编号") private Long channelId; - @ApiModelProperty(value = "渠道编码") + @Schema(title = "渠道编码") private String channelCode; - @ApiModelProperty(value = "支付订单编号 pay_order 表id") + @Schema(title = "支付订单编号 pay_order 表id") private Long orderId; - @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段") + @Schema(title = "交易订单号 pay_extension 表no 字段") private String tradeNo; - @ApiModelProperty(value = "商户订单编号(商户系统生成)") + @Schema(title = "商户订单编号(商户系统生成)") private String merchantOrderId; - @ApiModelProperty(value = "商户退款订单号(商户系统生成)") + @Schema(title = "商户退款订单号(商户系统生成)") private String merchantRefundNo; - @ApiModelProperty(value = "异步通知商户地址") + @Schema(title = "异步通知商户地址") private String notifyUrl; - @ApiModelProperty(value = "通知商户退款结果的回调状态") + @Schema(title = "通知商户退款结果的回调状态") private Integer notifyStatus; - @ApiModelProperty(value = "退款状态") + @Schema(title = "退款状态") private Integer status; - @ApiModelProperty(value = "退款类型(部分退款,全部退款)") + @Schema(title = "退款类型(部分退款,全部退款)") private Integer type; - @ApiModelProperty(value = "支付金额,单位分") + @Schema(title = "支付金额,单位分") private Long payAmount; - @ApiModelProperty(value = "退款金额,单位分") + @Schema(title = "退款金额,单位分") private Long refundAmount; - @ApiModelProperty(value = "退款原因") + @Schema(title = "退款原因") private String reason; - @ApiModelProperty(value = "用户 IP") + @Schema(title = "用户 IP") private String userIp; - @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应") + @Schema(title = "渠道订单号,pay_order 中的channel_order_no 对应") private String channelOrderNo; - @ApiModelProperty(value = "渠道退款单号,渠道返回") + @Schema(title = "渠道退款单号,渠道返回") private String channelRefundNo; - @ApiModelProperty(value = "渠道调用报错时,错误码") + @Schema(title = "渠道调用报错时,错误码") private String channelErrorCode; - @ApiModelProperty(value = "渠道调用报错时,错误信息") + @Schema(title = "渠道调用报错时,错误信息") private String channelErrorMsg; - @ApiModelProperty(value = "支付渠道的额外参数") + @Schema(title = "支付渠道的额外参数") private String channelExtras; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "退款失效时间") + @Schema(title = "退款失效时间") private LocalDateTime[] expireTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "退款成功时间") + @Schema(title = "退款成功时间") private LocalDateTime[] successTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "退款通知时间") + @Schema(title = "退款通知时间") private LocalDateTime[] notifyTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java index e5453fbd4..6f040aafc 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 退款订单 Response VO") +@Schema(title = "管理后台 - 退款订单 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayRefundRespVO extends PayRefundBaseVO { - @ApiModelProperty(value = "支付退款编号", required = true) + @Schema(title = "支付退款编号", required = true) private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java index b7d555563..1cb8c7506 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java @@ -1,16 +1,15 @@ package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; - +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 退款订单更新 Request VO") +@Schema(title = "管理后台 - 退款订单更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayRefundUpdateReqVO extends PayRefundBaseVO { - @ApiModelProperty(value = "支付退款编号", required = true) + @Schema(title = "支付退款编号", required = true) @NotNull(message = "支付退款编号不能为空") private Long id; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java index e01f7f4f4..8d99bc6a4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java @@ -12,8 +12,8 @@ import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitReqDTO; import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitRespDTO; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -26,7 +26,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; -@Api(tags = "用户 APP - 支付订单") +@Tag(name = "用户 APP - 支付订单") @RestController @RequestMapping("/pay/order") @Validated @@ -42,7 +42,7 @@ public class AppPayOrderController { private PayClientFactory payClientFactory; @PostMapping("/submit") - @ApiOperation("提交支付订单") + @Operation(summary = "提交支付订单") // @PreAuthenticated // TODO 暂时不加登陆验证,前端暂时没做好 public CommonResult submitPayOrder(@RequestBody AppPayOrderSubmitReqVO reqVO) { // 获得订单 @@ -63,7 +63,7 @@ public class AppPayOrderController { // TODO @芋艿:是不是放到 notify 模块更合适 //TODO 芋道源码 换成了统一的地址了 /notify/{channelId},测试通过可以删除 @PostMapping("/notify/wx-pub/{channelId}") - @ApiOperation("通知微信公众号支付的结果") + @Operation(summary = "通知微信公众号支付的结果") public String notifyWxPayOrder(@PathVariable("channelId") Long channelId, @RequestBody String xmlData) throws Exception { orderService.notifyPayOrder(channelId, PayNotifyDataDTO.builder().body(xmlData).build()); @@ -77,7 +77,7 @@ public class AppPayOrderController { * @return 返回跳转页面 */ @GetMapping(value = "/return/{channelId}") - @ApiOperation("渠道统一的支付成功返回地址") + @Operation(summary = "渠道统一的支付成功返回地址") public String returnAliPayOrder(@PathVariable("channelId") Long channelId, @RequestParam Map params){ //TODO 可以根据渠道和 app_id 返回不同的页面 log.info("app_id is {}", params.get("app_id")); @@ -93,7 +93,7 @@ public class AppPayOrderController { * @return 成功返回 "success" */ @PostMapping(value = "/notify/{channelId}") - @ApiOperation("渠道统一的支付成功,或退款成功 通知url") + @Operation(summary = "渠道统一的支付成功,或退款成功 通知url") public String notifyChannelPay(@PathVariable("channelId") Long channelId, @RequestParam Map params, @RequestBody String originData) throws Exception { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java index 6834c3838..e2275f6e4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.controller.app.order.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.experimental.Accessors; @@ -9,20 +8,20 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.Map; -@ApiModel("用户 APP - 支付订单提交 Request VO") +@Schema(title = "用户 APP - 支付订单提交 Request VO") @Data @Accessors(chain = true) public class AppPayOrderSubmitReqVO { - @ApiModelProperty(value = "支付单编号", required = true, example = "1024") + @Schema(title = "支付单编号", required = true, example = "1024") @NotNull(message = "支付单编号不能为空") private Long id; - @ApiModelProperty(value = "支付渠道", required = true, example = "wx_pub") + @Schema(title = "支付渠道", required = true, example = "wx_pub") @NotEmpty(message = "支付渠道不能为空") private String channelCode; - @ApiModelProperty(value = "支付渠道的额外参数", notes = "例如说,微信公众号需要传递 openid 参数") + @Schema(title = "支付渠道的额外参数", description = "例如说,微信公众号需要传递 openid 参数") private Map channelExtras; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java index 7fcffd097..ee33ef6ac 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java @@ -1,13 +1,13 @@ package cn.iocoder.yudao.module.pay.controller.app.order.vo; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -@ApiModel("用户 APP - 支付订单提交 Response VO") +@Schema(title = "用户 APP - 支付订单提交 Response VO") @Data @Accessors(chain = true) @Builder diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/AppPayRefundController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/AppPayRefundController.java index 42fdc5dcb..855687c04 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/AppPayRefundController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/AppPayRefundController.java @@ -8,8 +8,8 @@ import cn.iocoder.yudao.module.pay.convert.refund.PayRefundConvert; import cn.iocoder.yudao.module.pay.service.order.dto.PayRefundReqDTO; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; import cn.iocoder.yudao.module.pay.util.PaySeqUtils; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; @@ -22,7 +22,7 @@ import javax.annotation.Resource; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -@Api(tags = "用户 APP - 退款订单") +@Tag(name = "用户 APP - 退款订单") @RestController @RequestMapping("/pay/refund") @Validated @@ -33,7 +33,7 @@ public class AppPayRefundController { private PayRefundService refundService; @PostMapping("/refund") - @ApiOperation("提交退款订单") + @Operation(summary = "提交退款订单") public CommonResult submitRefundOrder(@RequestBody AppPayRefundReqVO reqVO){ PayRefundReqDTO req = PayRefundConvert.INSTANCE.convert(reqVO); req.setUserIp(getClientIP()); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java index 627874561..6ea1528f1 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.controller.app.refund.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -9,25 +8,25 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("用户 APP - 退款订单 Req VO") +@Schema(title = "用户 APP - 退款订单 Req VO") @Data @NoArgsConstructor @AllArgsConstructor public class AppPayRefundReqVO { - @ApiModelProperty(value = "支付订单编号自增", required = true, example = "10") + @Schema(title = "支付订单编号自增", required = true, example = "10") @NotNull(message = "支付订单编号自增") private Long payOrderId; - @ApiModelProperty(value = "退款金额", required = true, example = "1") + @Schema(title = "退款金额", required = true, example = "1") @NotNull(message = "退款金额") private Long amount; - @ApiModelProperty(value = "退款原因", required = true, example = "不喜欢") + @Schema(title = "退款原因", required = true, example = "不喜欢") @NotEmpty(message = "退款原因") private String reason; - @ApiModelProperty(value = "商户退款订单号", required = true, example = "MR202111180000000001") + @Schema(title = "商户退款订单号", required = true, example = "MR202111180000000001") //TODO 测试暂时模拟生成 //@NotEmpty(message = "商户退款订单号") private String merchantRefundId; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java index 534243281..21466c05d 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java @@ -1,14 +1,13 @@ package cn.iocoder.yudao.module.pay.controller.app.refund.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -@ApiModel("用户 APP - 提交退款订单 Response VO") +@Schema(title = "用户 APP - 提交退款订单 Response VO") @Data @Accessors(chain = true) @Builder @@ -16,7 +15,7 @@ import lombok.experimental.Accessors; @AllArgsConstructor public class AppPayRefundRespVO { - @ApiModelProperty(value = "退款订单编号", required = true, example = "10") + @Schema(title = "退款订单编号", required = true, example = "10") private Long refundId; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java index d4f6c1eae..c9e753c67 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.service.notify.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,18 +9,18 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel(value = "支付单的通知 Request VO", description = "业务方接入支付回调时,使用该 VO 对象") +@Schema(title = "支付单的通知 Request VO", description = "业务方接入支付回调时,使用该 VO 对象") @Data @Builder @NoArgsConstructor @AllArgsConstructor public class PayNotifyOrderReqVO { - @ApiModelProperty(value = "商户订单编号", required = true, example = "10") + @Schema(title = "商户订单编号", required = true, example = "10") @NotEmpty(message = "商户订单号不能为空") private String merchantOrderId; - @ApiModelProperty(value = "支付订单编号", required = true, example = "20") + @Schema(title = "支付订单编号", required = true, example = "20") @NotNull(message = "支付订单编号不能为空") private Long payOrderId; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java index 978283d1b..ab7d6ea03 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.pay.service.notify.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,22 +9,22 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel(value = "退款单的通知 Request VO", description = "业务方接入退款回调时,使用该 VO 对象") +@Schema(title = "退款单的通知 Request VO", description = "业务方接入退款回调时,使用该 VO 对象") @Data @Builder @NoArgsConstructor @AllArgsConstructor public class PayRefundOrderReqVO { - @ApiModelProperty(value = "商户退款单编号", required = true, example = "10") + @Schema(title = "商户退款单编号", required = true, example = "10") @NotEmpty(message = "商户退款单编号不能为空") private String merchantOrderId; - @ApiModelProperty(value = "支付退款编号", required = true, example = "20") + @Schema(title = "支付退款编号", required = true, example = "20") @NotNull(message = "支付退款编号不能为空") private Long payRefundId; - @ApiModelProperty(value = "退款状态(成功,失败)", required = true, example = "10") + @Schema(title = "退款状态(成功,失败)", required = true, example = "10") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/pom.xml b/yudao-module-system/yudao-module-system-biz/pom.xml index ecac34aa5..cf8cf5e58 100644 --- a/yudao-module-system/yudao-module-system-biz/pom.xml +++ b/yudao-module-system/yudao-module-system-biz/pom.xml @@ -61,6 +61,11 @@ yudao-spring-boot-starter-security + + org.springframework.boot + spring-boot-starter-validation + + cn.iocoder.boot diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java index 9a9c0a95e..6acceae52 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java @@ -18,10 +18,10 @@ import cn.iocoder.yudao.module.system.service.permission.PermissionService; import cn.iocoder.yudao.module.system.service.permission.RoleService; import cn.iocoder.yudao.module.system.service.social.SocialUserService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -38,7 +38,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.obtainAuthorization; import static java.util.Collections.singleton; -@Api(tags = "管理后台 - 认证") +@Tag(name = "管理后台 - 认证") @RestController @RequestMapping("/system/auth") @Validated @@ -60,7 +60,7 @@ public class AuthController { @PostMapping("/login") @PermitAll - @ApiOperation("使用账号密码登录") + @Operation(summary = "使用账号密码登录") @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult login(@RequestBody @Valid AuthLoginReqVO reqVO) { return success(authService.login(reqVO)); @@ -68,7 +68,7 @@ public class AuthController { @PostMapping("/logout") @PermitAll - @ApiOperation("登出系统") + @Operation(summary = "登出系统") @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult logout(HttpServletRequest request) { String token = obtainAuthorization(request, securityProperties.getTokenHeader()); @@ -80,15 +80,15 @@ public class AuthController { @PostMapping("/refresh-token") @PermitAll - @ApiOperation("刷新令牌") - @ApiImplicitParam(name = "refreshToken", value = "刷新令牌", required = true, dataTypeClass = String.class) + @Operation(summary = "刷新令牌") + @Parameter(name = "refreshToken", description = "刷新令牌", required = true) @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult refreshToken(@RequestParam("refreshToken") String refreshToken) { return success(authService.refreshToken(refreshToken)); } @GetMapping("/get-permission-info") - @ApiOperation("获取登录用户的权限信息") + @Operation(summary = "获取登录用户的权限信息") public CommonResult getPermissionInfo() { // 获得用户信息 AdminUserDO user = userService.getUser(getLoginUserId()); @@ -107,7 +107,7 @@ public class AuthController { } @GetMapping("/list-menus") - @ApiOperation("获得登录用户的菜单列表") + @Operation(summary = "获得登录用户的菜单列表") public CommonResult> getMenus() { // 获得角色列表 Set roleIds = permissionService.getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); @@ -123,7 +123,7 @@ public class AuthController { @PostMapping("/sms-login") @PermitAll - @ApiOperation("使用短信验证码登录") + @Operation(summary = "使用短信验证码登录") @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) { return success(authService.smsLogin(reqVO)); @@ -131,7 +131,7 @@ public class AuthController { @PostMapping("/send-sms-code") @PermitAll - @ApiOperation(value = "发送手机验证码") + @Operation(summary = "发送手机验证码") @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult sendLoginSmsCode(@RequestBody @Valid AuthSmsSendReqVO reqVO) { authService.sendSmsCode(reqVO); @@ -142,10 +142,10 @@ public class AuthController { @GetMapping("/social-auth-redirect") @PermitAll - @ApiOperation("社交授权的跳转") - @ApiImplicitParams({ - @ApiImplicitParam(name = "type", value = "社交类型", required = true, dataTypeClass = Integer.class), - @ApiImplicitParam(name = "redirectUri", value = "回调路径", dataTypeClass = String.class) + @Operation(summary = "社交授权的跳转") + @Parameters({ + @Parameter(name = "type", description = "社交类型", required = true), + @Parameter(name = "redirectUri", description = "回调路径") }) public CommonResult socialLogin(@RequestParam("type") Integer type, @RequestParam("redirectUri") String redirectUri) { @@ -154,7 +154,7 @@ public class AuthController { @PostMapping("/social-login") @PermitAll - @ApiOperation(value = "社交快捷登录,使用 code 授权码", notes = "适合未登录的用户,但是社交账号已绑定用户") + @Operation(summary = "社交快捷登录,使用 code 授权码", description = "适合未登录的用户,但是社交账号已绑定用户") @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult socialQuickLogin(@RequestBody @Valid AuthSocialLoginReqVO reqVO) { return success(authService.socialLogin(reqVO)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java index bafc322e2..2f8ab7f36 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java @@ -3,8 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.auth.vo; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -15,42 +14,42 @@ import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; -@ApiModel(value = "管理后台 - 账号密码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") +@Schema(title = "管理后台 - 账号密码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthLoginReqVO { - @ApiModelProperty(value = "账号", required = true, example = "yudaoyuanma") + @Schema(title = "账号", required = true, example = "yudaoyuanma") @NotEmpty(message = "登录账号不能为空") @Length(min = 4, max = 16, message = "账号长度为 4-16 位") @Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母") private String username; - @ApiModelProperty(value = "密码", required = true, example = "buzhidao") + @Schema(title = "密码", required = true, example = "buzhidao") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; // ========== 图片验证码相关 ========== - @ApiModelProperty(value = "验证码", required = true, + @Schema(title = "验证码", required = true, example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==", - notes = "验证码开启时,需要传递") + description = "验证码开启时,需要传递") @NotEmpty(message = "验证码不能为空", groups = CodeEnableGroup.class) private String captchaVerification; // ========== 绑定社交登录时,需要传递如下参数 ========== - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") @InEnum(SocialTypeEnum.class) private Integer socialType; - @ApiModelProperty(value = "授权码", required = true, example = "1024") + @Schema(title = "授权码", required = true, example = "1024") private String socialCode; - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") private String socialState; /** diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginRespVO.java index 6e1882887..2faf84567 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.auth.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,23 +8,23 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@ApiModel("管理后台 - 登录 Response VO") +@Schema(title = "管理后台 - 登录 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthLoginRespVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1024") + @Schema(title = "用户编号", required = true, example = "1024") private Long userId; - @ApiModelProperty(value = "访问令牌", required = true, example = "happy") + @Schema(title = "访问令牌", required = true, example = "happy") private String accessToken; - @ApiModelProperty(value = "刷新令牌", required = true, example = "nice") + @Schema(title = "刷新令牌", required = true, example = "nice") private String refreshToken; - @ApiModelProperty(value = "过期时间", required = true) + @Schema(title = "过期时间", required = true) private LocalDateTime expiresTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthMenuRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthMenuRespVO.java index 2ae7eaac8..9af118f70 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthMenuRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthMenuRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.auth.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,35 +8,35 @@ import lombok.NoArgsConstructor; import java.util.List; -@ApiModel("管理后台 - 登录用户的菜单信息 Response VO") +@Schema(title = "管理后台 - 登录用户的菜单信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthMenuRespVO { - @ApiModelProperty(value = "菜单名称", required = true, example = "芋道") + @Schema(title = "菜单名称", required = true, example = "芋道") private Long id; - @ApiModelProperty(value = "父菜单 ID", required = true, example = "1024") + @Schema(title = "父菜单 ID", required = true, example = "1024") private Long parentId; - @ApiModelProperty(value = "菜单名称", required = true, example = "芋道") + @Schema(title = "菜单名称", required = true, example = "芋道") private String name; - @ApiModelProperty(value = "路由地址", example = "post", notes = "仅菜单类型为菜单或者目录时,才需要传") + @Schema(title = "路由地址", example = "post", description = "仅菜单类型为菜单或者目录时,才需要传") private String path; - @ApiModelProperty(value = "组件路径", example = "system/post/index", notes = "仅菜单类型为菜单时,才需要传") + @Schema(title = "组件路径", example = "system/post/index", description = "仅菜单类型为菜单时,才需要传") private String component; - @ApiModelProperty(value = "菜单图标", example = "/menu/list", notes = "仅菜单类型为菜单或者目录时,才需要传") + @Schema(title = "菜单图标", example = "/menu/list", description = "仅菜单类型为菜单或者目录时,才需要传") private String icon; - @ApiModelProperty(value = "是否可见", required = true, example = "false") + @Schema(title = "是否可见", required = true, example = "false") private Boolean visible; - @ApiModelProperty(value = "是否缓存", required = true, example = "false") + @Schema(title = "是否缓存", required = true, example = "false") private Boolean keepAlive; /** diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java index 0e809226c..cfe8725b0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.auth.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,36 +8,36 @@ import lombok.NoArgsConstructor; import java.util.Set; -@ApiModel(value = "管理后台 - 登录用户的权限信息 Response VO", description = "额外包括用户信息和角色列表") +@Schema(title = "管理后台 - 登录用户的权限信息 Response VO", description = "额外包括用户信息和角色列表") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthPermissionInfoRespVO { - @ApiModelProperty(value = "用户信息", required = true) + @Schema(title = "用户信息", required = true) private UserVO user; - @ApiModelProperty(value = "角色标识数组", required = true) + @Schema(title = "角色标识数组", required = true) private Set roles; - @ApiModelProperty(value = "操作权限数组", required = true) + @Schema(title = "操作权限数组", required = true) private Set permissions; - @ApiModel("用户信息 VO") + @Schema(title = "用户信息 VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public static class UserVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1024") + @Schema(title = "用户编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "用户昵称", required = true, example = "芋道源码") + @Schema(title = "用户昵称", required = true, example = "芋道源码") private String nickname; - @ApiModelProperty(value = "用户头像", required = true, example = "http://www.iocoder.cn/xx.jpg") + @Schema(title = "用户头像", required = true, example = "http://www.iocoder.cn/xx.jpg") private String avatar; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsLoginReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsLoginReqVO.java index b641bcca6..61e084254 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsLoginReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsLoginReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.auth.vo; import cn.iocoder.yudao.framework.common.validation.Mobile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -10,19 +9,19 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 短信验证码的登录 Request VO") +@Schema(title = "管理后台 - 短信验证码的登录 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthSmsLoginReqVO { - @ApiModelProperty(value = "手机号", required = true, example = "yudaoyuanma") + @Schema(title = "手机号", required = true, example = "yudaoyuanma") @NotEmpty(message = "手机号不能为空") @Mobile private String mobile; - @ApiModelProperty(value = "短信验证码", required = true, example = "1024") + @Schema(title = "短信验证码", required = true, example = "1024") @NotEmpty(message = "验证码不能为空") private String code; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsSendReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsSendReqVO.java index 0df9a521e..89b4cb97d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsSendReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsSendReqVO.java @@ -3,8 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.auth.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.Mobile; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -13,19 +12,19 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 发送手机验证码 Request VO") +@Schema(title = "管理后台 - 发送手机验证码 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthSmsSendReqVO { - @ApiModelProperty(value = "手机号", required = true, example = "yudaoyuanma") + @Schema(title = "手机号", required = true, example = "yudaoyuanma") @NotEmpty(message = "手机号不能为空") @Mobile private String mobile; - @ApiModelProperty(value = "短信场景", required = true, example = "1") + @Schema(title = "短信场景", required = true, example = "1") @NotNull(message = "发送场景不能为空") @InEnum(SmsSceneEnum.class) private Integer scene; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSocialLoginReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSocialLoginReqVO.java index e52a49288..10648edd3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSocialLoginReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSocialLoginReqVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.system.controller.admin.auth.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,23 +11,23 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 社交绑定登录 Request VO,使用 code 授权码 + 账号密码") +@Schema(title = "管理后台 - 社交绑定登录 Request VO,使用 code 授权码 + 账号密码") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthSocialLoginReqVO { - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 UserSocialTypeEnum 枚举值") + @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 UserSocialTypeEnum 枚举值") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @ApiModelProperty(value = "授权码", required = true, example = "1024") + @Schema(title = "授权码", required = true, example = "1024") @NotEmpty(message = "授权码不能为空") private String code; - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") @NotEmpty(message = "state 不能为空") private String state; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java index fbdd665e8..4d6bcee28 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.system.controller.admin.captcha; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import com.anji.captcha.model.common.ResponseModel; import com.anji.captcha.model.vo.CaptchaVO; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -21,13 +21,13 @@ import javax.servlet.http.HttpServletRequest; * * @author 芋道源码 */ -@Api(tags = "管理后台 - 验证码") +@Tag(name = "管理后台 - 验证码") @RestController("adminCaptchaController") @RequestMapping("/system/captcha") public class CaptchaController extends com.anji.captcha.controller.CaptchaController { @PostMapping({"/get"}) - @ApiOperation("获得验证码") + @Operation(summary = "获得验证码") @PermitAll @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 @Override @@ -36,7 +36,7 @@ public class CaptchaController extends com.anji.captcha.controller.CaptchaContro } @PostMapping("/check") - @ApiOperation("校验验证码") + @Operation(summary = "校验验证码") @PermitAll @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 @Override diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java index 0a292e243..7c9338c40 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.*; import cn.iocoder.yudao.module.system.convert.dept.DeptConvert; import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; import cn.iocoder.yudao.module.system.service.dept.DeptService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 部门") +@Tag(name = "管理后台 - 部门") @RestController @RequestMapping("/system/dept") @Validated @@ -30,7 +30,7 @@ public class DeptController { private DeptService deptService; @PostMapping("create") - @ApiOperation("创建部门") + @Operation(summary = "创建部门") @PreAuthorize("@ss.hasPermission('system:dept:create')") public CommonResult createDept(@Valid @RequestBody DeptCreateReqVO reqVO) { Long deptId = deptService.createDept(reqVO); @@ -38,7 +38,7 @@ public class DeptController { } @PutMapping("update") - @ApiOperation("更新部门") + @Operation(summary = "更新部门") @PreAuthorize("@ss.hasPermission('system:dept:update')") public CommonResult updateDept(@Valid @RequestBody DeptUpdateReqVO reqVO) { deptService.updateDept(reqVO); @@ -46,8 +46,8 @@ public class DeptController { } @DeleteMapping("delete") - @ApiOperation("删除部门") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除部门") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:dept:delete')") public CommonResult deleteDept(@RequestParam("id") Long id) { deptService.deleteDept(id); @@ -55,7 +55,7 @@ public class DeptController { } @GetMapping("/list") - @ApiOperation("获取部门列表") + @Operation(summary = "获取部门列表") @PreAuthorize("@ss.hasPermission('system:dept:query')") public CommonResult> listDepts(DeptListReqVO reqVO) { List list = deptService.getSimpleDepts(reqVO); @@ -64,7 +64,7 @@ public class DeptController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获取部门精简信息列表", notes = "只包含被开启的部门,主要用于前端的下拉选项") + @Operation(summary = "获取部门精简信息列表", description = "只包含被开启的部门,主要用于前端的下拉选项") public CommonResult> getSimpleDepts() { // 获得部门列表,只要开启状态的 DeptListReqVO reqVO = new DeptListReqVO(); @@ -76,8 +76,8 @@ public class DeptController { } @GetMapping("/get") - @ApiOperation("获得部门信息") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得部门信息") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:dept:query')") public CommonResult getDept(@RequestParam("id") Long id) { return success(DeptConvert.INSTANCE.convert(deptService.getDept(id))); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java index 5275dc0c4..79cd44d3a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.*; import cn.iocoder.yudao.module.system.convert.dept.PostConvert; import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO; import cn.iocoder.yudao.module.system.service.dept.PostService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -27,7 +27,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 岗位") +@Tag(name = "管理后台 - 岗位") @RestController @RequestMapping("/system/post") @Validated @@ -37,7 +37,7 @@ public class PostController { private PostService postService; @PostMapping("/create") - @ApiOperation("创建岗位") + @Operation(summary = "创建岗位") @PreAuthorize("@ss.hasPermission('system:post:create')") public CommonResult createPost(@Valid @RequestBody PostCreateReqVO reqVO) { Long postId = postService.createPost(reqVO); @@ -45,7 +45,7 @@ public class PostController { } @PutMapping("/update") - @ApiOperation("修改岗位") + @Operation(summary = "修改岗位") @PreAuthorize("@ss.hasPermission('system:post:update')") public CommonResult updatePost(@Valid @RequestBody PostUpdateReqVO reqVO) { postService.updatePost(reqVO); @@ -53,7 +53,7 @@ public class PostController { } @DeleteMapping("/delete") - @ApiOperation("删除岗位") + @Operation(summary = "删除岗位") @PreAuthorize("@ss.hasPermission('system:post:delete')") public CommonResult deletePost(@RequestParam("id") Long id) { postService.deletePost(id); @@ -61,15 +61,15 @@ public class PostController { } @GetMapping(value = "/get") - @ApiOperation("获得岗位信息") - @ApiImplicitParam(name = "id", value = "岗位编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得岗位信息") + @Parameter(name = "id", description = "岗位编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:post:query')") public CommonResult getPost(@RequestParam("id") Long id) { return success(PostConvert.INSTANCE.convert(postService.getPost(id))); } @GetMapping("/list-all-simple") - @ApiOperation(value = "获取岗位精简信息列表", notes = "只包含被开启的岗位,主要用于前端的下拉选项") + @Operation(summary = "获取岗位精简信息列表", description = "只包含被开启的岗位,主要用于前端的下拉选项") public CommonResult> getSimplePosts() { // 获得岗位列表,只要开启状态的 List list = postService.getPosts(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus())); @@ -79,14 +79,14 @@ public class PostController { } @GetMapping("/page") - @ApiOperation("获得岗位分页列表") + @Operation(summary = "获得岗位分页列表") @PreAuthorize("@ss.hasPermission('system:post:query')") public CommonResult> getPostPage(@Validated PostPageReqVO reqVO) { return success(PostConvert.INSTANCE.convertPage(postService.getPostPage(reqVO))); } @GetMapping("/export") - @ApiOperation("岗位管理") + @Operation(summary = "岗位管理") @PreAuthorize("@ss.hasPermission('system:post:export')") @OperateLog(type = EXPORT) public void export(HttpServletResponse response, @Validated PostExportReqVO reqVO) throws IOException { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptBaseVO.java index 699a27694..c07c45ffc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.Email; @@ -15,31 +14,31 @@ import javax.validation.constraints.Size; @Data public class DeptBaseVO { - @ApiModelProperty(value = "菜单名称", required = true, example = "芋道") + @Schema(title = "菜单名称", required = true, example = "芋道") @NotBlank(message = "部门名称不能为空") @Size(max = 30, message = "部门名称长度不能超过30个字符") private String name; - @ApiModelProperty(value = "父菜单 ID", example = "1024") + @Schema(title = "父菜单 ID", example = "1024") private Long parentId; - @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") + @Schema(title = "显示顺序不能为空", required = true, example = "1024") @NotNull(message = "显示顺序不能为空") private Integer sort; - @ApiModelProperty(value = "负责人的用户编号", example = "2048") + @Schema(title = "负责人的用户编号", example = "2048") private Long leaderUserId; - @ApiModelProperty(value = "联系电话", example = "15601691000") + @Schema(title = "联系电话", example = "15601691000") @Size(max = 11, message = "联系电话长度不能超过11个字符") private String phone; - @ApiModelProperty(value = "邮箱", example = "yudao@iocoder.cn") + @Schema(title = "邮箱", example = "yudao@iocoder.cn") @Email(message = "邮箱格式不正确") @Size(max = 50, message = "邮箱长度不能超过50个字符") private String email; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") // @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") private Integer status; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptCreateReqVO.java index efd6c39a3..8db5621e0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptCreateReqVO.java @@ -1,11 +1,10 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept; - -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 部门创建 Request VO") +@Schema(title = "管理后台 - 部门创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptListReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptListReqVO.java index c4ff55243..75de37bf1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptListReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptListReqVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("管理后台 - 部门列表 Request VO") +@Schema(title = "管理后台 - 部门列表 Request VO") @Data public class DeptListReqVO { - @ApiModelProperty(value = "部门名称", example = "芋道", notes = "模糊匹配") + @Schema(title = "部门名称", example = "芋道", description = "模糊匹配") private String name; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptRespVO.java index a3361cdd6..bbc55e91c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptRespVO.java @@ -1,24 +1,23 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import java.time.LocalDateTime; -@ApiModel("管理后台 - 部门信息 Response VO") +@Schema(title = "管理后台 - 部门信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) public class DeptRespVO extends DeptBaseVO { - @ApiModelProperty(value = "部门编号", required = true, example = "1024") + @Schema(title = "部门编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + @Schema(title = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptSimpleRespVO.java index 1a3d64f6e..ad353fdd8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptSimpleRespVO.java @@ -1,24 +1,23 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel("管理后台 - 部门精简信息 Response VO") +@Schema(title = "管理后台 - 部门精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class DeptSimpleRespVO { - @ApiModelProperty(value = "部门编号", required = true, example = "1024") + @Schema(title = "部门编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "部门名称", required = true, example = "芋道") + @Schema(title = "部门名称", required = true, example = "芋道") private String name; - @ApiModelProperty(value = "父部门 ID", required = true, example = "1024") + @Schema(title = "父部门 ID", required = true, example = "1024") private Long parentId; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptUpdateReqVO.java index 3e2f13a84..ec40b6e7b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptUpdateReqVO.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 部门更新 Request VO") +@Schema(title = "管理后台 - 部门更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DeptUpdateReqVO extends DeptBaseVO { - @ApiModelProperty(value = "部门编号", required = true, example = "1024") + @Schema(title = "部门编号", required = true, example = "1024") @NotNull(message = "部门编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostBaseVO.java index 98c1bf212..2504f21e5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -14,24 +13,24 @@ import javax.validation.constraints.Size; @Data public class PostBaseVO { - @ApiModelProperty(value = "岗位名称", required = true, example = "小博主") + @Schema(title = "岗位名称", required = true, example = "小博主") @NotBlank(message = "岗位名称不能为空") @Size(max = 50, message = "岗位名称长度不能超过50个字符") private String name; - @ApiModelProperty(value = "岗位编码", required = true, example = "yudao") + @Schema(title = "岗位编码", required = true, example = "yudao") @NotBlank(message = "岗位编码不能为空") @Size(max = 64, message = "岗位编码长度不能超过64个字符") private String code; - @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") + @Schema(title = "显示顺序不能为空", required = true, example = "1024") @NotNull(message = "显示顺序不能为空") private Integer sort; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "备注", example = "快乐的备注") + @Schema(title = "备注", example = "快乐的备注") private String remark; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostCreateReqVO.java index 547739c0d..807454840 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostCreateReqVO.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel("管理后台 - 岗位创建 Request VO") +@Schema(title = "管理后台 - 岗位创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class PostCreateReqVO extends PostBaseVO { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostExportReqVO.java index 735bfcce1..9e349ce12 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostExportReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel(value = "管理后台 - 岗位导出 Request VO", description = "参数和 PostExcelVO 是一致的") +@Schema(title = "管理后台 - 岗位导出 Request VO", description = "参数和 PostExcelVO 是一致的") @Data public class PostExportReqVO { - @ApiModelProperty(value = "岗位编码", example = "yudao", notes = "模糊匹配") + @Schema(title = "岗位编码", example = "yudao", description = "模糊匹配") private String code; - @ApiModelProperty(value = "岗位名称", example = "芋道", notes = "模糊匹配") + @Schema(title = "岗位名称", example = "芋道", description = "模糊匹配") private String name; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostListReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostListReqVO.java index 58ba469e1..2450c39ee 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostListReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostListReqVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel("管理后台 - 岗位列表 Request VO") +@Schema(title = "管理后台 - 岗位列表 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class PostListReqVO extends PostBaseVO { - @ApiModelProperty(value = "岗位名称", example = "芋道", notes = "模糊匹配") + @Schema(title = "岗位名称", example = "芋道", description = "模糊匹配") private String name; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostPageReqVO.java index be9ebeab4..3a027ea29 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostPageReqVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel("管理后台 - 岗位分页 Request VO") +@Schema(title = "管理后台 - 岗位分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class PostPageReqVO extends PageParam { - @ApiModelProperty(value = "岗位编码", example = "yudao", notes = "模糊匹配") + @Schema(title = "岗位编码", example = "yudao", description = "模糊匹配") private String code; - @ApiModelProperty(value = "岗位名称", example = "芋道", notes = "模糊匹配") + @Schema(title = "岗位名称", example = "芋道", description = "模糊匹配") private String name; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostRespVO.java index d6aa60d17..acd66af5e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostRespVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import java.time.LocalDateTime; -@ApiModel("管理后台 - 岗位信息 Response VO") +@Schema(title = "管理后台 - 岗位信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) public class PostRespVO extends PostBaseVO { - @ApiModelProperty(value = "岗位序号", required = true, example = "1024") + @Schema(title = "岗位序号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + @Schema(title = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostSimpleRespVO.java index 0334a7652..b94398007 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostSimpleRespVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel("管理后台 - 岗位精简信息 Response VO") +@Schema(title = "管理后台 - 岗位精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class PostSimpleRespVO { - @ApiModelProperty(value = "岗位编号", required = true, example = "1024") + @Schema(title = "岗位编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "岗位名称", required = true, example = "芋道") + @Schema(title = "岗位名称", required = true, example = "芋道") private String name; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostUpdateReqVO.java index aeb91998b..d32c8e8fa 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostUpdateReqVO.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 岗位更新 Request VO") +@Schema(title = "管理后台 - 岗位更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class PostUpdateReqVO extends PostBaseVO { - @ApiModelProperty(value = "岗位编号", required = true, example = "1024") + @Schema(title = "岗位编号", required = true, example = "1024") @NotNull(message = "岗位编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java index 124e5fd05..37793a904 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.*; import cn.iocoder.yudao.module.system.convert.dict.DictDataConvert; import cn.iocoder.yudao.module.system.service.dict.DictDataService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -24,7 +24,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 字典数据") +@Tag(name = "管理后台 - 字典数据") @RestController @RequestMapping("/system/dict-data") @Validated @@ -34,7 +34,7 @@ public class DictDataController { private DictDataService dictDataService; @PostMapping("/create") - @ApiOperation("新增字典数据") + @Operation(summary = "新增字典数据") @PreAuthorize("@ss.hasPermission('system:dict:create')") public CommonResult createDictData(@Valid @RequestBody DictDataCreateReqVO reqVO) { Long dictDataId = dictDataService.createDictData(reqVO); @@ -42,7 +42,7 @@ public class DictDataController { } @PutMapping("update") - @ApiOperation("修改字典数据") + @Operation(summary = "修改字典数据") @PreAuthorize("@ss.hasPermission('system:dict:update')") public CommonResult updateDictData(@Valid @RequestBody DictDataUpdateReqVO reqVO) { dictDataService.updateDictData(reqVO); @@ -50,8 +50,8 @@ public class DictDataController { } @DeleteMapping("/delete") - @ApiOperation("删除字典数据") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除字典数据") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:dict:delete')") public CommonResult deleteDictData(Long id) { dictDataService.deleteDictData(id); @@ -59,7 +59,7 @@ public class DictDataController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地") + @Operation(summary = "获得全部字典数据列表", description = "一般用于管理后台缓存字典数据在本地") // 无需添加权限认证,因为前端全局都需要 public CommonResult> getSimpleDictDatas() { List list = dictDataService.getDictDatas(); @@ -67,22 +67,22 @@ public class DictDataController { } @GetMapping("/page") - @ApiOperation("/获得字典类型的分页列表") + @Operation(summary = "/获得字典类型的分页列表") @PreAuthorize("@ss.hasPermission('system:dict:query')") public CommonResult> getDictTypePage(@Valid DictDataPageReqVO reqVO) { return success(DictDataConvert.INSTANCE.convertPage(dictDataService.getDictDataPage(reqVO))); } @GetMapping(value = "/get") - @ApiOperation("/查询字典数据详细") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "/查询字典数据详细") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:dict:query')") public CommonResult getDictData(@RequestParam("id") Long id) { return success(DictDataConvert.INSTANCE.convert(dictDataService.getDictData(id))); } @GetMapping("/export") - @ApiOperation("导出字典数据") + @Operation(summary = "导出字典数据") @PreAuthorize("@ss.hasPermission('system:dict:export')") @OperateLog(type = EXPORT) public void export(HttpServletResponse response, @Valid DictDataExportReqVO reqVO) throws IOException { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java index e7c9b8894..d78c62e9a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.*; import cn.iocoder.yudao.module.system.convert.dict.DictTypeConvert; import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO; import cn.iocoder.yudao.module.system.service.dict.DictTypeService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -24,7 +24,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 字典类型") +@Tag(name = "管理后台 - 字典类型") @RestController @RequestMapping("/system/dict-type") @Validated @@ -34,7 +34,7 @@ public class DictTypeController { private DictTypeService dictTypeService; @PostMapping("/create") - @ApiOperation("创建字典类型") + @Operation(summary = "创建字典类型") @PreAuthorize("@ss.hasPermission('system:dict:create')") public CommonResult createDictType(@Valid @RequestBody DictTypeCreateReqVO reqVO) { Long dictTypeId = dictTypeService.createDictType(reqVO); @@ -42,7 +42,7 @@ public class DictTypeController { } @PutMapping("/update") - @ApiOperation("修改字典类型") + @Operation(summary = "修改字典类型") @PreAuthorize("@ss.hasPermission('system:dict:update')") public CommonResult updateDictType(@Valid @RequestBody DictTypeUpdateReqVO reqVO) { dictTypeService.updateDictType(reqVO); @@ -50,23 +50,23 @@ public class DictTypeController { } @DeleteMapping("/delete") - @ApiOperation("删除字典类型") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除字典类型") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:dict:delete')") public CommonResult deleteDictType(Long id) { dictTypeService.deleteDictType(id); return success(true); } - @ApiOperation("/获得字典类型的分页列表") + @Operation(summary = "/获得字典类型的分页列表") @GetMapping("/page") @PreAuthorize("@ss.hasPermission('system:dict:query')") public CommonResult> pageDictTypes(@Valid DictTypePageReqVO reqVO) { return success(DictTypeConvert.INSTANCE.convertPage(dictTypeService.getDictTypePage(reqVO))); } - @ApiOperation("/查询字典类型详细") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "/查询字典类型详细") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @GetMapping(value = "/get") @PreAuthorize("@ss.hasPermission('system:dict:query')") public CommonResult getDictType(@RequestParam("id") Long id) { @@ -74,14 +74,14 @@ public class DictTypeController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获得全部字典类型列表", notes = "包括开启 + 禁用的字典类型,主要用于前端的下拉选项") + @Operation(summary = "获得全部字典类型列表", description = "包括开启 + 禁用的字典类型,主要用于前端的下拉选项") // 无需添加权限认证,因为前端全局都需要 public CommonResult> listSimpleDictTypes() { List list = dictTypeService.getDictTypeList(); return success(DictTypeConvert.INSTANCE.convertList(list)); } - @ApiOperation("导出数据类型") + @Operation(summary = "导出数据类型") @GetMapping("/export") @PreAuthorize("@ss.hasPermission('system:dict:query')") @OperateLog(type = EXPORT) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataBaseVO.java index b3e14e8b4..79c32b9a8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -14,36 +14,36 @@ import javax.validation.constraints.Size; @Data public class DictDataBaseVO { - @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") + @Schema(title = "显示顺序不能为空", required = true, example = "1024") @NotNull(message = "显示顺序不能为空") private Integer sort; - @ApiModelProperty(value = "字典标签", required = true, example = "芋道") + @Schema(title = "字典标签", required = true, example = "芋道") @NotBlank(message = "字典标签不能为空") @Size(max = 100, message = "字典标签长度不能超过100个字符") private String label; - @ApiModelProperty(value = "字典值", required = true, example = "iocoder") + @Schema(title = "字典值", required = true, example = "iocoder") @NotBlank(message = "字典键值不能为空") @Size(max = 100, message = "字典键值长度不能超过100个字符") private String value; - @ApiModelProperty(value = "字典类型", required = true, example = "sys_common_sex") + @Schema(title = "字典类型", required = true, example = "sys_common_sex") @NotBlank(message = "字典类型不能为空") @Size(max = 100, message = "字典类型长度不能超过100个字符") private String dictType; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") // @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") private Integer status; - @ApiModelProperty(value = "颜色类型", example = "default", notes = "default、primary、success、info、warning、danger") + @Schema(title = "颜色类型", example = "default", description = "default、primary、success、info、warning、danger") private String colorType; - @ApiModelProperty(value = "css 样式", example = "btn-visible") + @Schema(title = "css 样式", example = "btn-visible") private String cssClass; - @ApiModelProperty(value = "备注", example = "我是一个角色") + @Schema(title = "备注", example = "我是一个角色") private String remark; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataCreateReqVO.java index 57dc770d0..b4fe37ba9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataCreateReqVO.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.data; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel("管理后台 - 字典数据创建 Request VO") +@Schema(title = "管理后台 - 字典数据创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictDataCreateReqVO extends DictDataBaseVO { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataExportReqVO.java index 90290cbdb..94f1a4ffb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataExportReqVO.java @@ -1,24 +1,23 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.Size; -@ApiModel("管理后台 - 字典类型导出 Request VO") +@Schema(title = "管理后台 - 字典类型导出 Request VO") @Data public class DictDataExportReqVO { - @ApiModelProperty(value = "字典标签", example = "芋道") + @Schema(title = "字典标签", example = "芋道") @Size(max = 100, message = "字典标签长度不能超过100个字符") private String label; - @ApiModelProperty(value = "字典类型", example = "sys_common_sex", notes = "模糊匹配") + @Schema(title = "字典类型", example = "sys_common_sex", description = "模糊匹配") @Size(max = 100, message = "字典类型类型长度不能超过100个字符") private String dictType; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataPageReqVO.java index 9df4605df..a883c8048 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataPageReqVO.java @@ -1,27 +1,26 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.data; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.Size; -@ApiModel("管理后台 - 字典类型分页列表 Request VO") +@Schema(title = "管理后台 - 字典类型分页列表 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictDataPageReqVO extends PageParam { - @ApiModelProperty(value = "字典标签", example = "芋道") + @Schema(title = "字典标签", example = "芋道") @Size(max = 100, message = "字典标签长度不能超过100个字符") private String label; - @ApiModelProperty(value = "字典类型", example = "sys_common_sex", notes = "模糊匹配") + @Schema(title = "字典类型", example = "sys_common_sex", description = "模糊匹配") @Size(max = 100, message = "字典类型类型长度不能超过100个字符") private String dictType; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataRespVO.java index 3cf1177d1..72cb23cf7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -9,17 +8,17 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@ApiModel("管理后台 - 字典数据信息 Response VO") +@Schema(title = "管理后台 - 字典数据信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class DictDataRespVO extends DictDataBaseVO { - @ApiModelProperty(value = "字典数据编号", required = true, example = "1024") + @Schema(title = "字典数据编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + @Schema(title = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataSimpleRespVO.java index 4ea0c5f9b..d61458446 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataSimpleRespVO.java @@ -1,25 +1,24 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("管理后台 - 数据字典精简 Response VO") +@Schema(title = "管理后台 - 数据字典精简 Response VO") @Data public class DictDataSimpleRespVO { - @ApiModelProperty(value = "字典类型", required = true, example = "gender") + @Schema(title = "字典类型", required = true, example = "gender") private String dictType; - @ApiModelProperty(value = "字典键值", required = true, example = "1") + @Schema(title = "字典键值", required = true, example = "1") private String value; - @ApiModelProperty(value = "字典标签", required = true, example = "男") + @Schema(title = "字典标签", required = true, example = "男") private String label; - @ApiModelProperty(value = "颜色类型", example = "default", notes = "default、primary、success、info、warning、danger") + @Schema(title = "颜色类型", example = "default", description = "default、primary、success、info、warning、danger") private String colorType; - @ApiModelProperty(value = "css 样式", example = "btn-visible") + @Schema(title = "css 样式", example = "btn-visible") private String cssClass; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataUpdateReqVO.java index f6f9b81a2..9481ab1b4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataUpdateReqVO.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 字典数据更新 Request VO") +@Schema(title = "管理后台 - 字典数据更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictDataUpdateReqVO extends DictDataBaseVO { - @ApiModelProperty(value = "字典数据编号", required = true, example = "1024") + @Schema(title = "字典数据编号", required = true, example = "1024") @NotNull(message = "字典数据编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeBaseVO.java index 4da6da0b3..d4e28e043 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.type; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -14,16 +14,16 @@ import javax.validation.constraints.Size; @Data public class DictTypeBaseVO { - @ApiModelProperty(value = "字典名称", required = true, example = "性别") + @Schema(title = "字典名称", required = true, example = "性别") @NotBlank(message = "字典名称不能为空") @Size(max = 100, message = "字典类型名称长度不能超过100个字符") private String name; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") @NotNull(message = "状态不能为空") private Integer status; - @ApiModelProperty(value = "备注", example = "快乐的备注") + @Schema(title = "备注", example = "快乐的备注") private String remark; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeCreateReqVO.java index ee2f45ae1..f7c158503 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeCreateReqVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.type; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; -@ApiModel("管理后台 - 字典类型创建 Request VO") +@Schema(title = "管理后台 - 字典类型创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictTypeCreateReqVO extends DictTypeBaseVO { - @ApiModelProperty(value = "字典类型", required = true, example = "sys_common_sex") + @Schema(title = "字典类型", required = true, example = "sys_common_sex") @NotNull(message = "字典类型不能为空") @Size(max = 100, message = "字典类型类型长度不能超过100个字符") private String type; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeExportReqVO.java index 4a54fb3fc..73d7093e6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.type; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,21 +8,21 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 字典类型分页列表 Request VO") +@Schema(title = "管理后台 - 字典类型分页列表 Request VO") @Data public class DictTypeExportReqVO { - @ApiModelProperty(value = "字典类型名称", example = "芋道", notes = "模糊匹配") + @Schema(title = "字典类型名称", example = "芋道", description = "模糊匹配") private String name; - @ApiModelProperty(value = "字典类型", example = "sys_common_sex", notes = "模糊匹配") + @Schema(title = "字典类型", example = "sys_common_sex", description = "模糊匹配") private String type; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypePageReqVO.java index f32886196..1c7b48a91 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.type; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.format.annotation.DateTimeFormat; @@ -12,23 +11,23 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 字典类型分页列表 Request VO") +@Schema(title = "管理后台 - 字典类型分页列表 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictTypePageReqVO extends PageParam { - @ApiModelProperty(value = "字典类型名称", example = "芋道", notes = "模糊匹配") + @Schema(title = "字典类型名称", example = "芋道", description = "模糊匹配") private String name; - @ApiModelProperty(value = "字典类型", example = "sys_common_sex", notes = "模糊匹配") + @Schema(title = "字典类型", example = "sys_common_sex", description = "模糊匹配") @Size(max = 100, message = "字典类型类型长度不能超过100个字符") private String type; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeRespVO.java index c508df6af..cb39b1acf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.type; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -9,20 +8,20 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@ApiModel("管理后台 - 字典类型信息 Response VO") +@Schema(title = "管理后台 - 字典类型信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class DictTypeRespVO extends DictTypeBaseVO { - @ApiModelProperty(value = "字典类型编号", required = true, example = "1024") + @Schema(title = "字典类型编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "字典类型", required = true, example = "sys_common_sex") + @Schema(title = "字典类型", required = true, example = "sys_common_sex") private String type; - @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + @Schema(title = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeSimpleRespVO.java index 8cca026a9..b68f5ebf1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeSimpleRespVO.java @@ -1,24 +1,23 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.type; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel("管理后台 - 字典类型精简信息 Response VO") +@Schema(title = "管理后台 - 字典类型精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class DictTypeSimpleRespVO { - @ApiModelProperty(value = "字典类型编号", required = true, example = "1024") + @Schema(title = "字典类型编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "字典类型名称", required = true, example = "芋道") + @Schema(title = "字典类型名称", required = true, example = "芋道") private String name; - @ApiModelProperty(value = "字典类型", required = true, example = "sys_common_sex") + @Schema(title = "字典类型", required = true, example = "sys_common_sex") private String type; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeUpdateReqVO.java index 00955f4fe..579108d23 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeUpdateReqVO.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.type; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 字典类型更新 Request VO") +@Schema(title = "管理后台 - 字典类型更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictTypeUpdateReqVO extends DictTypeBaseVO { - @ApiModelProperty(value = "字典类型编号", required = true, example = "1024") + @Schema(title = "字典类型编号", required = true, example = "1024") @NotNull(message = "字典类型编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/ErrorCodeController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/ErrorCodeController.java index e3161b8aa..90879472b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/ErrorCodeController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/ErrorCodeController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.module.system.convert.errorcode.ErrorCodeConvert; import cn.iocoder.yudao.module.system.controller.admin.errorcode.vo.*; import cn.iocoder.yudao.module.system.dal.dataobject.errorcode.ErrorCodeDO; import cn.iocoder.yudao.module.system.service.errorcode.ErrorCodeService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -24,7 +24,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 错误码") +@Tag(name = "管理后台 - 错误码") @RestController @RequestMapping("/system/error-code") @Validated @@ -34,14 +34,14 @@ public class ErrorCodeController { private ErrorCodeService errorCodeService; @PostMapping("/create") - @ApiOperation("创建错误码") + @Operation(summary = "创建错误码") @PreAuthorize("@ss.hasPermission('system:error-code:create')") public CommonResult createErrorCode(@Valid @RequestBody ErrorCodeCreateReqVO createReqVO) { return success(errorCodeService.createErrorCode(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新错误码") + @Operation(summary = "更新错误码") @PreAuthorize("@ss.hasPermission('system:error-code:update')") public CommonResult updateErrorCode(@Valid @RequestBody ErrorCodeUpdateReqVO updateReqVO) { errorCodeService.updateErrorCode(updateReqVO); @@ -49,8 +49,8 @@ public class ErrorCodeController { } @DeleteMapping("/delete") - @ApiOperation("删除错误码") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除错误码") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('system:error-code:delete')") public CommonResult deleteErrorCode(@RequestParam("id") Long id) { errorCodeService.deleteErrorCode(id); @@ -58,8 +58,8 @@ public class ErrorCodeController { } @GetMapping("/get") - @ApiOperation("获得错误码") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得错误码") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:error-code:query')") public CommonResult getErrorCode(@RequestParam("id") Long id) { ErrorCodeDO errorCode = errorCodeService.getErrorCode(id); @@ -67,7 +67,7 @@ public class ErrorCodeController { } @GetMapping("/page") - @ApiOperation("获得错误码分页") + @Operation(summary = "获得错误码分页") @PreAuthorize("@ss.hasPermission('system:error-code:query')") public CommonResult> getErrorCodePage(@Valid ErrorCodePageReqVO pageVO) { PageResult pageResult = errorCodeService.getErrorCodePage(pageVO); @@ -75,7 +75,7 @@ public class ErrorCodeController { } @GetMapping("/export-excel") - @ApiOperation("导出错误码 Excel") + @Operation(summary = "导出错误码 Excel") @PreAuthorize("@ss.hasPermission('system:error-code:export')") @OperateLog(type = EXPORT) public void exportErrorCodeExcel(@Valid ErrorCodeExportReqVO exportReqVO, diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeBaseVO.java index 150401aa3..ac5c7445f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.errorcode.vo; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -12,19 +12,19 @@ import javax.validation.constraints.NotNull; @Data public class ErrorCodeBaseVO { - @ApiModelProperty(value = "应用名", required = true, example = "dashboard") + @Schema(title = "应用名", required = true, example = "dashboard") @NotNull(message = "应用名不能为空") private String applicationName; - @ApiModelProperty(value = "错误码编码", required = true, example = "1234") + @Schema(title = "错误码编码", required = true, example = "1234") @NotNull(message = "错误码编码不能为空") private Integer code; - @ApiModelProperty(value = "错误码错误提示", required = true, example = "帅气") + @Schema(title = "错误码错误提示", required = true, example = "帅气") @NotNull(message = "错误码错误提示不能为空") private String message; - @ApiModelProperty(value = "备注", example = "哈哈哈") + @Schema(title = "备注", example = "哈哈哈") private String memo; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeCreateReqVO.java index a0f36af1a..7d85826d1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeCreateReqVO.java @@ -1,11 +1,11 @@ package cn.iocoder.yudao.module.system.controller.admin.errorcode.vo; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 错误码创建 Request VO") +@Schema(title = "管理后台 - 错误码创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeExportReqVO.java index e44858160..90f5e739a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.errorcode.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,24 +8,24 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 错误码 Excel 导出 Request VO", description = "参数和 InfErrorCodePageReqVO 是一致的") +@Schema(title = "管理后台 - 错误码 Excel 导出 Request VO", description = "参数和 InfErrorCodePageReqVO 是一致的") @Data public class ErrorCodeExportReqVO { - @ApiModelProperty(value = "错误码类型", example = "1") + @Schema(title = "错误码类型", example = "1") private Integer type; - @ApiModelProperty(value = "应用名", example = "dashboard") + @Schema(title = "应用名", example = "dashboard") private String applicationName; - @ApiModelProperty(value = "错误码编码", example = "1234") + @Schema(title = "错误码编码", example = "1234") private Integer code; - @ApiModelProperty(value = "错误码错误提示", example = "帅气") + @Schema(title = "错误码错误提示", example = "帅气") private String message; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodePageReqVO.java index 8c719006c..baeb1e203 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.errorcode.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,26 +11,26 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 错误码分页 Request VO") +@Schema(title = "管理后台 - 错误码分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ErrorCodePageReqVO extends PageParam { - @ApiModelProperty(value = "错误码类型", example = "1", notes = "参见 ErrorCodeTypeEnum 枚举类") + @Schema(title = "错误码类型", example = "1", description = "参见 ErrorCodeTypeEnum 枚举类") private Integer type; - @ApiModelProperty(value = "应用名", example = "dashboard") + @Schema(title = "应用名", example = "dashboard") private String applicationName; - @ApiModelProperty(value = "错误码编码", example = "1234") + @Schema(title = "错误码编码", example = "1234") private Integer code; - @ApiModelProperty(value = "错误码错误提示", example = "帅气") + @Schema(title = "错误码错误提示", example = "帅气") private String message; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeRespVO.java index 47276517c..35712ad76 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeRespVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.system.controller.admin.errorcode.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 错误码 Response VO") +@Schema(title = "管理后台 - 错误码 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ErrorCodeRespVO extends ErrorCodeBaseVO { - @ApiModelProperty(value = "错误码编号", required = true, example = "1024") + @Schema(title = "错误码编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "错误码类型", required = true, example = "1", notes = "参见 ErrorCodeTypeEnum 枚举类") + @Schema(title = "错误码类型", required = true, example = "1", description = "参见 ErrorCodeTypeEnum 枚举类") private Integer type; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeUpdateReqVO.java index ff16c0283..cb0bb2055 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.errorcode.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 错误码更新 Request VO") +@Schema(title = "管理后台 - 错误码更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ErrorCodeUpdateReqVO extends ErrorCodeBaseVO { - @ApiModelProperty(value = "错误码编号", required = true, example = "1024") + @Schema(title = "错误码编号", required = true, example = "1024") @NotNull(message = "错误码编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/LoginLogController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/LoginLogController.java index 7cb3ac4b7..f5262697a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/LoginLogController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/LoginLogController.java @@ -11,8 +11,8 @@ import cn.iocoder.yudao.module.system.controller.admin.logger.vo.loginlog.LoginL import cn.iocoder.yudao.module.system.controller.admin.logger.vo.loginlog.LoginLogRespVO; import cn.iocoder.yudao.module.system.convert.logger.LoginLogConvert; import cn.iocoder.yudao.module.system.service.logger.LoginLogService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -27,7 +27,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 登录日志") +@Tag(name = "管理后台 - 登录日志") @RestController @RequestMapping("/system/login-log") @Validated @@ -37,7 +37,7 @@ public class LoginLogController { private LoginLogService loginLogService; @GetMapping("/page") - @ApiOperation("获得登录日志分页列表") + @Operation(summary = "获得登录日志分页列表") @PreAuthorize("@ss.hasPermission('system:login-log:query')") public CommonResult> getLoginLogPage(@Valid LoginLogPageReqVO reqVO) { PageResult page = loginLogService.getLoginLogPage(reqVO); @@ -45,7 +45,7 @@ public class LoginLogController { } @GetMapping("/export") - @ApiOperation("导出登录日志 Excel") + @Operation(summary = "导出登录日志 Excel") @PreAuthorize("@ss.hasPermission('system:login-log:export')") @OperateLog(type = EXPORT) public void exportLoginLog(HttpServletResponse response, @Valid LoginLogExportReqVO reqVO) throws IOException { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java index d23477eb8..c794f0ca8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java @@ -15,8 +15,8 @@ import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.system.service.user.AdminUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -35,7 +35,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 操作日志") +@Tag(name = "管理后台 - 操作日志") @RestController @RequestMapping("/system/operate-log") @Validated @@ -47,7 +47,7 @@ public class OperateLogController { private AdminUserService userService; @GetMapping("/page") - @ApiOperation("查看操作日志分页列表") + @Operation(summary = "查看操作日志分页列表") @PreAuthorize("@ss.hasPermission('system:operate-log:query')") public CommonResult> pageOperateLog(@Valid OperateLogPageReqVO reqVO) { PageResult pageResult = operateLogService.getOperateLogPage(reqVO); @@ -66,7 +66,7 @@ public class OperateLogController { return success(new PageResult<>(list, pageResult.getTotal())); } - @ApiOperation("导出操作日志") + @Operation(summary = "导出操作日志") @GetMapping("/export") @PreAuthorize("@ss.hasPermission('system:operate-log:export')") @OperateLog(type = EXPORT) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogBaseVO.java index 4b5cc22bf..0e749c544 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.loginlog; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -15,28 +15,28 @@ import javax.validation.constraints.Size; @Data public class LoginLogBaseVO { - @ApiModelProperty(value = "日志类型", required = true, example = "1", notes = "参见 LoginLogTypeEnum 枚举类") + @Schema(title = "日志类型", required = true, example = "1", description = "参见 LoginLogTypeEnum 枚举类") @NotNull(message = "日志类型不能为空") private Integer logType; - @ApiModelProperty(value = "链路追踪编号", example = "89aca178-a370-411c-ae02-3f0d672be4ab") + @Schema(title = "链路追踪编号", example = "89aca178-a370-411c-ae02-3f0d672be4ab") @NotEmpty(message = "链路追踪编号不能为空") private String traceId; - @ApiModelProperty(value = "用户账号", required = true, example = "yudao") + @Schema(title = "用户账号", required = true, example = "yudao") @NotBlank(message = "用户账号不能为空") @Size(max = 30, message = "用户账号长度不能超过30个字符") private String username; - @ApiModelProperty(value = "登录结果", required = true, example = "1", notes = "参见 LoginResultEnum 枚举类") + @Schema(title = "登录结果", required = true, example = "1", description = "参见 LoginResultEnum 枚举类") @NotNull(message = "登录结果不能为空") private Integer result; - @ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1") + @Schema(title = "用户 IP", required = true, example = "127.0.0.1") @NotEmpty(message = "用户 IP 不能为空") private String userIp; - @ApiModelProperty(value = "浏览器 UserAgent", example = "Mozilla/5.0") + @Schema(title = "浏览器 UserAgent", example = "Mozilla/5.0") private String userAgent; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogExportReqVO.java index 50f36edb3..c95be8148 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.loginlog; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,20 +8,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 登录日志分页列表 Request VO") +@Schema(title = "管理后台 - 登录日志分页列表 Request VO") @Data public class LoginLogExportReqVO { - @ApiModelProperty(value = "用户 IP", example = "127.0.0.1", notes = "模拟匹配") + @Schema(title = "用户 IP", example = "127.0.0.1", description = "模拟匹配") private String userIp; - @ApiModelProperty(value = "用户账号", example = "芋道", notes = "模拟匹配") + @Schema(title = "用户账号", example = "芋道", description = "模拟匹配") private String username; - @ApiModelProperty(value = "操作状态", example = "true") + @Schema(title = "操作状态", example = "true") private Boolean status; - @ApiModelProperty(value = "登录时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "登录时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogPageReqVO.java index 51ed062e8..1767fd298 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.loginlog; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.format.annotation.DateTimeFormat; @@ -11,21 +10,21 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 登录日志分页列表 Request VO") +@Schema(title = "管理后台 - 登录日志分页列表 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class LoginLogPageReqVO extends PageParam { - @ApiModelProperty(value = "用户 IP", example = "127.0.0.1", notes = "模拟匹配") + @Schema(title = "用户 IP", example = "127.0.0.1", description = "模拟匹配") private String userIp; - @ApiModelProperty(value = "用户账号", example = "芋道", notes = "模拟匹配") + @Schema(title = "用户账号", example = "芋道", description = "模拟匹配") private String username; - @ApiModelProperty(value = "操作状态", example = "true") + @Schema(title = "操作状态", example = "true") private Boolean status; - @ApiModelProperty(value = "登录时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "登录时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogRespVO.java index 4eb121c02..4c57e0d59 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.loginlog; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,23 +8,23 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@ApiModel("管理后台 - 登录日志 Response VO") +@Schema(title = "管理后台 - 登录日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class LoginLogRespVO extends LoginLogBaseVO { - @ApiModelProperty(value = "日志编号", required = true, example = "1024") + @Schema(title = "日志编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "用户编号", example = "666") + @Schema(title = "用户编号", example = "666") private Long userId; - @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举") + @Schema(title = "用户类型", required = true, example = "2", description = "参见 UserTypeEnum 枚举") @NotNull(message = "用户类型不能为空") private Integer userType; - @ApiModelProperty(value = "登录时间", required = true) + @Schema(title = "登录时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogBaseVO.java index abaf41247..e36da5c07 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -15,71 +15,71 @@ import java.util.Map; @Data public class OperateLogBaseVO { - @ApiModelProperty(value = "链路追踪编号", required = true, example = "89aca178-a370-411c-ae02-3f0d672be4ab") + @Schema(title = "链路追踪编号", required = true, example = "89aca178-a370-411c-ae02-3f0d672be4ab") @NotEmpty(message = "链路追踪编号不能为空") private String traceId; - @ApiModelProperty(value = "用户编号", required = true, example = "1024") + @Schema(title = "用户编号", required = true, example = "1024") @NotNull(message = "用户编号不能为空") private Long userId; - @ApiModelProperty(value = "操作模块", required = true, example = "订单") + @Schema(title = "操作模块", required = true, example = "订单") @NotEmpty(message = "操作模块不能为空") private String module; - @ApiModelProperty(value = "操作名", required = true, example = "创建订单") + @Schema(title = "操作名", required = true, example = "创建订单") @NotEmpty(message = "操作名") private String name; - @ApiModelProperty(value = "操作分类", required = true, example = "1", notes = "参见 OperateLogTypeEnum 枚举类") + @Schema(title = "操作分类", required = true, example = "1", description = "参见 OperateLogTypeEnum 枚举类") @NotNull(message = "操作分类不能为空") private Integer type; - @ApiModelProperty(value = "操作明细", example = "修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。") + @Schema(title = "操作明细", example = "修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。") private String content; - @ApiModelProperty(value = "拓展字段", example = "{'orderId': 1}") + @Schema(title = "拓展字段", example = "{'orderId': 1}") private Map exts; - @ApiModelProperty(value = "请求方法名", required = true, example = "GET") + @Schema(title = "请求方法名", required = true, example = "GET") @NotEmpty(message = "请求方法名不能为空") private String requestMethod; - @ApiModelProperty(value = "请求地址", required = true, example = "/xxx/yyy") + @Schema(title = "请求地址", required = true, example = "/xxx/yyy") @NotEmpty(message = "请求地址不能为空") private String requestUrl; - @ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1") + @Schema(title = "用户 IP", required = true, example = "127.0.0.1") @NotEmpty(message = "用户 IP 不能为空") private String userIp; - @ApiModelProperty(value = "浏览器 UserAgent", required = true, example = "Mozilla/5.0") + @Schema(title = "浏览器 UserAgent", required = true, example = "Mozilla/5.0") @NotEmpty(message = "浏览器 UserAgent 不能为空") private String userAgent; - @ApiModelProperty(value = "Java 方法名", required = true, example = "cn.iocoder.yudao.adminserver.UserController.save(...)") + @Schema(title = "Java 方法名", required = true, example = "cn.iocoder.yudao.adminserver.UserController.save(...)") @NotEmpty(message = "Java 方法名不能为空") private String javaMethod; - @ApiModelProperty(value = "Java 方法的参数") + @Schema(title = "Java 方法的参数") private String javaMethodArgs; - @ApiModelProperty(value = "开始时间", required = true) + @Schema(title = "开始时间", required = true) @NotNull(message = "开始时间不能为空") private LocalDateTime startTime; - @ApiModelProperty(value = "执行时长,单位:毫秒", required = true) + @Schema(title = "执行时长,单位:毫秒", required = true) @NotNull(message = "执行时长不能为空") private Integer duration; - @ApiModelProperty(value = "结果码", required = true) + @Schema(title = "结果码", required = true) @NotNull(message = "结果码不能为空") private Integer resultCode; - @ApiModelProperty(value = "结果提示") + @Schema(title = "结果提示") private String resultMsg; - @ApiModelProperty(value = "结果数据") + @Schema(title = "结果数据") private String resultData; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogExportReqVO.java index 254681250..c323b2cb6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,23 +8,23 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 操作日志分页列表 Request VO") +@Schema(title = "管理后台 - 操作日志分页列表 Request VO") @Data public class OperateLogExportReqVO { - @ApiModelProperty(value = "操作模块", example = "订单", notes = "模拟匹配") + @Schema(title = "操作模块", example = "订单", description = "模拟匹配") private String module; - @ApiModelProperty(value = "用户昵称", example = "芋道", notes = "模拟匹配") + @Schema(title = "用户昵称", example = "芋道", description = "模拟匹配") private String userNickname; - @ApiModelProperty(value = "操作分类", example = "1", notes = "参见 OperateLogTypeEnum 枚举类") + @Schema(title = "操作分类", example = "1", description = "参见 OperateLogTypeEnum 枚举类") private Integer type; - @ApiModelProperty(value = "操作状态", example = "true") + @Schema(title = "操作状态", example = "true") private Boolean success; - @ApiModelProperty(value = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] startTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogPageReqVO.java index 9fa6fed66..c6eed986e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -10,23 +9,23 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 操作日志分页列表 Request VO") +@Schema(title = "管理后台 - 操作日志分页列表 Request VO") @Data public class OperateLogPageReqVO extends PageParam { - @ApiModelProperty(value = "操作模块", example = "订单", notes = "模拟匹配") + @Schema(title = "操作模块", example = "订单", description = "模拟匹配") private String module; - @ApiModelProperty(value = "用户昵称", example = "芋道", notes = "模拟匹配") + @Schema(title = "用户昵称", example = "芋道", description = "模拟匹配") private String userNickname; - @ApiModelProperty(value = "操作分类", example = "1", notes = "参见 OperateLogTypeEnum 枚举类") + @Schema(title = "操作分类", example = "1", description = "参见 OperateLogTypeEnum 枚举类") private Integer type; - @ApiModelProperty(value = "操作状态", example = "true") + @Schema(title = "操作状态", example = "true") private Boolean success; - @ApiModelProperty(value = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] startTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogRespVO.java index 445b40060..139f1b20e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogRespVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 操作日志 Response VO") +@Schema(title = "管理后台 - 操作日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class OperateLogRespVO extends OperateLogBaseVO { - @ApiModelProperty(value = "日志编号", required = true, example = "1024") + @Schema(title = "日志编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") + @Schema(title = "用户昵称", required = true, example = "芋艿") private String userNickname; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java index d14cfb733..7143b934e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java @@ -8,9 +8,10 @@ import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeRespVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeUpdateReqVO; import cn.iocoder.yudao.module.system.convert.notice.NoticeConvert; import cn.iocoder.yudao.module.system.service.notice.NoticeService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +21,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 通知公告") +@Tag(name = "管理后台 - 通知公告") @RestController @RequestMapping("/system/notice") @Validated @@ -30,7 +31,7 @@ public class NoticeController { private NoticeService noticeService; @PostMapping("/create") - @ApiOperation("创建通知公告") + @Operation(summary = "创建通知公告") @PreAuthorize("@ss.hasPermission('system:notice:create')") public CommonResult createNotice(@Valid @RequestBody NoticeCreateReqVO reqVO) { Long noticeId = noticeService.createNotice(reqVO); @@ -38,7 +39,7 @@ public class NoticeController { } @PutMapping("/update") - @ApiOperation("修改通知公告") + @Operation(summary = "修改通知公告") @PreAuthorize("@ss.hasPermission('system:notice:update')") public CommonResult updateNotice(@Valid @RequestBody NoticeUpdateReqVO reqVO) { noticeService.updateNotice(reqVO); @@ -46,8 +47,8 @@ public class NoticeController { } @DeleteMapping("/delete") - @ApiOperation("删除通知公告") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除通知公告") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:notice:delete')") public CommonResult deleteNotice(@RequestParam("id") Long id) { noticeService.deleteNotice(id); @@ -55,15 +56,15 @@ public class NoticeController { } @GetMapping("/page") - @ApiOperation("获取通知公告列表") + @Operation(summary = "获取通知公告列表") @PreAuthorize("@ss.hasPermission('system:notice:query')") public CommonResult> pageNotices(@Validated NoticePageReqVO reqVO) { return success(NoticeConvert.INSTANCE.convertPage(noticeService.pageNotices(reqVO))); } @GetMapping("/get") - @ApiOperation("获得通知公告") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得通知公告") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:notice:query')") public CommonResult getNotice(@RequestParam("id") Long id) { return success(NoticeConvert.INSTANCE.convert(noticeService.getNotice(id))); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeBaseVO.java index 43cacd1d5..218812656 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.notice.vo; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -14,19 +14,19 @@ import javax.validation.constraints.Size; @Data public class NoticeBaseVO { - @ApiModelProperty(value = "公告标题", required = true, example = "小博主") + @Schema(title = "公告标题", required = true, example = "小博主") @NotBlank(message = "公告标题不能为空") @Size(max = 50, message = "公告标题不能超过50个字符") private String title; - @ApiModelProperty(value = "公告类型", required = true, example = "小博主") + @Schema(title = "公告类型", required = true, example = "小博主") @NotNull(message = "公告类型不能为空") private Integer type; - @ApiModelProperty(value = "公告内容", required = true, example = "半生编码") + @Schema(title = "公告内容", required = true, example = "半生编码") private String content; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeCreateReqVO.java index 49e671ce1..ceb834306 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeCreateReqVO.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.module.system.controller.admin.notice.vo; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel("管理后台 - 通知公告创建 Request VO") +@Schema(title = "管理后台 - 通知公告创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class NoticeCreateReqVO extends NoticeBaseVO { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticePageReqVO.java index ba1287c47..1939e288e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticePageReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.notice.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel("管理后台 - 通知公告分页 Request VO") +@Schema(title = "管理后台 - 通知公告分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class NoticePageReqVO extends PageParam { - @ApiModelProperty(value = "通知公告名称", example = "芋道", notes = "模糊匹配") + @Schema(title = "通知公告名称", example = "芋道", description = "模糊匹配") private String title; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeRespVO.java index bfa986b04..0e84852d0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeRespVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.system.controller.admin.notice.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import java.time.LocalDateTime; -@ApiModel("管理后台 - 通知公告信息 Response VO") +@Schema(title = "管理后台 - 通知公告信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) public class NoticeRespVO extends NoticeBaseVO { - @ApiModelProperty(value = "通知公告序号", required = true, example = "1024") + @Schema(title = "通知公告序号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + @Schema(title = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeUpdateReqVO.java index 30f4a3720..89f80173d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeUpdateReqVO.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.system.controller.admin.notice.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 岗位公告更新 Request VO") +@Schema(title = "管理后台 - 岗位公告更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class NoticeUpdateReqVO extends NoticeBaseVO { - @ApiModelProperty(value = "岗位公告编号", required = true, example = "1024") + @Schema(title = "岗位公告编号", required = true, example = "1024") @NotNull(message = "岗位公告编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2ClientController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2ClientController.java index d6b927857..358f94678 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2ClientController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2ClientController.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2Cl import cn.iocoder.yudao.module.system.convert.auth.OAuth2ClientConvert; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO; import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -21,7 +21,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - OAuth2 客户端") +@Tag(name = "管理后台 - OAuth2 客户端") @RestController @RequestMapping("/system/oauth2-client") @Validated @@ -31,14 +31,14 @@ public class OAuth2ClientController { private OAuth2ClientService oAuth2ClientService; @PostMapping("/create") - @ApiOperation("创建 OAuth2 客户端") + @Operation(summary = "创建 OAuth2 客户端") @PreAuthorize("@ss.hasPermission('system:oauth2-client:create')") public CommonResult createOAuth2Client(@Valid @RequestBody OAuth2ClientCreateReqVO createReqVO) { return success(oAuth2ClientService.createOAuth2Client(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新 OAuth2 客户端") + @Operation(summary = "更新 OAuth2 客户端") @PreAuthorize("@ss.hasPermission('system:oauth2-client:update')") public CommonResult updateOAuth2Client(@Valid @RequestBody OAuth2ClientUpdateReqVO updateReqVO) { oAuth2ClientService.updateOAuth2Client(updateReqVO); @@ -46,8 +46,8 @@ public class OAuth2ClientController { } @DeleteMapping("/delete") - @ApiOperation("删除 OAuth2 客户端") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除 OAuth2 客户端") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('system:oauth2-client:delete')") public CommonResult deleteOAuth2Client(@RequestParam("id") Long id) { oAuth2ClientService.deleteOAuth2Client(id); @@ -55,8 +55,8 @@ public class OAuth2ClientController { } @GetMapping("/get") - @ApiOperation("获得 OAuth2 客户端") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得 OAuth2 客户端") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:oauth2-client:query')") public CommonResult getOAuth2Client(@RequestParam("id") Long id) { OAuth2ClientDO oAuth2Client = oAuth2ClientService.getOAuth2Client(id); @@ -64,7 +64,7 @@ public class OAuth2ClientController { } @GetMapping("/page") - @ApiOperation("获得OAuth2 客户端分页") + @Operation(summary = "获得OAuth2 客户端分页") @PreAuthorize("@ss.hasPermission('system:oauth2-client:query')") public CommonResult> getOAuth2ClientPage(@Valid OAuth2ClientPageReqVO pageVO) { PageResult pageResult = oAuth2ClientService.getOAuth2ClientPage(pageVO); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java index 608f5341a..2ff359235 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java @@ -22,10 +22,10 @@ import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService; import cn.iocoder.yudao.module.system.service.oauth2.OAuth2GrantService; import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService; import cn.iocoder.yudao.module.system.util.oauth2.OAuth2Utils; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -55,7 +55,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti * * @author 芋道源码 */ -@Api(tags = "管理后台 - OAuth2.0 授权") +@Tag(name = "管理后台 - OAuth2.0 授权") @RestController @RequestMapping("/system/oauth2") @Validated @@ -84,16 +84,16 @@ public class OAuth2OpenController { */ @PostMapping("/token") @PermitAll - @ApiOperation(value = "获得访问令牌", notes = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用") - @ApiImplicitParams({ - @ApiImplicitParam(name = "grant_type", required = true, value = "授权类型", example = "code", dataTypeClass = String.class), - @ApiImplicitParam(name = "code", value = "授权范围", example = "userinfo.read", dataTypeClass = String.class), - @ApiImplicitParam(name = "redirect_uri", value = "重定向 URI", example = "https://www.iocoder.cn", dataTypeClass = String.class), - @ApiImplicitParam(name = "state", value = "状态", example = "1", dataTypeClass = String.class), - @ApiImplicitParam(name = "username", example = "tudou", dataTypeClass = String.class), - @ApiImplicitParam(name = "password", example = "cai", dataTypeClass = String.class), // 多个使用空格分隔 - @ApiImplicitParam(name = "scope", example = "user_info", dataTypeClass = String.class), - @ApiImplicitParam(name = "refresh_token", example = "123424233", dataTypeClass = String.class), + @Operation(summary = "获得访问令牌", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用") + @Parameters({ + @Parameter(name = "grant_type", required = true, description = "授权类型", example = "code"), + @Parameter(name = "code", description = "授权范围", example = "userinfo.read"), + @Parameter(name = "redirect_uri", description = "重定向 URI", example = "https://www.iocoder.cn"), + @Parameter(name = "state", description = "状态", example = "1"), + @Parameter(name = "username", example = "tudou"), + @Parameter(name = "password", example = "cai"), // 多个使用空格分隔 + @Parameter(name = "scope", example = "user_info"), + @Parameter(name = "refresh_token", example = "123424233"), }) @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult postAccessToken(HttpServletRequest request, @@ -144,8 +144,8 @@ public class OAuth2OpenController { @DeleteMapping("/token") @PermitAll - @ApiOperation(value = "删除访问令牌") - @ApiImplicitParam(name = "token", required = true, value = "访问令牌", example = "biu", dataTypeClass = String.class) + @Operation(summary = "删除访问令牌") + @Parameter(name = "token", required = true, description = "访问令牌", example = "biu") @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult revokeToken(HttpServletRequest request, @RequestParam("token") String token) { @@ -163,8 +163,8 @@ public class OAuth2OpenController { */ @PostMapping("/check-token") @PermitAll - @ApiOperation(value = "校验访问令牌") - @ApiImplicitParam(name = "token", required = true, value = "访问令牌", example = "biu", dataTypeClass = String.class) + @Operation(summary = "校验访问令牌") + @Parameter(name = "token", required = true, description = "访问令牌", example = "biu") @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult checkToken(HttpServletRequest request, @RequestParam("token") String token) { @@ -183,8 +183,8 @@ public class OAuth2OpenController { * 对应 Spring Security OAuth 的 AuthorizationEndpoint 类的 authorize 方法 */ @GetMapping("/authorize") - @ApiOperation(value = "获得授权信息", notes = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用") - @ApiImplicitParam(name = "clientId", required = true, value = "客户端编号", example = "tudou", dataTypeClass = String.class) + @Operation(summary = "获得授权信息", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用") + @Parameter(name = "clientId", required = true, description = "客户端编号", example = "tudou") public CommonResult authorize(@RequestParam("clientId") String clientId) { // 0. 校验用户已经登录。通过 Spring Security 实现 @@ -207,14 +207,14 @@ public class OAuth2OpenController { * 因为前后端分离,Axios 无法很好的处理 302 重定向,所以和 Spring Security OAuth 略有不同,返回结果是重定向的 URL,剩余交给前端处理 */ @PostMapping("/authorize") - @ApiOperation(value = "申请授权", notes = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【提交】调用") - @ApiImplicitParams({ - @ApiImplicitParam(name = "response_type", required = true, value = "响应类型", example = "code", dataTypeClass = String.class), - @ApiImplicitParam(name = "client_id", required = true, value = "客户端编号", example = "tudou", dataTypeClass = String.class), - @ApiImplicitParam(name = "scope", value = "授权范围", example = "userinfo.read", dataTypeClass = String.class), // 使用 Map 格式,Spring MVC 暂时不支持这么接收参数 - @ApiImplicitParam(name = "redirect_uri", required = true, value = "重定向 URI", example = "https://www.iocoder.cn", dataTypeClass = String.class), - @ApiImplicitParam(name = "auto_approve", required = true, value = "用户是否接受", example = "true", dataTypeClass = Boolean.class), - @ApiImplicitParam(name = "state", example = "1", dataTypeClass = String.class) + @Operation(summary = "申请授权", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【提交】调用") + @Parameters({ + @Parameter(name = "response_type", required = true, description = "响应类型", example = "code"), + @Parameter(name = "client_id", required = true, description = "客户端编号", example = "tudou"), + @Parameter(name = "scope", description = "授权范围", example = "userinfo.read"), // 使用 Map 格式,Spring MVC 暂时不支持这么接收参数 + @Parameter(name = "redirect_uri", required = true, description = "重定向 URI", example = "https://www.iocoder.cn"), + @Parameter(name = "auto_approve", required = true, description = "用户是否接受", example = "true"), + @Parameter(name = "state", example = "1") }) @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public CommonResult approveOrDeny(@RequestParam("response_type") String responseType, diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2TokenController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2TokenController.java index c055a19df..d1e0364dc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2TokenController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2TokenController.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; import cn.iocoder.yudao.module.system.service.auth.AdminAuthService; import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - OAuth2.0 令牌") +@Tag(name = "管理后台 - OAuth2.0 令牌") @RestController @RequestMapping("/system/oauth2-token") public class OAuth2TokenController { @@ -31,7 +31,7 @@ public class OAuth2TokenController { private AdminAuthService authService; @GetMapping("/page") - @ApiOperation(value = "获得访问令牌分页", notes = "只返回有效期内的") + @Operation(summary = "获得访问令牌分页", description = "只返回有效期内的") @PreAuthorize("@ss.hasPermission('system:oauth2-token:page')") public CommonResult> getAccessTokenPage(@Valid OAuth2AccessTokenPageReqVO reqVO) { PageResult pageResult = oauth2TokenService.getAccessTokenPage(reqVO); @@ -39,8 +39,8 @@ public class OAuth2TokenController { } @DeleteMapping("/delete") - @ApiOperation("删除访问令牌") - @ApiImplicitParam(name = "accessToken", value = "访问令牌", required = true, dataTypeClass = String.class, example = "tudou") + @Operation(summary = "删除访问令牌") + @Parameter(name = "accessToken", description = "访问令牌", required = true, example = "tudou") @PreAuthorize("@ss.hasPermission('system:oauth2-token:delete')") public CommonResult deleteAccessToken(@RequestParam("accessToken") String accessToken) { authService.logout(accessToken, LoginLogTypeEnum.LOGOUT_DELETE.getType()); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java index 39b6125ab..865646801 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java @@ -11,8 +11,8 @@ import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.service.dept.DeptService; import cn.iocoder.yudao.module.system.service.dept.PostService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; @@ -33,7 +33,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti * * @author 芋道源码 */ -@Api(tags = "管理后台 - OAuth2.0 用户") +@Tag(name = "管理后台 - OAuth2.0 用户") @RestController @RequestMapping("/system/oauth2/user") @Validated @@ -48,7 +48,7 @@ public class OAuth2UserController { private PostService postService; @GetMapping("/get") - @ApiOperation("获得用户基本信息") + @Operation(summary = "获得用户基本信息") @PreAuthorize("@ss.hasScope('user.read')") // public CommonResult getUserInfo() { // 获得用户基本信息 @@ -68,7 +68,7 @@ public class OAuth2UserController { } @PutMapping("/update") - @ApiOperation("更新用户基本信息") + @Operation(summary = "更新用户基本信息") @PreAuthorize("@ss.hasScope('user.write')") public CommonResult updateUserInfo(@Valid @RequestBody OAuth2UserUpdateReqVO reqVO) { // 这里将 UserProfileUpdateReqVO =》UserProfileUpdateReqVO 对象,实现接口的复用。 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientBaseVO.java index dbd74e552..aea3e059b 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientBaseVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.hibernate.validator.constraints.URL; @@ -18,60 +18,60 @@ import java.util.List; @Data public class OAuth2ClientBaseVO { - @ApiModelProperty(value = "客户端编号", required = true, example = "tudou") + @Schema(title = "客户端编号", required = true, example = "tudou") @NotNull(message = "客户端编号不能为空") private String clientId; - @ApiModelProperty(value = "客户端密钥", required = true, example = "fan") + @Schema(title = "客户端密钥", required = true, example = "fan") @NotNull(message = "客户端密钥不能为空") private String secret; - @ApiModelProperty(value = "应用名", required = true, example = "土豆") + @Schema(title = "应用名", required = true, example = "土豆") @NotNull(message = "应用名不能为空") private String name; - @ApiModelProperty(value = "应用图标", required = true, example = "https://www.iocoder.cn/xx.png") + @Schema(title = "应用图标", required = true, example = "https://www.iocoder.cn/xx.png") @NotNull(message = "应用图标不能为空") @URL(message = "应用图标的地址不正确") private String logo; - @ApiModelProperty(value = "应用描述", example = "我是一个应用") + @Schema(title = "应用描述", example = "我是一个应用") private String description; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") private Integer status; - @ApiModelProperty(value = "访问令牌的有效期", required = true, example = "8640") + @Schema(title = "访问令牌的有效期", required = true, example = "8640") @NotNull(message = "访问令牌的有效期不能为空") private Integer accessTokenValiditySeconds; - @ApiModelProperty(value = "刷新令牌的有效期", required = true, example = "8640000") + @Schema(title = "刷新令牌的有效期", required = true, example = "8640000") @NotNull(message = "刷新令牌的有效期不能为空") private Integer refreshTokenValiditySeconds; - @ApiModelProperty(value = "可重定向的 URI 地址", required = true, example = "https://www.iocoder.cn") + @Schema(title = "可重定向的 URI 地址", required = true, example = "https://www.iocoder.cn") @NotNull(message = "可重定向的 URI 地址不能为空") private List<@NotEmpty(message = "重定向的 URI 不能为空") @URL(message = "重定向的 URI 格式不正确") String> redirectUris; - @ApiModelProperty(value = "授权类型", required = true, example = "password", notes = "参见 OAuth2GrantTypeEnum 枚举") + @Schema(title = "授权类型", required = true, example = "password", description = "参见 OAuth2GrantTypeEnum 枚举") @NotNull(message = "授权类型不能为空") private List authorizedGrantTypes; - @ApiModelProperty(value = "授权范围", example = "user_info") + @Schema(title = "授权范围", example = "user_info") private List scopes; - @ApiModelProperty(value = "自动通过的授权范围", example = "user_info") + @Schema(title = "自动通过的授权范围", example = "user_info") private List autoApproveScopes; - @ApiModelProperty(value = "权限", example = "system:user:query") + @Schema(title = "权限", example = "system:user:query") private List authorities; - @ApiModelProperty(value = "资源", example = "1024") + @Schema(title = "资源", example = "1024") private List resourceIds; - @ApiModelProperty(value = "附加信息", example = "{yunai: true}") + @Schema(title = "附加信息", example = "{yunai: true}") private String additionalInformation; @AssertTrue(message = "附加信息必须是 JSON 格式") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientCreateReqVO.java index b241277ac..34c4350ba 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientCreateReqVO.java @@ -1,9 +1,9 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - OAuth2 客户端创建 Request VO") +@Schema(title = "管理后台 - OAuth2 客户端创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientPageReqVO.java index 286fc73ac..c815331e9 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientPageReqVO.java @@ -1,19 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; -@ApiModel("管理后台 - OAuth2 客户端分页 Request VO") +@Schema(title = "管理后台 - OAuth2 客户端分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class OAuth2ClientPageReqVO extends PageParam { - @ApiModelProperty(value = "应用名", example = "土豆", notes = "模糊匹配") + @Schema(title = "应用名", example = "土豆", description = "模糊匹配") private String name; - @ApiModelProperty(value = "状态", example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(title = "状态", example = "1", description = "参见 CommonStatusEnum 枚举") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientRespVO.java index f4bdf4cc7..dc39d7c2a 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - OAuth2 客户端 Response VO") +@Schema(title = "管理后台 - OAuth2 客户端 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class OAuth2ClientRespVO extends OAuth2ClientBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientUpdateReqVO.java index 024a1511f..32968b4cd 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - OAuth2 客户端更新 Request VO") +@Schema(title = "管理后台 - OAuth2 客户端更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class OAuth2ClientUpdateReqVO extends OAuth2ClientBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAccessTokenRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAccessTokenRespVO.java index 4fdb4e539..3c6412ae0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAccessTokenRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAccessTokenRespVO.java @@ -1,35 +1,34 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel("管理后台 - 【开放接口】访问令牌 Response VO") +@Schema(title = "管理后台 - 【开放接口】访问令牌 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class OAuth2OpenAccessTokenRespVO { - @ApiModelProperty(value = "访问令牌", required = true, example = "tudou") + @Schema(title = "访问令牌", required = true, example = "tudou") @JsonProperty("access_token") private String accessToken; - @ApiModelProperty(value = "刷新令牌", required = true, example = "nice") + @Schema(title = "刷新令牌", required = true, example = "nice") @JsonProperty("refresh_token") private String refreshToken; - @ApiModelProperty(value = "令牌类型", required = true, example = "bearer") + @Schema(title = "令牌类型", required = true, example = "bearer") @JsonProperty("token_type") private String tokenType; - @ApiModelProperty(value = "过期时间", required = true, example = "42430", notes = "单位:秒") + @Schema(title = "过期时间", required = true, example = "42430", description = "单位:秒") @JsonProperty("expires_in") private Long expiresIn; - @ApiModelProperty(value = "授权范围", example = "user_info", notes = "如果多个授权范围,使用空格分隔") + @Schema(title = "授权范围", example = "user_info", description = "如果多个授权范围,使用空格分隔") private String scope; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAuthorizeInfoRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAuthorizeInfoRespVO.java index d2a7bb36e..73a89817f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAuthorizeInfoRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAuthorizeInfoRespVO.java @@ -1,15 +1,14 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open; import cn.iocoder.yudao.framework.common.core.KeyValue; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; -@ApiModel("管理后台 - 授权页的信息 Response VO") +@Schema(title = "管理后台 - 授权页的信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @@ -20,7 +19,7 @@ public class OAuth2OpenAuthorizeInfoRespVO { */ private Client client; - @ApiModelProperty(value = "scope 的选中信息", required = true, notes = "使用 List 保证有序性,Key 是 scope,Value 为是否选中") + @Schema(title = "scope 的选中信息", required = true, description = "使用 List 保证有序性,Key 是 scope,Value 为是否选中") private List> scopes; @Data @@ -28,10 +27,10 @@ public class OAuth2OpenAuthorizeInfoRespVO { @AllArgsConstructor public static class Client { - @ApiModelProperty(value = "应用名", required = true, example = "土豆") + @Schema(title = "应用名", required = true, example = "土豆") private String name; - @ApiModelProperty(value = "应用图标", required = true, example = "https://www.iocoder.cn/xx.png") + @Schema(title = "应用图标", required = true, example = "https://www.iocoder.cn/xx.png") private String logo; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenCheckTokenRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenCheckTokenRespVO.java index e1639e9ac..3cf843f4f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenCheckTokenRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenCheckTokenRespVO.java @@ -1,41 +1,40 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; -@ApiModel("管理后台 - 【开放接口】校验令牌 Response VO") +@Schema(title = "管理后台 - 【开放接口】校验令牌 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class OAuth2OpenCheckTokenRespVO { - @ApiModelProperty(value = "用户编号", required = true, example = "666") + @Schema(title = "用户编号", required = true, example = "666") @JsonProperty("user_id") private Long userId; - @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举") + @Schema(title = "用户类型", required = true, example = "2", description = "参见 UserTypeEnum 枚举") @JsonProperty("user_type") private Integer userType; - @ApiModelProperty(value = "租户编号", required = true, example = "1024") + @Schema(title = "租户编号", required = true, example = "1024") @JsonProperty("tenant_id") private Long tenantId; - @ApiModelProperty(value = "客户端编号", required = true, example = "car") + @Schema(title = "客户端编号", required = true, example = "car") @JsonProperty("client_id") private String clientId; - @ApiModelProperty(value = "授权范围", required = true, example = "user_info") + @Schema(title = "授权范围", required = true, example = "user_info") private List scopes; - @ApiModelProperty(value = "访问令牌", required = true, example = "tudou") + @Schema(title = "访问令牌", required = true, example = "tudou") @JsonProperty("access_token") private String accessToken; - @ApiModelProperty(value = "过期时间", required = true, example = "1593092157", notes = "时间戳 / 1000,即单位:秒") + @Schema(title = "过期时间", required = true, example = "1593092157", description = "时间戳 / 1000,即单位:秒") private Long exp; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenPageReqVO.java index 65103adc6..7bd1fa5d3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenPageReqVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.token; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel("管理后台 - 访问令牌分页 Request VO") +@Schema(title = "管理后台 - 访问令牌分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class OAuth2AccessTokenPageReqVO extends PageParam { - @ApiModelProperty(value = "用户编号", required = true, example = "666") + @Schema(title = "用户编号", required = true, example = "666") private Long userId; - @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举") + @Schema(title = "用户类型", required = true, example = "2", description = "参见 UserTypeEnum 枚举") private Integer userType; - @ApiModelProperty(value = "客户端编号", required = true, example = "2") + @Schema(title = "客户端编号", required = true, example = "2") private String clientId; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenRespVO.java index 76a2bb7d5..b7b258ca2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenRespVO.java @@ -1,41 +1,40 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.token; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@ApiModel("管理后台 - 访问令牌 Response VO") +@Schema(title = "管理后台 - 访问令牌 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class OAuth2AccessTokenRespVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "访问令牌", required = true, example = "tudou") + @Schema(title = "访问令牌", required = true, example = "tudou") private String accessToken; - @ApiModelProperty(value = "刷新令牌", required = true, example = "nice") + @Schema(title = "刷新令牌", required = true, example = "nice") private String refreshToken; - @ApiModelProperty(value = "用户编号", required = true, example = "666") + @Schema(title = "用户编号", required = true, example = "666") private Long userId; - @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举") + @Schema(title = "用户类型", required = true, example = "2", description = "参见 UserTypeEnum 枚举") private Integer userType; - @ApiModelProperty(value = "客户端编号", required = true, example = "2") + @Schema(title = "客户端编号", required = true, example = "2") private String clientId; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; - @ApiModelProperty(value = "过期时间", required = true) + @Schema(title = "过期时间", required = true) private LocalDateTime expiresTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java index f22c14a9f..ab561607b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java @@ -1,37 +1,36 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; -@ApiModel("管理后台 - OAuth2 获得用户基本信息 Response VO") +@Schema(title = "管理后台 - OAuth2 获得用户基本信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class OAuth2UserInfoRespVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1") + @Schema(title = "用户编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "用户账号", required = true, example = "芋艿") + @Schema(title = "用户账号", required = true, example = "芋艿") private String username; - @ApiModelProperty(value = "用户昵称", required = true, example = "芋道") + @Schema(title = "用户昵称", required = true, example = "芋道") private String nickname; - @ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn") + @Schema(title = "用户邮箱", example = "yudao@iocoder.cn") private String email; - @ApiModelProperty(value = "手机号码", example = "15601691300") + @Schema(title = "手机号码", example = "15601691300") private String mobile; - @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SexEnum 枚举类") + @Schema(title = "用户性别", example = "1", description = "参见 SexEnum 枚举类") private Integer sex; - @ApiModelProperty(value = "用户头像", example = "https://www.iocoder.cn/xxx.png") + @Schema(title = "用户头像", example = "https://www.iocoder.cn/xxx.png") private String avatar; /** @@ -44,26 +43,26 @@ public class OAuth2UserInfoRespVO { */ private List posts; - @ApiModel("部门") + @Schema(title = "部门") @Data public static class Dept { - @ApiModelProperty(value = "部门编号", required = true, example = "1") + @Schema(title = "部门编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "部门名称", required = true, example = "研发部") + @Schema(title = "部门名称", required = true, example = "研发部") private String name; } - @ApiModel("岗位") + @Schema(title = "岗位") @Data public static class Post { - @ApiModelProperty(value = "岗位编号", required = true, example = "1") + @Schema(title = "岗位编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "岗位名称", required = true, example = "开发") + @Schema(title = "岗位名称", required = true, example = "开发") private String name; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java index 16082a75e..5d7c9c267 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.user; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -10,26 +9,26 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.Email; import javax.validation.constraints.Size; -@ApiModel("管理后台 - OAuth2 更新用户基本信息 Request VO") +@Schema(title = "管理后台 - OAuth2 更新用户基本信息 Request VO") @Data @NoArgsConstructor @AllArgsConstructor public class OAuth2UserUpdateReqVO { - @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") + @Schema(title = "用户昵称", required = true, example = "芋艿") @Size(max = 30, message = "用户昵称长度不能超过 30 个字符") private String nickname; - @ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn") + @Schema(title = "用户邮箱", example = "yudao@iocoder.cn") @Email(message = "邮箱格式不正确") @Size(max = 50, message = "邮箱长度不能超过 50 个字符") private String email; - @ApiModelProperty(value = "手机号码", example = "15601691300") + @Schema(title = "手机号码", example = "15601691300") @Length(min = 11, max = 11, message = "手机号长度必须 11 位") private String mobile; - @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SexEnum 枚举类") + @Schema(title = "用户性别", example = "1", description = "参见 SexEnum 枚举类") private Integer sex; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java index 9813d8c0a..ad7b14c29 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.*; import cn.iocoder.yudao.module.system.convert.permission.MenuConvert; import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; import cn.iocoder.yudao.module.system.service.permission.MenuService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 菜单") +@Tag(name = "管理后台 - 菜单") @RestController @RequestMapping("/system/menu") @Validated @@ -30,7 +30,7 @@ public class MenuController { private MenuService menuService; @PostMapping("/create") - @ApiOperation("创建菜单") + @Operation(summary = "创建菜单") @PreAuthorize("@ss.hasPermission('system:menu:create')") public CommonResult createMenu(@Valid @RequestBody MenuCreateReqVO reqVO) { Long menuId = menuService.createMenu(reqVO); @@ -38,7 +38,7 @@ public class MenuController { } @PutMapping("/update") - @ApiOperation("修改菜单") + @Operation(summary = "修改菜单") @PreAuthorize("@ss.hasPermission('system:menu:update')") public CommonResult updateMenu(@Valid @RequestBody MenuUpdateReqVO reqVO) { menuService.updateMenu(reqVO); @@ -46,8 +46,8 @@ public class MenuController { } @DeleteMapping("/delete") - @ApiOperation("删除菜单") - @ApiImplicitParam(name = "id", value = "角色编号", required= true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除菜单") + @Parameter(name = "id", description = "角色编号", required= true, example = "1024") @PreAuthorize("@ss.hasPermission('system:menu:delete')") public CommonResult deleteMenu(@RequestParam("id") Long id) { menuService.deleteMenu(id); @@ -55,7 +55,7 @@ public class MenuController { } @GetMapping("/list") - @ApiOperation(value = "获取菜单列表", notes = "用于【菜单管理】界面") + @Operation(summary = "获取菜单列表", description = "用于【菜单管理】界面") @PreAuthorize("@ss.hasPermission('system:menu:query')") public CommonResult> getMenus(MenuListReqVO reqVO) { List list = menuService.getMenus(reqVO); @@ -64,7 +64,7 @@ public class MenuController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获取菜单精简信息列表", notes = "只包含被开启的菜单,用于【角色分配菜单】功能的选项。" + + @Operation(summary = "获取菜单精简信息列表", description = "只包含被开启的菜单,用于【角色分配菜单】功能的选项。" + "在多租户的场景下,会只返回租户所在套餐有的菜单") public CommonResult> getSimpleMenus() { // 获得菜单列表,只要开启状态的 @@ -77,7 +77,7 @@ public class MenuController { } @GetMapping("/get") - @ApiOperation("获取菜单信息") + @Operation(summary = "获取菜单信息") @PreAuthorize("@ss.hasPermission('system:menu:query')") public CommonResult getMenu(Long id) { MenuDO menu = menuService.getMenu(id); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/PermissionController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/PermissionController.java index 01ae9ea7b..ca768d14f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/PermissionController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/PermissionController.java @@ -7,9 +7,9 @@ import cn.iocoder.yudao.module.system.controller.admin.permission.vo.permission. import cn.iocoder.yudao.module.system.controller.admin.permission.vo.permission.PermissionAssignUserRoleReqVO; import cn.iocoder.yudao.module.system.service.permission.PermissionService; import cn.iocoder.yudao.module.system.service.tenant.TenantService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -25,7 +25,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; * * @author 芋道源码 */ -@Api(tags = "管理后台 - 权限") +@Tag(name = "管理后台 - 权限") @RestController @RequestMapping("/system/permission") public class PermissionController { @@ -35,8 +35,8 @@ public class PermissionController { @Resource private TenantService tenantService; - @ApiOperation("获得角色拥有的菜单编号") - @ApiImplicitParam(name = "roleId", value = "角色编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "获得角色拥有的菜单编号") + @Parameter(name = "roleId", description = "角色编号", required = true) @GetMapping("/list-role-resources") @PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')") public CommonResult> listRoleMenus(Long roleId) { @@ -44,7 +44,7 @@ public class PermissionController { } @PostMapping("/assign-role-menu") - @ApiOperation("赋予角色菜单") + @Operation(summary = "赋予角色菜单") @PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')") public CommonResult assignRoleMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) { // 开启多租户的情况下,需要过滤掉未开通的菜单 @@ -56,22 +56,22 @@ public class PermissionController { } @PostMapping("/assign-role-data-scope") - @ApiOperation("赋予角色数据权限") + @Operation(summary = "赋予角色数据权限") @PreAuthorize("@ss.hasPermission('system:permission:assign-role-data-scope')") public CommonResult assignRoleDataScope(@Valid @RequestBody PermissionAssignRoleDataScopeReqVO reqVO) { permissionService.assignRoleDataScope(reqVO.getRoleId(), reqVO.getDataScope(), reqVO.getDataScopeDeptIds()); return success(true); } - @ApiOperation("获得管理员拥有的角色编号列表") - @ApiImplicitParam(name = "userId", value = "用户编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "获得管理员拥有的角色编号列表") + @Parameter(name = "userId", description = "用户编号", required = true) @GetMapping("/list-user-roles") @PreAuthorize("@ss.hasPermission('system:permission:assign-user-role')") public CommonResult> listAdminRoles(@RequestParam("userId") Long userId) { return success(permissionService.getUserRoleIdListByUserId(userId)); } - @ApiOperation("赋予用户角色") + @Operation(summary = "赋予用户角色") @PostMapping("/assign-user-role") @PreAuthorize("@ss.hasPermission('system:permission:assign-user-role')") public CommonResult assignUserRole(@Validated @RequestBody PermissionAssignUserRoleReqVO reqVO) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java index 3716c8e7c..cde85f9e4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.*; import cn.iocoder.yudao.module.system.convert.permission.RoleConvert; import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; import cn.iocoder.yudao.module.system.service.permission.RoleService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -27,7 +27,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 角色") +@Tag(name = "管理后台 - 角色") @RestController @RequestMapping("/system/role") @Validated @@ -37,14 +37,14 @@ public class RoleController { private RoleService roleService; @PostMapping("/create") - @ApiOperation("创建角色") + @Operation(summary = "创建角色") @PreAuthorize("@ss.hasPermission('system:role:create')") public CommonResult createRole(@Valid @RequestBody RoleCreateReqVO reqVO) { return success(roleService.createRole(reqVO, null)); } @PutMapping("/update") - @ApiOperation("修改角色") + @Operation(summary = "修改角色") @PreAuthorize("@ss.hasPermission('system:role:update')") public CommonResult updateRole(@Valid @RequestBody RoleUpdateReqVO reqVO) { roleService.updateRole(reqVO); @@ -52,7 +52,7 @@ public class RoleController { } @PutMapping("/update-status") - @ApiOperation("修改角色状态") + @Operation(summary = "修改角色状态") @PreAuthorize("@ss.hasPermission('system:role:update')") public CommonResult updateRoleStatus(@Valid @RequestBody RoleUpdateStatusReqVO reqVO) { roleService.updateRoleStatus(reqVO.getId(), reqVO.getStatus()); @@ -60,8 +60,8 @@ public class RoleController { } @DeleteMapping("/delete") - @ApiOperation("删除角色") - @ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除角色") + @Parameter(name = "id", description = "角色编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:role:delete')") public CommonResult deleteRole(@RequestParam("id") Long id) { roleService.deleteRole(id); @@ -69,7 +69,7 @@ public class RoleController { } @GetMapping("/get") - @ApiOperation("获得角色信息") + @Operation(summary = "获得角色信息") @PreAuthorize("@ss.hasPermission('system:role:query')") public CommonResult getRole(@RequestParam("id") Long id) { RoleDO role = roleService.getRole(id); @@ -77,14 +77,14 @@ public class RoleController { } @GetMapping("/page") - @ApiOperation("获得角色分页") + @Operation(summary = "获得角色分页") @PreAuthorize("@ss.hasPermission('system:role:query')") public CommonResult> getRolePage(RolePageReqVO reqVO) { return success(roleService.getRolePage(reqVO)); } @GetMapping("/list-all-simple") - @ApiOperation(value = "获取角色精简信息列表", notes = "只包含被开启的角色,主要用于前端的下拉选项") + @Operation(summary = "获取角色精简信息列表", description = "只包含被开启的角色,主要用于前端的下拉选项") public CommonResult> getSimpleRoles() { // 获得角色列表,只要开启状态的 List list = roleService.getRoles(Collections.singleton(CommonStatusEnum.ENABLE.getStatus())); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuBaseVO.java index 7c64dd13f..a316ad577 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -14,46 +14,46 @@ import javax.validation.constraints.Size; @Data public class MenuBaseVO { - @ApiModelProperty(value = "菜单名称", required = true, example = "芋道") + @Schema(title = "菜单名称", required = true, example = "芋道") @NotBlank(message = "菜单名称不能为空") @Size(max = 50, message = "菜单名称长度不能超过50个字符") private String name; - @ApiModelProperty(value = "权限标识", example = "sys:menu:add", notes = "仅菜单类型为按钮时,才需要传递") + @Schema(title = "权限标识", example = "sys:menu:add", description = "仅菜单类型为按钮时,才需要传递") @Size(max = 100) private String permission; - @ApiModelProperty(value = "类型", required = true, example = "1", notes = "参见 MenuTypeEnum 枚举类") + @Schema(title = "类型", required = true, example = "1", description = "参见 MenuTypeEnum 枚举类") @NotNull(message = "菜单类型不能为空") private Integer type; - @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") + @Schema(title = "显示顺序不能为空", required = true, example = "1024") @NotNull(message = "显示顺序不能为空") private Integer sort; - @ApiModelProperty(value = "父菜单 ID", required = true, example = "1024") + @Schema(title = "父菜单 ID", required = true, example = "1024") @NotNull(message = "父菜单 ID 不能为空") private Long parentId; - @ApiModelProperty(value = "路由地址", example = "post", notes = "仅菜单类型为菜单或者目录时,才需要传") + @Schema(title = "路由地址", example = "post", description = "仅菜单类型为菜单或者目录时,才需要传") @Size(max = 200, message = "路由地址不能超过200个字符") private String path; - @ApiModelProperty(value = "菜单图标", example = "/menu/list", notes = "仅菜单类型为菜单或者目录时,才需要传") + @Schema(title = "菜单图标", example = "/menu/list", description = "仅菜单类型为菜单或者目录时,才需要传") private String icon; - @ApiModelProperty(value = "组件路径", example = "system/post/index", notes = "仅菜单类型为菜单时,才需要传") + @Schema(title = "组件路径", example = "system/post/index", description = "仅菜单类型为菜单时,才需要传") @Size(max = 200, message = "组件路径不能超过255个字符") private String component; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") private Integer status; - @ApiModelProperty(value = "是否可见", example = "false") + @Schema(title = "是否可见", example = "false") private Boolean visible; - @ApiModelProperty(value = "是否缓存", example = "false") + @Schema(title = "是否缓存", example = "false") private Boolean keepAlive; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuCreateReqVO.java index a793997ff..3930c8116 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuCreateReqVO.java @@ -1,9 +1,9 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@ApiModel("管理后台 - 菜单创建 Request VO") +@Schema(title = "管理后台 - 菜单创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class MenuCreateReqVO extends MenuBaseVO { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java index 2600fb92b..0f1410878 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("管理后台 - 菜单列表 Request VO") +@Schema(title = "管理后台 - 菜单列表 Request VO") @Data public class MenuListReqVO { - @ApiModelProperty(value = "菜单名称", example = "芋道", notes = "模糊匹配") + @Schema(title = "菜单名称", example = "芋道", description = "模糊匹配") private String name; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuRespVO.java index c6482b296..0d5e9b2e1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -9,20 +8,20 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@ApiModel("管理后台 - 菜单信息 Response VO") +@Schema(title = "管理后台 - 菜单信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class MenuRespVO extends MenuBaseVO { - @ApiModelProperty(value = "菜单编号", required = true, example = "1024") + @Schema(title = "菜单编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + @Schema(title = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuSimpleRespVO.java index 8f99d1e21..53a10ed2b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuSimpleRespVO.java @@ -1,29 +1,28 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 菜单精简信息 Response VO") +@Schema(title = "管理后台 - 菜单精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class MenuSimpleRespVO { - @ApiModelProperty(value = "菜单编号", required = true, example = "1024") + @Schema(title = "菜单编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "菜单名称", required = true, example = "芋道") + @Schema(title = "菜单名称", required = true, example = "芋道") private String name; - @ApiModelProperty(value = "父菜单 ID", required = true, example = "1024") + @Schema(title = "父菜单 ID", required = true, example = "1024") private Long parentId; - @ApiModelProperty(value = "类型", required = true, example = "1", notes = "参见 MenuTypeEnum 枚举类") + @Schema(title = "类型", required = true, example = "1", description = "参见 MenuTypeEnum 枚举类") private Integer type; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuUpdateReqVO.java index 7a1784363..01783beff 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuUpdateReqVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 菜单更新 Request VO") +@Schema(title = "管理后台 - 菜单更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class MenuUpdateReqVO extends MenuBaseVO { - @ApiModelProperty(value = "菜单编号", required = true, example = "1024") + @Schema(title = "菜单编号", required = true, example = "1024") @NotNull(message = "菜单编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleDataScopeReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleDataScopeReqVO.java index 6adb8c854..9d3c126df 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleDataScopeReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleDataScopeReqVO.java @@ -1,27 +1,26 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.permission; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.Collections; import java.util.Set; -@ApiModel("管理后台 - 赋予角色数据权限 Request VO") +@Schema(title = "管理后台 - 赋予角色数据权限 Request VO") @Data public class PermissionAssignRoleDataScopeReqVO { - @ApiModelProperty(value = "角色编号", required = true, example = "1") + @Schema(title = "角色编号", required = true, example = "1") @NotNull(message = "角色编号不能为空") private Long roleId; - @ApiModelProperty(value = "数据范围", required = true, example = "1", notes = "参见 DataScopeEnum 枚举类") + @Schema(title = "数据范围", required = true, example = "1", description = "参见 DataScopeEnum 枚举类") @NotNull(message = "数据范围不能为空") // TODO 这里要多一个枚举校验 private Integer dataScope; - @ApiModelProperty(value = "部门编号列表", example = "1,3,5", notes = "只有范围类型为 DEPT_CUSTOM 时,该字段才需要") + @Schema(title = "部门编号列表", example = "1,3,5", description = "只有范围类型为 DEPT_CUSTOM 时,该字段才需要") private Set dataScopeDeptIds = Collections.emptySet(); // 兜底 } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleMenuReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleMenuReqVO.java index 3fc4dcb2c..70a33591d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleMenuReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleMenuReqVO.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.permission; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.Collections; import java.util.Set; -@ApiModel("管理后台 - 赋予角色菜单 Request VO") +@Schema(title = "管理后台 - 赋予角色菜单 Request VO") @Data public class PermissionAssignRoleMenuReqVO { - @ApiModelProperty(value = "角色编号", required = true, example = "1") + @Schema(title = "角色编号", required = true, example = "1") @NotNull(message = "角色编号不能为空") private Long roleId; - @ApiModelProperty(value = "菜单编号列表", example = "1,3,5") + @Schema(title = "菜单编号列表", example = "1,3,5") private Set menuIds = Collections.emptySet(); // 兜底 } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignUserRoleReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignUserRoleReqVO.java index 93cc8ffa2..bcb4d46bf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignUserRoleReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignUserRoleReqVO.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.permission; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.Collections; import java.util.Set; -@ApiModel("管理后台 - 赋予用户角色 Request VO") +@Schema(title = "管理后台 - 赋予用户角色 Request VO") @Data public class PermissionAssignUserRoleReqVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1") + @Schema(title = "用户编号", required = true, example = "1") @NotNull(message = "用户编号不能为空") private Long userId; - @ApiModelProperty(value = "角色编号列表", example = "1,3,5") + @Schema(title = "角色编号列表", example = "1,3,5") private Set roleIds = Collections.emptySet(); // 兜底 } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleBaseVO.java index 60d678aa9..ee320c01b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotBlank; @@ -14,21 +14,21 @@ import javax.validation.constraints.Size; @Data public class RoleBaseVO { - @ApiModelProperty(value = "角色名称", required = true, example = "管理员") + @Schema(title = "角色名称", required = true, example = "管理员") @NotBlank(message = "角色名称不能为空") @Size(max = 30, message = "角色名称长度不能超过30个字符") private String name; @NotBlank(message = "角色标志不能为空") @Size(max = 100, message = "角色标志长度不能超过100个字符") - @ApiModelProperty(value = "角色编码", required = true, example = "ADMIN") + @Schema(title = "角色编码", required = true, example = "ADMIN") private String code; - @ApiModelProperty(value = "显示顺序不能为空", required = true, example = "1024") + @Schema(title = "显示顺序不能为空", required = true, example = "1024") @NotNull(message = "显示顺序不能为空") private Integer sort; - @ApiModelProperty(value = "备注", example = "我是一个角色") + @Schema(title = "备注", example = "我是一个角色") private String remark; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleCreateReqVO.java index 785f65815..0f21c3c2f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleCreateReqVO.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel("管理后台 - 角色创建 Request VO") +@Schema(title = "管理后台 - 角色创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class RoleCreateReqVO extends RoleBaseVO { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleExportReqVO.java index ca9bed7cd..a16deff7a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,20 +8,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 角色分页 Request VO") +@Schema(title = "管理后台 - 角色分页 Request VO") @Data public class RoleExportReqVO { - @ApiModelProperty(value = "角色名称", example = "芋道", notes = "模糊匹配") + @Schema(title = "角色名称", example = "芋道", description = "模糊匹配") private String name; - @ApiModelProperty(value = "角色标识", example = "yudao", notes = "模糊匹配") + @Schema(title = "角色标识", example = "yudao", description = "模糊匹配") private String code; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RolePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RolePageReqVO.java index 040462a6f..b37cdb485 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RolePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RolePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.springframework.format.annotation.DateTimeFormat; @@ -11,21 +10,21 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 角色分页 Request VO") +@Schema(title = "管理后台 - 角色分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class RolePageReqVO extends PageParam { - @ApiModelProperty(value = "角色名称", example = "芋道", notes = "模糊匹配") + @Schema(title = "角色名称", example = "芋道", description = "模糊匹配") private String name; - @ApiModelProperty(value = "角色标识", example = "yudao", notes = "模糊匹配") + @Schema(title = "角色标识", example = "yudao", description = "模糊匹配") private String code; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleRespVO.java index 6653820b0..654eff898 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -10,29 +9,29 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; import java.util.Set; -@ApiModel("管理后台 - 角色信息 Response VO") +@Schema(title = "管理后台 - 角色信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class RoleRespVO extends RoleBaseVO { - @ApiModelProperty(value = "角色编号", required = true, example = "1") + @Schema(title = "角色编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "数据范围", required = true, example = "1", notes = "参见 DataScopeEnum 枚举类") + @Schema(title = "数据范围", required = true, example = "1", description = "参见 DataScopeEnum 枚举类") private Integer dataScope; - @ApiModelProperty(value = "数据范围(指定部门数组)", example = "1") + @Schema(title = "数据范围(指定部门数组)", example = "1") private Set dataScopeDeptIds; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "角色类型", required = true, example = "1", notes = "参见 RoleTypeEnum 枚举类") + @Schema(title = "角色类型", required = true, example = "1", description = "参见 RoleTypeEnum 枚举类") private Integer type; - @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + @Schema(title = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleSimpleRespVO.java index c0a4c3083..a7fced888 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleSimpleRespVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel("管理后台 - 角色精简信息 Response VO") +@Schema(title = "管理后台 - 角色精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class RoleSimpleRespVO { - @ApiModelProperty(value = "角色编号", required = true, example = "1024") + @Schema(title = "角色编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "角色名称", required = true, example = "芋道") + @Schema(title = "角色名称", required = true, example = "芋道") private String name; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateReqVO.java index 362cbb290..5c02ff2d9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateReqVO.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 角色更新 Request VO") +@Schema(title = "管理后台 - 角色更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class RoleUpdateReqVO extends RoleBaseVO { - @ApiModelProperty(value = "角色编号", required = true, example = "1024") + @Schema(title = "角色编号", required = true, example = "1024") @NotNull(message = "角色编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateStatusReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateStatusReqVO.java index 790accd92..ed4a72604 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateStatusReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateStatusReqVO.java @@ -2,21 +2,20 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.role; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 角色更新状态 Request VO") +@Schema(title = "管理后台 - 角色更新状态 Request VO") @Data public class RoleUpdateStatusReqVO { - @ApiModelProperty(value = "角色编号", required = true, example = "1024") + @Schema(title = "角色编号", required = true, example = "1024") @NotNull(message = "角色编号不能为空") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") private Integer status; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java index e9536ad9a..684480be6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.*; import cn.iocoder.yudao.module.system.convert.sensitiveword.SensitiveWordConvert; import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO; import cn.iocoder.yudao.module.system.service.sensitiveword.SensitiveWordService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -25,7 +25,7 @@ import java.util.Set; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 敏感词") +@Tag(name = "管理后台 - 敏感词") @RestController @RequestMapping("/system/sensitive-word") @Validated @@ -35,14 +35,14 @@ public class SensitiveWordController { private SensitiveWordService sensitiveWordService; @PostMapping("/create") - @ApiOperation("创建敏感词") + @Operation(summary = "创建敏感词") @PreAuthorize("@ss.hasPermission('system:sensitive-word:create')") public CommonResult createSensitiveWord(@Valid @RequestBody SensitiveWordCreateReqVO createReqVO) { return success(sensitiveWordService.createSensitiveWord(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新敏感词") + @Operation(summary = "更新敏感词") @PreAuthorize("@ss.hasPermission('system:sensitive-word:update')") public CommonResult updateSensitiveWord(@Valid @RequestBody SensitiveWordUpdateReqVO updateReqVO) { sensitiveWordService.updateSensitiveWord(updateReqVO); @@ -50,8 +50,8 @@ public class SensitiveWordController { } @DeleteMapping("/delete") - @ApiOperation("删除敏感词") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除敏感词") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('system:sensitive-word:delete')") public CommonResult deleteSensitiveWord(@RequestParam("id") Long id) { sensitiveWordService.deleteSensitiveWord(id); @@ -59,8 +59,8 @@ public class SensitiveWordController { } @GetMapping("/get") - @ApiOperation("获得敏感词") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得敏感词") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:sensitive-word:query')") public CommonResult getSensitiveWord(@RequestParam("id") Long id) { SensitiveWordDO sensitiveWord = sensitiveWordService.getSensitiveWord(id); @@ -68,7 +68,7 @@ public class SensitiveWordController { } @GetMapping("/page") - @ApiOperation("获得敏感词分页") + @Operation(summary = "获得敏感词分页") @PreAuthorize("@ss.hasPermission('system:sensitive-word:query')") public CommonResult> getSensitiveWordPage(@Valid SensitiveWordPageReqVO pageVO) { PageResult pageResult = sensitiveWordService.getSensitiveWordPage(pageVO); @@ -76,7 +76,7 @@ public class SensitiveWordController { } @GetMapping("/export-excel") - @ApiOperation("导出敏感词 Excel") + @Operation(summary = "导出敏感词 Excel") @PreAuthorize("@ss.hasPermission('system:sensitive-word:export')") @OperateLog(type = EXPORT) public void exportSensitiveWordExcel(@Valid SensitiveWordExportReqVO exportReqVO, @@ -88,14 +88,14 @@ public class SensitiveWordController { } @GetMapping("/get-tags") - @ApiOperation("获取所有敏感词的标签数组") + @Operation(summary = "获取所有敏感词的标签数组") @PreAuthorize("@ss.hasPermission('system:sensitive-word:query')") public CommonResult> getSensitiveWordTags() throws IOException { return success(sensitiveWordService.getSensitiveWordTags()); } @GetMapping("/validate-text") - @ApiOperation("获得文本所包含的不合法的敏感词数组") + @Operation(summary = "获得文本所包含的不合法的敏感词数组") public CommonResult> validateText(@RequestParam("text") String text, @RequestParam(value = "tags", required = false) List tags) { return success(sensitiveWordService.validateText(text, tags)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordBaseVO.java index 770a22b92..f7539f944 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -13,19 +13,19 @@ import java.util.List; @Data public class SensitiveWordBaseVO { - @ApiModelProperty(value = "敏感词", required = true, example = "敏感词") + @Schema(title = "敏感词", required = true, example = "敏感词") @NotNull(message = "敏感词不能为空") private String name; - @ApiModelProperty(value = "标签", required = true, example = "短信,评论") + @Schema(title = "标签", required = true, example = "短信,评论") @NotNull(message = "标签不能为空") private List tags; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") @NotNull(message = "状态不能为空") private Integer status; - @ApiModelProperty(value = "描述", example = "污言秽语") + @Schema(title = "描述", example = "污言秽语") private String description; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordCreateReqVO.java index bb206652b..bc833d276 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordCreateReqVO.java @@ -1,11 +1,11 @@ package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 敏感词创建 Request VO") +@Schema(title = "管理后台 - 敏感词创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExportReqVO.java index 1addc4cfe..7df2b7aa7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,21 +8,21 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 敏感词 Excel 导出 Request VO", description = "参数和 SensitiveWordPageReqVO 是一致的") +@Schema(title = "管理后台 - 敏感词 Excel 导出 Request VO", description = "参数和 SensitiveWordPageReqVO 是一致的") @Data public class SensitiveWordExportReqVO { - @ApiModelProperty(value = "敏感词", example = "敏感词") + @Schema(title = "敏感词", example = "敏感词") private String name; - @ApiModelProperty(value = "标签", example = "短信,评论") + @Schema(title = "标签", example = "短信,评论") private String tag; - @ApiModelProperty(value = "状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java index 087670180..f913b9270 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,23 +11,23 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 敏感词分页 Request VO") +@Schema(title = "管理后台 - 敏感词分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SensitiveWordPageReqVO extends PageParam { - @ApiModelProperty(value = "敏感词", example = "敏感词") + @Schema(title = "敏感词", example = "敏感词") private String name; - @ApiModelProperty(value = "标签", example = "短信,评论") + @Schema(title = "标签", example = "短信,评论") private String tag; - @ApiModelProperty(value = "状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordRespVO.java index c92a8d4e0..f97333f58 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 敏感词 Response VO") +@Schema(title = "管理后台 - 敏感词 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SensitiveWordRespVO extends SensitiveWordBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1") + @Schema(title = "编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordUpdateReqVO.java index f87aa3a62..2dc0ad37b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 敏感词更新 Request VO") +@Schema(title = "管理后台 - 敏感词更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SensitiveWordUpdateReqVO extends SensitiveWordBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1") + @Schema(title = "编号", required = true, example = "1") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsCallbackController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsCallbackController.java index 8a0767652..05f13d257 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsCallbackController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsCallbackController.java @@ -5,8 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.sms.core.enums.SmsChannelEnum; import cn.iocoder.yudao.module.system.service.sms.SmsSendService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -17,7 +17,7 @@ import javax.servlet.http.HttpServletRequest; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 短信回调") +@Tag(name = "管理后台 - 短信回调") @RestController @RequestMapping("/system/sms/callback") public class SmsCallbackController { @@ -27,7 +27,7 @@ public class SmsCallbackController { @PostMapping("/aliyun") @PermitAll - @ApiOperation(value = "阿里云短信的回调", notes = "参见 https://help.aliyun.com/document_detail/120998.html 文档") + @Operation(summary = "阿里云短信的回调", description = "参见 https://help.aliyun.com/document_detail/120998.html 文档") @OperateLog(enable = false) public CommonResult receiveAliyunSmsStatus(HttpServletRequest request) throws Throwable { String text = ServletUtil.getBody(request); @@ -37,7 +37,7 @@ public class SmsCallbackController { @PostMapping("/tencent") @PermitAll - @ApiOperation(value = "腾讯云短信的回调", notes = "参见 https://cloud.tencent.com/document/product/382/52077 文档") + @Operation(summary = "腾讯云短信的回调", description = "参见 https://cloud.tencent.com/document/product/382/52077 文档") @OperateLog(enable = false) public CommonResult receiveTencentSmsStatus(HttpServletRequest request) throws Throwable { String text = ServletUtil.getBody(request); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsChannelController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsChannelController.java index 638140d21..73057a090 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsChannelController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsChannelController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO; import cn.iocoder.yudao.module.system.service.sms.SmsChannelService; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 短信渠道") +@Tag(name = "管理后台 - 短信渠道") @RestController @RequestMapping("system/sms-channel") public class SmsChannelController { @@ -28,14 +28,14 @@ public class SmsChannelController { private SmsChannelService smsChannelService; @PostMapping("/create") - @ApiOperation("创建短信渠道") + @Operation(summary = "创建短信渠道") @PreAuthorize("@ss.hasPermission('system:sms-channel:create')") public CommonResult createSmsChannel(@Valid @RequestBody SmsChannelCreateReqVO createReqVO) { return success(smsChannelService.createSmsChannel(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新短信渠道") + @Operation(summary = "更新短信渠道") @PreAuthorize("@ss.hasPermission('system:sms-channel:update')") public CommonResult updateSmsChannel(@Valid @RequestBody SmsChannelUpdateReqVO updateReqVO) { smsChannelService.updateSmsChannel(updateReqVO); @@ -43,8 +43,8 @@ public class SmsChannelController { } @DeleteMapping("/delete") - @ApiOperation("删除短信渠道") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除短信渠道") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('system:sms-channel:delete')") public CommonResult deleteSmsChannel(@RequestParam("id") Long id) { smsChannelService.deleteSmsChannel(id); @@ -52,8 +52,8 @@ public class SmsChannelController { } @GetMapping("/get") - @ApiOperation("获得短信渠道") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得短信渠道") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:sms-channel:query')") public CommonResult getSmsChannel(@RequestParam("id") Long id) { SmsChannelDO smsChannel = smsChannelService.getSmsChannel(id); @@ -61,7 +61,7 @@ public class SmsChannelController { } @GetMapping("/page") - @ApiOperation("获得短信渠道分页") + @Operation(summary = "获得短信渠道分页") @PreAuthorize("@ss.hasPermission('system:sms-channel:query')") public CommonResult> getSmsChannelPage(@Valid SmsChannelPageReqVO pageVO) { PageResult pageResult = smsChannelService.getSmsChannelPage(pageVO); @@ -69,7 +69,7 @@ public class SmsChannelController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获得短信渠道精简列表", notes = "包含被禁用的短信渠道") + @Operation(summary = "获得短信渠道精简列表", description = "包含被禁用的短信渠道") public CommonResult> getSimpleSmsChannels() { List list = smsChannelService.getSmsChannelList(); // 排序后,返回给前端 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsLogController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsLogController.java index 5fbf10e74..27b957bd6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsLogController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsLogController.java @@ -11,8 +11,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; @@ -28,7 +28,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 短信日志") +@Tag(name = "管理后台 - 短信日志") @RestController @RequestMapping("/system/sms-log") @Validated @@ -38,7 +38,7 @@ public class SmsLogController { private SmsLogService smsLogService; @GetMapping("/page") - @ApiOperation("获得短信日志分页") + @Operation(summary = "获得短信日志分页") @PreAuthorize("@ss.hasPermission('system:sms-log:query')") public CommonResult> getSmsLogPage(@Valid SmsLogPageReqVO pageVO) { PageResult pageResult = smsLogService.getSmsLogPage(pageVO); @@ -46,7 +46,7 @@ public class SmsLogController { } @GetMapping("/export-excel") - @ApiOperation("导出短信日志 Excel") + @Operation(summary = "导出短信日志 Excel") @PreAuthorize("@ss.hasPermission('system:sms-log:export')") @OperateLog(type = EXPORT) public void exportSmsLogExcel(@Valid SmsLogExportReqVO exportReqVO, diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsTemplateController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsTemplateController.java index 3eef58652..173d8f643 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsTemplateController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsTemplateController.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -24,7 +24,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 短信模板") +@Tag(name = "管理后台 - 短信模板") @RestController @RequestMapping("/system/sms-template") public class SmsTemplateController { @@ -35,14 +35,14 @@ public class SmsTemplateController { private SmsSendService smsSendService; @PostMapping("/create") - @ApiOperation("创建短信模板") + @Operation(summary = "创建短信模板") @PreAuthorize("@ss.hasPermission('system:sms-template:create')") public CommonResult createSmsTemplate(@Valid @RequestBody SmsTemplateCreateReqVO createReqVO) { return success(smsTemplateService.createSmsTemplate(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新短信模板") + @Operation(summary = "更新短信模板") @PreAuthorize("@ss.hasPermission('system:sms-template:update')") public CommonResult updateSmsTemplate(@Valid @RequestBody SmsTemplateUpdateReqVO updateReqVO) { smsTemplateService.updateSmsTemplate(updateReqVO); @@ -50,8 +50,8 @@ public class SmsTemplateController { } @DeleteMapping("/delete") - @ApiOperation("删除短信模板") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除短信模板") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('system:sms-template:delete')") public CommonResult deleteSmsTemplate(@RequestParam("id") Long id) { smsTemplateService.deleteSmsTemplate(id); @@ -59,8 +59,8 @@ public class SmsTemplateController { } @GetMapping("/get") - @ApiOperation("获得短信模板") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得短信模板") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:sms-template:query')") public CommonResult getSmsTemplate(@RequestParam("id") Long id) { SmsTemplateDO smsTemplate = smsTemplateService.getSmsTemplate(id); @@ -68,7 +68,7 @@ public class SmsTemplateController { } @GetMapping("/page") - @ApiOperation("获得短信模板分页") + @Operation(summary = "获得短信模板分页") @PreAuthorize("@ss.hasPermission('system:sms-template:query')") public CommonResult> getSmsTemplatePage(@Valid SmsTemplatePageReqVO pageVO) { PageResult pageResult = smsTemplateService.getSmsTemplatePage(pageVO); @@ -76,7 +76,7 @@ public class SmsTemplateController { } @GetMapping("/export-excel") - @ApiOperation("导出短信模板 Excel") + @Operation(summary = "导出短信模板 Excel") @PreAuthorize("@ss.hasPermission('system:sms-template:export')") @OperateLog(type = EXPORT) public void exportSmsTemplateExcel(@Valid SmsTemplateExportReqVO exportReqVO, @@ -88,7 +88,7 @@ public class SmsTemplateController { } @PostMapping("/send-sms") - @ApiOperation("发送短信") + @Operation(summary = "发送短信") @PreAuthorize("@ss.hasPermission('system:sms-template:send-sms')") public CommonResult sendSms(@Valid @RequestBody SmsTemplateSendReqVO sendReqVO) { return success(smsSendService.sendSingleSmsToAdmin(sendReqVO.getMobile(), null, diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelBaseVO.java index b98697d5a..c63d4545e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.hibernate.validator.constraints.URL; @@ -13,25 +12,25 @@ import javax.validation.constraints.NotNull; @Data public class SmsChannelBaseVO { - @ApiModelProperty(value = "短信签名", required = true, example = "芋道源码") + @Schema(title = "短信签名", required = true, example = "芋道源码") @NotNull(message = "短信签名不能为空") private String signature; - @ApiModelProperty(value = "启用状态", required = true, example = "1") + @Schema(title = "启用状态", required = true, example = "1") @NotNull(message = "启用状态不能为空") private Integer status; - @ApiModelProperty(value = "备注", example = "好吃!") + @Schema(title = "备注", example = "好吃!") private String remark; - @ApiModelProperty(value = "短信 API 的账号", required = true, example = "yudao") + @Schema(title = "短信 API 的账号", required = true, example = "yudao") @NotNull(message = "短信 API 的账号不能为空") private String apiKey; - @ApiModelProperty(value = "短信 API 的密钥", example = "yuanma") + @Schema(title = "短信 API 的密钥", example = "yuanma") private String apiSecret; - @ApiModelProperty(value = "短信发送回调 URL", example = "http://www.iocoder.cn") + @Schema(title = "短信发送回调 URL", example = "http://www.iocoder.cn") @URL(message = "回调 URL 格式不正确") private String callbackUrl; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelCreateReqVO.java index edc162f47..b8940af40 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelCreateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 短信渠道创建 Request VO") +@Schema(title = "管理后台 - 短信渠道创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsChannelCreateReqVO extends SmsChannelBaseVO { - @ApiModelProperty(value = "渠道编码", required = true, example = "YUN_PIAN", notes = "参见 SmsChannelEnum 枚举类") + @Schema(title = "渠道编码", required = true, example = "YUN_PIAN", description = "参见 SmsChannelEnum 枚举类") @NotNull(message = "渠道编码不能为空") private String code; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelPageReqVO.java index f35c5e8ac..9b79a3170 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 短信渠道分页 Request VO") +@Schema(title = "管理后台 - 短信渠道分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsChannelPageReqVO extends PageParam { - @ApiModelProperty(value = "任务状态", example = "1") + @Schema(title = "任务状态", example = "1") private Integer status; - @ApiModelProperty(value = "短信签名", example = "芋道源码", notes = "模糊匹配") + @Schema(title = "短信签名", example = "芋道源码", description = "模糊匹配") private String signature; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelRespVO.java index d52b6d9e7..04b8d95e1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelRespVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 短信渠道 Response VO") +@Schema(title = "管理后台 - 短信渠道 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsChannelRespVO extends SmsChannelBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "渠道编码", required = true, example = "YUN_PIAN", notes = "参见 SmsChannelEnum 枚举类") + @Schema(title = "渠道编码", required = true, example = "YUN_PIAN", description = "参见 SmsChannelEnum 枚举类") private String code; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelSimpleRespVO.java index 22b5bc1d4..57c4c3fb9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelSimpleRespVO.java @@ -1,24 +1,23 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 短信渠道精简 Response VO") +@Schema(title = "管理后台 - 短信渠道精简 Response VO") @Data public class SmsChannelSimpleRespVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; - @ApiModelProperty(value = "短信签名", required = true, example = "芋道源码") + @Schema(title = "短信签名", required = true, example = "芋道源码") @NotNull(message = "短信签名不能为空") private String signature; - @ApiModelProperty(value = "渠道编码", required = true, example = "YUN_PIAN", notes = "参见 SmsChannelEnum 枚举类") + @Schema(title = "渠道编码", required = true, example = "YUN_PIAN", description = "参见 SmsChannelEnum 枚举类") private String code; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelUpdateReqVO.java index 683328745..0d4606821 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 短信渠道更新 Request VO") +@Schema(title = "管理后台 - 短信渠道更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsChannelUpdateReqVO extends SmsChannelBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExportReqVO.java index 55a723a9c..57093888d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.log; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,31 +8,31 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 短信日志 Excel 导出 Request VO", description = "参数和 SmsLogPageReqVO 是一致的") +@Schema(title = "管理后台 - 短信日志 Excel 导出 Request VO", description = "参数和 SmsLogPageReqVO 是一致的") @Data public class SmsLogExportReqVO { - @ApiModelProperty(value = "短信渠道编号", example = "10") + @Schema(title = "短信渠道编号", example = "10") private Long channelId; - @ApiModelProperty(value = "模板编号", example = "20") + @Schema(title = "模板编号", example = "20") private Long templateId; - @ApiModelProperty(value = "手机号", example = "15601691300") + @Schema(title = "手机号", example = "15601691300") private String mobile; - @ApiModelProperty(value = "发送状态", example = "1") + @Schema(title = "发送状态", example = "1") private Integer sendStatus; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始发送时间") + @Schema(title = "开始发送时间") private LocalDateTime[] sendTime; - @ApiModelProperty(value = "接收状态", example = "0") + @Schema(title = "接收状态", example = "0") private Integer receiveStatus; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始接收时间") + @Schema(title = "开始接收时间") private LocalDateTime[] receiveTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java index 87e804796..ce00897dd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.log; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,33 +11,33 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 短信日志分页 Request VO") +@Schema(title = "管理后台 - 短信日志分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsLogPageReqVO extends PageParam { - @ApiModelProperty(value = "短信渠道编号", example = "10") + @Schema(title = "短信渠道编号", example = "10") private Long channelId; - @ApiModelProperty(value = "模板编号", example = "20") + @Schema(title = "模板编号", example = "20") private Long templateId; - @ApiModelProperty(value = "手机号", example = "15601691300") + @Schema(title = "手机号", example = "15601691300") private String mobile; - @ApiModelProperty(value = "发送状态", example = "1", notes = "参见 SmsSendStatusEnum 枚举类") + @Schema(title = "发送状态", example = "1", description = "参见 SmsSendStatusEnum 枚举类") private Integer sendStatus; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "发送时间") + @Schema(title = "发送时间") private LocalDateTime[] sendTime; - @ApiModelProperty(value = "接收状态", example = "0", notes = "参见 SmsReceiveStatusEnum 枚举类") + @Schema(title = "接收状态", example = "0", description = "参见 SmsReceiveStatusEnum 枚举类") private Integer receiveStatus; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "接收时间") + @Schema(title = "接收时间") private LocalDateTime[] receiveTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogRespVO.java index aee9657c8..98ec37f94 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogRespVO.java @@ -1,89 +1,88 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.log; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; import java.util.Map; -@ApiModel("管理后台 - 短信日志 Response VO") +@Schema(title = "管理后台 - 短信日志 Response VO") @Data public class SmsLogRespVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "短信渠道编号", required = true, example = "10") + @Schema(title = "短信渠道编号", required = true, example = "10") private Long channelId; - @ApiModelProperty(value = "短信渠道编码", required = true, example = "ALIYUN") + @Schema(title = "短信渠道编码", required = true, example = "ALIYUN") private String channelCode; - @ApiModelProperty(value = "模板编号", required = true, example = "20") + @Schema(title = "模板编号", required = true, example = "20") private Long templateId; - @ApiModelProperty(value = "模板编码", required = true, example = "test-01") + @Schema(title = "模板编码", required = true, example = "test-01") private String templateCode; - @ApiModelProperty(value = "短信类型", required = true, example = "1") + @Schema(title = "短信类型", required = true, example = "1") private Integer templateType; - @ApiModelProperty(value = "短信内容", required = true, example = "你好,你的验证码是 1024") + @Schema(title = "短信内容", required = true, example = "你好,你的验证码是 1024") private String templateContent; - @ApiModelProperty(value = "短信参数", required = true, example = "name,code") + @Schema(title = "短信参数", required = true, example = "name,code") private Map templateParams; - @ApiModelProperty(value = "短信 API 的模板编号", required = true, example = "SMS_207945135") + @Schema(title = "短信 API 的模板编号", required = true, example = "SMS_207945135") private String apiTemplateId; - @ApiModelProperty(value = "手机号", required = true, example = "15601691300") + @Schema(title = "手机号", required = true, example = "15601691300") private String mobile; - @ApiModelProperty(value = "用户编号", example = "10") + @Schema(title = "用户编号", example = "10") private Long userId; - @ApiModelProperty(value = "用户类型", example = "1") + @Schema(title = "用户类型", example = "1") private Integer userType; - @ApiModelProperty(value = "发送状态", required = true, example = "1") + @Schema(title = "发送状态", required = true, example = "1") private Integer sendStatus; - @ApiModelProperty(value = "发送时间") + @Schema(title = "发送时间") private LocalDateTime sendTime; - @ApiModelProperty(value = "发送结果的编码", example = "0") + @Schema(title = "发送结果的编码", example = "0") private Integer sendCode; - @ApiModelProperty(value = "发送结果的提示", example = "成功") + @Schema(title = "发送结果的提示", example = "成功") private String sendMsg; - @ApiModelProperty(value = "短信 API 发送结果的编码", example = "SUCCESS") + @Schema(title = "短信 API 发送结果的编码", example = "SUCCESS") private String apiSendCode; - @ApiModelProperty(value = "短信 API 发送失败的提示", example = "成功") + @Schema(title = "短信 API 发送失败的提示", example = "成功") private String apiSendMsg; - @ApiModelProperty(value = "短信 API 发送返回的唯一请求 ID", example = "3837C6D3-B96F-428C-BBB2-86135D4B5B99") + @Schema(title = "短信 API 发送返回的唯一请求 ID", example = "3837C6D3-B96F-428C-BBB2-86135D4B5B99") private String apiRequestId; - @ApiModelProperty(value = "短信 API 发送返回的序号", example = "62923244790") + @Schema(title = "短信 API 发送返回的序号", example = "62923244790") private String apiSerialNo; - @ApiModelProperty(value = "接收状态", required = true, example = "0") + @Schema(title = "接收状态", required = true, example = "0") private Integer receiveStatus; - @ApiModelProperty(value = "接收时间") + @Schema(title = "接收时间") private LocalDateTime receiveTime; - @ApiModelProperty(value = "API 接收结果的编码", example = "DELIVRD") + @Schema(title = "API 接收结果的编码", example = "DELIVRD") private String apiReceiveCode; - @ApiModelProperty(value = "API 接收结果的说明", example = "用户接收成功") + @Schema(title = "API 接收结果的说明", example = "用户接收成功") private String apiReceiveMsg; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateBaseVO.java index ca9220f8a..664d52948 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateBaseVO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.template; - -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -12,34 +11,34 @@ import javax.validation.constraints.NotNull; @Data public class SmsTemplateBaseVO { - @ApiModelProperty(value = "短信类型", required = true, example = "1", notes = "参见 SmsTemplateTypeEnum 枚举类") + @Schema(title = "短信类型", required = true, example = "1", description = "参见 SmsTemplateTypeEnum 枚举类") @NotNull(message = "短信类型不能为空") private Integer type; - @ApiModelProperty(value = "开启状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "开启状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") @NotNull(message = "开启状态不能为空") private Integer status; - @ApiModelProperty(value = "模板编码", required = true, example = "test_01") + @Schema(title = "模板编码", required = true, example = "test_01") @NotNull(message = "模板编码不能为空") private String code; - @ApiModelProperty(value = "模板名称", required = true, example = "yudao") + @Schema(title = "模板名称", required = true, example = "yudao") @NotNull(message = "模板名称不能为空") private String name; - @ApiModelProperty(value = "模板内容", required = true, example = "你好,{name}。你长的太{like}啦!") + @Schema(title = "模板内容", required = true, example = "你好,{name}。你长的太{like}啦!") @NotNull(message = "模板内容不能为空") private String content; - @ApiModelProperty(value = "备注", example = "哈哈哈") + @Schema(title = "备注", example = "哈哈哈") private String remark; - @ApiModelProperty(value = "短信 API 的模板编号", required = true, example = "4383920") + @Schema(title = "短信 API 的模板编号", required = true, example = "4383920") @NotNull(message = "短信 API 的模板编号不能为空") private String apiTemplateId; - @ApiModelProperty(value = "短信渠道编号", required = true, example = "10") + @Schema(title = "短信渠道编号", required = true, example = "10") @NotNull(message = "短信渠道编号不能为空") private Long channelId; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateCreateReqVO.java index ab8b89ebd..9546b83e7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateCreateReqVO.java @@ -1,11 +1,10 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.template; - -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 短信模板创建 Request VO") +@Schema(title = "管理后台 - 短信模板创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExportReqVO.java index df5947adc..0f84463af 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.template; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,30 +8,30 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 短信模板 Excel 导出 Request VO", description = "参数和 SmsTemplatePageReqVO 是一致的") +@Schema(title = "管理后台 - 短信模板 Excel 导出 Request VO", description = "参数和 SmsTemplatePageReqVO 是一致的") @Data public class SmsTemplateExportReqVO { - @ApiModelProperty(value = "短信签名", example = "1") + @Schema(title = "短信签名", example = "1") private Integer type; - @ApiModelProperty(value = "开启状态", example = "1") + @Schema(title = "开启状态", example = "1") private Integer status; - @ApiModelProperty(value = "模板编码", example = "test_01", notes = "模糊匹配") + @Schema(title = "模板编码", example = "test_01", description = "模糊匹配") private String code; - @ApiModelProperty(value = "模板内容", example = "你好,{name}。你长的太{like}啦!", notes = "模糊匹配") + @Schema(title = "模板内容", example = "你好,{name}。你长的太{like}啦!", description = "模糊匹配") private String content; - @ApiModelProperty(value = "短信 API 的模板编号", example = "4383920", notes = "模糊匹配") + @Schema(title = "短信 API 的模板编号", example = "4383920", description = "模糊匹配") private String apiTemplateId; - @ApiModelProperty(value = "短信渠道编号", example = "10") + @Schema(title = "短信渠道编号", example = "10") private Long channelId; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplatePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplatePageReqVO.java index 129e0f7a8..3cb26d228 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplatePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplatePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.template; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,32 +11,32 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 短信模板分页 Request VO") +@Schema(title = "管理后台 - 短信模板分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsTemplatePageReqVO extends PageParam { - @ApiModelProperty(value = "短信签名", example = "1") + @Schema(title = "短信签名", example = "1") private Integer type; - @ApiModelProperty(value = "开启状态", example = "1") + @Schema(title = "开启状态", example = "1") private Integer status; - @ApiModelProperty(value = "模板编码", example = "test_01", notes = "模糊匹配") + @Schema(title = "模板编码", example = "test_01", description = "模糊匹配") private String code; - @ApiModelProperty(value = "模板内容", example = "你好,{name}。你长的太{like}啦!", notes = "模糊匹配") + @Schema(title = "模板内容", example = "你好,{name}。你长的太{like}啦!", description = "模糊匹配") private String content; - @ApiModelProperty(value = "短信 API 的模板编号", example = "4383920", notes = "模糊匹配") + @Schema(title = "短信 API 的模板编号", example = "4383920", description = "模糊匹配") private String apiTemplateId; - @ApiModelProperty(value = "短信渠道编号", example = "10") + @Schema(title = "短信渠道编号", example = "10") private Long channelId; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateRespVO.java index 8a10503cb..853056b16 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.template; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,22 +8,22 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@ApiModel("管理后台 - 短信模板 Response VO") +@Schema(title = "管理后台 - 短信模板 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsTemplateRespVO extends SmsTemplateBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "短信渠道编码", required = true, example = "ALIYUN") + @Schema(title = "短信渠道编码", required = true, example = "ALIYUN") private String channelCode; - @ApiModelProperty(value = "参数数组", example = "name,code") + @Schema(title = "参数数组", example = "name,code") private List params; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateSendReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateSendReqVO.java index 956b4839e..f8ca2a0e0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateSendReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateSendReqVO.java @@ -1,25 +1,24 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.template; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.Map; -@ApiModel("管理后台 - 短信模板的发送 Request VO") +@Schema(title = "管理后台 - 短信模板的发送 Request VO") @Data public class SmsTemplateSendReqVO { - @ApiModelProperty(value = "手机号", required = true, example = "15601691300") + @Schema(title = "手机号", required = true, example = "15601691300") @NotNull(message = "手机号不能为空") private String mobile; - @ApiModelProperty(value = "模板编码", required = true, example = "test_01") + @Schema(title = "模板编码", required = true, example = "test_01") @NotNull(message = "模板编码不能为空") private String templateCode; - @ApiModelProperty(value = "模板参数") + @Schema(title = "模板参数") private Map templateParams; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateUpdateReqVO.java index 86bdbba9a..44531e799 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.sms.vo.template; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 短信模板更新 Request VO") +@Schema(title = "管理后台 - 短信模板更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsTemplateUpdateReqVO extends SmsTemplateBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(title = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/SocialUserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/SocialUserController.java index 85585f537..0a0682f69 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/SocialUserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/SocialUserController.java @@ -6,8 +6,8 @@ import cn.iocoder.yudao.module.system.controller.admin.socail.vo.SocialUserBindR import cn.iocoder.yudao.module.system.controller.admin.socail.vo.SocialUserUnbindReqVO; import cn.iocoder.yudao.module.system.convert.social.SocialUserConvert; import cn.iocoder.yudao.module.system.service.social.SocialUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -16,7 +16,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Api(tags = "管理后台 - 社交用户") +@Tag(name = "管理后台 - 社交用户") @RestController @RequestMapping("/system/social-user") @Validated @@ -26,14 +26,14 @@ public class SocialUserController { private SocialUserService socialUserService; @PostMapping("/bind") - @ApiOperation("社交绑定,使用 code 授权码") + @Operation(summary = "社交绑定,使用 code 授权码") public CommonResult socialBind(@RequestBody @Valid SocialUserBindReqVO reqVO) { socialUserService.bindSocialUser(SocialUserConvert.INSTANCE.convert(getLoginUserId(), UserTypeEnum.ADMIN.getValue(), reqVO)); return CommonResult.success(true); } @DeleteMapping("/unbind") - @ApiOperation("取消社交绑定") + @Operation(summary = "取消社交绑定") public CommonResult socialUnbind(@RequestBody SocialUserUnbindReqVO reqVO) { socialUserService.unbindSocialUser(getLoginUserId(), UserTypeEnum.ADMIN.getValue(), reqVO.getType(), reqVO.getOpenid()); return CommonResult.success(true); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserBindReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserBindReqVO.java index 27dd6b79a..54d52e1f0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserBindReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserBindReqVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.system.controller.admin.socail.vo; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,23 +11,23 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 社交绑定 Request VO,使用 code 授权码") +@Schema(title = "管理后台 - 社交绑定 Request VO,使用 code 授权码") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class SocialUserBindReqVO { - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 UserSocialTypeEnum 枚举值") + @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 UserSocialTypeEnum 枚举值") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @ApiModelProperty(value = "授权码", required = true, example = "1024") + @Schema(title = "授权码", required = true, example = "1024") @NotEmpty(message = "授权码不能为空") private String code; - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") @NotEmpty(message = "state 不能为空") private String state; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserUnbindReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserUnbindReqVO.java index 68904ce58..933e06d9b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserUnbindReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserUnbindReqVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.system.controller.admin.socail.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -12,19 +11,19 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 取消社交绑定 Request VO") +@Schema(title = "管理后台 - 取消社交绑定 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class SocialUserUnbindReqVO { - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 UserSocialTypeEnum 枚举值") + @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 UserSocialTypeEnum 枚举值") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @ApiModelProperty(value = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") + @Schema(title = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") @NotEmpty(message = "社交用户的 openid 不能为空") private String openid; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java index acc21d3fa..0020c9280 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.*; import cn.iocoder.yudao.module.system.convert.tenant.TenantConvert; import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; import cn.iocoder.yudao.module.system.service.tenant.TenantService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -24,7 +24,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 租户") +@Tag(name = "管理后台 - 租户") @RestController @RequestMapping("/system/tenant") public class TenantController { @@ -34,22 +34,22 @@ public class TenantController { @GetMapping("/get-id-by-name") @PermitAll - @ApiOperation(value = "使用租户名,获得租户编号", notes = "登录界面,根据用户的租户名,获得租户编号") - @ApiImplicitParam(name = "name", value = "租户名", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "使用租户名,获得租户编号", description = "登录界面,根据用户的租户名,获得租户编号") + @Parameter(name = "name", description = "租户名", required = true, example = "1024") public CommonResult getTenantIdByName(@RequestParam("name") String name) { TenantDO tenantDO = tenantService.getTenantByName(name); return success(tenantDO != null ? tenantDO.getId() : null); } @PostMapping("/create") - @ApiOperation("创建租户") + @Operation(summary = "创建租户") @PreAuthorize("@ss.hasPermission('system:tenant:create')") public CommonResult createTenant(@Valid @RequestBody TenantCreateReqVO createReqVO) { return success(tenantService.createTenant(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新租户") + @Operation(summary = "更新租户") @PreAuthorize("@ss.hasPermission('system:tenant:update')") public CommonResult updateTenant(@Valid @RequestBody TenantUpdateReqVO updateReqVO) { tenantService.updateTenant(updateReqVO); @@ -57,8 +57,8 @@ public class TenantController { } @DeleteMapping("/delete") - @ApiOperation("删除租户") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除租户") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:tenant:delete')") public CommonResult deleteTenant(@RequestParam("id") Long id) { tenantService.deleteTenant(id); @@ -66,8 +66,8 @@ public class TenantController { } @GetMapping("/get") - @ApiOperation("获得租户") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得租户") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:tenant:query')") public CommonResult getTenant(@RequestParam("id") Long id) { TenantDO tenant = tenantService.getTenant(id); @@ -75,7 +75,7 @@ public class TenantController { } @GetMapping("/page") - @ApiOperation("获得租户分页") + @Operation(summary = "获得租户分页") @PreAuthorize("@ss.hasPermission('system:tenant:query')") public CommonResult> getTenantPage(@Valid TenantPageReqVO pageVO) { PageResult pageResult = tenantService.getTenantPage(pageVO); @@ -83,7 +83,7 @@ public class TenantController { } @GetMapping("/export-excel") - @ApiOperation("导出租户 Excel") + @Operation(summary = "导出租户 Excel") @PreAuthorize("@ss.hasPermission('system:tenant:export')") @OperateLog(type = EXPORT) public void exportTenantExcel(@Valid TenantExportReqVO exportReqVO, diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantPackageController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantPackageController.java index b69b0dca5..ec4782388 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantPackageController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantPackageController.java @@ -7,9 +7,9 @@ import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.*; import cn.iocoder.yudao.module.system.convert.tenant.TenantPackageConvert; import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO; import cn.iocoder.yudao.module.system.service.tenant.TenantPackageService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 租户套餐") +@Tag(name = "管理后台 - 租户套餐") @RestController @RequestMapping("/system/tenant-package") @Validated @@ -30,14 +30,14 @@ public class TenantPackageController { private TenantPackageService tenantPackageService; @PostMapping("/create") - @ApiOperation("创建租户套餐") + @Operation(summary = "创建租户套餐") @PreAuthorize("@ss.hasPermission('system:tenant-package:create')") public CommonResult createTenantPackage(@Valid @RequestBody TenantPackageCreateReqVO createReqVO) { return success(tenantPackageService.createTenantPackage(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新租户套餐") + @Operation(summary = "更新租户套餐") @PreAuthorize("@ss.hasPermission('system:tenant-package:update')") public CommonResult updateTenantPackage(@Valid @RequestBody TenantPackageUpdateReqVO updateReqVO) { tenantPackageService.updateTenantPackage(updateReqVO); @@ -45,8 +45,8 @@ public class TenantPackageController { } @DeleteMapping("/delete") - @ApiOperation("删除租户套餐") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除租户套餐") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('system:tenant-package:delete')") public CommonResult deleteTenantPackage(@RequestParam("id") Long id) { tenantPackageService.deleteTenantPackage(id); @@ -54,8 +54,8 @@ public class TenantPackageController { } @GetMapping("/get") - @ApiOperation("获得租户套餐") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得租户套餐") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:tenant-package:query')") public CommonResult getTenantPackage(@RequestParam("id") Long id) { TenantPackageDO tenantPackage = tenantPackageService.getTenantPackage(id); @@ -63,7 +63,7 @@ public class TenantPackageController { } @GetMapping("/page") - @ApiOperation("获得租户套餐分页") + @Operation(summary = "获得租户套餐分页") @PreAuthorize("@ss.hasPermission('system:tenant-package:query')") public CommonResult> getTenantPackagePage(@Valid TenantPackagePageReqVO pageVO) { PageResult pageResult = tenantPackageService.getTenantPackagePage(pageVO); @@ -71,7 +71,7 @@ public class TenantPackageController { } @GetMapping("/get-simple-list") - @ApiOperation(value = "获取租户套餐精简信息列表", notes = "只包含被开启的租户套餐,主要用于前端的下拉选项") + @Operation(summary = "获取租户套餐精简信息列表", description = "只包含被开启的租户套餐,主要用于前端的下拉选项") public CommonResult> getTenantPackageList() { // 获得角色列表,只要开启状态的 List list = tenantPackageService.getTenantPackageListByStatus(CommonStatusEnum.ENABLE.getStatus()); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageBaseVO.java index 36c838366..d4ff85926 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; @@ -13,18 +13,18 @@ import java.util.Set; @Data public class TenantPackageBaseVO { - @ApiModelProperty(value = "套餐名", required = true, example = "VIP") + @Schema(title = "套餐名", required = true, example = "VIP") @NotNull(message = "套餐名不能为空") private String name; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") private Integer status; - @ApiModelProperty(value = "备注", example = "好") + @Schema(title = "备注", example = "好") private String remark; - @ApiModelProperty(value = "关联的菜单编号", required = true) + @Schema(title = "关联的菜单编号", required = true) @NotNull(message = "关联的菜单编号不能为空") private Set menuIds; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageCreateReqVO.java index 2290e5ca6..46f544fa6 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageCreateReqVO.java @@ -1,11 +1,11 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 租户套餐创建 Request VO") +@Schema(title = "管理后台 - 租户套餐创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java index 7a2fd2493..984dafb39 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,22 +11,22 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 租户套餐分页 Request VO") +@Schema(title = "管理后台 - 租户套餐分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantPackagePageReqVO extends PageParam { - @ApiModelProperty(value = "套餐名", example = "VIP") + @Schema(title = "套餐名", example = "VIP") private String name; - @ApiModelProperty(value = "状态", example = "1") + @Schema(title = "状态", example = "1") private Integer status; - @ApiModelProperty(value = "备注", example = "好") + @Schema(title = "备注", example = "好") private String remark; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java index b46772922..e1734cd7b 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java @@ -1,23 +1,22 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.time.LocalDateTime; -@ApiModel("管理后台 - 租户套餐 Response VO") +@Schema(title = "管理后台 - 租户套餐 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantPackageRespVO extends TenantPackageBaseVO { - @ApiModelProperty(value = "套餐编号", required = true, example = "1024") + @Schema(title = "套餐编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java index 4ec1c97f7..112495807 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 租户套餐精简 Response VO") +@Schema(title = "管理后台 - 租户套餐精简 Response VO") @Data public class TenantPackageSimpleRespVO { - @ApiModelProperty(value = "套餐编号", required = true, example = "1024") + @Schema(title = "套餐编号", required = true, example = "1024") @NotNull(message = "套餐编号不能为空") private Long id; - @ApiModelProperty(value = "套餐名", required = true, example = "VIP") + @Schema(title = "套餐名", required = true, example = "VIP") @NotNull(message = "套餐名不能为空") private String name; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageUpdateReqVO.java index b1d269607..4e4a9cdfc 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageUpdateReqVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import java.util.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 租户套餐更新 Request VO") +@Schema(title = "管理后台 - 租户套餐更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantPackageUpdateReqVO extends TenantPackageBaseVO { - @ApiModelProperty(value = "套餐编号", required = true, example = "1024") + @Schema(title = "套餐编号", required = true, example = "1024") @NotNull(message = "套餐编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java index 226c9b449..4a1570135 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -import org.hibernate.validator.constraints.URL; import javax.validation.constraints.*; import java.time.LocalDateTime; @@ -14,34 +13,33 @@ import java.time.LocalDateTime; @Data public class TenantBaseVO { - @ApiModelProperty(value = "租户名", required = true, example = "芋道") + @Schema(title = "租户名", required = true, example = "芋道") @NotNull(message = "租户名不能为空") private String name; - @ApiModelProperty(value = "联系人", required = true, example = "芋艿") + @Schema(title = "联系人", required = true, example = "芋艿") @NotNull(message = "联系人不能为空") private String contactName; - @ApiModelProperty(value = "联系手机", example = "15601691300") + @Schema(title = "联系手机", example = "15601691300") private String contactMobile; - @ApiModelProperty(value = "租户状态", required = true, example = "1") + @Schema(title = "租户状态", required = true, example = "1") @NotNull(message = "租户状态") private Integer status; - @ApiModelProperty(value = "绑定域名", example = "https://www.iocoder.cn") - @URL(message = "绑定域名的地址非 URL 格式") + @Schema(title = "绑定域名", example = "https://www.iocoder.cn") private String domain; - @ApiModelProperty(value = "租户套餐编号", required = true, example = "1024") + @Schema(title = "租户套餐编号", required = true, example = "1024") @NotNull(message = "租户套餐编号不能为空") private Long packageId; - @ApiModelProperty(value = "过期时间", required = true) + @Schema(title = "过期时间", required = true) @NotNull(message = "过期时间不能为空") private LocalDateTime expireTime; - @ApiModelProperty(value = "账号数量", required = true, example = "1024") + @Schema(title = "账号数量", required = true, example = "1024") @NotNull(message = "账号数量不能为空") private Integer accountCount; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantCreateReqVO.java index ff52811eb..209643cea 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantCreateReqVO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotBlank; @@ -9,19 +9,19 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; -@ApiModel("管理后台 - 租户创建 Request VO") +@Schema(title = "管理后台 - 租户创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantCreateReqVO extends TenantBaseVO { - @ApiModelProperty(value = "用户账号", required = true, example = "yudao") + @Schema(title = "用户账号", required = true, example = "yudao") @NotBlank(message = "用户账号不能为空") @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成") @Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符") private String username; - @ApiModelProperty(value = "密码", required = true, example = "123456") + @Schema(title = "密码", required = true, example = "123456") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantExportReqVO.java index 6498714af..92e365912 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -9,24 +8,24 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 租户 Excel 导出 Request VO", description = "参数和 TenantPageReqVO 是一致的") +@Schema(title = "管理后台 - 租户 Excel 导出 Request VO", description = "参数和 TenantPageReqVO 是一致的") @Data public class TenantExportReqVO { - @ApiModelProperty(value = "租户名", example = "芋道") + @Schema(title = "租户名", example = "芋道") private String name; - @ApiModelProperty(value = "联系人", example = "芋艿") + @Schema(title = "联系人", example = "芋艿") private String contactName; - @ApiModelProperty(value = "联系手机", example = "15601691300") + @Schema(title = "联系手机", example = "15601691300") private String contactMobile; - @ApiModelProperty(value = "租户状态(0正常 1停用)", example = "1") + @Schema(title = "租户状态(0正常 1停用)", example = "1") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java index 499ecfd2f..501d75a77 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,26 +11,26 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 租户分页 Request VO") +@Schema(title = "管理后台 - 租户分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantPageReqVO extends PageParam { - @ApiModelProperty(value = "租户名", example = "芋道") + @Schema(title = "租户名", example = "芋道") private String name; - @ApiModelProperty(value = "联系人", example = "芋艿") + @Schema(title = "联系人", example = "芋艿") private String contactName; - @ApiModelProperty(value = "联系手机", example = "15601691300") + @Schema(title = "联系手机", example = "15601691300") private String contactMobile; - @ApiModelProperty(value = "租户状态(0正常 1停用)", example = "1") + @Schema(title = "租户状态(0正常 1停用)", example = "1") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(title = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java index b2345d167..bbd3932c9 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java @@ -1,20 +1,20 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import java.time.LocalDateTime; -@ApiModel("管理后台 - 租户 Response VO") +@Schema(title = "管理后台 - 租户 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantRespVO extends TenantBaseVO { - @ApiModelProperty(value = "租户编号", required = true, example = "1024") + @Schema(title = "租户编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(title = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantUpdateReqVO.java index 881d5fb87..dd8be9659 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantUpdateReqVO.java @@ -1,16 +1,16 @@ package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 租户更新 Request VO") +@Schema(title = "管理后台 - 租户更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantUpdateReqVO extends TenantBaseVO { - @ApiModelProperty(value = "租户编号", required = true, example = "1024") + @Schema(title = "租户编号", required = true, example = "1024") @NotNull(message = "租户编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index 993b66dea..82fc0acd4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java @@ -14,10 +14,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -34,7 +34,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -@Api(tags = "管理后台 - 用户") +@Tag(name = "管理后台 - 用户") @RestController @RequestMapping("/system/user") @Validated @@ -46,7 +46,7 @@ public class UserController { private DeptService deptService; @PostMapping("/create") - @ApiOperation("新增用户") + @Operation(summary = "新增用户") @PreAuthorize("@ss.hasPermission('system:user:create')") public CommonResult createUser(@Valid @RequestBody UserCreateReqVO reqVO) { Long id = userService.createUser(reqVO); @@ -54,7 +54,7 @@ public class UserController { } @PutMapping("update") - @ApiOperation("修改用户") + @Operation(summary = "修改用户") @PreAuthorize("@ss.hasPermission('system:user:update')") public CommonResult updateUser(@Valid @RequestBody UserUpdateReqVO reqVO) { userService.updateUser(reqVO); @@ -62,8 +62,8 @@ public class UserController { } @DeleteMapping("/delete") - @ApiOperation("删除用户") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除用户") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:user:delete')") public CommonResult deleteUser(@RequestParam("id") Long id) { userService.deleteUser(id); @@ -71,7 +71,7 @@ public class UserController { } @PutMapping("/update-password") - @ApiOperation("重置用户密码") + @Operation(summary = "重置用户密码") @PreAuthorize("@ss.hasPermission('system:user:update-password')") public CommonResult updateUserPassword(@Valid @RequestBody UserUpdatePasswordReqVO reqVO) { userService.updateUserPassword(reqVO.getId(), reqVO.getPassword()); @@ -79,7 +79,7 @@ public class UserController { } @PutMapping("/update-status") - @ApiOperation("修改用户状态") + @Operation(summary = "修改用户状态") @PreAuthorize("@ss.hasPermission('system:user:update')") public CommonResult updateUserStatus(@Valid @RequestBody UserUpdateStatusReqVO reqVO) { userService.updateUserStatus(reqVO.getId(), reqVO.getStatus()); @@ -87,7 +87,7 @@ public class UserController { } @GetMapping("/page") - @ApiOperation("获得用户分页列表") + @Operation(summary = "获得用户分页列表") @PreAuthorize("@ss.hasPermission('system:user:list')") public CommonResult> getUserPage(@Valid UserPageReqVO reqVO) { // 获得用户分页列表 @@ -110,7 +110,7 @@ public class UserController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获取用户精简信息列表", notes = "只包含被开启的用户,主要用于前端的下拉选项") + @Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项") public CommonResult> getSimpleUsers() { // 获用户门列表,只要开启状态的 List list = userService.getUsersByStatus(CommonStatusEnum.ENABLE.getStatus()); @@ -119,15 +119,15 @@ public class UserController { } @GetMapping("/get") - @ApiOperation("获得用户详情") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得用户详情") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:user:query')") public CommonResult getInfo(@RequestParam("id") Long id) { return success(UserConvert.INSTANCE.convert(userService.getUser(id))); } @GetMapping("/export") - @ApiOperation("导出用户") + @Operation(summary = "导出用户") @PreAuthorize("@ss.hasPermission('system:user:export')") @OperateLog(type = EXPORT) public void exportUsers(@Validated UserExportReqVO reqVO, @@ -159,7 +159,7 @@ public class UserController { } @GetMapping("/get-import-template") - @ApiOperation("获得导入用户模板") + @Operation(summary = "获得导入用户模板") public void importTemplate(HttpServletResponse response) throws IOException { // 手动创建导出 demo List list = Arrays.asList( @@ -174,10 +174,10 @@ public class UserController { } @PostMapping("/import") - @ApiOperation("导入用户") - @ApiImplicitParams({ - @ApiImplicitParam(name = "file", value = "Excel 文件", required = true, dataTypeClass = MultipartFile.class), - @ApiImplicitParam(name = "updateSupport", value = "是否支持更新,默认为 false", example = "true", dataTypeClass = Boolean.class) + @Operation(summary = "导入用户") + @Parameters({ + @Parameter(name = "file", description = "Excel 文件", required = true), + @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") }) @PreAuthorize("@ss.hasPermission('system:user:import')") public CommonResult importExcel(@RequestParam("file") MultipartFile file, diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java index d65994379..50e1ef0cd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java @@ -20,8 +20,8 @@ import cn.iocoder.yudao.module.system.service.permission.PermissionService; import cn.iocoder.yudao.module.system.service.permission.RoleService; import cn.iocoder.yudao.module.system.service.social.SocialUserService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -35,7 +35,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_IS_EMPTY; -@Api(tags = "管理后台 - 用户个人中心") +@Tag(name = "管理后台 - 用户个人中心") @RestController @RequestMapping("/system/user/profile") @Validated @@ -56,7 +56,7 @@ public class UserProfileController { private SocialUserService socialService; @GetMapping("/get") - @ApiOperation("获得登录用户信息") + @Operation(summary = "获得登录用户信息") @DataPermission(enable = false) // 关闭数据权限,避免只查看自己时,查询不到部门。 public CommonResult profile() { // 获得用户基本信息 @@ -82,21 +82,21 @@ public class UserProfileController { } @PutMapping("/update") - @ApiOperation("修改用户个人信息") + @Operation(summary = "修改用户个人信息") public CommonResult updateUserProfile(@Valid @RequestBody UserProfileUpdateReqVO reqVO) { userService.updateUserProfile(getLoginUserId(), reqVO); return success(true); } @PutMapping("/update-password") - @ApiOperation("修改用户个人密码") + @Operation(summary = "修改用户个人密码") public CommonResult updateUserProfilePassword(@Valid @RequestBody UserProfileUpdatePasswordReqVO reqVO) { userService.updateUserPassword(getLoginUserId(), reqVO); return success(true); } @RequestMapping(value = "/update-avatar", method = {RequestMethod.POST, RequestMethod.PUT}) // 解决 uni-app 不支持 Put 上传文件的问题 - @ApiOperation("上传用户个人头像") + @Operation(summary = "上传用户个人头像") public CommonResult updateUserAvatar(@RequestParam("avatarFile") MultipartFile file) throws Exception { if (file.isEmpty()) { throw ServiceExceptionUtil.exception(FILE_IS_EMPTY); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java index 8767c0593..4a0dd9b9d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.profile; import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserBaseVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -16,22 +15,22 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @NoArgsConstructor @AllArgsConstructor -@ApiModel("管理后台 - 用户个人中心信息 Response VO") +@Schema(title = "管理后台 - 用户个人中心信息 Response VO") public class UserProfileRespVO extends UserBaseVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1") + @Schema(title = "用户编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "最后登录 IP", required = true, example = "192.168.1.1") + @Schema(title = "最后登录 IP", required = true, example = "192.168.1.1") private String loginIp; - @ApiModelProperty(value = "最后登录时间", required = true, example = "时间戳格式") + @Schema(title = "最后登录时间", required = true, example = "时间戳格式") private LocalDateTime loginDate; - @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + @Schema(title = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; /** @@ -53,50 +52,50 @@ public class UserProfileRespVO extends UserBaseVO { */ private List socialUsers; - @ApiModel("角色") + @Schema(title = "角色") @Data public static class Role { - @ApiModelProperty(value = "角色编号", required = true, example = "1") + @Schema(title = "角色编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "角色名称", required = true, example = "普通角色") + @Schema(title = "角色名称", required = true, example = "普通角色") private String name; } - @ApiModel("部门") + @Schema(title = "部门") @Data public static class Dept { - @ApiModelProperty(value = "部门编号", required = true, example = "1") + @Schema(title = "部门编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "部门名称", required = true, example = "研发部") + @Schema(title = "部门名称", required = true, example = "研发部") private String name; } - @ApiModel("岗位") + @Schema(title = "岗位") @Data public static class Post { - @ApiModelProperty(value = "岗位编号", required = true, example = "1") + @Schema(title = "岗位编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "岗位名称", required = true, example = "开发") + @Schema(title = "岗位名称", required = true, example = "开发") private String name; } - @ApiModel("社交用户") + @Schema(title = "社交用户") @Data public static class SocialUser { - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SocialTypeEnum 枚举类") + @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SocialTypeEnum 枚举类") private Integer type; - @ApiModelProperty(value = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") + @Schema(title = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") private String openid; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdatePasswordReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdatePasswordReqVO.java index 2269b37df..94684ce6c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdatePasswordReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdatePasswordReqVO.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 用户个人中心更新密码 Request VO") +@Schema(title = "管理后台 - 用户个人中心更新密码 Request VO") @Data public class UserProfileUpdatePasswordReqVO { - @ApiModelProperty(value = "旧密码", required = true, example = "123456") + @Schema(title = "旧密码", required = true, example = "123456") @NotEmpty(message = "旧密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String oldPassword; - @ApiModelProperty(value = "新密码", required = true, example = "654321") + @Schema(title = "新密码", required = true, example = "654321") @NotEmpty(message = "新密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String newPassword; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java index 5ab28d1e7..e9696add5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java @@ -1,31 +1,29 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import org.hibernate.validator.constraints.Length; import javax.validation.constraints.Email; import javax.validation.constraints.Size; -@ApiModel("管理后台 - 用户个人信息更新 Request VO") + +@Schema(title = "管理后台 - 用户个人信息更新 Request VO") @Data public class UserProfileUpdateReqVO { - @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") + @Schema(title = "用户昵称", required = true, example = "芋艿") @Size(max = 30, message = "用户昵称长度不能超过 30 个字符") private String nickname; - @ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn") + @Schema(title = "用户邮箱", example = "yudao@iocoder.cn") @Email(message = "邮箱格式不正确") @Size(max = 50, message = "邮箱长度不能超过 50 个字符") private String email; - @ApiModelProperty(value = "手机号码", example = "15601691300") - @Length(min = 11, max = 11, message = "手机号长度必须 11 位") + @Schema(title = "手机号码", example = "15601691300") private String mobile; - @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SexEnum 枚举类") + @Schema(title = "用户性别", example = "1", description = "参见 SexEnum 枚举类") private Integer sex; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserBaseVO.java index 5268b10c7..ea9fff93b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserBaseVO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; import cn.iocoder.yudao.framework.common.validation.Mobile; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.Email; @@ -17,38 +17,38 @@ import java.util.Set; @Data public class UserBaseVO { - @ApiModelProperty(value = "用户账号", required = true, example = "yudao") + @Schema(title = "用户账号", required = true, example = "yudao") @NotBlank(message = "用户账号不能为空") @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成") @Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符") private String username; - @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿") + @Schema(title = "用户昵称", required = true, example = "芋艿") @Size(max = 30, message = "用户昵称长度不能超过30个字符") private String nickname; - @ApiModelProperty(value = "备注", example = "我是一个用户") + @Schema(title = "备注", example = "我是一个用户") private String remark; - @ApiModelProperty(value = "部门ID", example = "我是一个用户") + @Schema(title = "部门ID", example = "我是一个用户") private Long deptId; - @ApiModelProperty(value = "岗位编号数组", example = "1") + @Schema(title = "岗位编号数组", example = "1") private Set postIds; - @ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn") + @Schema(title = "用户邮箱", example = "yudao@iocoder.cn") @Email(message = "邮箱格式不正确") @Size(max = 50, message = "邮箱长度不能超过 50 个字符") private String email; - @ApiModelProperty(value = "手机号码", example = "15601691300") + @Schema(title = "手机号码", example = "15601691300") @Mobile private String mobile; - @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SexEnum 枚举类") + @Schema(title = "用户性别", example = "1", description = "参见 SexEnum 枚举类") private Integer sex; - @ApiModelProperty(value = "用户头像", example = "https://www.iocoder.cn/xxx.png") + @Schema(title = "用户头像", example = "https://www.iocoder.cn/xxx.png") private String avatar; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserCreateReqVO.java index 9d0ff1988..940ad80a3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserCreateReqVO.java @@ -1,20 +1,18 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 用户创建 Request VO") +@Schema(title = "管理后台 - 用户创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class UserCreateReqVO extends UserBaseVO { - @ApiModelProperty(value = "密码", required = true, example = "123456") + @Schema(title = "密码", required = true, example = "123456") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserExportReqVO.java index 387ad784a..356db6444 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserExportReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -11,26 +10,26 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel(value = "管理后台 - 用户导出 Request VO", description = "参数和 UserPageReqVO 是一致的") +@Schema(title = "管理后台 - 用户导出 Request VO", description = "参数和 UserPageReqVO 是一致的") @Data @NoArgsConstructor @AllArgsConstructor public class UserExportReqVO { - @ApiModelProperty(value = "用户账号", example = "yudao", notes = "模糊匹配") + @Schema(title = "用户账号", example = "yudao", description = "模糊匹配") private String username; - @ApiModelProperty(value = "手机号码", example = "yudao", notes = "模糊匹配") + @Schema(title = "手机号码", example = "yudao", description = "模糊匹配") private String mobile; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; - @ApiModelProperty(value = "部门编号", example = "1024", notes = "同时筛选子部门") + @Schema(title = "部门编号", example = "1024", description = "同时筛选子部门") private Long deptId; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportRespVO.java index 49f9b98d1..36ffa2f71 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportRespVO.java @@ -1,25 +1,24 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import java.util.List; import java.util.Map; -@ApiModel("管理后台 - 用户导入 Response VO") +@Schema(title = "管理后台 - 用户导入 Response VO") @Data @Builder public class UserImportRespVO { - @ApiModelProperty(value = "创建成功的用户名数组", required = true) + @Schema(title = "创建成功的用户名数组", required = true) private List createUsernames; - @ApiModelProperty(value = "更新成功的用户名数组", required = true) + @Schema(title = "更新成功的用户名数组", required = true) private List updateUsernames; - @ApiModelProperty(value = "导入失败的用户集合", required = true, notes = "key 为用户名,value 为失败原因") + @Schema(title = "导入失败的用户集合", required = true, description = "key 为用户名,value 为失败原因") private Map failureUsernames; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageItemRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageItemRespVO.java index bcfe9ea23..21f72b090 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageItemRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageItemRespVO.java @@ -1,13 +1,12 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -@ApiModel(value = "管理后台 - 用户分页时的信息 Response VO", description = "相比用户基本信息来说,会多部门信息") +@Schema(title = "管理后台 - 用户分页时的信息 Response VO", description = "相比用户基本信息来说,会多部门信息") @Data @NoArgsConstructor @AllArgsConstructor @@ -19,14 +18,14 @@ public class UserPageItemRespVO extends UserRespVO { */ private Dept dept; - @ApiModel("部门") + @Schema(title = "部门") @Data public static class Dept { - @ApiModelProperty(value = "部门编号", required = true, example = "1") + @Schema(title = "部门编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "部门名称", required = true, example = "研发部") + @Schema(title = "部门名称", required = true, example = "研发部") private String name; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java index cbac2d9a5..193a74807 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -13,27 +12,27 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 用户分页 Request VO") +@Schema(title = "管理后台 - 用户分页 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class UserPageReqVO extends PageParam { - @ApiModelProperty(value = "用户账号", example = "yudao", notes = "模糊匹配") + @Schema(title = "用户账号", example = "yudao", description = "模糊匹配") private String username; - @ApiModelProperty(value = "手机号码", example = "yudao", notes = "模糊匹配") + @Schema(title = "手机号码", example = "yudao", description = "模糊匹配") private String mobile; - @ApiModelProperty(value = "展示状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; - @ApiModelProperty(value = "部门编号", example = "1024", notes = "同时筛选子部门") + @Schema(title = "部门编号", example = "1024", description = "同时筛选子部门") private Long deptId; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java index 972b3818b..68208729c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java @@ -1,32 +1,31 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -@ApiModel("管理后台 - 用户信息 Response VO") +@Schema(title = "管理后台 - 用户信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class UserRespVO extends UserBaseVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1") + @Schema(title = "用户编号", required = true, example = "1") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") private Integer status; - @ApiModelProperty(value = "最后登录 IP", required = true, example = "192.168.1.1") + @Schema(title = "最后登录 IP", required = true, example = "192.168.1.1") private String loginIp; - @ApiModelProperty(value = "最后登录时间", required = true, example = "时间戳格式") + @Schema(title = "最后登录时间", required = true, example = "时间戳格式") private LocalDateTime loginDate; - @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + @Schema(title = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSimpleRespVO.java index a815253e9..0a2daaf6f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSimpleRespVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel("用户精简信息 Response VO") +@Schema(title = "用户精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class UserSimpleRespVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1024") + @Schema(title = "用户编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "用户昵称", required = true, example = "芋道") + @Schema(title = "用户昵称", required = true, example = "芋道") private String nickname; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdatePasswordReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdatePasswordReqVO.java index 542fc2b0f..44e5eb3f7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdatePasswordReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdatePasswordReqVO.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 用户更新密码 Request VO") +@Schema(title = "管理后台 - 用户更新密码 Request VO") @Data public class UserUpdatePasswordReqVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1024") + @Schema(title = "用户编号", required = true, example = "1024") @NotNull(message = "用户编号不能为空") private Long id; - @ApiModelProperty(value = "密码", required = true, example = "123456") + @Schema(title = "密码", required = true, example = "123456") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateReqVO.java index 84a3de60f..f5d4cc92f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateReqVO.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 用户更新 Request VO") +@Schema(title = "管理后台 - 用户更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class UserUpdateReqVO extends UserBaseVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1024") + @Schema(title = "用户编号", required = true, example = "1024") @NotNull(message = "用户编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateStatusReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateStatusReqVO.java index 2c7a83f22..11b9afd2f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateStatusReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateStatusReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.user.vo.user; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 用户更新状态 Request VO") +@Schema(title = "管理后台 - 用户更新状态 Request VO") @Data public class UserUpdateStatusReqVO { - @ApiModelProperty(value = "用户编号", required = true, example = "1024") + @Schema(title = "用户编号", required = true, example = "1024") @NotNull(message = "角色编号不能为空") private Long id; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 CommonStatusEnum 枚举") + @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") @NotNull(message = "状态不能为空") // @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") private Integer status; diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 3b64dc858..86dd6baae 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -57,17 +57,17 @@ ${revision} - - - - - + + cn.iocoder.boot + yudao-module-visualization-biz + ${revision} + - - - - - + + cn.iocoder.boot + yudao-module-bpm-biz + ${revision} + cn.iocoder.boot yudao-spring-boot-starter-biz-error-code diff --git a/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/AppShopOrderController.java b/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/AppShopOrderController.java index 2753b711b..210c6a560 100644 --- a/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/AppShopOrderController.java +++ b/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/AppShopOrderController.java @@ -7,8 +7,8 @@ import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderCreateReqDTO; import cn.iocoder.yudao.module.pay.util.PaySeqUtils; import cn.iocoder.yudao.module.shop.controller.app.vo.AppShopOrderCreateRespVO; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; @@ -23,7 +23,7 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -@Api(tags = "用户 APP - 商城订单") +@Tag(name = "用户 APP - 商城订单") @RestController @RequestMapping("/shop/order") @Validated @@ -34,7 +34,7 @@ public class AppShopOrderController { private PayOrderService payOrderService; @PostMapping("/create") - @ApiOperation("创建商城订单") + @Operation(summary = "创建商城订单") // @PreAuthenticated // TODO 暂时不加登陆验证,前端暂时没做好 public CommonResult create() { // 假装创建商城订单 @@ -57,14 +57,14 @@ public class AppShopOrderController { } @PostMapping("/pay-notify") - @ApiOperation("支付回调") + @Operation(summary = "支付回调") public CommonResult payNotify(@RequestBody @Valid PayNotifyOrderReqVO reqVO) { log.info("[payNotify][回调成功]"); return success(true); } @PostMapping("/refund-notify") - @ApiOperation("退款回调") + @Operation(summary = "退款回调") public CommonResult refundNotify(@RequestBody @Valid PayRefundOrderReqVO reqVO) { log.info("[refundNotify][回调成功]"); return success(true); diff --git a/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/vo/AppShopOrderCreateRespVO.java b/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/vo/AppShopOrderCreateRespVO.java index 06a677dbb..6879beab4 100644 --- a/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/vo/AppShopOrderCreateRespVO.java +++ b/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/vo/AppShopOrderCreateRespVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.shop.controller.app.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; -@ApiModel("用户 APP - 商城订单创建 Response VO") +@Schema(title = "用户 APP - 商城订单创建 Response VO") @Data @Builder @AllArgsConstructor public class AppShopOrderCreateRespVO { - @ApiModelProperty(value = "商城订单编号", required = true, example = "1024") + @Schema(title = "商城订单编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "支付订单编号", required = true, example = "2048") + @Schema(title = "支付订单编号", required = true, example = "2048") private Long payOrderId; } diff --git a/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue b/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue index 5d4697c1a..574e9ddd2 100644 --- a/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue +++ b/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue @@ -8,5 +8,5 @@ import { ref } from 'vue' import { IFrame } from '@/components/IFrame' const BASE_URL = import.meta.env.VITE_BASE_URL -const src = ref(BASE_URL + '/doc.html') +const src = ref(BASE_URL + '/swagger-ui') From 88ce5e540e06f3f49383ba0fd93936e55654ad45 Mon Sep 17 00:00:00 2001 From: xingyu4j Date: Fri, 9 Dec 2022 14:24:09 +0800 Subject: [PATCH 02/59] =?UTF-8?q?refactor:=20springdoc=20=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=20springfox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-dependencies/pom.xml | 2 +- yudao-framework/yudao-common/pom.xml | 5 --- .../yudao-spring-boot-starter-web/pom.xml | 2 +- .../config/YudaoSwaggerAutoConfiguration.java | 35 +++++++++++++------ 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 6390fefef..e16cf71e5 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -165,7 +165,7 @@ org.springdoc - springdoc-openapi-javadoc + springdoc-openapi-ui ${springdoc.version} diff --git a/yudao-framework/yudao-common/pom.xml b/yudao-framework/yudao-common/pom.xml index 699fa9528..d46e4c7d6 100644 --- a/yudao-framework/yudao-common/pom.xml +++ b/yudao-framework/yudao-common/pom.xml @@ -63,11 +63,6 @@ springdoc-openapi-webmvc-core - - org.springdoc - springdoc-openapi-javadoc - - org.apache.skywalking diff --git a/yudao-framework/yudao-spring-boot-starter-web/pom.xml b/yudao-framework/yudao-spring-boot-starter-web/pom.xml index 437503a40..9c820e956 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-web/pom.xml @@ -40,7 +40,7 @@ org.springdoc - springdoc-openapi-javadoc + springdoc-openapi-ui diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index 01fcb6ed2..acdc21467 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.framework.swagger.config; import io.swagger.v3.oas.models.Components; -import io.swagger.v3.oas.models.ExternalDocumentation; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; @@ -15,6 +14,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.http.HttpHeaders; +import java.util.Arrays; + /** * Swagger3 自动配置类 * @@ -29,15 +30,30 @@ public class YudaoSwaggerAutoConfiguration { @Bean public OpenAPI createRestApi(SwaggerProperties properties) { - return new OpenAPI() - .info(new Info().title(properties.getTitle()) - .description(properties.getDescription()) - .version(properties.getVersion()) - .license(new License().name("MIT").url("https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE"))) - .externalDocs(new ExternalDocumentation() - .description(properties.getDescription()) - .url("https://gitee.com/zhijiantianya/ruoyi-vue-pro")); + //信息 + Info info = new Info() + .title(properties.getTitle()) + .description(properties.getDescription()) + .version(properties.getVersion()) + .license(new License().name("MIT").url("https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE")); + //鉴权组件(随便起名的) + SecurityScheme securityScheme = new SecurityScheme() + .type(SecurityScheme.Type.OAUTH2) + .scheme("bearer")//固定写法 + .bearerFormat("JWT") + .in(SecurityScheme.In.HEADER) + .name(HttpHeaders.AUTHORIZATION); + Components components = new Components() + .addSecuritySchemes("bearer", securityScheme); + //鉴权限制要求(随便起名的) + SecurityRequirement securityRequirement = new SecurityRequirement() + .addList("bearer", Arrays.asList("read", "write")); + + return new OpenAPI() + .info(info) + .components(components) + .addSecurityItem(securityRequirement); } @Bean @@ -56,5 +72,4 @@ public class YudaoSwaggerAutoConfiguration { .build(); } - } From 69420c0a9cbe1142f9a4426e7353d88222d7e8e9 Mon Sep 17 00:00:00 2001 From: xingyu Date: Wed, 21 Dec 2022 22:52:47 +0800 Subject: [PATCH 03/59] =?UTF-8?q?feat:=20=E9=80=82=E9=85=8Dspringboot=202.?= =?UTF-8?q?7=20configuration=20=3D=3D>=20AutoConfiguration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-dependencies/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 4b29995cf..128165c44 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -18,7 +18,7 @@ 2.7.6 - 1.6.13 + 1.6.14 3.0.3 2.5 From cacefb4eeac4c76b63e0ae0782230d66bd058317 Mon Sep 17 00:00:00 2001 From: xingyu Date: Thu, 22 Dec 2022 00:25:22 +0800 Subject: [PATCH 04/59] feat: knife4j springdoc --- README.md | 2 +- yudao-dependencies/pom.xml | 8 +-- yudao-framework/yudao-common/pom.xml | 5 +- .../framework/common/pojo/PageParam.java | 6 +-- .../framework/common/pojo/PageResult.java | 6 +-- .../yudao-spring-boot-starter-web/pom.xml | 4 +- .../config/YudaoSwaggerAutoConfiguration.java | 6 +-- .../definition/vo/form/BpmFormBaseVO.java | 6 +-- .../vo/form/BpmFormCreateReqVO.java | 6 +-- .../definition/vo/form/BpmFormPageReqVO.java | 4 +- .../definition/vo/form/BpmFormRespVO.java | 10 ++-- .../vo/form/BpmFormSimpleRespVO.java | 6 +-- .../vo/form/BpmFormUpdateReqVO.java | 8 +-- .../vo/group/BpmUserGroupBaseVO.java | 8 +-- .../vo/group/BpmUserGroupCreateReqVO.java | 2 +- .../vo/group/BpmUserGroupPageReqVO.java | 8 +-- .../vo/group/BpmUserGroupRespVO.java | 6 +-- .../vo/group/BpmUserGroupSimpleRespVO.java | 6 +-- .../vo/group/BpmUserGroupUpdateReqVO.java | 4 +- .../vo/model/BpmModeImportReqVO.java | 4 +- .../definition/vo/model/BpmModelBaseVO.java | 20 +++---- .../vo/model/BpmModelCreateReqVO.java | 8 +-- .../vo/model/BpmModelPageItemRespVO.java | 18 +++---- .../vo/model/BpmModelPageReqVO.java | 8 +-- .../definition/vo/model/BpmModelRespVO.java | 8 +-- .../vo/model/BpmModelUpdateReqVO.java | 24 ++++----- .../vo/model/BpmModelUpdateStateReqVO.java | 6 +-- .../BpmProcessDefinitionListReqVO.java | 4 +- .../BpmProcessDefinitionPageItemRespVO.java | 6 +-- .../BpmProcessDefinitionPageReqVO.java | 4 +- .../process/BpmProcessDefinitionRespVO.java | 32 ++++++----- .../vo/rule/BpmTaskAssignRuleBaseVO.java | 4 +- .../vo/rule/BpmTaskAssignRuleCreateReqVO.java | 6 +-- .../vo/rule/BpmTaskAssignRuleRespVO.java | 12 ++--- .../vo/rule/BpmTaskAssignRuleUpdateReqVO.java | 4 +- .../admin/oa/vo/BpmOALeaveBaseVO.java | 8 +-- .../admin/oa/vo/BpmOALeaveCreateReqVO.java | 2 +- .../admin/oa/vo/BpmOALeavePageReqVO.java | 10 ++-- .../admin/oa/vo/BpmOALeaveRespVO.java | 10 ++-- .../task/vo/activity/BpmActivityRespVO.java | 12 ++--- .../BpmProcessInstanceCancelReqVO.java | 6 +-- .../BpmProcessInstanceCreateReqVO.java | 6 +-- .../BpmProcessInstanceMyPageReqVO.java | 14 ++--- .../BpmProcessInstancePageItemRespVO.java | 24 ++++----- .../vo/instance/BpmProcessInstanceRespVO.java | 54 +++++++++---------- .../task/vo/task/BpmTaskApproveReqVO.java | 6 +-- .../vo/task/BpmTaskDonePageItemRespVO.java | 10 ++-- .../task/vo/task/BpmTaskDonePageReqVO.java | 8 +-- .../task/vo/task/BpmTaskRejectReqVO.java | 6 +-- .../admin/task/vo/task/BpmTaskRespVO.java | 14 ++--- .../vo/task/BpmTaskTodoPageItemRespVO.java | 24 ++++----- .../task/vo/task/BpmTaskTodoPageReqVO.java | 8 +-- .../vo/task/BpmTaskUpdateAssigneeReqVO.java | 6 +-- .../codegen/vo/CodegenCreateListReqVO.java | 6 +-- .../admin/codegen/vo/CodegenDetailRespVO.java | 6 +-- .../codegen/vo/CodegenPreviewRespVO.java | 6 +-- .../admin/codegen/vo/CodegenUpdateReqVO.java | 10 ++-- .../vo/column/CodegenColumnBaseVO.java | 36 ++++++------- .../vo/column/CodegenColumnRespVO.java | 6 +-- .../codegen/vo/table/CodegenTableBaseVO.java | 28 +++++----- .../vo/table/CodegenTablePageReqVO.java | 8 +-- .../codegen/vo/table/CodegenTableRespVO.java | 10 ++-- .../codegen/vo/table/DatabaseTableRespVO.java | 6 +-- .../admin/config/vo/ConfigBaseVO.java | 10 ++-- .../admin/config/vo/ConfigCreateReqVO.java | 4 +- .../admin/config/vo/ConfigExportReqVO.java | 10 ++-- .../admin/config/vo/ConfigPageReqVO.java | 10 ++-- .../admin/config/vo/ConfigRespVO.java | 10 ++-- .../admin/config/vo/ConfigUpdateReqVO.java | 4 +- .../admin/db/vo/DataSourceConfigBaseVO.java | 6 +-- .../db/vo/DataSourceConfigCreateReqVO.java | 4 +- .../admin/db/vo/DataSourceConfigRespVO.java | 6 +-- .../db/vo/DataSourceConfigUpdateReqVO.java | 6 +-- .../file/vo/config/FileConfigBaseVO.java | 4 +- .../file/vo/config/FileConfigCreateReqVO.java | 6 +-- .../file/vo/config/FileConfigPageReqVO.java | 8 +-- .../file/vo/config/FileConfigRespVO.java | 12 ++--- .../file/vo/config/FileConfigUpdateReqVO.java | 6 +-- .../admin/file/vo/file/FilePageReqVO.java | 8 +-- .../admin/file/vo/file/FileRespVO.java | 18 +++---- .../admin/file/vo/file/FileUploadReqVO.java | 6 +-- .../admin/job/vo/job/JobBaseVO.java | 12 ++--- .../admin/job/vo/job/JobCreateReqVO.java | 4 +- .../admin/job/vo/job/JobExportReqVO.java | 8 +-- .../admin/job/vo/job/JobPageReqVO.java | 8 +-- .../admin/job/vo/job/JobRespVO.java | 10 ++-- .../admin/job/vo/job/JobUpdateReqVO.java | 4 +- .../admin/job/vo/log/JobLogBaseVO.java | 18 +++---- .../admin/job/vo/log/JobLogExportReqVO.java | 12 ++--- .../admin/job/vo/log/JobLogPageReqVO.java | 12 ++--- .../admin/job/vo/log/JobLogRespVO.java | 6 +-- .../vo/apiaccesslog/ApiAccessLogBaseVO.java | 28 +++++----- .../apiaccesslog/ApiAccessLogExportReqVO.java | 16 +++--- .../apiaccesslog/ApiAccessLogPageReqVO.java | 16 +++--- .../vo/apiaccesslog/ApiAccessLogRespVO.java | 6 +-- .../vo/apierrorlog/ApiErrorLogBaseVO.java | 38 ++++++------- .../apierrorlog/ApiErrorLogExportReqVO.java | 14 ++--- .../vo/apierrorlog/ApiErrorLogPageReqVO.java | 14 ++--- .../vo/apierrorlog/ApiErrorLogRespVO.java | 10 ++-- .../admin/redis/vo/RedisKeyDefineRespVO.java | 14 ++--- .../admin/redis/vo/RedisKeyValueRespVO.java | 4 +- .../admin/redis/vo/RedisMonitorRespVO.java | 16 +++--- .../admin/test/vo/TestDemoBaseVO.java | 10 ++-- .../admin/test/vo/TestDemoCreateReqVO.java | 2 +- .../admin/test/vo/TestDemoExportReqVO.java | 14 ++--- .../admin/test/vo/TestDemoPageReqVO.java | 14 ++--- .../admin/test/vo/TestDemoRespVO.java | 6 +-- .../admin/test/vo/TestDemoUpdateReqVO.java | 4 +- .../codegen/java/controller/vo/_column.vm | 2 +- .../codegen/java/controller/vo/createReqVO.vm | 2 +- .../codegen/java/controller/vo/exportReqVO.vm | 6 +-- .../codegen/java/controller/vo/pageReqVO.vm | 6 +-- .../codegen/java/controller/vo/respVO.vm | 4 +- .../codegen/java/controller/vo/updateReqVO.vm | 2 +- .../admin/brand/vo/ProductBrandBaseVO.java | 10 ++-- .../brand/vo/ProductBrandCreateReqVO.java | 2 +- .../admin/brand/vo/ProductBrandListReqVO.java | 4 +- .../admin/brand/vo/ProductBrandPageReqVO.java | 8 +-- .../admin/brand/vo/ProductBrandRespVO.java | 6 +-- .../brand/vo/ProductBrandUpdateReqVO.java | 4 +- .../category/vo/ProductCategoryBaseVO.java | 12 ++--- .../vo/ProductCategoryCreateReqVO.java | 2 +- .../category/vo/ProductCategoryListReqVO.java | 4 +- .../category/vo/ProductCategoryRespVO.java | 6 +-- .../vo/ProductCategoryUpdateReqVO.java | 4 +- .../vo/ProductPropertyViewRespVO.java | 10 ++-- .../ProductPropertyAndValueRespVO.java | 6 +-- .../vo/property/ProductPropertyBaseVO.java | 6 +-- .../property/ProductPropertyCreateReqVO.java | 2 +- .../vo/property/ProductPropertyListReqVO.java | 6 +-- .../vo/property/ProductPropertyPageReqVO.java | 8 +-- .../vo/property/ProductPropertyRespVO.java | 6 +-- .../property/ProductPropertyUpdateReqVO.java | 4 +- .../vo/value/ProductPropertyValueBaseVO.java | 8 +-- .../ProductPropertyValueCreateReqVO.java | 2 +- .../value/ProductPropertyValuePageReqVO.java | 8 +-- .../vo/value/ProductPropertyValueRespVO.java | 6 +-- .../ProductPropertyValueUpdateReqVO.java | 4 +- .../admin/sku/vo/ProductSkuBaseVO.java | 28 +++++----- .../sku/vo/ProductSkuCreateOrUpdateReqVO.java | 4 +- .../admin/sku/vo/ProductSkuOptionRespVO.java | 14 ++--- .../admin/sku/vo/ProductSkuRespVO.java | 6 +-- .../admin/spu/vo/ProductSpuBaseVO.java | 38 ++++++------- .../admin/spu/vo/ProductSpuCreateReqVO.java | 2 +- .../admin/spu/vo/ProductSpuDetailRespVO.java | 18 +++---- .../admin/spu/vo/ProductSpuPageReqVO.java | 22 ++++---- .../admin/spu/vo/ProductSpuRespVO.java | 6 +-- .../admin/spu/vo/ProductSpuSimpleRespVO.java | 10 ++-- .../admin/spu/vo/ProductSpuUpdateReqVO.java | 4 +- .../app/category/vo/AppCategoryRespVO.java | 10 ++-- .../app/spu/vo/AppSpuPageReqVO.java | 4 +- .../app/spu/vo/AppSpuPageRespVO.java | 24 ++++----- .../controller/app/spu/vo/AppSpuRespVO.java | 2 +- .../admin/banner/vo/BannerBaseVO.java | 12 ++--- .../admin/banner/vo/BannerCreateReqVO.java | 2 +- .../admin/banner/vo/BannerPageReqVO.java | 8 +-- .../admin/banner/vo/BannerRespVO.java | 6 +-- .../admin/banner/vo/BannerUpdateReqVO.java | 4 +- .../admin/coupon/vo/coupon/CouponBaseVO.java | 32 +++++------ .../vo/coupon/CouponPageItemRespVO.java | 4 +- .../coupon/vo/coupon/CouponPageReqVO.java | 10 ++-- .../admin/coupon/vo/coupon/CouponRespVO.java | 6 +-- .../vo/template/CouponTemplateBaseVO.java | 32 +++++------ .../template/CouponTemplateCreateReqVO.java | 2 +- .../vo/template/CouponTemplatePageReqVO.java | 10 ++-- .../vo/template/CouponTemplateRespVO.java | 12 ++--- .../template/CouponTemplateUpdateReqVO.java | 4 +- .../CouponTemplateUpdateStatusReqVO.java | 6 +-- .../discount/vo/DiscountActivityBaseVO.java | 20 +++---- .../vo/DiscountActivityCreateReqVO.java | 2 +- .../vo/DiscountActivityDetailRespVO.java | 2 +- .../vo/DiscountActivityPageReqVO.java | 8 +-- .../discount/vo/DiscountActivityRespVO.java | 8 +-- .../vo/DiscountActivityUpdateReqVO.java | 4 +- .../admin/reward/vo/RewardActivityBaseVO.java | 28 +++++----- .../reward/vo/RewardActivityCreateReqVO.java | 2 +- .../reward/vo/RewardActivityPageReqVO.java | 6 +-- .../admin/reward/vo/RewardActivityRespVO.java | 8 +-- .../reward/vo/RewardActivityUpdateReqVO.java | 4 +- .../AppProductPropertyValueDetailRespVO.java | 10 ++-- .../app/base/sku/AppProductSkuBaseRespVO.java | 8 +-- .../app/base/spu/AppProductSpuBaseRespVO.java | 6 +-- .../app/cart/vo/AppTradeCartDetailRespVO.java | 46 ++++++++-------- .../vo/AppTradeCartItemAddCountReqVO.java | 6 +-- .../vo/AppTradeCartItemUpdateCountReqVO.java | 6 +-- .../AppTradeCartItemUpdateSelectedReqVO.java | 6 +-- .../order/vo/AppTradeOrderCreateReqVO.java | 16 +++--- .../vo/AppTradeOrderGetCreateInfoRespVO.java | 12 ++--- .../app/order/vo/TradeOrderItemRespVO.java | 40 +++++++------- .../app/order/vo/TradeOrderPageReqVO.java | 4 +- .../app/order/vo/TradeOrderRespVO.java | 52 +++++++++--------- .../app/address/vo/AppAddressBaseVO.java | 12 ++--- .../app/address/vo/AppAddressCreateReqVO.java | 2 +- .../app/address/vo/AppAddressRespVO.java | 6 +-- .../app/address/vo/AppAddressUpdateReqVO.java | 4 +- .../app/auth/vo/AppAuthCheckCodeReqVO.java | 8 +-- .../app/auth/vo/AppAuthLoginReqVO.java | 12 ++--- .../app/auth/vo/AppAuthLoginRespVO.java | 10 ++-- .../auth/vo/AppAuthResetPasswordReqVO.java | 8 +-- .../app/auth/vo/AppAuthSmsLoginReqVO.java | 12 ++--- .../app/auth/vo/AppAuthSmsSendReqVO.java | 6 +-- .../app/auth/vo/AppAuthSocialLoginReqVO.java | 8 +-- .../auth/vo/AppAuthUpdatePasswordReqVO.java | 6 +-- .../vo/AppAuthWeixinMiniAppLoginReqVO.java | 6 +-- .../app/social/vo/AppSocialUserBindReqVO.java | 8 +-- .../social/vo/AppSocialUserUnbindReqVO.java | 6 +-- .../app/user/vo/AppUserInfoRespVO.java | 8 +-- .../app/user/vo/AppUserUpdateMobileReqVO.java | 10 ++-- .../admin/merchant/vo/app/PayAppBaseVO.java | 12 ++--- .../merchant/vo/app/PayAppCreateReqVO.java | 2 +- .../merchant/vo/app/PayAppExportReqVO.java | 16 +++--- .../merchant/vo/app/PayAppPageItemRespVO.java | 14 ++--- .../merchant/vo/app/PayAppPageReqVO.java | 16 +++--- .../admin/merchant/vo/app/PayAppRespVO.java | 6 +-- .../merchant/vo/app/PayAppUpdateReqVO.java | 4 +- .../vo/app/PayAppUpdateStatusReqVO.java | 6 +-- .../merchant/vo/channel/PayChannelBaseVO.java | 12 ++--- .../vo/channel/PayChannelCreateReqVO.java | 4 +- .../vo/channel/PayChannelExportReqVO.java | 18 +++---- .../vo/channel/PayChannelPageReqVO.java | 18 +++---- .../merchant/vo/channel/PayChannelRespVO.java | 8 +-- .../vo/channel/PayChannelUpdateReqVO.java | 6 +-- .../vo/merchant/PayMerchantBaseVO.java | 8 +-- .../vo/merchant/PayMerchantCreateReqVO.java | 2 +- .../vo/merchant/PayMerchantExportReqVO.java | 14 ++--- .../vo/merchant/PayMerchantPageReqVO.java | 14 ++--- .../vo/merchant/PayMerchantRespVO.java | 8 +-- .../vo/merchant/PayMerchantUpdateReqVO.java | 4 +- .../PayMerchantUpdateStatusReqVO.java | 6 +-- .../admin/order/vo/PayOrderBaseVO.java | 46 ++++++++-------- .../admin/order/vo/PayOrderDetailsRespVO.java | 18 +++---- .../admin/order/vo/PayOrderExportReqVO.java | 50 ++++++++--------- .../order/vo/PayOrderPageItemRespVO.java | 14 ++--- .../admin/order/vo/PayOrderPageReqVO.java | 50 ++++++++--------- .../admin/order/vo/PayOrderRespVO.java | 6 +-- .../admin/refund/vo/PayRefundBaseVO.java | 48 ++++++++--------- .../admin/refund/vo/PayRefundCreateReqVO.java | 2 +- .../refund/vo/PayRefundDetailsRespVO.java | 14 ++--- .../admin/refund/vo/PayRefundExportReqVO.java | 52 +++++++++--------- .../refund/vo/PayRefundPageItemRespVO.java | 12 ++--- .../admin/refund/vo/PayRefundPageReqVO.java | 52 +++++++++--------- .../admin/refund/vo/PayRefundRespVO.java | 6 +-- .../admin/refund/vo/PayRefundUpdateReqVO.java | 4 +- .../app/order/vo/AppPayOrderSubmitReqVO.java | 8 +-- .../app/order/vo/AppPayOrderSubmitRespVO.java | 2 +- .../app/refund/vo/AppPayRefundReqVO.java | 10 ++-- .../app/refund/vo/AppPayRefundRespVO.java | 4 +- .../notify/vo/PayNotifyOrderReqVO.java | 6 +-- .../notify/vo/PayRefundOrderReqVO.java | 8 +-- .../admin/auth/vo/AuthLoginReqVO.java | 17 +++--- .../admin/auth/vo/AuthLoginRespVO.java | 10 ++-- .../admin/auth/vo/AuthMenuRespVO.java | 18 +++---- .../auth/vo/AuthPermissionInfoRespVO.java | 16 +++--- .../admin/auth/vo/AuthSmsLoginReqVO.java | 6 +-- .../admin/auth/vo/AuthSmsSendReqVO.java | 6 +-- .../admin/auth/vo/AuthSocialLoginReqVO.java | 8 +-- .../admin/dept/vo/dept/DeptBaseVO.java | 14 ++--- .../admin/dept/vo/dept/DeptCreateReqVO.java | 2 +- .../admin/dept/vo/dept/DeptListReqVO.java | 6 +-- .../admin/dept/vo/dept/DeptRespVO.java | 8 +-- .../admin/dept/vo/dept/DeptSimpleRespVO.java | 8 +-- .../admin/dept/vo/dept/DeptUpdateReqVO.java | 4 +- .../admin/dept/vo/post/PostBaseVO.java | 10 ++-- .../admin/dept/vo/post/PostCreateReqVO.java | 2 +- .../admin/dept/vo/post/PostExportReqVO.java | 8 +-- .../admin/dept/vo/post/PostListReqVO.java | 6 +-- .../admin/dept/vo/post/PostPageReqVO.java | 8 +-- .../admin/dept/vo/post/PostRespVO.java | 6 +-- .../admin/dept/vo/post/PostSimpleRespVO.java | 6 +-- .../admin/dept/vo/post/PostUpdateReqVO.java | 4 +- .../admin/dict/vo/data/DictDataBaseVO.java | 16 +++--- .../dict/vo/data/DictDataCreateReqVO.java | 2 +- .../dict/vo/data/DictDataExportReqVO.java | 8 +-- .../admin/dict/vo/data/DictDataPageReqVO.java | 8 +-- .../admin/dict/vo/data/DictDataRespVO.java | 6 +-- .../dict/vo/data/DictDataSimpleRespVO.java | 12 ++--- .../dict/vo/data/DictDataUpdateReqVO.java | 4 +- .../admin/dict/vo/type/DictTypeBaseVO.java | 6 +-- .../dict/vo/type/DictTypeCreateReqVO.java | 4 +- .../dict/vo/type/DictTypeExportReqVO.java | 10 ++-- .../admin/dict/vo/type/DictTypePageReqVO.java | 10 ++-- .../admin/dict/vo/type/DictTypeRespVO.java | 8 +-- .../dict/vo/type/DictTypeSimpleRespVO.java | 8 +-- .../dict/vo/type/DictTypeUpdateReqVO.java | 4 +- .../admin/errorcode/vo/ErrorCodeBaseVO.java | 8 +-- .../errorcode/vo/ErrorCodeCreateReqVO.java | 2 +- .../errorcode/vo/ErrorCodeExportReqVO.java | 12 ++--- .../errorcode/vo/ErrorCodePageReqVO.java | 12 ++--- .../admin/errorcode/vo/ErrorCodeRespVO.java | 8 +-- .../errorcode/vo/ErrorCodeUpdateReqVO.java | 4 +- .../logger/vo/loginlog/LoginLogBaseVO.java | 12 ++--- .../vo/loginlog/LoginLogExportReqVO.java | 10 ++-- .../logger/vo/loginlog/LoginLogPageReqVO.java | 10 ++-- .../logger/vo/loginlog/LoginLogRespVO.java | 10 ++-- .../vo/operatelog/OperateLogBaseVO.java | 36 ++++++------- .../vo/operatelog/OperateLogExportReqVO.java | 12 ++--- .../vo/operatelog/OperateLogPageReqVO.java | 12 ++--- .../vo/operatelog/OperateLogRespVO.java | 6 +-- .../admin/notice/vo/NoticeBaseVO.java | 8 +-- .../admin/notice/vo/NoticeCreateReqVO.java | 2 +- .../admin/notice/vo/NoticePageReqVO.java | 6 +-- .../admin/notice/vo/NoticeRespVO.java | 6 +-- .../admin/notice/vo/NoticeUpdateReqVO.java | 4 +- .../oauth2/vo/client/OAuth2ClientBaseVO.java | 30 +++++------ .../vo/client/OAuth2ClientCreateReqVO.java | 2 +- .../vo/client/OAuth2ClientPageReqVO.java | 6 +-- .../oauth2/vo/client/OAuth2ClientRespVO.java | 6 +-- .../vo/client/OAuth2ClientUpdateReqVO.java | 4 +- .../vo/open/OAuth2OpenAccessTokenRespVO.java | 12 ++--- .../open/OAuth2OpenAuthorizeInfoRespVO.java | 8 +-- .../vo/open/OAuth2OpenCheckTokenRespVO.java | 16 +++--- .../vo/token/OAuth2AccessTokenPageReqVO.java | 8 +-- .../vo/token/OAuth2AccessTokenRespVO.java | 18 +++---- .../oauth2/vo/user/OAuth2UserInfoRespVO.java | 28 +++++----- .../oauth2/vo/user/OAuth2UserUpdateReqVO.java | 10 ++-- .../admin/permission/vo/menu/MenuBaseVO.java | 22 ++++---- .../permission/vo/menu/MenuCreateReqVO.java | 2 +- .../permission/vo/menu/MenuListReqVO.java | 6 +-- .../admin/permission/vo/menu/MenuRespVO.java | 8 +-- .../permission/vo/menu/MenuSimpleRespVO.java | 10 ++-- .../permission/vo/menu/MenuUpdateReqVO.java | 4 +- .../PermissionAssignRoleDataScopeReqVO.java | 8 +-- .../PermissionAssignRoleMenuReqVO.java | 6 +-- .../PermissionAssignUserRoleReqVO.java | 6 +-- .../admin/permission/vo/role/RoleBaseVO.java | 8 +-- .../permission/vo/role/RoleCreateReqVO.java | 2 +- .../permission/vo/role/RoleExportReqVO.java | 10 ++-- .../permission/vo/role/RolePageReqVO.java | 10 ++-- .../admin/permission/vo/role/RoleRespVO.java | 14 ++--- .../permission/vo/role/RoleSimpleRespVO.java | 6 +-- .../permission/vo/role/RoleUpdateReqVO.java | 4 +- .../vo/role/RoleUpdateStatusReqVO.java | 6 +-- .../sensitiveword/vo/SensitiveWordBaseVO.java | 8 +-- .../vo/SensitiveWordCreateReqVO.java | 2 +- .../vo/SensitiveWordExportReqVO.java | 10 ++-- .../vo/SensitiveWordPageReqVO.java | 10 ++-- .../sensitiveword/vo/SensitiveWordRespVO.java | 6 +-- .../vo/SensitiveWordUpdateReqVO.java | 4 +- .../sms/vo/channel/SmsChannelBaseVO.java | 12 ++--- .../sms/vo/channel/SmsChannelCreateReqVO.java | 4 +- .../sms/vo/channel/SmsChannelPageReqVO.java | 8 +-- .../sms/vo/channel/SmsChannelRespVO.java | 8 +-- .../vo/channel/SmsChannelSimpleRespVO.java | 8 +-- .../sms/vo/channel/SmsChannelUpdateReqVO.java | 4 +- .../admin/sms/vo/log/SmsLogExportReqVO.java | 16 +++--- .../admin/sms/vo/log/SmsLogPageReqVO.java | 16 +++--- .../admin/sms/vo/log/SmsLogRespVO.java | 52 +++++++++--------- .../sms/vo/template/SmsTemplateBaseVO.java | 16 +++--- .../vo/template/SmsTemplateCreateReqVO.java | 2 +- .../vo/template/SmsTemplateExportReqVO.java | 16 +++--- .../sms/vo/template/SmsTemplatePageReqVO.java | 16 +++--- .../sms/vo/template/SmsTemplateRespVO.java | 10 ++-- .../sms/vo/template/SmsTemplateSendReqVO.java | 8 +-- .../vo/template/SmsTemplateUpdateReqVO.java | 4 +- .../admin/socail/vo/SocialUserBindReqVO.java | 8 +-- .../socail/vo/SocialUserUnbindReqVO.java | 6 +-- .../vo/packages/TenantPackageBaseVO.java | 8 +-- .../vo/packages/TenantPackageCreateReqVO.java | 2 +- .../vo/packages/TenantPackagePageReqVO.java | 10 ++-- .../vo/packages/TenantPackageRespVO.java | 6 +-- .../packages/TenantPackageSimpleRespVO.java | 6 +-- .../vo/packages/TenantPackageUpdateReqVO.java | 4 +- .../admin/tenant/vo/tenant/TenantBaseVO.java | 16 +++--- .../tenant/vo/tenant/TenantCreateReqVO.java | 6 +-- .../tenant/vo/tenant/TenantExportReqVO.java | 12 ++--- .../tenant/vo/tenant/TenantPageReqVO.java | 12 ++--- .../admin/tenant/vo/tenant/TenantRespVO.java | 6 +-- .../tenant/vo/tenant/TenantUpdateReqVO.java | 4 +- .../user/vo/profile/UserProfileRespVO.java | 36 ++++++------- .../UserProfileUpdatePasswordReqVO.java | 6 +-- .../vo/profile/UserProfileUpdateReqVO.java | 10 ++-- .../admin/user/vo/user/UserBaseVO.java | 18 +++---- .../admin/user/vo/user/UserCreateReqVO.java | 4 +- .../admin/user/vo/user/UserExportReqVO.java | 12 ++--- .../admin/user/vo/user/UserImportRespVO.java | 8 +-- .../user/vo/user/UserPageItemRespVO.java | 8 +-- .../admin/user/vo/user/UserPageReqVO.java | 12 ++--- .../admin/user/vo/user/UserRespVO.java | 12 ++--- .../admin/user/vo/user/UserSimpleRespVO.java | 6 +-- .../user/vo/user/UserUpdatePasswordReqVO.java | 6 +-- .../admin/user/vo/user/UserUpdateReqVO.java | 4 +- .../user/vo/user/UserUpdateStatusReqVO.java | 6 +-- .../app/vo/AppShopOrderCreateRespVO.java | 6 +-- .../src/main/resources/application.yaml | 4 ++ .../src/views/infra/swagger/index.vue | 2 +- 385 files changed, 1939 insertions(+), 1941 deletions(-) diff --git a/README.md b/README.md index 4c328a844..c29db5bf9 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ ps:核心功能已经实现,正在对接微信小程序中... | [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.5 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) | | [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 6.7.2 | [文档](https://doc.iocoder.cn/bpm/) | | [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) | -| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) | +| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 4.0.0 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) | | [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.1 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) | | [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.12.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) | | [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.7.9 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) | diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 128165c44..a6f23dfe1 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -19,7 +19,7 @@ 2.7.6 1.6.14 - 3.0.3 + 4.0.0 2.5 1.2.15 @@ -158,9 +158,9 @@ - org.springdoc - springdoc-openapi-webmvc-core - ${springdoc.version} + com.github.xiaoymin + knife4j-openapi3-spring-boot-starter + ${knife4j.version} diff --git a/yudao-framework/yudao-common/pom.xml b/yudao-framework/yudao-common/pom.xml index d46e4c7d6..24fc39dec 100644 --- a/yudao-framework/yudao-common/pom.xml +++ b/yudao-framework/yudao-common/pom.xml @@ -59,10 +59,9 @@ - org.springdoc - springdoc-openapi-webmvc-core + com.github.xiaoymin + knife4j-openapi3-spring-boot-starter - org.apache.skywalking diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java index 3cb1fc3ad..9c553055a 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageParam.java @@ -8,19 +8,19 @@ import javax.validation.constraints.Max; import javax.validation.constraints.NotNull; import java.io.Serializable; -@Schema(title="分页参数") +@Schema(description="分页参数") @Data public class PageParam implements Serializable { private static final Integer PAGE_NO = 1; private static final Integer PAGE_SIZE = 10; - @Schema(title = "页码,从 1 开始", required = true,example = "1") + @Schema(description = "页码,从 1 开始", required = true,example = "1") @NotNull(message = "页码不能为空") @Min(value = 1, message = "页码最小值为 1") private Integer pageNo = PAGE_NO; - @Schema(title = "每页条数,最大值为 100", required = true, example = "10") + @Schema(description = "每页条数,最大值为 100", required = true, example = "10") @NotNull(message = "每页条数不能为空") @Min(value = 1, message = "每页条数最小值为 1") @Max(value = 100, message = "每页条数最大值为 100") diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java index 655dea180..f0048517d 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java @@ -6,14 +6,14 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; -@Schema(title = "分页结果") +@Schema(description = "分页结果") @Data public final class PageResult implements Serializable { - @Schema(title = "数据", required = true) + @Schema(description = "数据", required = true) private List list; - @Schema(title = "总量", required = true) + @Schema(description = "总量", required = true) private Long total; public PageResult() { diff --git a/yudao-framework/yudao-spring-boot-starter-web/pom.xml b/yudao-framework/yudao-spring-boot-starter-web/pom.xml index 9c820e956..0e7e7854a 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-web/pom.xml @@ -34,8 +34,8 @@ - org.springdoc - springdoc-openapi-webmvc-core + com.github.xiaoymin + knife4j-openapi3-spring-boot-starter diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index acdc21467..4bb2d77ac 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -57,10 +57,10 @@ public class YudaoSwaggerAutoConfiguration { } @Bean - public GroupedOpenApi publicApi() { + public GroupedOpenApi appApi() { return GroupedOpenApi.builder() .group("app") - .pathsToMatch("/app/**") + .pathsToMatch("/app-api/**") .build(); } @@ -68,7 +68,7 @@ public class YudaoSwaggerAutoConfiguration { public GroupedOpenApi adminApi() { return GroupedOpenApi.builder() .group("admin") - .pathsToMatch("/admin/**") + .pathsToMatch("/admin-api/**") .build(); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java index 3345adb52..c51984f0c 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormBaseVO.java @@ -10,15 +10,15 @@ import javax.validation.constraints.*; @Data public class BpmFormBaseVO { - @Schema(title = "表单名称", required = true, example = "芋道") + @Schema(description = "表单名称", required = true, example = "芋道") @NotNull(message = "表单名称不能为空") private String name; - @Schema(title = "表单状态", required = true, description = "参见 CommonStatusEnum 枚举", example = "1") + @Schema(description = "表单状态-参见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "表单状态不能为空") private Integer status; - @Schema(title = "备注", example = "我是备注") + @Schema(description = "备注", example = "我是备注") private String remark; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java index ce3410ced..5a096667a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormCreateReqVO.java @@ -5,17 +5,17 @@ import lombok.*; import javax.validation.constraints.NotNull; import java.util.List; -@Schema(title = "管理后台 - 动态表单创建 Request VO") +@Schema(description = "管理后台 - 动态表单创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmFormCreateReqVO extends BpmFormBaseVO { - @Schema(title = "表单的配置", required = true, description = "JSON 字符串") + @Schema(description = "表单的配置-JSON 字符串", required = true) @NotNull(message = "表单的配置不能为空") private String conf; - @Schema(title = "表单项的数组", required = true, description = "JSON 字符串的数组") + @Schema(description = "表单项的数组-JSON 字符串的数组", required = true) @NotNull(message = "表单项的数组不能为空") private List fields; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java index 87adc3f63..0227e0ad9 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormPageReqVO.java @@ -6,13 +6,13 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 动态表单分页 Request VO") +@Schema(description = "管理后台 - 动态表单分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmFormPageReqVO extends PageParam { - @Schema(title = "表单名称", example = "芋道") + @Schema(description = "表单名称", example = "芋道") private String name; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java index b93b66012..5d7f4e765 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormRespVO.java @@ -8,24 +8,24 @@ import javax.validation.constraints.NotNull; import java.time.LocalDateTime; import java.util.List; -@Schema(title = "管理后台 - 动态表单 Response VO") +@Schema(description = "管理后台 - 动态表单 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmFormRespVO extends BpmFormBaseVO { - @Schema(title = "表单编号", required = true, example = "1024") + @Schema(description = "表单编号", required = true, example = "1024") private Long id; - @Schema(title = "表单的配置", required = true, description = "JSON 字符串") + @Schema(description = "表单的配置-JSON 字符串", required = true) @NotNull(message = "表单的配置不能为空") private String conf; - @Schema(title = "表单项的数组", required = true, description = "JSON 字符串的数组") + @Schema(description = "表单项的数组-JSON 字符串的数组", required = true) @NotNull(message = "表单项的数组不能为空") private List fields; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java index 9764a9835..2e19f441c 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormSimpleRespVO.java @@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 流程表单精简 Response VO") +@Schema(description = "管理后台 - 流程表单精简 Response VO") @Data public class BpmFormSimpleRespVO { - @Schema(title = "表单编号", required = true, example = "1024") + @Schema(description = "表单编号", required = true, example = "1024") private Long id; - @Schema(title = "表单名称", required = true, example = "芋道") + @Schema(description = "表单名称", required = true, example = "芋道") private String name; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java index 641e57617..e315ef370 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/form/BpmFormUpdateReqVO.java @@ -4,21 +4,21 @@ import lombok.*; import javax.validation.constraints.*; import java.util.List; -@Schema(title = "管理后台 - 动态表单更新 Request VO") +@Schema(description = "管理后台 - 动态表单更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmFormUpdateReqVO extends BpmFormBaseVO { - @Schema(title = "表单编号", required = true, example = "1024") + @Schema(description = "表单编号", required = true, example = "1024") @NotNull(message = "表单编号不能为空") private Long id; - @Schema(title = "表单的配置", required = true, description = "JSON 字符串") + @Schema(description = "表单的配置-JSON 字符串", required = true) @NotNull(message = "表单的配置不能为空") private String conf; - @Schema(title = "表单项的数组", required = true, description = "JSON 字符串的数组") + @Schema(description = "表单项的数组-JSON 字符串的数组", required = true) @NotNull(message = "表单项的数组不能为空") private List fields; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java index b82f6d1d5..d78d3c02d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupBaseVO.java @@ -11,19 +11,19 @@ import javax.validation.constraints.*; @Data public class BpmUserGroupBaseVO { - @Schema(title = "组名", required = true, example = "芋道") + @Schema(description = "组名", required = true, example = "芋道") @NotNull(message = "组名不能为空") private String name; - @Schema(title = "描述", required = true, example = "芋道源码") + @Schema(description = "描述", required = true, example = "芋道源码") @NotNull(message = "描述不能为空") private String description; - @Schema(title = "成员编号数组", required = true, example = "1,2,3") + @Schema(description = "成员编号数组", required = true, example = "1,2,3") @NotNull(message = "成员编号数组不能为空") private Set memberUserIds; - @Schema(title = "状态", required = true, example = "1") + @Schema(description = "状态", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java index 7509746a7..416c4793a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupCreateReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.group; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - 用户组创建 Request VO") +@Schema(description = "管理后台 - 用户组创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java index c5d417131..05f17788a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupPageReqVO.java @@ -10,20 +10,20 @@ import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 用户组分页 Request VO") +@Schema(description = "管理后台 - 用户组分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmUserGroupPageReqVO extends PageParam { - @Schema(title = "组名", example = "芋道") + @Schema(description = "组名", example = "芋道") private String name; - @Schema(title = "状态", example = "1") + @Schema(description = "状态", example = "1") private Integer status; @DateTimeFormat(pattern = DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java index e7399d228..2a390a9cf 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupRespVO.java @@ -5,16 +5,16 @@ import lombok.*; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 用户组 Response VO") +@Schema(description = "管理后台 - 用户组 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmUserGroupRespVO extends BpmUserGroupBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java index 785e9e571..aedd100f3 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupSimpleRespVO.java @@ -5,16 +5,16 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@Schema(title = "管理后台 - 用户组精简信息 Response VO") +@Schema(description = "管理后台 - 用户组精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class BpmUserGroupSimpleRespVO { - @Schema(title = "用户组编号", required = true, example = "1024") + @Schema(description = "用户组编号", required = true, example = "1024") private Long id; - @Schema(title = "用户组名字", required = true, example = "芋道") + @Schema(description = "用户组名字", required = true, example = "芋道") private String name; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java index 88846644f..81db5649d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/group/BpmUserGroupUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 用户组更新 Request VO") +@Schema(description = "管理后台 - 用户组更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmUserGroupUpdateReqVO extends BpmUserGroupBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java index 79771bfcb..007cfed10 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModeImportReqVO.java @@ -8,13 +8,13 @@ import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 流程模型的导入 Request VO", description = "相比流程模型的新建来说,只是多了一个 bpmnFile 文件") +@Schema(description = "管理后台 - 流程模型的导入 Request VO 相比流程模型的新建来说,只是多了一个 bpmnFile 文件") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmModeImportReqVO extends BpmModelCreateReqVO { - @Schema(title = "BPMN 文件", required = true) + @Schema(description = "BPMN 文件", required = true) @NotNull(message = "BPMN 文件不能为空") private MultipartFile bpmnFile; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java index 639967286..8750ad913 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java @@ -11,30 +11,30 @@ import javax.validation.constraints.NotEmpty; @Data public class BpmModelBaseVO { - @Schema(title = "流程标识", required = true, example = "process_yudao") + @Schema(description = "流程标识", required = true, example = "process_yudao") @NotEmpty(message = "流程标识不能为空") private String key; - @Schema(title = "流程名称", required = true, example = "芋道") + @Schema(description = "流程名称", required = true, example = "芋道") @NotEmpty(message = "流程名称不能为空") private String name; - @Schema(title = "流程描述", example = "我是描述") + @Schema(description = "流程描述", example = "我是描述") private String description; - @Schema(title = "流程分类", description = "参见 bpm_model_category 数据字典", example = "1") + @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1") @NotEmpty(message = "流程分类不能为空") private String category; - @Schema(title = "表单类型", description = "参见 bpm_model_form_type 数据字典", example = "1") + @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1") private Integer formType; - @Schema(title = "表单编号", example = "1024", description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024") private Long formId; - @Schema(title = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", - description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", + example = "/bpm/oa/leave/create") private String formCustomCreatePath; - @Schema(title = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", - description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", + example = "/bpm/oa/leave/view") private String formCustomViewPath; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java index d100b744f..5b77bc2de 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelCreateReqVO.java @@ -7,19 +7,19 @@ import lombok.ToString; import javax.validation.constraints.NotEmpty; -@Schema(title = "管理后台 - 流程模型的创建 Request VO") +@Schema(description = "管理后台 - 流程模型的创建 Request VO") @Data public class BpmModelCreateReqVO { - @Schema(title = "流程标识", required = true, example = "process_yudao") + @Schema(description = "流程标识", required = true, example = "process_yudao") @NotEmpty(message = "流程标识不能为空") private String key; - @Schema(title = "流程名称", required = true, example = "芋道") + @Schema(description = "流程名称", required = true, example = "芋道") @NotEmpty(message = "流程名称不能为空") private String name; - @Schema(title = "流程描述", example = "我是描述") + @Schema(description = "流程描述", example = "我是描述") private String description; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java index cfd646ebc..9edc119c9 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java @@ -7,19 +7,19 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 流程模型的分页的每一项 Response VO") +@Schema(description = "管理后台 - 流程模型的分页的每一项 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmModelPageItemRespVO extends BpmModelBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private String id; - @Schema(title = "表单名字", example = "请假表单") + @Schema(description = "表单名字", example = "请假表单") private String formName; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; /** @@ -27,20 +27,20 @@ public class BpmModelPageItemRespVO extends BpmModelBaseVO { */ private ProcessDefinition processDefinition; - @Schema(title = "流程定义") + @Schema(description = "流程定义") @Data public static class ProcessDefinition { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private String id; - @Schema(title = "版本", required = true, example = "1") + @Schema(description = "版本", required = true, example = "1") private Integer version; - @Schema(title = "部署时间", required = true) + @Schema(description = "部署时间", required = true) private LocalDateTime deploymentTime; - @Schema(title = "中断状态", required = true, example = "1", description = "参见 SuspensionState 枚举") + @Schema(description = "中断状态-参见 SuspensionState 枚举", required = true, example = "1") private Integer suspensionState; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java index ce2f4ae1c..15283208e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java @@ -7,19 +7,19 @@ import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 流程模型分页 Request VO") +@Schema(description = "管理后台 - 流程模型分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmModelPageReqVO extends PageParam { - @Schema(title = "标识", example = "process1641042089407", description = "精准匹配") + @Schema(description = "标识-精准匹配", example = "process1641042089407") private String key; - @Schema(title = "名字", example = "芋道", description = "模糊匹配") + @Schema(description = "名字-模糊匹配", example = "芋道") private String name; - @Schema(title = "流程分类", description = "参见 bpm_model_category 数据字典", example = "1") + @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1") private String category; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java index f8e520078..26bc2f9a6 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java @@ -7,19 +7,19 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 流程模型的创建 Request VO") +@Schema(description = "管理后台 - 流程模型的创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmModelRespVO extends BpmModelBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private String id; - @Schema(title = "BPMN XML", required = true) + @Schema(description = "BPMN XML", required = true) private String bpmnXml; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java index b480d0b1f..94271034b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java @@ -5,35 +5,35 @@ import lombok.Data; import javax.validation.constraints.NotEmpty; -@Schema(title = "管理后台 - 流程模型的更新 Request VO") +@Schema(description = "管理后台 - 流程模型的更新 Request VO") @Data public class BpmModelUpdateReqVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotEmpty(message = "编号不能为空") private String id; - @Schema(title = "流程名称", example = "芋道") + @Schema(description = "流程名称", example = "芋道") private String name; - @Schema(title = "流程描述", example = "我是描述") + @Schema(description = "流程描述", example = "我是描述") private String description; - @Schema(title = "流程分类", description = "参见 bpm_model_category 数据字典", example = "1") + @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1") private String category; - @Schema(title = "BPMN XML", required = true) + @Schema(description = "BPMN XML", required = true) private String bpmnXml; - @Schema(title = "表单类型", description = "参见 bpm_model_form_type 数据字典", example = "1") + @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1") private Integer formType; - @Schema(title = "表单编号", example = "1024", description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024") private Long formId; - @Schema(title = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", - description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", + example = "/bpm/oa/leave/create") private String formCustomCreatePath; - @Schema(title = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", - description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", + example = "/bpm/oa/leave/view") private String formCustomViewPath; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java index d07b3b249..e59cc32fb 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java @@ -5,15 +5,15 @@ import lombok.Data; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 流程模型更新状态 Request VO") +@Schema(description = "管理后台 - 流程模型更新状态 Request VO") @Data public class BpmModelUpdateStateReqVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private String id; - @Schema(title = "状态", required = true, example = "1", description = "见 SuspensionState 枚举") + @Schema(description = "状态-见 SuspensionState 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer state; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java index 664d3b27b..35243d2ac 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java @@ -6,13 +6,13 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 流程定义列表 Request VO") +@Schema(description = "管理后台 - 流程定义列表 Request VO") @Data @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class BpmProcessDefinitionListReqVO extends PageParam { - @Schema(title = "中断状态", example = "1", description = "参见 SuspensionState 枚举") + @Schema(description = "中断状态-参见 SuspensionState 枚举", example = "1") private Integer suspensionState; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java index 5bf9bf42a..26bc79c80 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 流程定义的分页的每一项 Response VO") +@Schema(description = "管理后台 - 流程定义的分页的每一项 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmProcessDefinitionPageItemRespVO extends BpmProcessDefinitionRespVO { - @Schema(title = "表单名字", example = "请假表单") + @Schema(description = "表单名字", example = "请假表单") private String formName; - @Schema(title = "部署时间", required = true) + @Schema(description = "部署时间", required = true) private LocalDateTime deploymentTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java index 0b92700e3..f5c7f36d6 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageReqVO.java @@ -6,13 +6,13 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 流程定义分页 Request VO") +@Schema(description = "管理后台 - 流程定义分页 Request VO") @Data @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class BpmProcessDefinitionPageReqVO extends PageParam { - @Schema(title = "标识", example = "process1641042089407", description = "精准匹配") + @Schema(description = "标识-精准匹配", example = "process1641042089407") private String key; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java index f4c540f2d..5fee0dd4e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java @@ -7,45 +7,43 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; -@Schema(title = "管理后台 - 流程定义 Response VO") +@Schema(description = "管理后台 - 流程定义 Response VO") @Data public class BpmProcessDefinitionRespVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private String id; - @Schema(title = "版本", required = true, example = "1") + @Schema(description = "版本", required = true, example = "1") private Integer version; - @Schema(title = "流程名称", required = true, example = "芋道") + @Schema(description = "流程名称", required = true, example = "芋道") @NotEmpty(message = "流程名称不能为空") private String name; - @Schema(title = "流程描述", example = "我是描述") + @Schema(description = "流程描述", example = "我是描述") private String description; - @Schema(title = "流程分类", description = "参见 bpm_model_category 数据字典", example = "1") + @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1") @NotEmpty(message = "流程分类不能为空") private String category; - @Schema(title = "表单类型", description = "参见 bpm_model_form_type 数据字典", example = "1") + @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1") private Integer formType; - @Schema(title = "表单编号", example = "1024", description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024") private Long formId; - @Schema(title = "表单的配置", required = true, - description = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "表单的配置-JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", required = true) private String formConf; - @Schema(title = "表单项的数组", required = true, - description = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "表单项的数组-JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", required = true) private List formFields; - @Schema(title = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", - description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", + example = "/bpm/oa/leave/create") private String formCustomCreatePath; - @Schema(title = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", - description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", + example = "/bpm/oa/leave/view") private String formCustomViewPath; - @Schema(title = "中断状态", required = true, example = "1", description = "参见 SuspensionState 枚举") + @Schema(description = "中断状态-参见 SuspensionState 枚举", required = true, example = "1") private Integer suspensionState; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java index 8ec779bad..7efb1c312 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleBaseVO.java @@ -13,11 +13,11 @@ import java.util.Set; @Data public class BpmTaskAssignRuleBaseVO { - @Schema(title = "规则类型", required = true, example = "bpm_task_assign_rule_type") + @Schema(description = "规则类型", required = true, example = "bpm_task_assign_rule_type") @NotNull(message = "规则类型不能为空") private Integer type; - @Schema(title = "规则值数组", required = true, example = "1,2,3") + @Schema(description = "规则值数组", required = true, example = "1,2,3") @NotNull(message = "规则值数组不能为空") private Set options; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java index b1cc63c18..97bb2de8f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleCreateReqVO.java @@ -7,17 +7,17 @@ import lombok.ToString; import javax.validation.constraints.NotEmpty; -@Schema(title = "管理后台 - 流程任务分配规则的创建 Request VO") +@Schema(description = "管理后台 - 流程任务分配规则的创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskAssignRuleCreateReqVO extends BpmTaskAssignRuleBaseVO { - @Schema(title = "流程模型的编号", required = true, example = "1024") + @Schema(description = "流程模型的编号", required = true, example = "1024") @NotEmpty(message = "流程模型的编号不能为空") private String modelId; - @Schema(title = "流程任务定义的编号", required = true, example = "2048") + @Schema(description = "流程任务定义的编号", required = true, example = "2048") @NotEmpty(message = "流程任务定义的编号不能为空") private String taskDefinitionKey; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java index 630952e14..50626edc7 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleRespVO.java @@ -5,24 +5,24 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 流程任务分配规则的 Response VO") +@Schema(description = "管理后台 - 流程任务分配规则的 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskAssignRuleRespVO extends BpmTaskAssignRuleBaseVO { - @Schema(title = "任务分配规则的编号", required = true, example = "1024") + @Schema(description = "任务分配规则的编号", required = true, example = "1024") private Long id; - @Schema(title = "流程模型的编号", required = true, example = "2048") + @Schema(description = "流程模型的编号", required = true, example = "2048") private String modelId; - @Schema(title = "流程定义的编号", required = true, example = "4096") + @Schema(description = "流程定义的编号", required = true, example = "4096") private String processDefinitionId; - @Schema(title = "流程任务定义的编号", required = true, example = "2048") + @Schema(description = "流程任务定义的编号", required = true, example = "2048") private String taskDefinitionKey; - @Schema(title = "流程任务定义的名字", required = true, example = "关注芋道") + @Schema(description = "流程任务定义的名字", required = true, example = "关注芋道") private String taskDefinitionName; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java index bb6f44374..5799f139f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/rule/BpmTaskAssignRuleUpdateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 流程任务分配规则的更新 Request VO") +@Schema(description = "管理后台 - 流程任务分配规则的更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskAssignRuleUpdateReqVO extends BpmTaskAssignRuleBaseVO { - @Schema(title = "任务分配规则的编号", required = true, example = "1024") + @Schema(description = "任务分配规则的编号", required = true, example = "1024") @NotNull(message = "任务分配规则的编号不能为空") private Long id; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java index 9d883af85..2ce0b1c52 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveBaseVO.java @@ -14,19 +14,19 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class BpmOALeaveBaseVO { - @Schema(title = "请假的开始时间", required = true) + @Schema(description = "请假的开始时间", required = true) @NotNull(message = "开始时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; - @Schema(title = "请假的结束时间", required = true) + @Schema(description = "请假的结束时间", required = true) @NotNull(message = "结束时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; - @Schema(title = "请假类型", required = true, example = "1", description = "参见 bpm_oa_type 枚举") + @Schema(description = "请假类型-参见 bpm_oa_type 枚举", required = true, example = "1") private Integer type; - @Schema(title = "原因", required = true, example = "阅读芋道源码") + @Schema(description = "原因", required = true, example = "阅读芋道源码") private String reason; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java index e1d7d082b..9bfd4488f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveCreateReqVO.java @@ -6,7 +6,7 @@ import lombok.ToString; import javax.validation.constraints.AssertTrue; -@Schema(title = "管理后台 - 请假申请创建 Request VO") +@Schema(description = "管理后台 - 请假申请创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java index 4341bd974..903a0fcf2 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeavePageReqVO.java @@ -7,23 +7,23 @@ import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 请假申请分页 Request VO") +@Schema(description = "管理后台 - 请假申请分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmOALeavePageReqVO extends PageParam { - @Schema(title = "状态", example = "1", description = "参见 bpm_process_instance_result 枚举") + @Schema(description = "状态-参见 bpm_process_instance_result 枚举", example = "1") private Integer result; - @Schema(title = "请假类型", example = "1", description = "参见 bpm_oa_type") + @Schema(description = "请假类型-参见 bpm_oa_type", example = "1") private Integer type; - @Schema(title = "原因", example = "阅读芋道源码", description = "模糊匹配") + @Schema(description = "原因-模糊匹配", example = "阅读芋道源码") private String reason; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "申请时间") + @Schema(description = "申请时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java index a30c41676..d79dac7d3 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/oa/vo/BpmOALeaveRespVO.java @@ -8,24 +8,24 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 请假申请 Response VO") +@Schema(description = "管理后台 - 请假申请 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmOALeaveRespVO extends BpmOALeaveBaseVO { - @Schema(title = "请假表单主键", required = true, example = "1024") + @Schema(description = "请假表单主键", required = true, example = "1024") private Long id; - @Schema(title = "状态", required = true, example = "1", description = "参见 bpm_process_instance_result 枚举") + @Schema(description = "状态-参见 bpm_process_instance_result 枚举", required = true, example = "1") private Integer result; - @Schema(title = "申请时间", required = true) + @Schema(description = "申请时间", required = true) @NotNull(message = "申请时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime createTime; - @Schema(title = "流程id") + @Schema(description = "流程id") private String processInstanceId; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java index 997b8bce0..1958fc739 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/activity/BpmActivityRespVO.java @@ -5,21 +5,21 @@ import lombok.Data; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 流程活动的 Response VO") +@Schema(description = "管理后台 - 流程活动的 Response VO") @Data public class BpmActivityRespVO { - @Schema(title = "流程活动的标识", required = true, example = "1024") + @Schema(description = "流程活动的标识", required = true, example = "1024") private String key; - @Schema(title = "流程活动的类型", required = true, example = "StartEvent") + @Schema(description = "流程活动的类型", required = true, example = "StartEvent") private String type; - @Schema(title = "流程活动的开始时间", required = true) + @Schema(description = "流程活动的开始时间", required = true) private LocalDateTime startTime; - @Schema(title = "流程活动的结束时间", required = true) + @Schema(description = "流程活动的结束时间", required = true) private LocalDateTime endTime; - @Schema(title = "关联的流程任务的编号", example = "2048", description = "关联的流程任务,只有 UserTask 等类型才有") + @Schema(description = "关联的流程任务的编号-关联的流程任务,只有 UserTask 等类型才有", example = "2048") private String taskId; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java index 3a2ea654c..c0903279b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCancelReqVO.java @@ -7,15 +7,15 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.Map; -@Schema(title = "管理后台 - 流程实例的取消 Request VO") +@Schema(description = "管理后台 - 流程实例的取消 Request VO") @Data public class BpmProcessInstanceCancelReqVO { - @Schema(title = "流程实例的编号", required = true, example = "1024") + @Schema(description = "流程实例的编号", required = true, example = "1024") @NotEmpty(message = "流程实例的编号不能为空") private String id; - @Schema(title = "取消原因", required = true, example = "不请假了!") + @Schema(description = "取消原因", required = true, example = "不请假了!") @NotEmpty(message = "取消原因不能为空") private String reason; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java index 588de54fd..48becaad2 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCreateReqVO.java @@ -6,15 +6,15 @@ import lombok.Data; import javax.validation.constraints.NotEmpty; import java.util.Map; -@Schema(title = "管理后台 - 流程实例的创建 Request VO") +@Schema(description = "管理后台 - 流程实例的创建 Request VO") @Data public class BpmProcessInstanceCreateReqVO { - @Schema(title = "流程定义的编号", required = true, example = "1024") + @Schema(description = "流程定义的编号", required = true, example = "1024") @NotEmpty(message = "流程定义编号不能为空") private String processDefinitionId; - @Schema(title = "变量实例") + @Schema(description = "变量实例") private Map variables; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java index 111c73b5d..5b5d9fb26 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java @@ -11,28 +11,28 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 流程实例的分页 Item Response VO") +@Schema(description = "管理后台 - 流程实例的分页 Item Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmProcessInstanceMyPageReqVO extends PageParam { - @Schema(title = "流程名称", example = "芋道") + @Schema(description = "流程名称", example = "芋道") private String name; - @Schema(title = "流程定义的编号", example = "2048") + @Schema(description = "流程定义的编号", example = "2048") private String processDefinitionId; - @Schema(title = "流程实例的状态", description = "参见 bpm_process_instance_status", example = "1") + @Schema(description = "流程实例的状态-参见 bpm_process_instance_status", example = "1") private Integer status; - @Schema(title = "流程实例的结果", description = "参见 bpm_process_instance_result", example = "2") + @Schema(description = "流程实例的结果-参见 bpm_process_instance_result", example = "2") private Integer result; - @Schema(title = "流程分类", description = "参见 bpm_model_category 数据字典", example = "1") + @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1") private String category; - @Schema(title = "创建时间") + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java index c367eaf5a..c38274138 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java @@ -6,32 +6,32 @@ import lombok.Data; import java.time.LocalDateTime; import java.util.List; -@Schema(title = "管理后台 - 流程实例的分页 Item Response VO") +@Schema(description = "管理后台 - 流程实例的分页 Item Response VO") @Data public class BpmProcessInstancePageItemRespVO { - @Schema(title = "流程实例的编号", required = true, example = "1024") + @Schema(description = "流程实例的编号", required = true, example = "1024") private String id; - @Schema(title = "流程名称", required = true, example = "芋道") + @Schema(description = "流程名称", required = true, example = "芋道") private String name; - @Schema(title = "流程定义的编号", required = true, example = "2048") + @Schema(description = "流程定义的编号", required = true, example = "2048") private String processDefinitionId; - @Schema(title = "流程分类", required = true, description = "参见 bpm_model_category 数据字典", example = "1") + @Schema(description = "流程分类-参见 bpm_model_category 数据字典", required = true, example = "1") private String category; - @Schema(title = "流程实例的状态", required = true, description = "参见 bpm_process_instance_status", example = "1") + @Schema(description = "流程实例的状态-参见 bpm_process_instance_status", required = true, example = "1") private Integer status; - @Schema(title = "流程实例的结果", required = true, description = "参见 bpm_process_instance_result", example = "2") + @Schema(description = "流程实例的结果-参见 bpm_process_instance_result", required = true, example = "2") private Integer result; - @Schema(title = "提交时间", required = true) + @Schema(description = "提交时间", required = true) private LocalDateTime createTime; - @Schema(title = "结束时间", required = true) + @Schema(description = "结束时间", required = true) private LocalDateTime endTime; /** @@ -39,14 +39,14 @@ public class BpmProcessInstancePageItemRespVO { */ private List tasks; - @Schema(title = "流程任务") + @Schema(description = "流程任务") @Data public static class Task { - @Schema(title = "流程任务的编号", required = true, example = "1024") + @Schema(description = "流程任务的编号", required = true, example = "1024") private String id; - @Schema(title = "任务名称", required = true, example = "芋道") + @Schema(description = "任务名称", required = true, example = "芋道") private String name; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java index 8d02aec71..5c6d381a0 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java @@ -7,35 +7,35 @@ import java.time.LocalDateTime; import java.util.List; import java.util.Map; -@Schema(title = "管理后台 - 流程实例的 Response VO") +@Schema(description = "管理后台 - 流程实例的 Response VO") @Data public class BpmProcessInstanceRespVO { - @Schema(title = "流程实例的编号", required = true, example = "1024") + @Schema(description = "流程实例的编号", required = true, example = "1024") private String id; - @Schema(title = "流程名称", required = true, example = "芋道") + @Schema(description = "流程名称", required = true, example = "芋道") private String name; - @Schema(title = "流程分类", required = true, description = "参见 bpm_model_category 数据字典", example = "1") + @Schema(description = "流程分类-参见 bpm_model_category 数据字典", required = true, example = "1") private String category; - @Schema(title = "流程实例的状态", required = true, description = "参见 bpm_process_instance_status", example = "1") + @Schema(description = "流程实例的状态-参见 bpm_process_instance_status", required = true, example = "1") private Integer status; - @Schema(title = "流程实例的结果", required = true, description = "参见 bpm_process_instance_result", example = "2") + @Schema(description = "流程实例的结果-参见 bpm_process_instance_result", required = true, example = "2") private Integer result; - @Schema(title = "提交时间", required = true) + @Schema(description = "提交时间", required = true) private LocalDateTime createTime; - @Schema(title = "结束时间", required = true) + @Schema(description = "结束时间", required = true) private LocalDateTime endTime; - @Schema(title = "提交的表单值", required = true) + @Schema(description = "提交的表单值", required = true) private Map formVariables; - @Schema(title = "业务的唯一标识", example = "1", description = "例如说,请假申请的编号") + @Schema(description = "业务的唯一标识-例如说,请假申请的编号", example = "1") private String businessKey; /** @@ -48,47 +48,45 @@ public class BpmProcessInstanceRespVO { */ private ProcessDefinition processDefinition; - @Schema(title = "用户信息") + @Schema(description = "用户信息") @Data public static class User { - @Schema(title = "用户编号", required = true, example = "1") + @Schema(description = "用户编号", required = true, example = "1") private Long id; - @Schema(title = "用户昵称", required = true, example = "芋艿") + @Schema(description = "用户昵称", required = true, example = "芋艿") private String nickname; - @Schema(title = "部门编号", required = true, example = "1") + @Schema(description = "部门编号", required = true, example = "1") private Long deptId; - @Schema(title = "部门名称", required = true, example = "研发部") + @Schema(description = "部门名称", required = true, example = "研发部") private String deptName; } - @Schema(title = "流程定义信息") + @Schema(description = "流程定义信息") @Data public static class ProcessDefinition { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private String id; - @Schema(title = "表单类型", description = "参见 bpm_model_form_type 数据字典", example = "1") + @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1") private Integer formType; - @Schema(title = "表单编号", example = "1024", description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024") private Long formId; - @Schema(title = "表单的配置", required = true, - description = "JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "表单的配置-JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", required = true) private String formConf; - @Schema(title = "表单项的数组", required = true, - description = "JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "表单项的数组-JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", required = true) private List formFields; - @Schema(title = "自定义表单的提交路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/create", - description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", + example = "/bpm/oa/leave/create") private String formCustomCreatePath; - @Schema(title = "自定义表单的查看路径,使用 Vue 的路由地址", example = "/bpm/oa/leave/view", - description = "在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空") + @Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", + example = "/bpm/oa/leave/view") private String formCustomViewPath; - @Schema(title = "BPMN XML", required = true) + @Schema(description = "BPMN XML", required = true) private String bpmnXml; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java index 5e023f2c1..5214f4650 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java @@ -5,15 +5,15 @@ import lombok.Data; import javax.validation.constraints.NotEmpty; -@Schema(title = "管理后台 - 通过流程任务的 Request VO") +@Schema(description = "管理后台 - 通过流程任务的 Request VO") @Data public class BpmTaskApproveReqVO { - @Schema(title = "任务编号", required = true, example = "1024") + @Schema(description = "任务编号", required = true, example = "1024") @NotEmpty(message = "任务编号不能为空") private String id; - @Schema(title = "审批意见", required = true, example = "不错不错!") + @Schema(description = "审批意见", required = true, example = "不错不错!") @NotEmpty(message = "审批意见不能为空") private String reason; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java index a77fb1002..12fa019d9 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageItemRespVO.java @@ -7,20 +7,20 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 流程任务的 Done 已完成的分页项 Response VO") +@Schema(description = "管理后台 - 流程任务的 Done 已完成的分页项 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskDonePageItemRespVO extends BpmTaskTodoPageItemRespVO { - @Schema(title = "结束时间", required = true) + @Schema(description = "结束时间", required = true) private LocalDateTime endTime; - @Schema(title = "持续时间", required = true, example = "1000") + @Schema(description = "持续时间", required = true, example = "1000") private Long durationInMillis; - @Schema(title = "任务结果", required = true, description = "参见 bpm_process_instance_result", example = "2") + @Schema(description = "任务结果-参见 bpm_process_instance_result", required = true, example = "2") private Integer result; - @Schema(title = "审批建议", required = true, example = "不请假了!") + @Schema(description = "审批建议", required = true, example = "不请假了!") private String reason; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java index fa152186c..52daea445 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskDonePageReqVO.java @@ -11,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 流程任务的 Done 已办的分页 Request VO") +@Schema(description = "管理后台 - 流程任务的 Done 已办的分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskDonePageReqVO extends PageParam { - @Schema(title = "流程任务名", example = "芋道") + @Schema(description = "流程任务名", example = "芋道") private String name; - @Schema(title = "开始的创建收间") + @Schema(description = "开始的创建收间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime beginCreateTime; - @Schema(title = "结束的创建时间") + @Schema(description = "结束的创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endCreateTime; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java index 1b7d0d34f..f51a69185 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRejectReqVO.java @@ -5,15 +5,15 @@ import lombok.Data; import javax.validation.constraints.NotEmpty; -@Schema(title = "管理后台 - 不通过流程任务的 Request VO") +@Schema(description = "管理后台 - 不通过流程任务的 Request VO") @Data public class BpmTaskRejectReqVO { - @Schema(title = "任务编号", required = true, example = "1024") + @Schema(description = "任务编号", required = true, example = "1024") @NotEmpty(message = "任务编号不能为空") private String id; - @Schema(title = "审批意见", required = true, example = "不错不错!") + @Schema(description = "审批意见", required = true, example = "不错不错!") @NotEmpty(message = "审批意见不能为空") private String reason; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java index df1e10764..9459c30c1 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java @@ -5,13 +5,13 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 流程任务的 Response VO") +@Schema(description = "管理后台 - 流程任务的 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO { - @Schema(title = "任务定义的标识", required = true, example = "user-001") + @Schema(description = "任务定义的标识", required = true, example = "user-001") private String definitionKey; /** @@ -19,18 +19,18 @@ public class BpmTaskRespVO extends BpmTaskDonePageItemRespVO { */ private User assigneeUser; - @Schema(title = "用户信息") + @Schema(description = "用户信息") @Data public static class User { - @Schema(title = "用户编号", required = true, example = "1") + @Schema(description = "用户编号", required = true, example = "1") private Long id; - @Schema(title = "用户昵称", required = true, example = "芋艿") + @Schema(description = "用户昵称", required = true, example = "芋艿") private String nickname; - @Schema(title = "部门编号", required = true, example = "1") + @Schema(description = "部门编号", required = true, example = "1") private Long deptId; - @Schema(title = "部门名称", required = true, example = "研发部") + @Schema(description = "部门名称", required = true, example = "研发部") private String deptName; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java index dbcdb7c14..cc71e1b2f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageItemRespVO.java @@ -5,23 +5,23 @@ import lombok.Data; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 流程任务的 Running 进行中的分页项 Response VO") +@Schema(description = "管理后台 - 流程任务的 Running 进行中的分页项 Response VO") @Data public class BpmTaskTodoPageItemRespVO { - @Schema(title = "任务编号", required = true, example = "1024") + @Schema(description = "任务编号", required = true, example = "1024") private String id; - @Schema(title = "任务名字", required = true, example = "芋道") + @Schema(description = "任务名字", required = true, example = "芋道") private String name; - @Schema(title = "接收时间", required = true) + @Schema(description = "接收时间", required = true) private LocalDateTime claimTime; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; - @Schema(title = "激活状态", required = true, example = "1", description = "参见 SuspensionState 枚举") + @Schema(description = "激活状态-参见 SuspensionState 枚举", required = true, example = "1") private Integer suspensionState; /** @@ -30,22 +30,22 @@ public class BpmTaskTodoPageItemRespVO { private ProcessInstance processInstance; @Data - @Schema(title = "流程实例") + @Schema(description = "流程实例") public static class ProcessInstance { - @Schema(title = "流程实例编号", required = true, example = "1024") + @Schema(description = "流程实例编号", required = true, example = "1024") private String id; - @Schema(title = "流程实例名称", required = true, example = "芋道") + @Schema(description = "流程实例名称", required = true, example = "芋道") private String name; - @Schema(title = "发起人的用户编号", required = true, example = "1024") + @Schema(description = "发起人的用户编号", required = true, example = "1024") private Long startUserId; - @Schema(title = "发起人的用户昵称", required = true, example = "芋艿") + @Schema(description = "发起人的用户昵称", required = true, example = "芋艿") private String startUserNickname; - @Schema(title = "流程定义的编号", required = true, example = "2048") + @Schema(description = "流程定义的编号", required = true, example = "2048") private String processDefinitionId; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java index d4994e272..7a4437e92 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskTodoPageReqVO.java @@ -11,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 流程任务的 TODO 待办的分页 Request VO") +@Schema(description = "管理后台 - 流程任务的 TODO 待办的分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BpmTaskTodoPageReqVO extends PageParam { - @Schema(title = "流程任务名", example = "芋道") + @Schema(description = "流程任务名", example = "芋道") private String name; - @Schema(title = "开始的创建收间") + @Schema(description = "开始的创建收间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime beginCreateTime; - @Schema(title = "结束的创建时间") + @Schema(description = "结束的创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endCreateTime; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java index 0bd364043..d0990a142 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskUpdateAssigneeReqVO.java @@ -9,15 +9,15 @@ import net.bytebuddy.implementation.bind.annotation.Empty; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 流程任务的更新负责人的 Request VO") +@Schema(description = "管理后台 - 流程任务的更新负责人的 Request VO") @Data public class BpmTaskUpdateAssigneeReqVO { - @Schema(title = "任务编号", required = true, example = "1024") + @Schema(description = "任务编号", required = true, example = "1024") @NotEmpty(message = "任务编号不能为空") private String id; - @Schema(title = "新审批人的用户编号", required = true, example = "2048") + @Schema(description = "新审批人的用户编号", required = true, example = "2048") @NotNull(message = "新审批人的用户编号不能为空") private Long assigneeUserId; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenCreateListReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenCreateListReqVO.java index c2a1497df..da9e2c674 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenCreateListReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenCreateListReqVO.java @@ -6,15 +6,15 @@ import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; -@Schema(title = "管理后台 - 基于数据库的表结构,创建代码生成器的表和字段定义 Request VO") +@Schema(description = "管理后台 - 基于数据库的表结构,创建代码生成器的表和字段定义 Request VO") @Data public class CodegenCreateListReqVO { - @Schema(title = "数据源配置的编号", required = true, example = "1") + @Schema(description = "数据源配置的编号", required = true, example = "1") @NotNull(message = "数据源配置的编号不能为空") private Long dataSourceConfigId; - @Schema(title = "表名数组", required = true, example = "[1, 2, 3]") + @Schema(description = "表名数组", required = true, example = "[1, 2, 3]") @NotNull(message = "表名数组不能为空") private List tableNames; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenDetailRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenDetailRespVO.java index 3b8e13e94..f7d8a62a4 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenDetailRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenDetailRespVO.java @@ -7,14 +7,14 @@ import lombok.Data; import java.util.List; -@Schema(title = "管理后台 - 代码生成表和字段的明细 Response VO") +@Schema(description = "管理后台 - 代码生成表和字段的明细 Response VO") @Data public class CodegenDetailRespVO { - @Schema(name = "表定义") + @Schema(description = "表定义") private CodegenTableRespVO table; - @Schema(name = "字段定义") + @Schema(description = "字段定义") private List columns; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenPreviewRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenPreviewRespVO.java index 597d4de8f..89e98e6c0 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenPreviewRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenPreviewRespVO.java @@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 代码生成预览 Response VO", description ="注意,每个文件都是一个该对象") +@Schema(description = "管理后台 - 代码生成预览 Response VO,注意,每个文件都是一个该对象") @Data public class CodegenPreviewRespVO { - @Schema(title = "文件路径", required = true, example = "java/cn/iocoder/yudao/adminserver/modules/system/controller/test/SysTestDemoController.java") + @Schema(description = "文件路径", required = true, example = "java/cn/iocoder/yudao/adminserver/modules/system/controller/test/SysTestDemoController.java") private String filePath; - @Schema(title = "代码", required = true, example = "Hello World") + @Schema(description = "代码", required = true, example = "Hello World") private String code; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenUpdateReqVO.java index 8ccde1284..b10885868 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/CodegenUpdateReqVO.java @@ -14,7 +14,7 @@ import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotNull; import java.util.List; -@Schema(title = "管理后台 - 代码生成表和字段的修改 Request VO") +@Schema(description = "管理后台 - 代码生成表和字段的修改 Request VO") @Data public class CodegenUpdateReqVO { @@ -26,14 +26,14 @@ public class CodegenUpdateReqVO { @NotNull(message = "字段定义不能为空") private List columns; - @Schema(title = "更新表定义") + @Schema(description = "更新表定义") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @Valid public static class Table extends CodegenTableBaseVO { - @Schema(title = "编号", required = true, example = "1") + @Schema(description = "编号", required = true, example = "1") private Long id; @AssertTrue(message = "上级菜单不能为空") @@ -45,13 +45,13 @@ public class CodegenUpdateReqVO { } - @Schema(title = "更新表定义") + @Schema(description = "更新表定义") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public static class Column extends CodegenColumnBaseVO { - @Schema(title = "编号", required = true, example = "1") + @Schema(description = "编号", required = true, example = "1") private Long id; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnBaseVO.java index f9a3a668b..abbb30983 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnBaseVO.java @@ -11,73 +11,73 @@ import javax.validation.constraints.NotNull; @Data public class CodegenColumnBaseVO { - @Schema(title = "表编号", required = true, example = "1") + @Schema(description = "表编号", required = true, example = "1") @NotNull(message = "表编号不能为空") private Long tableId; - @Schema(title = "字段名", required = true, example = "user_age") + @Schema(description = "字段名", required = true, example = "user_age") @NotNull(message = "字段名不能为空") private String columnName; - @Schema(title = "字段类型", required = true, example = "int(11)") + @Schema(description = "字段类型", required = true, example = "int(11)") @NotNull(message = "字段类型不能为空") private String dataType; - @Schema(title = "字段描述", required = true, example = "年龄") + @Schema(description = "字段描述", required = true, example = "年龄") @NotNull(message = "字段描述不能为空") private String columnComment; - @Schema(title = "是否允许为空", required = true, example = "true") + @Schema(description = "是否允许为空", required = true, example = "true") @NotNull(message = "是否允许为空不能为空") private Boolean nullable; - @Schema(title = "是否主键", required = true, example = "false") + @Schema(description = "是否主键", required = true, example = "false") @NotNull(message = "是否主键不能为空") private Boolean primaryKey; - @Schema(title = "是否自增", required = true, example = "true") + @Schema(description = "是否自增", required = true, example = "true") @NotNull(message = "是否自增不能为空") private String autoIncrement; - @Schema(title = "排序", required = true, example = "10") + @Schema(description = "排序", required = true, example = "10") @NotNull(message = "排序不能为空") private Integer ordinalPosition; - @Schema(title = "Java 属性类型", required = true, example = "userAge") + @Schema(description = "Java 属性类型", required = true, example = "userAge") @NotNull(message = "Java 属性类型不能为空") private String javaType; - @Schema(title = "Java 属性名", required = true, example = "Integer") + @Schema(description = "Java 属性名", required = true, example = "Integer") @NotNull(message = "Java 属性名不能为空") private String javaField; - @Schema(title = "字典类型", example = "sys_gender") + @Schema(description = "字典类型", example = "sys_gender") private String dictType; - @Schema(title = "数据示例", example = "1024") + @Schema(description = "数据示例", example = "1024") private String example; - @Schema(title = "是否为 Create 创建操作的字段", required = true, example = "true") + @Schema(description = "是否为 Create 创建操作的字段", required = true, example = "true") @NotNull(message = "是否为 Create 创建操作的字段不能为空") private Boolean createOperation; - @Schema(title = "是否为 Update 更新操作的字段", required = true, example = "false") + @Schema(description = "是否为 Update 更新操作的字段", required = true, example = "false") @NotNull(message = "是否为 Update 更新操作的字段不能为空") private Boolean updateOperation; - @Schema(title = "是否为 List 查询操作的字段", required = true, example = "true") + @Schema(description = "是否为 List 查询操作的字段", required = true, example = "true") @NotNull(message = "是否为 List 查询操作的字段不能为空") private Boolean listOperation; - @Schema(title = "List 查询操作的条件类型", required = true, example = "LIKE", description = "参见 CodegenColumnListConditionEnum 枚举") + @Schema(description = "List 查询操作的条件类型,参见 CodegenColumnListConditionEnum 枚举", required = true, example = "LIKE") @NotNull(message = "List 查询操作的条件类型不能为空") private String listOperationCondition; - @Schema(title = "是否为 List 查询操作的返回字段", required = true, example = "true") + @Schema(description = "是否为 List 查询操作的返回字段", required = true, example = "true") @NotNull(message = "是否为 List 查询操作的返回字段不能为空") private Boolean listOperationResult; - @Schema(title = "显示类型", required = true, example = "input") + @Schema(description = "显示类型", required = true, example = "input") @NotNull(message = "显示类型不能为空") private String htmlType; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnRespVO.java index c5abfa1e1..1ef17b0ea 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/column/CodegenColumnRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 代码生成字段定义 Response VO") +@Schema(description = "管理后台 - 代码生成字段定义 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CodegenColumnRespVO extends CodegenColumnBaseVO { - @Schema(title = "编号", required = true, example = "1") + @Schema(description = "编号", required = true, example = "1") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableBaseVO.java index 01cb907f4..11ed1144a 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableBaseVO.java @@ -5,52 +5,52 @@ import lombok.Data; import javax.validation.constraints.NotNull; /** -* 代码生成 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ + * 代码生成 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ @Data public class CodegenTableBaseVO { - @Schema(title = "生成场景", required = true, example = "1", description = "参见 CodegenSceneEnum 枚举") + @Schema(description = "生成场景,参见 CodegenSceneEnum 枚举", required = true, example = "1") @NotNull(message = "导入类型不能为空") private Integer scene; - @Schema(title = "表名称", required = true, example = "yudao") + @Schema(description = "表名称", required = true, example = "yudao") @NotNull(message = "表名称不能为空") private String tableName; - @Schema(title = "表描述", required = true, example = "芋道") + @Schema(description = "表描述", required = true, example = "芋道") @NotNull(message = "表描述不能为空") private String tableComment; - @Schema(title = "备注", example = "我是备注") + @Schema(description = "备注", example = "我是备注") private String remark; - @Schema(title = "模块名", required = true, example = "system") + @Schema(description = "模块名", required = true, example = "system") @NotNull(message = "模块名不能为空") private String moduleName; - @Schema(title = "业务名", required = true, example = "codegen") + @Schema(description = "业务名", required = true, example = "codegen") @NotNull(message = "业务名不能为空") private String businessName; - @Schema(title = "类名称", required = true, example = "CodegenTable") + @Schema(description = "类名称", required = true, example = "CodegenTable") @NotNull(message = "类名称不能为空") private String className; - @Schema(title = "类描述", required = true, example = "代码生成器的表定义") + @Schema(description = "类描述", required = true, example = "代码生成器的表定义") @NotNull(message = "类描述不能为空") private String classComment; - @Schema(title = "作者", required = true, example = "芋道源码") + @Schema(description = "作者", required = true, example = "芋道源码") @NotNull(message = "作者不能为空") private String author; - @Schema(title = "模板类型", required = true, example = "1", description = "参见 CodegenTemplateTypeEnum 枚举") + @Schema(description = "模板类型,参见 CodegenTemplateTypeEnum 枚举", required = true, example = "1") @NotNull(message = "模板类型不能为空") private Integer templateType; - @Schema(title = "父菜单编号", example = "1024") + @Schema(description = "父菜单编号", example = "1024") private Long parentMenuId; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTablePageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTablePageReqVO.java index 648869d7b..bc93e73ea 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTablePageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTablePageReqVO.java @@ -11,19 +11,19 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 表定义分页 Request VO") +@Schema(description = "管理后台 - 表定义分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CodegenTablePageReqVO extends PageParam { - @Schema(title = "表名称", example = "yudao", description = "模糊匹配") + @Schema(description = "表名称,模糊匹配", example = "yudao") private String tableName; - @Schema(title = "表描述", example = "芋道", description = "模糊匹配") + @Schema(description = "表描述,模糊匹配", example = "芋道") private String tableComment; - @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableRespVO.java index 4703fa4ae..af45018bd 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/CodegenTableRespVO.java @@ -7,22 +7,22 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 代码生成表定义 Response VO") +@Schema(description = "管理后台 - 代码生成表定义 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CodegenTableRespVO extends CodegenTableBaseVO { - @Schema(title = "编号", required = true, example = "1") + @Schema(description = "编号", required = true, example = "1") private Long id; - @Schema(title = "主键编号", required = true, example = "1024") + @Schema(description = "主键编号", required = true, example = "1024") private Integer dataSourceConfigId; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; - @Schema(title = "更新时间", required = true) + @Schema(description = "更新时间", required = true) private LocalDateTime updateTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/DatabaseTableRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/DatabaseTableRespVO.java index e2541666e..61668db15 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/DatabaseTableRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/vo/table/DatabaseTableRespVO.java @@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.infra.controller.admin.codegen.vo.table; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 数据库的表定义 Response VO") +@Schema(description = "管理后台 - 数据库的表定义 Response VO") @Data public class DatabaseTableRespVO { - @Schema(title = "表名称", required = true, example = "yuanma") + @Schema(description = "表名称", required = true, example = "yuanma") private String name; - @Schema(title = "表描述", required = true, example = "芋道源码") + @Schema(description = "表描述", required = true, example = "芋道源码") private String comment; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigBaseVO.java index acd680290..155b2da81 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigBaseVO.java @@ -14,26 +14,26 @@ import javax.validation.constraints.Size; @Data public class ConfigBaseVO { - @Schema(title = "参数分组", required = true, example = "biz") + @Schema(description = "参数分组", required = true, example = "biz") @NotEmpty(message = "参数分组不能为空") @Size(max = 50, message = "参数名称不能超过50个字符") private String category; - @Schema(title = "参数名称", required = true, example = "数据库名") + @Schema(description = "参数名称", required = true, example = "数据库名") @NotBlank(message = "参数名称不能为空") @Size(max = 100, message = "参数名称不能超过100个字符") private String name; - @Schema(title = "参数键值", required = true, example = "1024") + @Schema(description = "参数键值", required = true, example = "1024") @NotBlank(message = "参数键值不能为空") @Size(max = 500, message = "参数键值长度不能超过500个字符") private String value; - @Schema(title = "是否敏感", required = true, example = "true") + @Schema(description = "是否敏感", required = true, example = "true") @NotNull(message = "是否敏感不能为空") private Boolean visible; - @Schema(title = "备注", example = "备注一下很帅气!") + @Schema(description = "备注", example = "备注一下很帅气!") private String remark; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigCreateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigCreateReqVO.java index d9d369b20..186629b0f 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigCreateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigCreateReqVO.java @@ -7,12 +7,12 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; -@Schema(title = "管理后台 - 参数配置创建 Request VO") +@Schema(description = "管理后台 - 参数配置创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class ConfigCreateReqVO extends ConfigBaseVO { - @Schema(title = "参数键名", required = true, example = "yunai.db.username") + @Schema(description = "参数键名", required = true, example = "yunai.db.username") @NotBlank(message = "参数键名长度不能为空") @Size(max = 100, message = "参数键名长度不能超过100个字符") private String key; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigExportReqVO.java index 6bcf83a86..f0f4b4ff3 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigExportReqVO.java @@ -8,20 +8,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 参数配置导出 Request VO") +@Schema(description = "管理后台 - 参数配置导出 Request VO") @Data public class ConfigExportReqVO { - @Schema(title = "参数名称", example = "模糊匹配") + @Schema(description = "参数名称", example = "模糊匹配") private String name; - @Schema(title = "参数键名", example = "yunai.db.username", description = "模糊匹配") + @Schema(description = "参数键名,模糊匹配", example = "yunai.db.username") private String key; - @Schema(title = "参数类型", example = "1", description = "参见 SysConfigTypeEnum 枚举") + @Schema(description = "参数类型,参见 SysConfigTypeEnum 枚举", example = "1") private Integer type; - @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigPageReqVO.java index 34d9e5d88..8f87d6ee9 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigPageReqVO.java @@ -11,22 +11,22 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 参数配置分页 Request VO") +@Schema(description = "管理后台 - 参数配置分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ConfigPageReqVO extends PageParam { - @Schema(title = "数据源名称", example = "模糊匹配") + @Schema(description = "数据源名称,模糊匹配", example = "名称") private String name; - @Schema(title = "参数键名", example = "yunai.db.username", description = "模糊匹配") + @Schema(description = "参数键名,模糊匹配", example = "yunai.db.username") private String key; - @Schema(title = "参数类型", example = "1", description = "参见 SysConfigTypeEnum 枚举") + @Schema(description = "参数类型,参见 SysConfigTypeEnum 枚举", example = "1") private Integer type; - @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigRespVO.java index e9746f9a4..738cd6481 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigRespVO.java @@ -8,23 +8,23 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 参数配置信息 Response VO") +@Schema(description = "管理后台 - 参数配置信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) public class ConfigRespVO extends ConfigBaseVO { - @Schema(title = "参数配置序号", required = true, example = "1024") + @Schema(description = "参数配置序号", required = true, example = "1024") private Long id; - @Schema(title = "参数键名", required = true, example = "yunai.db.username") + @Schema(description = "参数键名", required = true, example = "yunai.db.username") @NotBlank(message = "参数键名长度不能为空") @Size(max = 100, message = "参数键名长度不能超过100个字符") private String key; - @Schema(title = "参数类型", required = true, example = "1", description = "参见 SysConfigTypeEnum 枚举") + @Schema(description = "参数类型,参见 SysConfigTypeEnum 枚举", required = true, example = "1") private Integer type; - @Schema(title = "创建时间", required = true, example = "时间戳格式") + @Schema(description = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigUpdateReqVO.java index 175f8a4dc..efa689d42 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/vo/ConfigUpdateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 参数配置创建 Request VO") +@Schema(description = "管理后台 - 参数配置创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ConfigUpdateReqVO extends ConfigBaseVO { - @Schema(title = "参数配置序号", required = true, example = "1024") + @Schema(description = "参数配置序号", required = true, example = "1024") @NotNull(message = "参数配置编号不能为空") private Long id; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigBaseVO.java index 53230df01..a757b0882 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigBaseVO.java @@ -10,15 +10,15 @@ import javax.validation.constraints.*; @Data public class DataSourceConfigBaseVO { - @Schema(title = "数据源名称", required = true, example = "test") + @Schema(description = "数据源名称", required = true, example = "test") @NotNull(message = "数据源名称不能为空") private String name; - @Schema(title = "数据源连接", required = true, example = "jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro") + @Schema(description = "数据源连接", required = true, example = "jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro") @NotNull(message = "数据源连接不能为空") private String url; - @Schema(title = "用户名", required = true, example = "root") + @Schema(description = "用户名", required = true, example = "root") @NotNull(message = "用户名不能为空") private String username; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigCreateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigCreateReqVO.java index 9f244c817..e8f4cc97d 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigCreateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigCreateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 数据源配置创建 Request VO") +@Schema(description = "管理后台 - 数据源配置创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DataSourceConfigCreateReqVO extends DataSourceConfigBaseVO { - @Schema(title = "密码", required = true, example = "123456") + @Schema(description = "密码", required = true, example = "123456") @NotNull(message = "密码不能为空") private String password; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java index 2f3b02faf..02bdff415 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java @@ -4,16 +4,16 @@ import lombok.*; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 数据源配置 Response VO") +@Schema(description = "管理后台 - 数据源配置 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DataSourceConfigRespVO extends DataSourceConfigBaseVO { - @Schema(title = "主键编号", required = true, example = "1024") + @Schema(description = "主键编号", required = true, example = "1024") private Integer id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigUpdateReqVO.java index 019ed0a20..5fac798ea 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigUpdateReqVO.java @@ -3,17 +3,17 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 数据源配置更新 Request VO") +@Schema(description = "管理后台 - 数据源配置更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DataSourceConfigUpdateReqVO extends DataSourceConfigBaseVO { - @Schema(title = "主键编号", required = true, example = "1024") + @Schema(description = "主键编号", required = true, example = "1024") @NotNull(message = "主键编号不能为空") private Long id; - @Schema(title = "密码", required = true, example = "123456") + @Schema(description = "密码", required = true, example = "123456") @NotNull(message = "密码不能为空") private String password; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigBaseVO.java index c9a1f9e4d..d7bc42d73 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigBaseVO.java @@ -11,11 +11,11 @@ import javax.validation.constraints.NotNull; @Data public class FileConfigBaseVO { - @Schema(title = "配置名", required = true, example = "S3 - 阿里云") + @Schema(description = "配置名", required = true, example = "S3 - 阿里云") @NotNull(message = "配置名不能为空") private String name; - @Schema(title = "备注", example = "我是备注") + @Schema(description = "备注", example = "我是备注") private String remark; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigCreateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigCreateReqVO.java index 10602bfd9..db64205f4 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigCreateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigCreateReqVO.java @@ -8,17 +8,17 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.util.Map; -@Schema(title = "管理后台 - 文件配置创建 Request VO") +@Schema(description = "管理后台 - 文件配置创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class FileConfigCreateReqVO extends FileConfigBaseVO { - @Schema(title = "存储器", required = true, example = "1", description = "参见 FileStorageEnum 枚举类") + @Schema(description = "存储器,参见 FileStorageEnum 枚举类参见 FileStorageEnum 枚举类", required = true, example = "1") @NotNull(message = "存储器不能为空") private Integer storage; - @Schema(title = "存储配置", required = true, description = "配置是动态参数,所以使用 Map 接收") + @Schema(description = "存储配置,配置是动态参数,所以使用 Map 接收", required = true) @NotNull(message = "存储配置不能为空") private Map config; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigPageReqVO.java index a8888f788..9d254adb1 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigPageReqVO.java @@ -11,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 文件配置分页 Request VO") +@Schema(description = "管理后台 - 文件配置分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class FileConfigPageReqVO extends PageParam { - @Schema(title = "配置名", example = "S3 - 阿里云") + @Schema(description = "配置名", example = "S3 - 阿里云") private String name; - @Schema(title = "存储器", example = "1") + @Schema(description = "存储器", example = "1") private Integer storage; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigRespVO.java index 25f1ebec3..ae194cd31 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigRespVO.java @@ -9,27 +9,27 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 文件配置 Response VO") +@Schema(description = "管理后台 - 文件配置 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class FileConfigRespVO extends FileConfigBaseVO { - @Schema(title = "编号", required = true, example = "1") + @Schema(description = "编号", required = true, example = "1") private Long id; - @Schema(title = "存储器", required = true, example = "1", description = "参见 FileStorageEnum 枚举类") + @Schema(description = "存储器,参见 FileStorageEnum 枚举类", required = true, example = "1") @NotNull(message = "存储器不能为空") private Integer storage; - @Schema(title = "是否为主配置", required = true, example = "true") + @Schema(description = "是否为主配置", required = true, example = "true") @NotNull(message = "是否为主配置不能为空") private Boolean master; - @Schema(title = "存储配置", required = true) + @Schema(description = "存储配置", required = true) private FileClientConfig config; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigUpdateReqVO.java index 079c67dc8..cd0c10802 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/config/FileConfigUpdateReqVO.java @@ -8,17 +8,17 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.util.Map; -@Schema(title = "管理后台 - 文件配置更新 Request VO") +@Schema(description = "管理后台 - 文件配置更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class FileConfigUpdateReqVO extends FileConfigBaseVO { - @Schema(title = "编号", required = true, example = "1") + @Schema(description = "编号", required = true, example = "1") @NotNull(message = "编号不能为空") private Long id; - @Schema(title = "存储配置", required = true, description = "配置是动态参数,所以使用 Map 接收") + @Schema(description = "存储配置,配置是动态参数,所以使用 Map 接收", required = true) @NotNull(message = "存储配置不能为空") private Map config; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java index 823a65bd5..fa8b84eef 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java @@ -11,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 文件分页 Request VO") +@Schema(description = "管理后台 - 文件分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class FilePageReqVO extends PageParam { - @Schema(title = "文件路径", example = "yudao", description = "模糊匹配") + @Schema(description = "文件路径,模糊匹配", example = "yudao") private String path; - @Schema(title = "文件类型", example = "application/octet-stream", description = "模糊匹配") + @Schema(description = "文件类型,模糊匹配", example = "application/octet-stream") private String type; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java index beccb8ccd..80607d8d0 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java @@ -5,32 +5,32 @@ import lombok.Data; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 文件 Response VO", description = "不返回 content 字段,太大") +@Schema(description = "管理后台 - 文件 Response VO,不返回 content 字段,太大") @Data public class FileRespVO { - @Schema(title = "文件编号", required = true, example = "1024") + @Schema(description = "文件编号", required = true, example = "1024") private Long id; - @Schema(title = "配置编号", required = true, example = "11") + @Schema(description = "配置编号", required = true, example = "11") private Long configId; - @Schema(title = "文件路径", required = true, example = "yudao.jpg") + @Schema(description = "文件路径", required = true, example = "yudao.jpg") private String path; - @Schema(title = "原文件名", required = true, example = "yudao.jpg") + @Schema(description = "原文件名", required = true, example = "yudao.jpg") private String name; - @Schema(title = "文件 URL", required = true, example = "https://www.iocoder.cn/yudao.jpg") + @Schema(description = "文件 URL", required = true, example = "https://www.iocoder.cn/yudao.jpg") private String url; - @Schema(title = "文件MIME类型", example = "application/octet-stream") + @Schema(description = "文件MIME类型", example = "application/octet-stream") private String type; - @Schema(title = "文件大小", example = "2048", required = true) + @Schema(description = "文件大小", example = "2048", required = true) private Integer size; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileUploadReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileUploadReqVO.java index 06b54a34d..7a4dcb1c2 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileUploadReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileUploadReqVO.java @@ -6,15 +6,15 @@ import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 上传文件 Request VO") +@Schema(description = "管理后台 - 上传文件 Request VO") @Data public class FileUploadReqVO { - @Schema(title = "文件附件", required = true) + @Schema(description = "文件附件", required = true) @NotNull(message = "文件附件不能为空") private MultipartFile file; - @Schema(title = "文件附件", example = "yudaoyuanma.png") + @Schema(description = "文件附件", example = "yudaoyuanma.png") private String path; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobBaseVO.java index 9cbecd604..e5927fe14 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobBaseVO.java @@ -11,26 +11,26 @@ import javax.validation.constraints.NotNull; @Data public class JobBaseVO { - @Schema(title = "任务名称", required = true, example = "测试任务") + @Schema(description = "任务名称", required = true, example = "测试任务") @NotNull(message = "任务名称不能为空") private String name; - @Schema(title = "处理器的参数", example = "yudao") + @Schema(description = "处理器的参数", example = "yudao") private String handlerParam; - @Schema(title = "CRON 表达式", required = true, example = "0/10 * * * * ? *") + @Schema(description = "CRON 表达式", required = true, example = "0/10 * * * * ? *") @NotNull(message = "CRON 表达式不能为空") private String cronExpression; - @Schema(title = "重试次数", required = true, example = "3") + @Schema(description = "重试次数", required = true, example = "3") @NotNull(message = "重试次数不能为空") private Integer retryCount; - @Schema(title = "重试间隔", required = true, example = "1000") + @Schema(description = "重试间隔", required = true, example = "1000") @NotNull(message = "重试间隔不能为空") private Integer retryInterval; - @Schema(title = "监控超时时间", example = "1000") + @Schema(description = "监控超时时间", example = "1000") private Integer monitorTimeout; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobCreateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobCreateReqVO.java index f4cd23a53..528392b52 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobCreateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobCreateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 定时任务创建 Request VO") +@Schema(description = "管理后台 - 定时任务创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobCreateReqVO extends JobBaseVO { - @Schema(title = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") + @Schema(description = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") @NotNull(message = "处理器的名字不能为空") private String handlerName; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobExportReqVO.java index 530d8fc99..49b7e83d3 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobExportReqVO.java @@ -3,17 +3,17 @@ package cn.iocoder.yudao.module.infra.controller.admin.job.vo.job; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 定时任务 Excel 导出 Request VO", description = "参数和 JobPageReqVO 是一致的") +@Schema(description = "管理后台 - 定时任务 Excel 导出 Request VO-参数和 JobPageReqVO 是一致的") @Data public class JobExportReqVO { - @Schema(title = "任务名称", example = "测试任务", description = "模糊匹配") + @Schema(description = "任务名称-模糊匹配", example = "测试任务") private String name; - @Schema(title = "任务状态", example = "1", description = "参见 JobStatusEnum 枚举") + @Schema(description = "任务状态-参见 JobStatusEnum 枚举", example = "1") private Integer status; - @Schema(title = "处理器的名字", example = "UserSessionTimeoutJob", description = "模糊匹配") + @Schema(description = "处理器的名字-模糊匹配", example = "UserSessionTimeoutJob") private String handlerName; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobPageReqVO.java index 860a14546..670c30f5c 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobPageReqVO.java @@ -6,19 +6,19 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 定时任务分页 Request VO") +@Schema(description = "管理后台 - 定时任务分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobPageReqVO extends PageParam { - @Schema(title = "任务名称", example = "测试任务", description = "模糊匹配") + @Schema(description = "任务名称,模糊匹配", example = "测试任务") private String name; - @Schema(title = "任务状态", example = "1", description = "参见 JobStatusEnum 枚举") + @Schema(description = "任务状态,参见 JobStatusEnum 枚举", example = "1") private Integer status; - @Schema(title = "处理器的名字", example = "sysUserSessionTimeoutJob", description = "模糊匹配") + @Schema(description = "处理器的名字,模糊匹配", example = "sysUserSessionTimeoutJob") private String handlerName; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobRespVO.java index fc0c4cc97..be73b1a06 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobRespVO.java @@ -8,23 +8,23 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 定时任务 Response VO") +@Schema(description = "管理后台 - 定时任务 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobRespVO extends JobBaseVO { - @Schema(title = "任务编号", required = true, example = "1024") + @Schema(description = "任务编号", required = true, example = "1024") private Long id; - @Schema(title = "任务状态", required = true, example = "1") + @Schema(description = "任务状态", required = true, example = "1") private Integer status; - @Schema(title = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") + @Schema(description = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") @NotNull(message = "处理器的名字不能为空") private String handlerName; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobUpdateReqVO.java index 013522be1..9587888b6 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/job/JobUpdateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 定时任务更新 Request VO") +@Schema(description = "管理后台 - 定时任务更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobUpdateReqVO extends JobBaseVO { - @Schema(title = "任务编号", required = true, example = "1024") + @Schema(description = "任务编号", required = true, example = "1024") @NotNull(message = "任务编号不能为空") private Long id; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogBaseVO.java index 03863815f..de95ca38d 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogBaseVO.java @@ -15,38 +15,38 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class JobLogBaseVO { - @Schema(title = "任务编号", required = true, example = "1024") + @Schema(description = "任务编号", required = true, example = "1024") @NotNull(message = "任务编号不能为空") private Long jobId; - @Schema(title = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") + @Schema(description = "处理器的名字", required = true, example = "sysUserSessionTimeoutJob") @NotNull(message = "处理器的名字不能为空") private String handlerName; - @Schema(title = "处理器的参数", example = "yudao") + @Schema(description = "处理器的参数", example = "yudao") private String handlerParam; - @Schema(title = "第几次执行", required = true, example = "1") + @Schema(description = "第几次执行", required = true, example = "1") @NotNull(message = "第几次执行不能为空") private Integer executeIndex; - @Schema(title = "开始执行时间", required = true) + @Schema(description = "开始执行时间", required = true) @NotNull(message = "开始执行时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime beginTime; - @Schema(title = "结束执行时间") + @Schema(description = "结束执行时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; - @Schema(title = "执行时长", example = "123") + @Schema(description = "执行时长", example = "123") private Integer duration; - @Schema(title = "任务状态", required = true, example = "1", description = "参见 JobLogStatusEnum 枚举") + @Schema(description = "任务状态,参见 JobLogStatusEnum 枚举", required = true, example = "1") @NotNull(message = "任务状态不能为空") private Integer status; - @Schema(title = "结果数据", example = "执行成功") + @Schema(description = "结果数据", example = "执行成功") private String result; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogExportReqVO.java index 8a4c468a4..6f5c7f69f 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogExportReqVO.java @@ -8,25 +8,25 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 定时任务 Excel 导出 Request VO", description = "参数和 JobLogPageReqVO 是一致的") +@Schema(description = "管理后台 - 定时任务 Excel 导出 Request VO,参数和 JobLogPageReqVO 是一致的") @Data public class JobLogExportReqVO { - @Schema(title = "任务编号", example = "10") + @Schema(description = "任务编号", example = "10") private Long jobId; - @Schema(title = "处理器的名字", description = "模糊匹配") + @Schema(description = "处理器的名字,模糊匹配") private String handlerName; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "开始执行时间") + @Schema(description = "开始执行时间") private LocalDateTime beginTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "结束执行时间") + @Schema(description = "结束执行时间") private LocalDateTime endTime; - @Schema(title = "任务状态", description = "参见 JobLogStatusEnum 枚举") + @Schema(description = "任务状态,参见 JobLogStatusEnum 枚举") private Integer status; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogPageReqVO.java index 6be08ce52..84bf9ca34 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogPageReqVO.java @@ -11,27 +11,27 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 定时任务日志分页 Request VO") +@Schema(description = "管理后台 - 定时任务日志分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobLogPageReqVO extends PageParam { - @Schema(title = "任务编号", example = "10") + @Schema(description = "任务编号", example = "10") private Long jobId; - @Schema(title = "处理器的名字", description = "模糊匹配") + @Schema(description = "处理器的名字,模糊匹配") private String handlerName; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "开始执行时间") + @Schema(description = "开始执行时间") private LocalDateTime beginTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "结束执行时间") + @Schema(description = "结束执行时间") private LocalDateTime endTime; - @Schema(title = "任务状态", description = "参见 JobLogStatusEnum 枚举") + @Schema(description = "任务状态,参见 JobLogStatusEnum 枚举") private Integer status; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogRespVO.java index e0412950b..79cce519b 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/vo/log/JobLogRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 定时任务日志 Response VO") +@Schema(description = "管理后台 - 定时任务日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class JobLogRespVO extends JobLogBaseVO { - @Schema(title = "日志编号", required = true, example = "1024") + @Schema(description = "日志编号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogBaseVO.java index e819c3d81..ec2a8e377 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogBaseVO.java @@ -15,60 +15,60 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class ApiAccessLogBaseVO { - @Schema(title = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002") + @Schema(description = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002") @NotNull(message = "链路追踪编号不能为空") private String traceId; - @Schema(title = "用户编号", required = true, example = "666") + @Schema(description = "用户编号", required = true, example = "666") @NotNull(message = "用户编号不能为空") private Long userId; - @Schema(title = "用户类型", required = true, example = "2", description = "参见 UserTypeEnum 枚举") + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", required = true, example = "2") @NotNull(message = "用户类型不能为空") private Integer userType; - @Schema(title = "应用名", required = true, example = "dashboard") + @Schema(description = "应用名", required = true, example = "dashboard") @NotNull(message = "应用名不能为空") private String applicationName; - @Schema(title = "请求方法名", required = true, example = "GET") + @Schema(description = "请求方法名", required = true, example = "GET") @NotNull(message = "请求方法名不能为空") private String requestMethod; - @Schema(title = "请求地址", required = true, example = "/xxx/yyy") + @Schema(description = "请求地址", required = true, example = "/xxx/yyy") @NotNull(message = "请求地址不能为空") private String requestUrl; - @Schema(title = "请求参数") + @Schema(description = "请求参数") private String requestParams; - @Schema(title = "用户 IP", required = true, example = "127.0.0.1") + @Schema(description = "用户 IP", required = true, example = "127.0.0.1") @NotNull(message = "用户 IP不能为空") private String userIp; - @Schema(title = "浏览器 UA", required = true, example = "Mozilla/5.0") + @Schema(description = "浏览器 UA", required = true, example = "Mozilla/5.0") @NotNull(message = "浏览器 UA不能为空") private String userAgent; - @Schema(title = "开始请求时间", required = true) + @Schema(description = "开始请求时间", required = true) @NotNull(message = "开始请求时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime beginTime; - @Schema(title = "结束请求时间", required = true) + @Schema(description = "结束请求时间", required = true) @NotNull(message = "结束请求时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; - @Schema(title = "执行时长", required = true, example = "100") + @Schema(description = "执行时长", required = true, example = "100") @NotNull(message = "执行时长不能为空") private Integer duration; - @Schema(title = "结果码", required = true, example = "0") + @Schema(description = "结果码", required = true, example = "0") @NotNull(message = "结果码不能为空") private Integer resultCode; - @Schema(title = "结果提示", example = "芋道源码,牛逼!") + @Schema(description = "结果提示", example = "芋道源码,牛逼!") private String resultMsg; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogExportReqVO.java index 70cd57afe..8894b82f8 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogExportReqVO.java @@ -8,30 +8,30 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - API 访问日志 Excel 导出 Request VO", description = "参数和 ApiAccessLogPageReqVO 是一致的") +@Schema(description = "管理后台 - API 访问日志 Excel 导出 Request VO,参数和 ApiAccessLogPageReqVO 是一致的") @Data public class ApiAccessLogExportReqVO { - @Schema(title = "用户编号", example = "666") + @Schema(description = "用户编号", example = "666") private Long userId; - @Schema(title = "用户类型", example = "2") + @Schema(description = "用户类型", example = "2") private Integer userType; - @Schema(title = "应用名", example = "dashboard") + @Schema(description = "应用名", example = "dashboard") private String applicationName; - @Schema(title = "请求地址", example = "/xxx/yyy", description = "模糊匹配") + @Schema(description = "请求地址,模糊匹配", example = "/xxx/yyy") private String requestUrl; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "开始请求时间") + @Schema(description = "开始请求时间") private LocalDateTime[] beginTime; - @Schema(title = "执行时长", example = "100", description = "大于等于,单位:毫秒") + @Schema(description = "执行时长,大于等于,单位:毫秒", example = "100") private Integer duration; - @Schema(title = "结果码", example = "0") + @Schema(description = "结果码", example = "0") private Integer resultCode; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogPageReqVO.java index ca1074450..daf2c616e 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogPageReqVO.java @@ -11,32 +11,32 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - API 访问日志分页 Request VO") +@Schema(description = "管理后台 - API 访问日志分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ApiAccessLogPageReqVO extends PageParam { - @Schema(title = "用户编号", example = "666") + @Schema(description = "用户编号", example = "666") private Long userId; - @Schema(title = "用户类型", example = "2") + @Schema(description = "用户类型", example = "2") private Integer userType; - @Schema(title = "应用名", example = "dashboard") + @Schema(description = "应用名", example = "dashboard") private String applicationName; - @Schema(title = "请求地址", example = "/xxx/yyy", description = "模糊匹配") + @Schema(description = "请求地址,模糊匹配", example = "/xxx/yyy") private String requestUrl; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "开始请求时间") + @Schema(description = "开始请求时间") private LocalDateTime[] beginTime; - @Schema(title = "执行时长", example = "100", description = "大于等于,单位:毫秒") + @Schema(description = "执行时长,大于等于,单位:毫秒", example = "100") private Integer duration; - @Schema(title = "结果码", example = "0") + @Schema(description = "结果码", example = "0") private Integer resultCode; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogRespVO.java index 9ab73751e..52bbb3184 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apiaccesslog/ApiAccessLogRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - API 访问日志 Response VO") +@Schema(description = "管理后台 - API 访问日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ApiAccessLogRespVO extends ApiAccessLogBaseVO { - @Schema(title = "日志主键", required = true, example = "1024") + @Schema(description = "日志主键", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogBaseVO.java index c05b0f2e7..6045e903e 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogBaseVO.java @@ -15,80 +15,80 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class ApiErrorLogBaseVO { - @Schema(title = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002") + @Schema(description = "链路追踪编号", required = true, example = "66600cb6-7852-11eb-9439-0242ac130002") @NotNull(message = "链路追踪编号不能为空") private String traceId; - @Schema(title = "用户编号", required = true, example = "666") + @Schema(description = "用户编号", required = true, example = "666") @NotNull(message = "用户编号不能为空") private Integer userId; - @Schema(title = "用户类型", required = true, example = "1") + @Schema(description = "用户类型", required = true, example = "1") @NotNull(message = "用户类型不能为空") private Integer userType; - @Schema(title = "应用名", required = true, example = "dashboard") + @Schema(description = "应用名", required = true, example = "dashboard") @NotNull(message = "应用名不能为空") private String applicationName; - @Schema(title = "请求方法名", required = true, example = "GET") + @Schema(description = "请求方法名", required = true, example = "GET") @NotNull(message = "请求方法名不能为空") private String requestMethod; - @Schema(title = "请求地址", required = true, example = "/xx/yy") + @Schema(description = "请求地址", required = true, example = "/xx/yy") @NotNull(message = "请求地址不能为空") private String requestUrl; - @Schema(title = "请求参数", required = true) + @Schema(description = "请求参数", required = true) @NotNull(message = "请求参数不能为空") private String requestParams; - @Schema(title = "用户 IP", required = true, example = "127.0.0.1") + @Schema(description = "用户 IP", required = true, example = "127.0.0.1") @NotNull(message = "用户 IP不能为空") private String userIp; - @Schema(title = "浏览器 UA", required = true, example = "Mozilla/5.0") + @Schema(description = "浏览器 UA", required = true, example = "Mozilla/5.0") @NotNull(message = "浏览器 UA不能为空") private String userAgent; - @Schema(title = "异常发生时间", required = true) + @Schema(description = "异常发生时间", required = true) @NotNull(message = "异常发生时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime exceptionTime; - @Schema(title = "异常名", required = true) + @Schema(description = "异常名", required = true) @NotNull(message = "异常名不能为空") private String exceptionName; - @Schema(title = "异常导致的消息", required = true) + @Schema(description = "异常导致的消息", required = true) @NotNull(message = "异常导致的消息不能为空") private String exceptionMessage; - @Schema(title = "异常导致的根消息", required = true) + @Schema(description = "异常导致的根消息", required = true) @NotNull(message = "异常导致的根消息不能为空") private String exceptionRootCauseMessage; - @Schema(title = "异常的栈轨迹", required = true) + @Schema(description = "异常的栈轨迹", required = true) @NotNull(message = "异常的栈轨迹不能为空") private String exceptionStackTrace; - @Schema(title = "异常发生的类全名", required = true) + @Schema(description = "异常发生的类全名", required = true) @NotNull(message = "异常发生的类全名不能为空") private String exceptionClassName; - @Schema(title = "异常发生的类文件", required = true) + @Schema(description = "异常发生的类文件", required = true) @NotNull(message = "异常发生的类文件不能为空") private String exceptionFileName; - @Schema(title = "异常发生的方法名", required = true) + @Schema(description = "异常发生的方法名", required = true) @NotNull(message = "异常发生的方法名不能为空") private String exceptionMethodName; - @Schema(title = "异常发生的方法所在行", required = true) + @Schema(description = "异常发生的方法所在行", required = true) @NotNull(message = "异常发生的方法所在行不能为空") private Integer exceptionLineNumber; - @Schema(title = "处理状态", required = true, example = "0") + @Schema(description = "处理状态", required = true, example = "0") @NotNull(message = "处理状态不能为空") private Integer processStatus; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogExportReqVO.java index a5b1698ce..dbc386729 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogExportReqVO.java @@ -8,27 +8,27 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - API 错误日志 Excel 导出 Request VO", description = "参数和 ApiErrorLogPageReqVO 是一致的") +@Schema(description = "管理后台 - API 错误日志 Excel 导出 Request VO,参数和 ApiErrorLogPageReqVO 是一致的") @Data public class ApiErrorLogExportReqVO { - @Schema(title = "用户编号", example = "666") + @Schema(description = "用户编号", example = "666") private Long userId; - @Schema(title = "用户类型", example = "1") + @Schema(description = "用户类型", example = "1") private Integer userType; - @Schema(title = "应用名", example = "dashboard") + @Schema(description = "应用名", example = "dashboard") private String applicationName; - @Schema(title = "请求地址", example = "/xx/yy") + @Schema(description = "请求地址", example = "/xx/yy") private String requestUrl; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "异常发生时间") + @Schema(description = "异常发生时间") private LocalDateTime[] exceptionTime; - @Schema(title = "处理状态", example = "0") + @Schema(description = "处理状态", example = "0") private Integer processStatus; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogPageReqVO.java index eb759c680..2ceb0d033 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogPageReqVO.java @@ -11,29 +11,29 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - API 错误日志分页 Request VO") +@Schema(description = "管理后台 - API 错误日志分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ApiErrorLogPageReqVO extends PageParam { - @Schema(title = "用户编号", example = "666") + @Schema(description = "用户编号", example = "666") private Long userId; - @Schema(title = "用户类型", example = "1") + @Schema(description = "用户类型", example = "1") private Integer userType; - @Schema(title = "应用名", example = "dashboard") + @Schema(description = "应用名", example = "dashboard") private String applicationName; - @Schema(title = "请求地址", example = "/xx/yy") + @Schema(description = "请求地址", example = "/xx/yy") private String requestUrl; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "异常发生时间") + @Schema(description = "异常发生时间") private LocalDateTime[] exceptionTime; - @Schema(title = "处理状态", example = "0") + @Schema(description = "处理状态", example = "0") private Integer processStatus; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogRespVO.java index d0a93f2a9..c4ce8faf6 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/logger/vo/apierrorlog/ApiErrorLogRespVO.java @@ -7,22 +7,22 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - API 错误日志 Response VO") +@Schema(description = "管理后台 - API 错误日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ApiErrorLogRespVO extends ApiErrorLogBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Integer id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; - @Schema(title = "处理时间", required = true) + @Schema(description = "处理时间", required = true) private LocalDateTime processTime; - @Schema(title = "处理用户编号", example = "233") + @Schema(description = "处理用户编号", example = "233") private Integer processUserId; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyDefineRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyDefineRespVO.java index c2b7836a8..f30ebb623 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyDefineRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyDefineRespVO.java @@ -8,28 +8,28 @@ import lombok.Data; import java.time.Duration; -@Schema(title = "管理后台 - Redis Key 信息 Response VO") +@Schema(description = "管理后台 - Redis Key 信息 Response VO") @Data @Builder @AllArgsConstructor public class RedisKeyDefineRespVO { - @Schema(title = "Key 模板", required = true, example = "login_user:%s") + @Schema(description = "Key 模板", required = true, example = "login_user:%s") private String keyTemplate; - @Schema(title = "Key 类型的枚举", required = true, example = "String") + @Schema(description = "Key 类型的枚举", required = true, example = "String") private RedisKeyDefine.KeyTypeEnum keyType; - @Schema(title = "Value 类型", required = true, example = "java.lang.String") + @Schema(description = "Value 类型", required = true, example = "java.lang.String") private Class valueType; - @Schema(title = "超时类型", required = true, example = "1") + @Schema(description = "超时类型", required = true, example = "1") private RedisKeyDefine.TimeoutTypeEnum timeoutType; - @Schema(title = "过期时间,单位:毫秒", required = true, example = "1024") + @Schema(description = "过期时间,单位:毫秒", required = true, example = "1024") private Duration timeout; - @Schema(title = "备注", required = true, example = "啦啦啦啦~") + @Schema(description = "备注", required = true, example = "啦啦啦啦~") private String memo; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyValueRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyValueRespVO.java index 71d4c1ec2..9dc893da0 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyValueRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyValueRespVO.java @@ -4,12 +4,12 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; -@Schema(title = "管理后台 - 单个 Redis Key Value Response VO") +@Schema(description = "管理后台 - 单个 Redis Key Value Response VO") @Data @AllArgsConstructor public class RedisKeyValueRespVO { - @Schema(title = "c5f6990767804a928f4bb96ca249febf", required = true, example = "String") + @Schema(description = "c5f6990767804a928f4bb96ca249febf", required = true, example = "String") private String key; @Schema(required = true, example = "String") diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisMonitorRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisMonitorRespVO.java index 42b8419ea..15d054282 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisMonitorRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisMonitorRespVO.java @@ -8,34 +8,34 @@ import lombok.Data; import java.util.List; import java.util.Properties; -@Schema(title = "管理后台 - Redis 监控信息 Response VO") +@Schema(description = "管理后台 - Redis 监控信息 Response VO") @Data @Builder @AllArgsConstructor public class RedisMonitorRespVO { - @Schema(title = "Redis info 指令结果", required = true, description = "具体字段,查看 Redis 文档") + @Schema(description = "Redis info 指令结果,具体字段,查看 Redis 文档", required = true) private Properties info; - @Schema(title = "Redis key 数量", required = true, example = "1024") + @Schema(description = "Redis key 数量", required = true, example = "1024") private Long dbSize; - @Schema(title = "CommandStat 数组", required = true) + @Schema(description = "CommandStat 数组", required = true) private List commandStats; - @Schema(title = "Redis 命令统计结果") + @Schema(description = "Redis 命令统计结果") @Data @Builder @AllArgsConstructor public static class CommandStat { - @Schema(title = "Redis 命令", required = true, example = "get") + @Schema(description = "Redis 命令", required = true, example = "get") private String command; - @Schema(title = "调用次数", required = true, example = "1024") + @Schema(description = "调用次数", required = true, example = "1024") private Long calls; - @Schema(title = "消耗 CPU 秒数", required = true, example = "666") + @Schema(description = "消耗 CPU 秒数", required = true, example = "666") private Long usec; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoBaseVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoBaseVO.java index 5f78f48f7..a0216683d 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoBaseVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoBaseVO.java @@ -10,23 +10,23 @@ import javax.validation.constraints.*; @Data public class TestDemoBaseVO { - @Schema(title = "名字", required = true) + @Schema(description = "名字", required = true) @NotNull(message = "名字不能为空") private String name; - @Schema(title = "状态", required = true) + @Schema(description = "状态", required = true) @NotNull(message = "状态不能为空") private Integer status; - @Schema(title = "类型", required = true) + @Schema(description = "类型", required = true) @NotNull(message = "类型不能为空") private Integer type; - @Schema(title = "分类", required = true) + @Schema(description = "分类", required = true) @NotNull(message = "分类不能为空") private Integer category; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoCreateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoCreateReqVO.java index f2b2786e5..3b46fd1cd 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoCreateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoCreateReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.infra.controller.admin.test.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - 字典类型创建 Request VO") +@Schema(description = "管理后台 - 字典类型创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoExportReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoExportReqVO.java index e12d753d4..8e10484e3 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoExportReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoExportReqVO.java @@ -7,27 +7,27 @@ import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 字典类型 Excel 导出 Request VO", description = "参数和 TestDemoPageReqVO 是一致的") +@Schema(description = "管理后台 - 字典类型 Excel 导出 Request VO,参数和 TestDemoPageReqVO 是一致的") @Data public class TestDemoExportReqVO { - @Schema(title = "名字") + @Schema(description = "名字") private String name; - @Schema(title = "状态") + @Schema(description = "状态") private Integer status; - @Schema(title = "类型") + @Schema(description = "类型") private Integer type; - @Schema(title = "分类") + @Schema(description = "分类") private Integer category; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoPageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoPageReqVO.java index 6881e17e2..abb5843db 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoPageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoPageReqVO.java @@ -8,29 +8,29 @@ import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 字典类型分页 Request VO") +@Schema(description = "管理后台 - 字典类型分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TestDemoPageReqVO extends PageParam { - @Schema(title = "名字") + @Schema(description = "名字") private String name; - @Schema(title = "状态") + @Schema(description = "状态") private Integer status; - @Schema(title = "类型") + @Schema(description = "类型") private Integer type; - @Schema(title = "分类") + @Schema(description = "分类") private Integer category; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoRespVO.java index 95af5b4b4..312a5eb98 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoRespVO.java @@ -4,16 +4,16 @@ import lombok.*; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 字典类型 Response VO") +@Schema(description = "管理后台 - 字典类型 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TestDemoRespVO extends TestDemoBaseVO { - @Schema(title = "编号", required = true) + @Schema(description = "编号", required = true) private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoUpdateReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoUpdateReqVO.java index 7c8315381..6df36addb 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoUpdateReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/test/vo/TestDemoUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 字典类型更新 Request VO") +@Schema(description = "管理后台 - 字典类型更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TestDemoUpdateReqVO extends TestDemoBaseVO { - @Schema(title = "编号", required = true) + @Schema(description = "编号", required = true) @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/_column.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/_column.vm index 71c4eebf8..89a8e348f 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/_column.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/_column.vm @@ -1,5 +1,5 @@ ## 提供给 baseVO、createVO、updateVO 生成字段 - @Schema(title = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(description = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end) #if (!${column.nullable})## 判断 @NotEmpty 和 @NotNull 注解 #if (${field.fieldType} == 'String') @NotEmpty(message = "${column.columnComment}不能为空") diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm index 315faf7fc..32ab0f2ba 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm @@ -15,7 +15,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; #end #end -@Schema(title = "${sceneEnum.name} - ${table.classComment}创建 Request VO") +@Schema(description = "${sceneEnum.name} - ${table.classComment}创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm index 749a43e25..9d3be20cd 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm @@ -16,18 +16,18 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; #end ## 字段模板 #macro(columnTpl $prefix $prefixStr) - @Schema(title = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(description = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end; #end -@Schema(title = "${sceneEnum.name} - ${table.classComment} Excel 导出 Request VO", description = "参数和 ${table.className}PageReqVO 是一致的") +@Schema(description = "${sceneEnum.name} - ${table.classComment} Excel 导出 Request VO,参数和 ${table.className}PageReqVO 是一致的") @Data public class ${sceneEnum.prefixClass}${table.className}ExportReqVO { #foreach ($column in $columns) #if (${column.listOperation})##查询操作 #if (${column.listOperationCondition} == "BETWEEN")## 情况一,Between 的时候 - @Schema(title = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(description = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private ${column.javaType}[] ${column.javaField}; #else##情况二,非 Between 的时间 diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm index 44a5307ea..3105132b9 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm @@ -16,11 +16,11 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; #end ## 字段模板 #macro(columnTpl $prefix $prefixStr) - @Schema(title = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(description = "${prefixStr}${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end; #end -@Schema(title = "${sceneEnum.name} - ${table.classComment}分页 Request VO") +@Schema(description = "${sceneEnum.name} - ${table.classComment}分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -29,7 +29,7 @@ public class ${sceneEnum.prefixClass}${table.className}PageReqVO extends PagePar #foreach ($column in $columns) #if (${column.listOperation})##查询操作 #if (${column.listOperationCondition} == "BETWEEN")## 情况一,Between 的时候 - @Schema(title = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(description = "${column.columnComment}"#if ("$!column.example" != ""), example = "${column.example}"#end) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private ${column.javaType}[] ${column.javaField}; #else##情况二,非 Between 的时间 diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm index f57b2fc12..ba49133af 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm @@ -9,7 +9,7 @@ import java.time.LocalDateTime; #end import io.swagger.annotations.*; -@Schema(title = "${sceneEnum.name} - ${table.classComment} Response VO") +@Schema(description = "${sceneEnum.name} - ${table.classComment} Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -17,7 +17,7 @@ public class ${sceneEnum.prefixClass}${table.className}RespVO extends ${sceneEnu #foreach ($column in $columns) #if (${column.listOperationResult} && (!${column.createOperation} || !${column.updateOperation}))##不是通用字段 - @Schema(title = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end) + @Schema(description = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end) private ${column.javaType} ${column.javaField}; #end diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm index fb9b42f00..1bdadf2ed 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm @@ -15,7 +15,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; #end #end -@Schema(title = "${sceneEnum.name} - ${table.classComment}更新 Request VO") +@Schema(description = "${sceneEnum.name} - ${table.classComment}更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java index f586e7415..033199d9f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java @@ -11,22 +11,22 @@ import javax.validation.constraints.NotNull; @Data public class ProductBrandBaseVO { - @Schema(title = "品牌名称", required = true, example = "芋道") + @Schema(description = "品牌名称", required = true, example = "芋道") @NotNull(message = "品牌名称不能为空") private String name; - @Schema(title = "品牌图片", required = true) + @Schema(description = "品牌图片", required = true) @NotNull(message = "品牌图片不能为空") private String picUrl; - @Schema(title = "品牌排序", required = true, example = "1") + @Schema(description = "品牌排序", required = true, example = "1") @NotNull(message = "品牌排序不能为空") private Integer sort; - @Schema(title = "品牌描述", example = "描述") + @Schema(description = "品牌描述", example = "描述") private String description; - @Schema(title = "状态", required = true, example = "0") + @Schema(description = "状态", required = true, example = "0") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java index 1ea83e259..2ab9c354a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.brand.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - 商品品牌创建 Request VO") +@Schema(description = "管理后台 - 商品品牌创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java index a1ea87ad8..63305810c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java @@ -3,11 +3,11 @@ package cn.iocoder.yudao.module.product.controller.admin.brand.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 商品品牌分页 Request VO") +@Schema(description = "管理后台 - 商品品牌分页 Request VO") @Data public class ProductBrandListReqVO { - @Schema(title = "品牌名称", example = "芋道") + @Schema(description = "品牌名称", example = "芋道") private String name; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java index b19a9a711..e90744a10 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java @@ -11,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 商品品牌分页 Request VO") +@Schema(description = "管理后台 - 商品品牌分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductBrandPageReqVO extends PageParam { - @Schema(title = "品牌名称", example = "芋道") + @Schema(description = "品牌名称", example = "芋道") private String name; - @Schema(title = "状态", example = "0", description = "参考 CommonStatusEnum 枚举") + @Schema(description = "状态-参考 CommonStatusEnum 枚举", example = "0") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java index a61cf5235..b68fbc5be 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 品牌 Response VO") +@Schema(description = "管理后台 - 品牌 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductBrandRespVO extends ProductBrandBaseVO { - @Schema(title = "品牌编号", required = true, example = "1") + @Schema(description = "品牌编号", required = true, example = "1") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java index e86112c92..15648164f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 商品品牌更新 Request VO") +@Schema(description = "管理后台 - 商品品牌更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductBrandUpdateReqVO extends ProductBrandBaseVO { - @Schema(title = "品牌编号", required = true, example = "1") + @Schema(description = "品牌编号", required = true, example = "1") @NotNull(message = "品牌编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java index 922ab321b..c2276e9ac 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java @@ -12,25 +12,25 @@ import javax.validation.constraints.NotNull; @Data public class ProductCategoryBaseVO { - @Schema(title = "父分类编号", required = true, example = "1") + @Schema(description = "父分类编号", required = true, example = "1") @NotNull(message = "父分类编号不能为空") private Long parentId; - @Schema(title = "分类名称", required = true, example = "办公文具") + @Schema(description = "分类名称", required = true, example = "办公文具") @NotBlank(message = "分类名称不能为空") private String name; - @Schema(title = "分类图片", required = true) + @Schema(description = "分类图片", required = true) @NotBlank(message = "分类图片不能为空") private String picUrl; - @Schema(title = "分类排序", required = true, example = "1") + @Schema(description = "分类排序", required = true, example = "1") private Integer sort; - @Schema(title = "分类描述", required = true, example = "描述") + @Schema(description = "分类描述", required = true, example = "描述") private String description; - @Schema(title = "开启状态", required = true, example = "0") + @Schema(description = "开启状态", required = true, example = "0") @NotNull(message = "开启状态不能为空") private Integer status; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java index 32e5e6719..577b9e774 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - 商品分类创建 Request VO") +@Schema(description = "管理后台 - 商品分类创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java index 3a8e83106..9c9439d3e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java @@ -3,11 +3,11 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 商品分类列表查询 Request VO") +@Schema(description = "管理后台 - 商品分类列表查询 Request VO") @Data public class ProductCategoryListReqVO { - @Schema(title = "分类名称", example = "办公文具") + @Schema(description = "分类名称", example = "办公文具") private String name; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java index 32298487b..4e2b64188 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java @@ -4,16 +4,16 @@ import lombok.*; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 商品分类 Response VO") +@Schema(description = "管理后台 - 商品分类 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductCategoryRespVO extends ProductCategoryBaseVO { - @Schema(title = "分类编号", required = true, example = "2") + @Schema(description = "分类编号", required = true, example = "2") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java index 1b8357f96..01deb165c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 商品分类更新 Request VO") +@Schema(description = "管理后台 - 商品分类更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO { - @Schema(title = "分类编号", required = true, example = "2") + @Schema(description = "分类编号", required = true, example = "2") @NotNull(message = "分类编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java index 7ef873264..d72a3036f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java @@ -12,22 +12,22 @@ import java.util.List; * @CreateDate: 2022/7/5 21:29 * @Version: 1.0.0 */ -@Schema(title = "管理后台 - 规格名称详情展示 Request VO") +@Schema(description = "管理后台 - 规格名称详情展示 Request VO") @Data @ToString(callSuper = true) public class ProductPropertyViewRespVO { - @Schema(title = "规格名称id", example = "1") + @Schema(description = "规格名称id", example = "1") public Long propertyId; - @Schema(title = "规格名称", example = "内存") + @Schema(description = "规格名称", example = "内存") public String name; - @Schema(title = "规格属性值集合", example = "[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]") + @Schema(description = "规格属性值集合", example = "[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]") public List propertyValues; @Data - @Schema(title = "规格属性值元组") + @Schema(description = "规格属性值元组") public static class Tuple2 { private final long id; private final String name; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java index 7c75830bb..300255724 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java @@ -9,16 +9,16 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@Schema(title = "管理后台 - 规格 + 规格值 Response VO") +@Schema(description = "管理后台 - 规格 + 规格值 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyAndValueRespVO extends ProductPropertyBaseVO { - @Schema(title = "规格的编号", required = true, example = "1024") + @Schema(description = "规格的编号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java index 22f92ebb8..3bb4ec530 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java @@ -12,14 +12,14 @@ import javax.validation.constraints.NotNull; @Data public class ProductPropertyBaseVO { - @Schema(title = "规格名称", required = true, example = "颜色") + @Schema(description = "规格名称", required = true, example = "颜色") @NotBlank(message = "规格名称不能为空") private String name; - @Schema(title = "备注", example = "颜色") + @Schema(description = "备注", example = "颜色") private String remark; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态-参见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java index 28b93d516..5cc8c099f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java @@ -4,7 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 规格名称创建 Request VO") +@Schema(description = "管理后台 - 规格名称创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java index 49b2e7a2f..00d3372fe 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java @@ -4,15 +4,15 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.ToString; -@Schema(title = "管理后台 - 规格名称 List Request VO") +@Schema(description = "管理后台 - 规格名称 List Request VO") @Data @ToString(callSuper = true) public class ProductPropertyListReqVO { - @Schema(title = "规格名称", example = "颜色") + @Schema(description = "规格名称", example = "颜色") private String name; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态,参见 CommonStatusEnum 枚举", required = true, example = "1") private Integer status; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java index 96551fd84..c997f9bcb 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java @@ -11,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 规格名称分页 Request VO") +@Schema(description = "管理后台 - 规格名称分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyPageReqVO extends PageParam { - @Schema(title = "规格名称", example = "颜色") + @Schema(description = "规格名称", example = "颜色") private String name; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态,参见 CommonStatusEnum 枚举", required = true, example = "1") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java index fc7e03911..1fb81461f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 规格 + 规格值 Response VO") +@Schema(description = "管理后台 - 规格 + 规格值 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyRespVO extends ProductPropertyBaseVO { - @Schema(title = "规格的编号", required = true, example = "1024") + @Schema(description = "规格的编号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java index bde40c9c0..87d7accd8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 规格名称更新 Request VO") +@Schema(description = "管理后台 - 规格名称更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyUpdateReqVO extends ProductPropertyBaseVO { - @Schema(title = "主键", required = true, example = "1") + @Schema(description = "主键", required = true, example = "1") @NotNull(message = "主键不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java index b4a526c47..966027c59 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java @@ -12,19 +12,19 @@ import javax.validation.constraints.NotNull; @Data public class ProductPropertyValueBaseVO { - @Schema(title = "规格编号", required = true, example = "1024") + @Schema(description = "规格编号", required = true, example = "1024") @NotNull(message = "规格编号不能为空") private Long propertyId; - @Schema(title = "规格值名字", required = true, example = "红色") + @Schema(description = "规格值名字", required = true, example = "红色") @NotEmpty(message = "规格值名字不能为空") private String name; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态,参见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; - @Schema(title = "备注", example = "颜色") + @Schema(description = "备注", example = "颜色") private String remark; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java index 6477b7091..23a23b0fe 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - 规格值创建 Request VO") +@Schema(description = "管理后台 - 规格值创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java index bcada5154..bafa24ebd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java @@ -12,19 +12,19 @@ import java.util.Date; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 规格名称值分页 Request VO") +@Schema(description = "管理后台 - 规格名称值分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyValuePageReqVO extends PageParam { - @Schema(title = "规格id", example = "1024") + @Schema(description = "规格id", example = "1024") private String propertyId; - @Schema(title = "规格值", example = "红色") + @Schema(description = "规格值", example = "红色") private String name; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态,参见 CommonStatusEnum 枚举", required = true, example = "1") private Integer status; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java index 2a40e0056..d914d88a1 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 规格值 Response VO") +@Schema(description = "管理后台 - 规格值 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyValueRespVO extends ProductPropertyValueBaseVO { - @Schema(title = "主键", required = true, example = "10") + @Schema(description = "主键", required = true, example = "10") private Long id; - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java index cb346c27c..b3a34aeb7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 规格值更新 Request VO") +@Schema(description = "管理后台 - 规格值更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductPropertyValueUpdateReqVO extends ProductPropertyValueBaseVO { - @Schema(title = "主键", required = true, example = "1024") + @Schema(description = "主键", required = true, example = "1024") @NotNull(message = "主键不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java index 8ae8c8a5a..313cedefa 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java @@ -15,54 +15,54 @@ import javax.validation.constraints.NotNull; @Data public class ProductSkuBaseVO { - @Schema(title = "商品 SKU 名字", required = true, example = "芋道") + @Schema(description = "商品 SKU 名字", required = true, example = "芋道") @NotEmpty(message = "商品 SKU 名字不能为空") private String name; - @Schema(title = "销售价格,单位:分", required = true, example = "1024", description = "单位:分") + @Schema(description = "销售价格,单位:分", required = true, example = "1024") @NotNull(message = "销售价格,单位:分不能为空") private Integer price; - @Schema(title = "市场价", example = "1024", description = "单位:分") + @Schema(description = "市场价,单位:分", example = "1024") private Integer marketPrice; - @Schema(title = "成本价", example = "1024", description = "单位:分") + @Schema(description = "成本价,单位:分", example = "1024") private Integer costPrice; - @Schema(title = "条形码", example = "haha") + @Schema(description = "条形码", example = "haha") private String barCode; - @Schema(title = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") + @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") @NotNull(message = "图片地址不能为空") private String picUrl; - @Schema(title = "SKU 状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") + @Schema(description = "SKU 状态,参见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "SKU 状态不能为空") @InEnum(CommonStatusEnum.class) private Integer status; - @Schema(title = "库存", required = true, example = "1") + @Schema(description = "库存", required = true, example = "1") @NotNull(message = "库存不能为空") private Integer stock; - @Schema(title = "预警预存", example = "1") + @Schema(description = "预警预存", example = "1") private Integer warnStock; - @Schema(title = "商品重量", example = "1", description = "单位:kg 千克") + @Schema(description = "商品重量,单位:kg 千克", example = "1") private Double weight; - @Schema(title = "商品体积", example = "1024", description = "单位:m^3 平米") + @Schema(description = "商品体积,单位:m^3 平米", example = "1024") private Double volume; - @Schema(title = "规格值") + @Schema(description = "规格值") @Data public static class Property { - @Schema(title = "属性编号", required = true, example = "1") + @Schema(description = "属性编号", required = true, example = "1") @NotNull(message = "属性编号不能为空") private Long propertyId; - @Schema(title = "属性值编号", required = true, example = "1024") + @Schema(description = "属性值编号", required = true, example = "1024") @NotNull(message = "属性值编号不能为空") private Long valueId; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java index 3648f3159..7383e2416 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import java.util.List; -@Schema(title = "管理后台 - 商品 SKU 创建/更新 Request VO") +@Schema(description = "管理后台 - 商品 SKU 创建/更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO { - @Schema(title = "商品 SKU 编号", example = "1") + @Schema(description = "商品 SKU 编号", example = "1") private Long id; /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java index dd71d6954..1522ca59e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java @@ -3,28 +3,28 @@ package cn.iocoder.yudao.module.product.controller.admin.sku.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 商品 SKU 选项 Response VO", description = "用于前端 SELECT 选项") +@Schema(description = "管理后台 - 商品 SKU 选项 Response VO,用于前端 SELECT 选项") @Data public class ProductSkuOptionRespVO { - @Schema(title = "主键", required = true, example = "1024") + @Schema(description = "主键", required = true, example = "1024") private Long id; - @Schema(title = "商品 SKU 名字", example = "红色") + @Schema(description = "商品 SKU 名字", example = "红色") private String name; - @Schema(title = "销售价格", required = true, example = "100", description = "单位:分") + @Schema(description = "销售价格,单位:分", required = true, example = "100") private String price; - @Schema(title = "库存", required = true, example = "100") + @Schema(description = "库存", required = true, example = "100") private Integer stock; // ========== 商品 SPU 信息 ========== - @Schema(title = "商品 SPU 编号", required = true, example = "1") + @Schema(description = "商品 SPU 编号", required = true, example = "1") private Long spuId; - @Schema(title = "商品 SPU 名字", required = true, example = "iPhone 11") + @Schema(description = "商品 SPU 名字", required = true, example = "iPhone 11") private String spuName; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java index 62e4ec9cc..0b0ec665a 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java @@ -8,16 +8,16 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@Schema(title = "管理后台 - 商品 SKU Response VO") +@Schema(description = "管理后台 - 商品 SKU Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSkuRespVO extends ProductSkuBaseVO { - @Schema(title = "主键", required = true, example = "1024") + @Schema(description = "主键", required = true, example = "1024") private Long id; - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime createTime; /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java index fa7e2717d..1c3c22485 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -17,75 +17,75 @@ import java.util.List; @Data public class ProductSpuBaseVO { - @Schema(title = "商品名称", required = true, example = "芋道") + @Schema(description = "商品名称", required = true, example = "芋道") @NotEmpty(message = "商品名称不能为空") private String name; - @Schema(title = "商品编码", example = "yudaoyuanma") + @Schema(description = "商品编码", example = "yudaoyuanma") private String code; - @Schema(title = "促销语", example = "好吃!") + @Schema(description = "促销语", example = "好吃!") private String sellPoint; - @Schema(title = "商品详情", required = true, example = "我是商品描述") + @Schema(description = "商品详情", required = true, example = "我是商品描述") @NotNull(message = "商品详情不能为空") private String description; - @Schema(title = "商品分类编号", required = true, example = "1") + @Schema(description = "商品分类编号", required = true, example = "1") @NotNull(message = "商品分类编号不能为空") private Long categoryId; - @Schema(title = "商品品牌编号", example = "1") + @Schema(description = "商品品牌编号", example = "1") private Long brandId; - @Schema(title = "商品图片的数组", required = true) + @Schema(description = "商品图片的数组", required = true) @NotNull(message = "商品图片的数组不能为空") private List picUrls; - @Schema(title = "商品视频", required = true) + @Schema(description = "商品视频", required = true) private String videoUrl; - @Schema(title = "排序字段", required = true, example = "1") + @Schema(description = "排序字段", required = true, example = "1") private Integer sort; - @Schema(title = "商品状态", required = true, example = "1", description = "参见 ProductSpuStatusEnum 枚举类") + @Schema(description = "商品状态,参见 ProductSpuStatusEnum 枚举类", required = true, example = "1") @NotNull(message = "商品状态不能为空") @InEnum(ProductSpuStatusEnum.class) private Integer status; // ========== SKU 相关字段 ========= - @Schema(title = "规格类型", required = true, example = "1", description = "参见 ProductSpuSpecTypeEnum 枚举类") + @Schema(description = "规格类型,参见 ProductSpuSpecTypeEnum 枚举类", required = true, example = "1") @NotNull(message = "规格类型不能为空") @InEnum(ProductSpuSpecTypeEnum.class) private Integer specType; - @Schema(title = "是否展示库存", required = true, example = "true") + @Schema(description = "是否展示库存", required = true, example = "true") @NotNull(message = "是否展示库存不能为空") private Boolean showStock; - @Schema(title = "库存", required = true, example = "true") + @Schema(description = "库存", required = true, example = "true") private Integer totalStock; - @Schema(title = "市场价", example = "1024") + @Schema(description = "市场价", example = "1024") private Integer marketPrice; - @Schema(title = " 最小价格,单位使用:分", required = true, example = "1024") + @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") private Integer minPrice; - @Schema(title = "最大价格,单位使用:分", required = true, example = "1024") + @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") private Integer maxPrice; // ========== 统计相关字段 ========= - @Schema(title = "商品销量", example = "1024") + @Schema(description = "商品销量", example = "1024") private Integer salesCount; - @Schema(title = "虚拟销量", required = true, example = "1024") + @Schema(description = "虚拟销量", required = true, example = "1024") @NotNull(message = "虚拟销量不能为空") private Integer virtualSalesCount; - @Schema(title = "点击量", example = "1024") + @Schema(description = "点击量", example = "1024") private Integer clickCount; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java index 50aef8570..c75ed4d2e 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java @@ -9,7 +9,7 @@ import lombok.ToString; import javax.validation.Valid; import java.util.List; -@Schema(title = "管理后台 - 商品 SPU 创建 Request VO") +@Schema(description = "管理后台 - 商品 SPU 创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java index 622d9eecd..e60d2fff5 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java @@ -10,16 +10,16 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@Schema(title = "管理后台 - 商品 SPU 详细 Response VO", description = "包括关联的 SKU 等信息") +@Schema(description = "管理后台 - 商品 SPU 详细 Response VO,包括关联的 SKU 等信息") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuDetailRespVO extends ProductSpuBaseVO { - @Schema(title = "主键", required = true, example = "1") + @Schema(description = "主键", required = true, example = "1") private Long id; - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime createTime; /** @@ -27,7 +27,7 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO { */ private List skus; - @Schema(title = "管理后台 - 商品 SKU 详细 Response VO") + @Schema(description = "管理后台 - 商品 SKU 详细 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -40,25 +40,25 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO { } - @Schema(title = "管理后台 - 商品规格的详细 Response VO") + @Schema(description = "管理后台 - 商品规格的详细 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public static class Property extends ProductSkuBaseVO.Property { - @Schema(title = "规格的名字", required = true, example = "颜色") + @Schema(description = "规格的名字", required = true, example = "颜色") private String propertyName; - @Schema(title = "规格值的名字", required = true, example = "蓝色") + @Schema(description = "规格值的名字", required = true, example = "蓝色") private String valueName; } - @Schema(title = "分类 id 数组,一直递归到一级父节点", example = "4") + @Schema(description = "分类 id 数组,一直递归到一级父节点", example = "4") private Long categoryId; // TODO @芋艿:在瞅瞅~ - @Schema(title = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]") + @Schema(description = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]") private List productPropertyViews; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java index 47ba5f213..3d30ad013 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java @@ -6,40 +6,40 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 商品 SPU 分页 Request VO") +@Schema(description = "管理后台 - 商品 SPU 分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuPageReqVO extends PageParam { - @Schema(title = "商品名称", example = "yutou") + @Schema(description = "商品名称", example = "yutou") private String name; - @Schema(title = "商品编码", example = "yudaoyuanma") + @Schema(description = "商品编码", example = "yudaoyuanma") private String code; - @Schema(title = "分类id", example = "1") + @Schema(description = "分类id", example = "1") private Long categoryId; - @Schema(title = "商品品牌编号", example = "1") + @Schema(description = "商品品牌编号", example = "1") private Long brandId; - @Schema(title = "上下架状态", example = "1", description = "参见 ProductSpuStatusEnum 枚举值") + @Schema(description = "上下架状态,参见 ProductSpuStatusEnum 枚举值", example = "1") private Integer status; - @Schema(title = "销量最小值", example = "1") + @Schema(description = "销量最小值", example = "1") private Integer salesCountMin; - @Schema(title = "销量最大值", example = "1024") + @Schema(description = "销量最大值", example = "1024") private Integer salesCountMax; - @Schema(title = "市场价最小值", example = "1") + @Schema(description = "市场价最小值", example = "1") private Integer marketPriceMin; - @Schema(title = "市场价最大值", example = "1024") + @Schema(description = "市场价最大值", example = "1024") private Integer marketPriceMax; - @Schema(title = "是否库存告警", example = "true") + @Schema(description = "是否库存告警", example = "true") private Boolean alarmStock; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java index 46a1639ad..a08c4900e 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java @@ -8,16 +8,16 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@Schema(title = "管理后台 - 商品 SPU Response VO") +@Schema(description = "管理后台 - 商品 SPU Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuRespVO extends ProductSpuBaseVO { - @Schema(title = "主键", required = true, example = "1") + @Schema(description = "主键", required = true, example = "1") private Long id; - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java index fe8e9a1c0..9cc7bf169 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java @@ -5,22 +5,22 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 商品 SPU 精简 Response VO") +@Schema(description = "管理后台 - 商品 SPU 精简 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuSimpleRespVO extends ProductSpuBaseVO { - @Schema(title = "主键", required = true, example = "1") + @Schema(description = "主键", required = true, example = "1") private Long id; - @Schema(title = "商品名称", required = true, example = "芋道") + @Schema(description = "商品名称", required = true, example = "芋道") private String name; - @Schema(title = " 最小价格,单位使用:分", required = true, example = "1024") + @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") private Integer minPrice; - @Schema(title = "最大价格,单位使用:分", required = true, example = "1024") + @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") private Integer maxPrice; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java index 5c988a3a2..6ea84fb9e 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java @@ -10,13 +10,13 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; import java.util.List; -@Schema(title = "管理后台 - 商品 SPU 更新 Request VO") +@Schema(description = "管理后台 - 商品 SPU 更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ProductSpuUpdateReqVO extends ProductSpuBaseVO { - @Schema(title = "商品编号", required = true, example = "1") + @Schema(description = "商品编号", required = true, example = "1") @NotNull(message = "商品编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java index 555677b9a..1dca05a3a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java @@ -7,21 +7,21 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @Data -@Schema(title = "用户 APP - 商品分类 Response VO") +@Schema(description = "用户 APP - 商品分类 Response VO") public class AppCategoryRespVO { - @Schema(title = "分类编号", required = true, example = "2") + @Schema(description = "分类编号", required = true, example = "2") private Long id; - @Schema(title = "父分类编号", required = true, example = "1") + @Schema(description = "父分类编号", required = true, example = "1") @NotNull(message = "父分类编号不能为空") private Long parentId; - @Schema(title = "分类名称", required = true, example = "办公文具") + @Schema(description = "分类名称", required = true, example = "办公文具") @NotBlank(message = "分类名称不能为空") private String name; - @Schema(title = "分类图片", required = true) + @Schema(description = "分类图片", required = true) @NotBlank(message = "分类图片不能为空") private String picUrl; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java index facabfa88..fb67a1708 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java @@ -6,12 +6,12 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "App - 商品spu分页 Request VO") +@Schema(description = "App - 商品spu分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class AppSpuPageReqVO extends PageParam { - @Schema(title = "分类id") + @Schema(description = "分类id") private Long categoryId; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java index 074058cb4..20c82afbc 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java @@ -6,46 +6,46 @@ import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; -@Schema(title = "App - 商品spu分页 Request VO") +@Schema(description = "App - 商品spu分页 Request VO") @Data public class AppSpuPageRespVO { - @Schema(title = "主键", required = true, example = "1") + @Schema(description = "主键", required = true, example = "1") private Long id; - @Schema(title = "商品名称") + @Schema(description = "商品名称") private String name; - @Schema(title = "卖点", required = true) + @Schema(description = "卖点", required = true) @NotNull(message = "卖点不能为空") private String sellPoint; - @Schema(title = "描述", required = true) + @Schema(description = "描述", required = true) @NotNull(message = "描述不能为空") private String description; - @Schema(title = "分类id", required = true) + @Schema(description = "分类id", required = true) @NotNull(message = "分类id不能为空") private Long categoryId; - @Schema(title = "商品主图地址,* 数组,以逗号分隔,最多上传15张", required = true) + @Schema(description = "商品主图地址,* 数组,以逗号分隔,最多上传15张", required = true) @NotNull(message = "商品主图地址,* 数组,以逗号分隔,最多上传15张不能为空") private List picUrls; - @Schema(title = "排序字段", required = true) + @Schema(description = "排序字段", required = true) @NotNull(message = "排序字段不能为空") private Integer sort; - @Schema(title = "点赞初始人数") + @Schema(description = "点赞初始人数") private Integer likeCount; - @Schema(title = "价格 单位使用:分") + @Schema(description = "价格 单位使用:分") private Integer price; - @Schema(title = "库存数量") + @Schema(description = "库存数量") private Integer quantity; - @Schema(title = "上下架状态: 0 上架(开启) 1 下架(禁用)") + @Schema(description = "上下架状态: 0 上架(开启) 1 下架(禁用)") private Integer status; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java index b63a78a52..79072074b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java @@ -12,7 +12,7 @@ import lombok.EqualsAndHashCode; * * @author LuoWenFeng */ -@Schema(title = "App - 商品spu Response VO") +@Schema(description = "App - 商品spu Response VO") @Data @EqualsAndHashCode(callSuper = true) public class AppSpuRespVO extends ProductSpuRespVO { diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java index 75109ff12..6c72155f4 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java @@ -15,28 +15,28 @@ import javax.validation.constraints.NotNull; @Data public class BannerBaseVO { - @Schema(title = "标题", required = true) + @Schema(description = "标题", required = true) @NotNull(message = "标题不能为空") private String title; - @Schema(title = "跳转链接", required = true) + @Schema(description = "跳转链接", required = true) @NotNull(message = "跳转链接不能为空") private String url; - @Schema(title = "图片地址", required = true) + @Schema(description = "图片地址", required = true) @NotNull(message = "图片地址不能为空") private String picUrl; - @Schema(title = "排序", required = true) + @Schema(description = "排序", required = true) @NotNull(message = "排序不能为空") private Integer sort; - @Schema(title = "状态", required = true) + @Schema(description = "状态", required = true) @NotNull(message = "状态不能为空") @InEnum(CommonStatusEnum.class) private Integer status; - @Schema(title = "备注") + @Schema(description = "备注") private String memo; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java index 488dc9aa3..eefdd175a 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java @@ -7,7 +7,7 @@ import lombok.ToString; /** * @author xia */ -@Schema(title = "管理后台 - Banner 创建 Request VO") +@Schema(description = "管理后台 - Banner 创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java index 99729038e..b97008ccd 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java @@ -16,22 +16,22 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ /** * @author xia */ -@Schema(title = "管理后台 - Banner 分页 Request VO") +@Schema(description = "管理后台 - Banner 分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BannerPageReqVO extends PageParam { - @Schema(title = "标题") + @Schema(description = "标题") private String title; - @Schema(title = "状态") + @Schema(description = "状态") @InEnum(CommonStatusEnum.class) private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java index 792585c7d..fb0010669 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java @@ -10,16 +10,16 @@ import java.time.LocalDateTime; /** * @author xia */ -@Schema(title = "管理后台 - Banner Response VO") +@Schema(description = "管理后台 - Banner Response VO") @Data @ToString(callSuper = true) public class BannerRespVO extends BannerBaseVO { - @Schema(title = "banner编号", required = true) + @Schema(description = "banner编号", required = true) @NotNull(message = "banner编号不能为空") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java index db4b28709..033b6054d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java @@ -10,13 +10,13 @@ import javax.validation.constraints.NotNull; /** * @author xia */ -@Schema(title = "管理后台 - Banner更新 Request VO") +@Schema(description = "管理后台 - Banner更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class BannerUpdateReqVO extends BannerBaseVO { - @Schema(title = "banner 编号", required = true) + @Schema(description = "banner 编号", required = true) @NotNull(message = "banner 编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java index 90f4c7278..43611a903 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java @@ -24,76 +24,76 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DE public class CouponBaseVO { // ========== 基本信息 BEGIN ========== - @Schema(title = "优惠劵模板编号", required = true, example = "1024") + @Schema(description = "优惠劵模板编号", required = true, example = "1024") @NotNull(message = "优惠劵模板编号不能为空") private Integer templateId; - @Schema(title = "优惠劵名", required = true, example = "春节送送送") + @Schema(description = "优惠劵名", required = true, example = "春节送送送") @NotNull(message = "优惠劵名不能为空") private String name; - @Schema(title = "优惠码状态", required = true, example = "1", description = "参见 CouponStatusEnum 枚举") + @Schema(description = "优惠码状态,参见 CouponStatusEnum 枚举", required = true, example = "1") private Integer status; // ========== 基本信息 END ========== // ========== 领取情况 BEGIN ========== - @Schema(title = "用户编号", required = true, example = "1") + @Schema(description = "用户编号", required = true, example = "1") @NotNull(message = "用户编号不能为空") private Long userId; - @Schema(title = "领取方式", required = true, example = "1", description = "参见 CouponTakeTypeEnum 枚举类") + @Schema(description = "领取方式,参见 CouponTakeTypeEnum 枚举类", required = true, example = "1") @NotNull(message = "领取方式不能为空") private Integer takeType; // ========== 领取情况 END ========== // ========== 使用规则 BEGIN ========== - @Schema(title = "是否设置满多少金额可用", required = true, example = "100", description = "单位:分;0 - 不限制") + @Schema(description = "是否设置满多少金额可用,单位:分;0 - 不限制", required = true, example = "100") @NotNull(message = "是否设置满多少金额可用不能为空") private Integer usePrice; - @Schema(title = "固定日期 - 生效开始时间") + @Schema(description = "固定日期 - 生效开始时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime validStartTime; - @Schema(title = "固定日期 - 生效结束时间") + @Schema(description = "固定日期 - 生效结束时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime validEndTime; - @Schema(title = "商品范围", required = true, example = "1", description = "参见 PromotionProductScopeEnum 枚举类") + @Schema(description = "商品范围,参见 PromotionProductScopeEnum 枚举类", required = true, example = "1") @NotNull(message = "商品范围不能为空") @InEnum(PromotionProductScopeEnum.class) private Integer productScope; - @Schema(title = "商品 SPU 编号的数组", example = "1,3") + @Schema(description = "商品 SPU 编号的数组", example = "1,3") private List productSpuIds; // ========== 使用规则 END ========== // ========== 使用效果 BEGIN ========== - @Schema(title = "优惠类型", required = true, example = "1", description = "参见 PromotionDiscountTypeEnum 枚举") + @Schema(description = "优惠类型,参见 PromotionDiscountTypeEnum 枚举", required = true, example = "1") @NotNull(message = "优惠类型不能为空") @InEnum(PromotionDiscountTypeEnum.class) private Integer discountType; - @Schema(title = "折扣百分比", example = "80", description = "例如说,80% 为 80") + @Schema(description = "折扣百分比,例如说,80% 为 80", example = "80") private Integer discountPercent; - @Schema(title = "优惠金额", example = "10", description = "单位:分") + @Schema(description = "优惠金额,单位:分", example = "10") @Min(value = 0, message = "优惠金额需要大于等于 0") private Integer discountPrice; - @Schema(title = "折扣上限", example = "100", description = "单位:分,仅在 discountType 为 PERCENT 使用") + @Schema(description = "折扣上限,单位:分,仅在 discountType 为 PERCENT 使用", example = "100") private Integer discountLimitPrice; // ========== 使用效果 END ========== // ========== 使用情况 BEGIN ========== - @Schema(title = "使用订单号", example = "4096") + @Schema(description = "使用订单号", example = "4096") private Long useOrderId; - @Schema(title = "使用时间") + @Schema(description = "使用时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime useTime; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java index 7529ee62b..118736ef6 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java @@ -5,13 +5,13 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 优惠劵分页的每一项 Response VO") +@Schema(description = "管理后台 - 优惠劵分页的每一项 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponPageItemRespVO extends CouponRespVO { - @Schema(title = "用户昵称", example = "老芋艿") + @Schema(description = "用户昵称", example = "老芋艿") private String nickname; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java index ba81ca1d4..e74f6327d 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java @@ -11,23 +11,23 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 优惠劵分页 Request VO") +@Schema(description = "管理后台 - 优惠劵分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponPageReqVO extends PageParam { - @Schema(title = "优惠劵模板编号", example = "2048") + @Schema(description = "优惠劵模板编号", example = "2048") private Long templateId; - @Schema(title = "优惠码状态", example = "1", description = "参见 CouponStatusEnum 枚举") + @Schema(description = "优惠码状态,参见 CouponStatusEnum 枚举", example = "1") private Integer status; - @Schema(title = "创建时间") + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; - @Schema(title = "用户昵称", example = "芋艿", description = "模糊匹配") + @Schema(description = "用户昵称,模糊匹配", example = "芋艿") private String nickname; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java index 8a07e28dc..68f0bc44e 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 优惠劵 Response VO") +@Schema(description = "管理后台 - 优惠劵 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponRespVO extends CouponBaseVO { - @Schema(title = "优惠劵编号", required = true, example = "1024") + @Schema(description = "优惠劵编号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java index 4c69a443e..0100c91c6 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java @@ -29,70 +29,70 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DE @Data public class CouponTemplateBaseVO { - @Schema(title = "优惠劵名", required = true, example = "春节送送送") + @Schema(description = "优惠劵名", required = true, example = "春节送送送") @NotNull(message = "优惠劵名不能为空") private String name; - @Schema(title = "发行总量", required = true, example = "1024", description = "-1 - 则表示不限制发放数量") + @Schema(description = "发行总量,-1 - 则表示不限制发放数量", required = true, example = "1024") @NotNull(message = "发行总量不能为空") private Integer totalCount; - @Schema(title = "每人限领个数", required = true, example = "66", description = "-1 - 则表示不限制") + @Schema(description = "每人限领个数,-1 - 则表示不限制", required = true, example = "66") @NotNull(message = "每人限领个数不能为空") private Integer takeLimitCount; - @Schema(title = "领取方式", required = true, example = "1", description = "参见 CouponTakeTypeEnum 枚举类") + @Schema(description = "领取方式,参见 CouponTakeTypeEnum 枚举类", required = true, example = "1") @NotNull(message = "领取方式不能为空") private Integer takeType; - @Schema(title = "是否设置满多少金额可用", required = true, example = "100", description = "单位:分;0 - 不限制") + @Schema(description = "是否设置满多少金额可用,单位:分;0 - 不限制", required = true, example = "100") @NotNull(message = "是否设置满多少金额可用不能为空") private Integer usePrice; - @Schema(title = "商品范围", required = true, example = "1", description = "参见 PromotionProductScopeEnum 枚举类") + @Schema(description = "商品范围,参见 PromotionProductScopeEnum 枚举类", required = true, example = "1") @NotNull(message = "商品范围不能为空") @InEnum(PromotionProductScopeEnum.class) private Integer productScope; - @Schema(title = "商品 SPU 编号的数组", example = "1,3") + @Schema(description = "商品 SPU 编号的数组", example = "1,3") private List productSpuIds; - @Schema(title = "生效日期类型", required = true, example = "1") + @Schema(description = "生效日期类型", required = true, example = "1") @NotNull(message = "生效日期类型不能为空") @InEnum(CouponTemplateValidityTypeEnum.class) private Integer validityType; - @Schema(title = "固定日期 - 生效开始时间") + @Schema(description = "固定日期 - 生效开始时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime validStartTime; - @Schema(title = "固定日期 - 生效结束时间") + @Schema(description = "固定日期 - 生效结束时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) private LocalDateTime validEndTime; - @Schema(title = "领取日期 - 开始天数") + @Schema(description = "领取日期 - 开始天数") @Min(value = 0L, message = "开始天数必须大于 0") private Integer fixedStartTerm; - @Schema(title = "领取日期 - 结束天数") + @Schema(description = "领取日期 - 结束天数") @Min(value = 1L, message = "开始天数必须大于 1") private Integer fixedEndTerm; - @Schema(title = "优惠类型", required = true, example = "1", description = "参见 PromotionDiscountTypeEnum 枚举") + @Schema(description = "优惠类型,参见 PromotionDiscountTypeEnum 枚举", required = true, example = "1") @NotNull(message = "优惠类型不能为空") @InEnum(PromotionDiscountTypeEnum.class) private Integer discountType; - @Schema(title = "折扣百分比", example = "80", description = "例如说,80% 为 80") + @Schema(description = "折扣百分比,例如说,80% 为 80", example = "80") private Integer discountPercent; - @Schema(title = "优惠金额", example = "10", description = "单位:分") + @Schema(description = "优惠金额,单位:分", example = "10") @Min(value = 0, message = "优惠金额需要大于等于 0") private Integer discountPrice; - @Schema(title = "折扣上限", example = "100", description = "单位:分,仅在 discountType 为 PERCENT 使用") + @Schema(description = "折扣上限,单位:分,仅在 discountType 为 PERCENT 使用", example = "100") private Integer discountLimitPrice; @AssertTrue(message = "商品 SPU 编号的数组不能为空") diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java index 60c37ee0d..7b24dbbdb 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java @@ -4,7 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 优惠劵模板创建 Request VO") +@Schema(description = "管理后台 - 优惠劵模板创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java index 6efb227cc..bcbafcd06 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java @@ -11,22 +11,22 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 优惠劵模板分页 Request VO") +@Schema(description = "管理后台 - 优惠劵模板分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponTemplatePageReqVO extends PageParam { - @Schema(title = "优惠劵名", example = "你好") + @Schema(description = "优惠劵名", example = "你好") private String name; - @Schema(title = "状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; - @Schema(title = "优惠类型", example = "1", description = "参见 PromotionDiscountTypeEnum 枚举") + @Schema(description = "优惠类型,参见 PromotionDiscountTypeEnum 枚举", example = "1") private Integer discountType; - @Schema(title = "创建时间") + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java index d3d71696b..b90407b43 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java @@ -9,26 +9,26 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 优惠劵模板 Response VO") +@Schema(description = "管理后台 - 优惠劵模板 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponTemplateRespVO extends CouponTemplateBaseVO { - @Schema(title = "模板编号", required = true, example = "1024") + @Schema(description = "模板编号", required = true, example = "1024") private Long id; - @Schema(title = "状态", required = true, example = "1") + @Schema(description = "状态", required = true, example = "1") @InEnum(CommonStatusEnum.class) private Integer status; - @Schema(title = "领取优惠券的数量", required = true, example = "1024") + @Schema(description = "领取优惠券的数量", required = true, example = "1024") private Integer takeCount; - @Schema(title = "使用优惠券的次数", required = true, example = "2048") + @Schema(description = "使用优惠券的次数", required = true, example = "2048") private Integer useCount; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java index 054ddbf6a..922e4f057 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 优惠劵模板更新 Request VO") +@Schema(description = "管理后台 - 优惠劵模板更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class CouponTemplateUpdateReqVO extends CouponTemplateBaseVO { - @Schema(title = "模板编号", required = true, example = "1024") + @Schema(description = "模板编号", required = true, example = "1024") @NotNull(message = "模板编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java index 9d6c48c41..f12f6b756 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java @@ -7,15 +7,15 @@ import lombok.Data; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 优惠劵模板更新状态 Request VO") +@Schema(description = "管理后台 - 优惠劵模板更新状态 Request VO") @Data public class CouponTemplateUpdateStatusReqVO { - @Schema(title = "优惠劵模板编号", required = true, example = "1024") + @Schema(description = "优惠劵模板编号", required = true, example = "1024") @NotNull(message = "优惠劵模板编号不能为空") private Long id; - @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") + @Schema(description = "状态,见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") private Integer status; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java index 35f3da2ad..d30df6c1c 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java @@ -22,44 +22,44 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class DiscountActivityBaseVO { - @Schema(title = "活动标题", required = true, example = "一个标题") + @Schema(description = "活动标题", required = true, example = "一个标题") @NotNull(message = "活动标题不能为空") private String name; - @Schema(title = "开始时间", required = true) + @Schema(description = "开始时间", required = true) @NotNull(message = "开始时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; - @Schema(title = "结束时间", required = true) + @Schema(description = "结束时间", required = true) @NotNull(message = "结束时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; - @Schema(title = "备注", example = "我是备注") + @Schema(description = "备注", example = "我是备注") private String remark; - @Schema(title = "商品") + @Schema(description = "商品") @Data public static class Product { - @Schema(title = "商品 SPU 编号", required = true, example = "1") + @Schema(description = "商品 SPU 编号", required = true, example = "1") @NotNull(message = "商品 SPU 编号不能为空") private Long spuId; - @Schema(title = "商品 SKU 编号", required = true, example = "1") + @Schema(description = "商品 SKU 编号", required = true, example = "1") @NotNull(message = "商品 SKU 编号不能为空") private Long skuId; - @Schema(title = "优惠类型", required = true, example = "1", description = "参见 PromotionDiscountTypeEnum 枚举") + @Schema(description = "优惠类型,参见 PromotionDiscountTypeEnum 枚举", required = true, example = "1") @NotNull(message = "优惠类型不能为空") @InEnum(PromotionDiscountTypeEnum.class) private Integer discountType; - @Schema(title = "折扣百分比", example = "80", description = "例如说,80% 为 80") + @Schema(description = "折扣百分比,例如说,80% 为 80", example = "80") private Integer discountPercent; - @Schema(title = "优惠金额", example = "10", description = "单位:分") + @Schema(description = "优惠金额,单位:分", example = "10") @Min(value = 0, message = "优惠金额需要大于等于 0") private Integer discountPrice; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java index 86eedc799..5b22cbd35 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java @@ -8,7 +8,7 @@ import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import java.util.List; -@Schema(title = "管理后台 - 限时折扣活动创建 Request VO") +@Schema(description = "管理后台 - 限时折扣活动创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java index 44cc1965c..caa0a648c 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java @@ -6,7 +6,7 @@ import lombok.ToString; import java.util.List; -@Schema(title = "管理后台 - 限时折扣活动的详细 Response VO") +@Schema(description = "管理后台 - 限时折扣活动的详细 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java index 2c8679566..4463555ea 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java @@ -11,19 +11,19 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 限时折扣活动分页 Request VO") +@Schema(description = "管理后台 - 限时折扣活动分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DiscountActivityPageReqVO extends PageParam { - @Schema(title = "活动标题", example = "一个标题") + @Schema(description = "活动标题", example = "一个标题") private String name; - @Schema(title = "活动状态", example = "1") + @Schema(description = "活动状态", example = "1") private Integer status; - @Schema(title = "创建时间") + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java index d46918edf..b552c56ed 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java @@ -8,20 +8,20 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 限时折扣活动 Response VO") +@Schema(description = "管理后台 - 限时折扣活动 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DiscountActivityRespVO extends DiscountActivityBaseVO { - @Schema(title = "活动编号", required = true, example = "1024") + @Schema(description = "活动编号", required = true, example = "1024") private Long id; - @Schema(title = "活动状态", required = true, example = "1") + @Schema(description = "活动状态", required = true, example = "1") @NotNull(message = "活动状态不能为空") private Integer status; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java index ff9aa27b3..f9bf48c06 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java @@ -10,13 +10,13 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; -@Schema(title = "管理后台 - 限时折扣活动更新 Request VO") +@Schema(description = "管理后台 - 限时折扣活动更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class DiscountActivityUpdateReqVO extends DiscountActivityBaseVO { - @Schema(title = "活动编号", required = true, example = "1024") + @Schema(description = "活动编号", required = true, example = "1024") @NotNull(message = "活动编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java index 75ab536de..6896e93c9 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java @@ -25,35 +25,35 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class RewardActivityBaseVO { - @Schema(title = "活动标题", required = true, example = "满啦满啦") + @Schema(description = "活动标题", required = true, example = "满啦满啦") @NotNull(message = "活动标题不能为空") private String name; - @Schema(title = "开始时间", required = true) + @Schema(description = "开始时间", required = true) @NotNull(message = "开始时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; - @Schema(title = "结束时间", required = true) + @Schema(description = "结束时间", required = true) @NotNull(message = "结束时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @Future(message = "结束时间必须大于当前时间") private LocalDateTime endTime; - @Schema(title = "备注", example = "biubiubiu") + @Schema(description = "备注", example = "biubiubiu") private String remark; - @Schema(title = "条件类型", required = true, example = "1") + @Schema(description = "条件类型", required = true, example = "1") @NotNull(message = "条件类型不能为空") @InEnum(value = PromotionConditionTypeEnum.class, message = "条件类型必须是 {value}") private Integer conditionType; - @Schema(title = "商品范围", required = true, example = "1") + @Schema(description = "商品范围", required = true, example = "1") @NotNull(message = "商品范围不能为空") @InEnum(value = PromotionConditionTypeEnum.class, message = "商品范围必须是 {value}") private Integer productScope; - @Schema(title = "商品 SPU 编号的数组", example = "1,2,3") + @Schema(description = "商品 SPU 编号的数组", example = "1,2,3") private List productSpuIds; /** @@ -62,29 +62,29 @@ public class RewardActivityBaseVO { @Valid // 校验下子对象 private List rules; - @Schema(title = "优惠规则") + @Schema(description = "优惠规则") @Data public static class Rule { - @Schema(title = "优惠门槛", required = true, example = "100", description = "1. 满 N 元,单位:分; 2. 满 N 件") + @Schema(description = "优惠门槛,1. 满 N 元,单位:分; 2. 满 N 件", required = true, example = "100") @Min(value = 1L, message = "优惠门槛必须大于等于 1") private Integer limit; - @Schema(title = "优惠价格", required = true, example = "100", description = "单位:分") + @Schema(description = "优惠价格,单位:分", required = true, example = "100") @Min(value = 1L, message = "优惠价格必须大于等于 1") private Integer discountPrice; - @Schema(title = "是否包邮", required = true, example = "true") + @Schema(description = "是否包邮", required = true, example = "true") private Boolean freeDelivery; - @Schema(title = "赠送的积分", required = true, example = "100") + @Schema(description = "赠送的积分", required = true, example = "100") @Min(value = 1L, message = "赠送的积分必须大于等于 1") private Integer point; - @Schema(title = "赠送的优惠劵编号的数组", example = "1,2,3") + @Schema(description = "赠送的优惠劵编号的数组", example = "1,2,3") private List couponIds; - @Schema(title = "赠送的优惠卷数量的数组", example = "1,2,3") + @Schema(description = "赠送的优惠卷数量的数组", example = "1,2,3") private List couponCounts; @AssertTrue(message = "优惠劵和数量必须一一对应") diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java index 222a704c6..a5f35e030 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - 满减送活动创建 Request VO") +@Schema(description = "管理后台 - 满减送活动创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java index 980f92bfc..dc99e79fa 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java @@ -3,16 +3,16 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; -@Schema(title = "管理后台 - 满减送活动分页 Request VO") +@Schema(description = "管理后台 - 满减送活动分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class RewardActivityPageReqVO extends PageParam { - @Schema(title = "活动标题", example = "满啦满啦") + @Schema(description = "活动标题", example = "满啦满啦") private String name; - @Schema(title = "活动状态", example = "1") + @Schema(description = "活动状态", example = "1") private Integer status; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java index 2eede11e2..8ad93cb59 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java @@ -7,19 +7,19 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 满减送活动 Response VO") +@Schema(description = "管理后台 - 满减送活动 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class RewardActivityRespVO extends RewardActivityBaseVO { - @Schema(title = "活动编号", required = true, example = "1024") + @Schema(description = "活动编号", required = true, example = "1024") private Integer id; - @Schema(title = "活动状态", required = true, example = "1") + @Schema(description = "活动状态", required = true, example = "1") private Integer status; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java index 9580868c6..5c1106d1e 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 满减送活动更新 Request VO") +@Schema(description = "管理后台 - 满减送活动更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class RewardActivityUpdateReqVO extends RewardActivityBaseVO { - @Schema(title = "活动编号", required = true, example = "1024") + @Schema(description = "活动编号", required = true, example = "1024") @NotNull(message = "活动编号不能为空") private Long id; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java index c4ec055c8..42b58e8e0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java @@ -3,20 +3,20 @@ package cn.iocoder.yudao.module.trade.controller.app.base.property; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "用户 App - 规格 + 规格值 Response VO") +@Schema(description = "用户 App - 规格 + 规格值 Response VO") @Data public class AppProductPropertyValueDetailRespVO { - @Schema(title = "属性的编号", required = true, example = "1") + @Schema(description = "属性的编号", required = true, example = "1") private Long propertyId; - @Schema(title = "属性的名称", required = true, example = "颜色") + @Schema(description = "属性的名称", required = true, example = "颜色") private String propertyName; - @Schema(title = "属性值的编号", required = true, example = "1024") + @Schema(description = "属性值的编号", required = true, example = "1024") private Long valueId; - @Schema(title = "属性值的名称", required = true, example = "红色") + @Schema(description = "属性值的名称", required = true, example = "红色") private String valueName; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java index 5d6499517..446f7f354 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java @@ -14,16 +14,16 @@ import java.util.List; @Data public class AppProductSkuBaseRespVO { - @Schema(title = "主键", required = true, example = "1024") + @Schema(description = "主键", required = true, example = "1024") private Long id; - @Schema(title = "商品 SKU 名字", required = true, example = "芋道") + @Schema(description = "商品 SKU 名字", required = true, example = "芋道") private String name; - @Schema(title = "图片地址", example = "https://www.iocoder.cn/xx.png") + @Schema(description = "图片地址", example = "https://www.iocoder.cn/xx.png") private String picUrl; - @Schema(title = "库存", required = true, example = "1") + @Schema(description = "库存", required = true, example = "1") private Integer stock; /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java index a3ebf3fe8..61ecf59d2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java @@ -12,13 +12,13 @@ import java.util.List; @Data public class AppProductSpuBaseRespVO { - @Schema(title = "主键", required = true, example = "1024") + @Schema(description = "主键", required = true, example = "1024") private Long id; - @Schema(title = "商品 SPU 名字", required = true, example = "芋道") + @Schema(description = "商品 SPU 名字", required = true, example = "芋道") private String name; - @Schema(title = "商品主图地址", example = "https://www.iocoder.cn/xx.png") + @Schema(description = "商品主图地址", example = "https://www.iocoder.cn/xx.png") private List picUrls; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java index 359917887..f58421b68 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java @@ -6,7 +6,7 @@ import lombok.Data; import java.util.List; -@Schema(title = "用户 App - 用户的购物车明细 Response VO") +@Schema(description = "用户 App - 用户的购物车明细 Response VO") @Data public class AppTradeCartDetailRespVO { @@ -20,7 +20,7 @@ public class AppTradeCartDetailRespVO { */ private Order order; - @Schema(title = "商品分组", description = "多个商品,参加同一个活动,从而形成分组") + @Schema(description = "商品分组,多个商品,参加同一个活动,从而形成分组") @Data public static class ItemGroup { @@ -35,7 +35,7 @@ public class AppTradeCartDetailRespVO { } - @Schema(title = "商品 SKU") + @Schema(description = "商品 SKU") @Data public static class Sku extends AppProductSkuBaseRespVO { @@ -46,26 +46,26 @@ public class AppTradeCartDetailRespVO { // ========== 购物车相关的字段 ========== - @Schema(title = "商品数量", required = true, example = "1") + @Schema(description = "商品数量", required = true, example = "1") private Integer count; - @Schema(title = "是否选中", required = true, example = "true") + @Schema(description = "是否选中", required = true, example = "true") private Boolean selected; // ========== 价格相关的字段,对应 PriceCalculateRespDTO.OrderItem 的属性 ========== // TODO 芋艿:后续可以去除一些无用的字段 - @Schema(title = "商品原价(单)", required = true, example = "100") + @Schema(description = "商品原价(单)", required = true, example = "100") private Integer originalPrice; - @Schema(title = "商品原价(总)", required = true, example = "200") + @Schema(description = "商品原价(总)", required = true, example = "200") private Integer totalOriginalPrice; - @Schema(title = "商品级优惠(总)", required = true, example = "300") + @Schema(description = "商品级优惠(总)", required = true, example = "300") private Integer totalPromotionPrice; - @Schema(title = "最终购买金额(总)", required = true, example = "400") + @Schema(description = "最终购买金额(总)", required = true, example = "400") private Integer totalPresentPrice; - @Schema(title = "最终购买金额(单)", required = true, example = "500") + @Schema(description = "最终购买金额(单)", required = true, example = "500") private Integer presentPrice; - @Schema(title = "应付金额(总)", required = true, example = "600") + @Schema(description = "应付金额(总)", required = true, example = "600") private Integer totalPayPrice; // ========== 营销相关的字段 ========== @@ -76,40 +76,40 @@ public class AppTradeCartDetailRespVO { } - @Schema(title = "订单", description = "对应 PriceCalculateRespDTO.Order 类,用于费用(合计)") + @Schema(description = "订单,对应 PriceCalculateRespDTO.Order 类,用于费用(合计)") @Data public static class Order { // TODO 芋艿:后续可以去除一些无用的字段 - @Schema(title = "商品原价(总)", required = true, example = "100") + @Schema(description = "商品原价(总)", required = true, example = "100") private Integer skuOriginalPrice; - @Schema(title = "商品优惠(总)", required = true, example = "200") + @Schema(description = "商品优惠(总)", required = true, example = "200") private Integer skuPromotionPrice; - @Schema(title = "订单优惠(总)", required = true, example = "300") + @Schema(description = "订单优惠(总)", required = true, example = "300") private Integer orderPromotionPrice; - @Schema(title = "运费金额", required = true, example = "400") + @Schema(description = "运费金额", required = true, example = "400") private Integer deliveryPrice; - @Schema(title = "应付金额(总)", required = true, example = "500") + @Schema(description = "应付金额(总)", required = true, example = "500") private Integer payPrice; } - @Schema(title = "营销活动", description = "对应 PriceCalculateRespDTO.Promotion 类的属性") + @Schema(description = "营销活动,对应 PriceCalculateRespDTO.Promotion 类的属性") @Data public static class Promotion { - @Schema(title = "营销编号", required = true, example = "1024", description = "营销活动的编号、优惠劵的编号") + @Schema(description = "营销编号,营销活动的编号、优惠劵的编号", required = true, example = "1024") private Long id; - @Schema(title = "营销名字", required = true, example = "xx 活动") + @Schema(description = "营销名字", required = true, example = "xx 活动") private String name; - @Schema(title = "营销类型", required = true, example = "1", description = "参见 PromotionTypeEnum 枚举类") + @Schema(description = "营销类型,参见 PromotionTypeEnum 枚举类", required = true, example = "1") private Integer type; // ========== 匹配情况 ========== - @Schema(title = "是否满足优惠条件", required = true, example = "true") + @Schema(description = "是否满足优惠条件", required = true, example = "true") private Boolean meet; - @Schema(title = "满足条件的提示", required = true, example = "圣诞价:省 150.00 元") + @Schema(description = "满足条件的提示", required = true, example = "圣诞价:省 150.00 元") private String meetTip; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java index 20c1e9e8b..280150537 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java @@ -6,15 +6,15 @@ import lombok.Data; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; -@Schema(title = "用户 App - 购物车添加购物项 Request VO") +@Schema(description = "用户 App - 购物车添加购物项 Request VO") @Data public class AppTradeCartItemAddCountReqVO { - @Schema(title = "商品 SKU 编号", required = true,example = "1024") + @Schema(description = "商品 SKU 编号", required = true,example = "1024") @NotNull(message = "商品 SKU 编号不能为空") private Long skuId; - @Schema(title = "商品数量", required = true, example = "1", description = "注意,这是新增数量") + @Schema(description = "商品数量,注意,这是新增数量", required = true, example = "1") @NotNull(message = "数量不能为空") @Min(message = "数量必须大于 0", value = 1L) private Integer count; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java index 3854b1bec..d3d12487e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java @@ -6,15 +6,15 @@ import lombok.Data; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; -@Schema(title = "用户 App - 购物车更新数量 Request VO") +@Schema(description = "用户 App - 购物车更新数量 Request VO") @Data public class AppTradeCartItemUpdateCountReqVO { - @Schema(title = "商品 SKU 编号", required = true, example = "1024") + @Schema(description = "商品 SKU 编号", required = true, example = "1024") @NotNull(message = "商品 SKU 编号不能为空") private Long skuId; - @Schema(title = "商品数量", required = true, example = "1") + @Schema(description = "商品数量", required = true, example = "1") @NotNull(message = "数量不能为空") @Min(message = "数量必须大于 0", value = 1L) private Integer count; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java index f126ed41b..62327f320 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java @@ -6,15 +6,15 @@ import lombok.Data; import javax.validation.constraints.NotNull; import java.util.Collection; -@Schema(title = "用户 App - 购物车更新是否选中 Request VO") +@Schema(description = "用户 App - 购物车更新是否选中 Request VO") @Data public class AppTradeCartItemUpdateSelectedReqVO { - @Schema(title = "商品 SKU 编号列表", required = true, example = "1024,2048") + @Schema(description = "商品 SKU 编号列表", required = true, example = "1024,2048") @NotNull(message = "商品 SKU 编号列表不能为空") private Collection skuIds; - @Schema(title = "是否选中", required = true, example = "true") + @Schema(description = "是否选中", required = true, example = "true") @NotNull(message = "是否选中不能为空") private Boolean selected; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java index 99700d2e7..e5b9e8e97 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java @@ -8,21 +8,21 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; -@Schema(title = "用户 App - 交易订单创建 Request VO") +@Schema(description = "用户 App - 交易订单创建 Request VO") @Data public class AppTradeOrderCreateReqVO { - @Schema(name = "收件地址编号", required = true, example = "1") + @Schema(description = "收件地址编号", required = true, example = "1") @NotNull(message = "收件地址不能为空") private Long addressId; - @Schema(name = "优惠劵编号", example = "1024") + @Schema(description = "优惠劵编号", example = "1024") private Long couponId; - @Schema(name = "备注", example = "这个是我的订单哟") + @Schema(description = "备注", example = "这个是我的订单哟") private String remark; - @Schema(name = "是否来自购物车", required = true, example = "true", description = "true - 来自购物车;false - 立即购买") + @Schema(description = "是否来自购物车,true - 来自购物车;false - 立即购买", required = true, example = "true") @NotNull(message = "是否来自购物车不能为空") private Boolean fromCart; @@ -32,15 +32,15 @@ public class AppTradeOrderCreateReqVO { @NotEmpty(message = "必须选择购买的商品") private List items; - @Schema(title = "订单商品项") + @Schema(description = "订单商品项") @Data public static class Item { - @Schema(name = "商品 SKU 编号", required = true, example = "111") + @Schema(description = "商品 SKU 编号", required = true, example = "111") @NotNull(message = "商品 SKU 编号不能为空") private Long skuId; - @Schema(name = "商品 SKU 购买数量", required = true, example = "1024") + @Schema(description = "商品 SKU 购买数量", required = true, example = "1024") @NotNull(message = "商品 SKU 购买数量不能为空") @Min(value = 1, message = "商品 SKU 购买数量必须大于 0") private Integer count; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java index ee73df098..873e12481 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java @@ -6,7 +6,7 @@ import lombok.Data; import java.util.List; -@Schema(title = "用户 App - 订单获得创建信息 Response VO") +@Schema(description = "用户 App - 订单获得创建信息 Response VO") @Data public class AppTradeOrderGetCreateInfoRespVO { @@ -24,7 +24,7 @@ public class AppTradeOrderGetCreateInfoRespVO { // */ // private List coupons; - @Schema(title = "商品分组", description = "多个商品,参加同一个活动,从而形成分组") + @Schema(description = "商品分组,多个商品,参加同一个活动,从而形成分组") @Data public static class ItemGroup { @@ -39,12 +39,12 @@ public class AppTradeOrderGetCreateInfoRespVO { } - @Schema(title = "商品 SKU") + @Schema(description = "商品 SKU") @Data public static class Sku { // SKU 自带信息 - @Schema(title = "SKU 编号", required = true, example = "1024") + @Schema(description = "SKU 编号", required = true, example = "1024") private Integer id; /** * SPU 信息 @@ -139,12 +139,12 @@ public class AppTradeOrderGetCreateInfoRespVO { } - @Schema(title = "费用(合计)") + @Schema(description = "费用(合计)") @Data @AllArgsConstructor public static class Fee { - @Schema(title = "购买总价", required = true, example = "1024") + @Schema(description = "购买总价", required = true, example = "1024") private Integer buyPrice; /** * 优惠总价 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java index a792c756e..6c92ceb0d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java @@ -5,47 +5,47 @@ import lombok.Data; import java.time.LocalDateTime; -@Schema(title = "交易订单项 Response VO") +@Schema(description = "交易订单项 Response VO") @Data public class TradeOrderItemRespVO { - @Schema(title = "id自增长", required = true) + @Schema(description = "id自增长", required = true) private Integer id; - @Schema(title = "订单编号", required = true) + @Schema(description = "订单编号", required = true) private Integer orderId; - @Schema(title = "订单项状态", required = true) + @Schema(description = "订单项状态", required = true) private Integer status; - @Schema(title = "商品 SKU 编号", required = true) + @Schema(description = "商品 SKU 编号", required = true) private Integer skuId; - @Schema(title = "商品 SPU 编号", required = true) + @Schema(description = "商品 SPU 编号", required = true) private Integer spuId; - @Schema(title = "商品名字", required = true) + @Schema(description = "商品名字", required = true) private String skuName; - @Schema(title = "图片名字", required = true) + @Schema(description = "图片名字", required = true) private String skuImage; - @Schema(title = "商品数量", required = true) + @Schema(description = "商品数量", required = true) private Integer quantity; - @Schema(title = "原始单价,单位:分", required = true) + @Schema(description = "原始单价,单位:分", required = true) private Integer originPrice; - @Schema(title = "购买单价,单位:分", required = true) + @Schema(description = "购买单价,单位:分", required = true) private Integer buyPrice; - @Schema(title = "最终价格,单位:分", required = true) + @Schema(description = "最终价格,单位:分", required = true) private Integer presentPrice; - @Schema(title = "购买总金额,单位:分", required = true) + @Schema(description = "购买总金额,单位:分", required = true) private Integer buyTotal; - @Schema(title = "优惠总金额,单位:分", required = true) + @Schema(description = "优惠总金额,单位:分", required = true) private Integer discountTotal; - @Schema(title = "最终总金额,单位:分", required = true) + @Schema(description = "最终总金额,单位:分", required = true) private Integer presentTotal; - @Schema(title = "退款总金额,单位:分", required = true) + @Schema(description = "退款总金额,单位:分", required = true) private Integer refundTotal; - @Schema(title = "物流id") + @Schema(description = "物流id") private Integer logisticsId; - @Schema(title = "售后状态", required = true) + @Schema(description = "售后状态", required = true) private Integer afterSaleStatus; - @Schema(title = "售后订单编号") + @Schema(description = "售后订单编号") private Integer afterSaleOrderId; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java index 23b5e9d47..4a408f4a9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderPageReqVO.java @@ -5,12 +5,12 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@Schema(title = "交易订单分页 Request VO") +@Schema(description = "交易订单分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class TradeOrderPageReqVO extends PageParam { - @Schema(title = "订单状态", example = "1", description = "参见 TradeOrderStatusEnum 枚举") + @Schema(description = "订单状态-参见 TradeOrderStatusEnum 枚举", example = "1") private Integer orderStatus; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java index c8630416d..85a902e1d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java @@ -5,59 +5,59 @@ import lombok.*; import java.time.LocalDateTime; import java.util.*; -@Schema(title = "订单交易 Response VO") +@Schema(description = "订单交易 Response VO") @Data public class TradeOrderRespVO { - @Schema(title = "订单编号", required = true) + @Schema(description = "订单编号", required = true) private Integer id; - @Schema(title = "用户编号", required = true) + @Schema(description = "用户编号", required = true) private Integer userId; - @Schema(title = "订单单号", required = true) + @Schema(description = "订单单号", required = true) private String orderNo; - @Schema(title = "订单状态", required = true) + @Schema(description = "订单状态", required = true) private Integer orderStatus; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; - @Schema(title = "订单结束时间") + @Schema(description = "订单结束时间") private LocalDateTime endTime; - @Schema(title = "订单金额(总金额),单位:分", required = true) + @Schema(description = "订单金额(总金额),单位:分", required = true) private Integer buyPrice; - @Schema(title = "优惠总金额,单位:分", required = true) + @Schema(description = "优惠总金额,单位:分", required = true) private Integer discountPrice; - @Schema(title = "物流金额,单位:分", required = true) + @Schema(description = "物流金额,单位:分", required = true) private Integer logisticsPrice; - @Schema(title = "最终金额,单位:分", required = true) + @Schema(description = "最终金额,单位:分", required = true) private Integer presentPrice; - @Schema(title = "支付金额,单位:分", required = true) + @Schema(description = "支付金额,单位:分", required = true) private Integer payPrice; - @Schema(title = "退款金额,单位:分", required = true) + @Schema(description = "退款金额,单位:分", required = true) private Integer refundPrice; - @Schema(title = "付款时间") + @Schema(description = "付款时间") private LocalDateTime payTime; - @Schema(title = "支付订单编号") + @Schema(description = "支付订单编号") private Integer payTransactionId; - @Schema(title = "支付渠道") + @Schema(description = "支付渠道") private Integer payChannel; - @Schema(title = "配送类型", required = true) + @Schema(description = "配送类型", required = true) private Integer deliveryType; - @Schema(title = "发货时间") + @Schema(description = "发货时间") private LocalDateTime deliveryTime; - @Schema(title = "收货时间") + @Schema(description = "收货时间") private LocalDateTime receiveTime; - @Schema(title = "收件人名称", required = true) + @Schema(description = "收件人名称", required = true) private String receiverName; - @Schema(title = "手机号", required = true) + @Schema(description = "手机号", required = true) private String receiverMobile; - @Schema(title = "地区编码", required = true) + @Schema(description = "地区编码", required = true) private Integer receiverAreaCode; - @Schema(title = "收件详细地址", required = true) + @Schema(description = "收件详细地址", required = true) private String receiverDetailAddress; - @Schema(title = "售后状态", required = true) + @Schema(description = "售后状态", required = true) private Integer afterSaleStatus; - @Schema(title = "优惠劵编号") + @Schema(description = "优惠劵编号") private Integer couponCardId; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; /** diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java index e82f78ea3..f207ad8be 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressBaseVO.java @@ -12,27 +12,27 @@ import javax.validation.constraints.NotNull; @Data public class AppAddressBaseVO { - @Schema(title = "收件人名称", required = true) + @Schema(description = "收件人名称", required = true) @NotNull(message = "收件人名称不能为空") private String name; - @Schema(title = "手机号", required = true) + @Schema(description = "手机号", required = true) @NotNull(message = "手机号不能为空") private String mobile; - @Schema(title = "地区编号", required = true) + @Schema(description = "地区编号", required = true) @NotNull(message = "地区编号不能为空") private Long areaId; - @Schema(title = "邮编", required = true) + @Schema(description = "邮编", required = true) @NotEmpty(message = "邮编不能为空") private String postCode; - @Schema(title = "收件详细地址", required = true) + @Schema(description = "收件详细地址", required = true) @NotNull(message = "收件详细地址不能为空") private String detailAddress; - @Schema(title = "是否默认地址", required = true) + @Schema(description = "是否默认地址", required = true) @NotNull(message = "是否默认地址不能为空") private Boolean defaulted; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressCreateReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressCreateReqVO.java index deaa7da87..c92687f27 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressCreateReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressCreateReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.address.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "用户 APP - 用户收件地址创建 Request VO") +@Schema(description = "用户 APP - 用户收件地址创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java index 0acc49b7b..4e9df9912 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressRespVO.java @@ -3,16 +3,16 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -@Schema(title = "用户 APP - 用户收件地址 Response VO") +@Schema(description = "用户 APP - 用户收件地址 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class AppAddressRespVO extends AppAddressBaseVO { - @Schema(title = "编号", required = true) + @Schema(description = "编号", required = true) private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java index c93d1dbc2..f94197ece 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/address/vo/AppAddressUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "用户 APP - 用户收件地址更新 Request VO") +@Schema(description = "用户 APP - 用户收件地址更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class AppAddressUpdateReqVO extends AppAddressBaseVO { - @Schema(title = "编号", required = true) + @Schema(description = "编号", required = true) @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java index 8cdd0fcd6..170ffa504 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthCheckCodeReqVO.java @@ -15,25 +15,25 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; // TODO 芋艿:code review 相关逻辑 -@Schema(title = "用户 APP - 校验验证码 Request VO") +@Schema(description = "用户 APP - 校验验证码 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthCheckCodeReqVO { - @Schema(title = "手机号", example = "15601691234") + @Schema(description = "手机号", example = "15601691234") @NotBlank(message = "手机号不能为空") @Mobile private String mobile; - @Schema(title = "手机验证码", required = true, example = "1024") + @Schema(description = "手机验证码", required = true, example = "1024") @NotBlank(message = "手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") private String code; - @Schema(title = "发送场景", example = "1", description = "对应 SmsSceneEnum 枚举") + @Schema(description = "发送场景,对应 SmsSceneEnum 枚举", example = "1") @NotNull(message = "发送场景不能为空") @InEnum(SmsSceneEnum.class) private Integer scene; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java index 9c347b990..237cd15dc 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java @@ -14,33 +14,33 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotEmpty; -@Schema(title = "用户 APP - 手机 + 密码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") +@Schema(description = "用户 APP - 手机 + 密码登录 Request VO,如果登录并绑定社交用户,需要传递 social 开头的参数") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthLoginReqVO { - @Schema(title = "手机号", required = true, example = "15601691300") + @Schema(description = "手机号", required = true, example = "15601691300") @NotEmpty(message = "手机号不能为空") @Mobile private String mobile; - @Schema(title = "密码", required = true, example = "buzhidao") + @Schema(description = "密码", required = true, example = "buzhidao") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; // ========== 绑定社交登录时,需要传递如下参数 ========== - @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", required = true, example = "10") @InEnum(SocialTypeEnum.class) private Integer socialType; - @Schema(title = "授权码", required = true, example = "1024") + @Schema(description = "授权码", required = true, example = "1024") private String socialCode; - @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(description = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") private String socialState; @AssertTrue(message = "授权码不能为空") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java index 734c01591..3794b1f4c 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java @@ -8,23 +8,23 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@Schema(title = "用户 APP - 登录 Response VO") +@Schema(description = "用户 APP - 登录 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthLoginRespVO { - @Schema(title = "用户编号", required = true, example = "1024") + @Schema(description = "用户编号", required = true, example = "1024") private Long userId; - @Schema(title = "访问令牌", required = true, example = "happy") + @Schema(description = "访问令牌", required = true, example = "happy") private String accessToken; - @Schema(title = "刷新令牌", required = true, example = "nice") + @Schema(description = "刷新令牌", required = true, example = "nice") private String refreshToken; - @Schema(title = "过期时间", required = true) + @Schema(description = "过期时间", required = true) private LocalDateTime expiresTime; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java index 0be071a84..e25139a31 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthResetPasswordReqVO.java @@ -13,25 +13,25 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; // TODO 芋艿:code review 相关逻辑 -@Schema(title = "用户 APP - 重置密码 Request VO") +@Schema(description = "用户 APP - 重置密码 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthResetPasswordReqVO { - @Schema(title = "新密码", required = true, example = "buzhidao") + @Schema(description = "新密码", required = true, example = "buzhidao") @NotEmpty(message = "新密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; - @Schema(title = "手机验证码", required = true, example = "1024") + @Schema(description = "手机验证码", required = true, example = "1024") @NotEmpty(message = "手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") private String code; - @Schema(title = "手机号",required = true,example = "15878962356") + @Schema(description = "手机号",required = true,example = "15878962356") @NotBlank(message = "手机号不能为空") @Mobile private String mobile; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java index 256a59452..c4fb20528 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java @@ -15,19 +15,19 @@ import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; -@Schema(title = "用户 APP - 手机 + 验证码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") +@Schema(description = "用户 APP - 手机 + 验证码登录 Request VO,如果登录并绑定社交用户,需要传递 social 开头的参数") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthSmsLoginReqVO { - @Schema(title = "手机号", required = true, example = "15601691300") + @Schema(description = "手机号", required = true, example = "15601691300") @NotEmpty(message = "手机号不能为空") @Mobile private String mobile; - @Schema(title = "手机验证码", required = true, example = "1024") + @Schema(description = "手机验证码", required = true, example = "1024") @NotEmpty(message = "手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") @@ -35,14 +35,14 @@ public class AppAuthSmsLoginReqVO { // ========== 绑定社交登录时,需要传递如下参数 ========== - @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", required = true, example = "10") @InEnum(SocialTypeEnum.class) private Integer socialType; - @Schema(title = "授权码", required = true, example = "1024") + @Schema(description = "授权码", required = true, example = "1024") private String socialCode; - @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(description = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") private String socialState; @AssertTrue(message = "授权码不能为空") diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsSendReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsSendReqVO.java index aaf4e30c7..5f4b030f3 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsSendReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsSendReqVO.java @@ -9,16 +9,16 @@ import lombok.experimental.Accessors; import javax.validation.constraints.NotNull; -@Schema(title = "用户 APP - 发送手机验证码 Request VO") +@Schema(description = "用户 APP - 发送手机验证码 Request VO") @Data @Accessors(chain = true) public class AppAuthSmsSendReqVO { - @Schema(title = "手机号", example = "15601691234") + @Schema(description = "手机号", example = "15601691234") @Mobile private String mobile; - @Schema(title = "发送场景", example = "1", description = "对应 SmsSceneEnum 枚举") + @Schema(description = "发送场景,对应 SmsSceneEnum 枚举", example = "1") @NotNull(message = "发送场景不能为空") @InEnum(SmsSceneEnum.class) private Integer scene; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java index 237017962..21d328064 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java @@ -11,23 +11,23 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "用户 APP - 社交快捷登录 Request VO,使用 code 授权码") +@Schema(description = "用户 APP - 社交快捷登录 Request VO,使用 code 授权码") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthSocialLoginReqVO { - @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", required = true, example = "10") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @Schema(title = "授权码", required = true, example = "1024") + @Schema(description = "授权码", required = true, example = "1024") @NotEmpty(message = "授权码不能为空") private String code; - @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(description = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") @NotEmpty(message = "state 不能为空") private String state; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java index d1926c9bb..e2a2d25be 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthUpdatePasswordReqVO.java @@ -11,19 +11,19 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; // TODO 芋艿:code review 相关逻辑 -@Schema(title = "用户 APP - 修改密码 Request VO") +@Schema(description = "用户 APP - 修改密码 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthUpdatePasswordReqVO { - @Schema(title = "用户旧密码", required = true, example = "123456") + @Schema(description = "用户旧密码", required = true, example = "123456") @NotBlank(message = "旧密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String oldPassword; - @Schema(title = "新密码", required = true, example = "buzhidao") + @Schema(description = "新密码", required = true, example = "buzhidao") @NotEmpty(message = "新密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java index 5245507a6..66475d013 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthWeixinMiniAppLoginReqVO.java @@ -8,18 +8,18 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; -@Schema(title = "用户 APP - 微信小程序手机登录 Request VO") +@Schema(description = "用户 APP - 微信小程序手机登录 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppAuthWeixinMiniAppLoginReqVO { - @Schema(title = "手机 code", required = true, example = "hello", description = "小程序通过 wx.getPhoneNumber 方法获得") + @Schema(description = "手机 code,小程序通过 wx.getPhoneNumber 方法获得", required = true, example = "hello") @NotEmpty(message = "手机 code 不能为空") private String phoneCode; - @Schema(title = "登录 code", required = true, example = "word", description = "小程序通过 wx.login 方法获得") + @Schema(description = "登录 code,小程序通过 wx.login 方法获得", required = true, example = "word") @NotEmpty(message = "登录 code 不能为空") private String loginCode; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserBindReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserBindReqVO.java index d1fde4e56..bd57ae155 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserBindReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserBindReqVO.java @@ -11,23 +11,23 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "用户 APP - 社交绑定 Request VO,使用 code 授权码") +@Schema(description = "用户 APP - 社交绑定 Request VO,使用 code 授权码") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppSocialUserBindReqVO { - @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", required = true, example = "10") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @Schema(title = "授权码", required = true, example = "1024") + @Schema(description = "授权码", required = true, example = "1024") @NotEmpty(message = "授权码不能为空") private String code; - @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(description = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") @NotEmpty(message = "state 不能为空") private String state; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserUnbindReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserUnbindReqVO.java index 5783983fe..7182643e6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserUnbindReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/social/vo/AppSocialUserUnbindReqVO.java @@ -11,19 +11,19 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "用户 APP - 取消社交绑定 Request VO") +@Schema(description = "用户 APP - 取消社交绑定 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppSocialUserUnbindReqVO { - @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", required = true, example = "10") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @Schema(title = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") + @Schema(description = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") @NotEmpty(message = "社交用户的 openid 不能为空") private String openid; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java index 7b09af358..ef0c3193b 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserInfoRespVO.java @@ -5,18 +5,18 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@Schema(title = "用户 APP - 用户个人信息 Response VO") +@Schema(description = "用户 APP - 用户个人信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class AppUserInfoRespVO { - @Schema(title = "用户昵称", required = true, example = "芋艿") + @Schema(description = "用户昵称", required = true, example = "芋艿") private String nickname; - @Schema(title = "用户头像", required = true, example = "/infra/file/get/35a12e57-4297-4faa-bf7d-7ed2f211c952") + @Schema(description = "用户头像", required = true, example = "/infra/file/get/35a12e57-4297-4faa-bf7d-7ed2f211c952") private String avatar; - @Schema(title = "用户手机号", required = true, example = "15601691300") + @Schema(description = "用户手机号", required = true, example = "15601691300") private String mobile; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java index e3c9021b1..d6edf48b9 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppUserUpdateMobileReqVO.java @@ -12,26 +12,26 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; -@Schema(title = "用户 APP - 修改手机 Request VO") +@Schema(description = "用户 APP - 修改手机 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AppUserUpdateMobileReqVO { - @Schema(title = "手机验证码", required = true, example = "1024") + @Schema(description = "手机验证码", required = true, example = "1024") @NotEmpty(message = "手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") private String code; - @Schema(title = "手机号",required = true,example = "15823654487") + @Schema(description = "手机号",required = true,example = "15823654487") @NotBlank(message = "手机号不能为空") @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") @Mobile private String mobile; - @Schema(title = "原手机验证码", required = true, example = "1024") + @Schema(description = "原手机验证码", required = true, example = "1024") @NotEmpty(message = "原手机验证码不能为空") @Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位") @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") @@ -39,7 +39,7 @@ public class AppUserUpdateMobileReqVO { // TODO @芋艿:oldMobile 应该不用传递 - @Schema(title = "原手机号",required = true,example = "15823654487") + @Schema(description = "原手机号",required = true,example = "15823654487") @NotBlank(message = "手机号不能为空") @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位") @Mobile diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java index 5ddbce516..54e62320d 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java @@ -10,26 +10,26 @@ import javax.validation.constraints.*; @Data public class PayAppBaseVO { - @Schema(title = "应用名", required = true) + @Schema(description = "应用名", required = true) @NotNull(message = "应用名不能为空") private String name; - @Schema(title = "开启状态", required = true) + @Schema(description = "开启状态", required = true) @NotNull(message = "开启状态不能为空") private Integer status; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; - @Schema(title = "支付结果的回调地址", required = true) + @Schema(description = "支付结果的回调地址", required = true) @NotNull(message = "支付结果的回调地址不能为空") private String payNotifyUrl; - @Schema(title = "退款结果的回调地址", required = true) + @Schema(description = "退款结果的回调地址", required = true) @NotNull(message = "退款结果的回调地址不能为空") private String refundNotifyUrl; - @Schema(title = "商户编号", required = true) + @Schema(description = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long merchantId; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java index 4c1086390..36816cc24 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - 支付应用信息创建 Request VO") +@Schema(description = "管理后台 - 支付应用信息创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java index f4cc07f40..b13a6e65b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java @@ -7,30 +7,30 @@ import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 支付应用信息 Excel 导出 Request VO", description = "参数和 PayAppPageReqVO 是一致的") +@Schema(description = "管理后台 - 支付应用信息 Excel 导出 Request VO,参数和 PayAppPageReqVO 是一致的") @Data public class PayAppExportReqVO { - @Schema(title = "应用名") + @Schema(description = "应用名") private String name; - @Schema(title = "开启状态") + @Schema(description = "开启状态") private Integer status; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; - @Schema(title = "支付结果的回调地址") + @Schema(description = "支付结果的回调地址") private String payNotifyUrl; - @Schema(title = "退款结果的回调地址") + @Schema(description = "退款结果的回调地址") private String refundNotifyUrl; - @Schema(title = "商户名称") + @Schema(description = "商户名称") private String merchantName; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java index 214d87ee8..72655db05 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java @@ -8,16 +8,16 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.Set; -@Schema(title = "管理后台 - 支付应用信息分页查询 Response VO", description = "相比于支付信息,还会多出应用渠道的开关信息") +@Schema(description = "管理后台 - 支付应用信息分页查询 Response VO,相比于支付信息,还会多出应用渠道的开关信息") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayAppPageItemRespVO extends PayAppBaseVO { - @Schema(title = "应用编号", required = true) + @Schema(description = "应用编号", required = true) private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; /** @@ -25,19 +25,19 @@ public class PayAppPageItemRespVO extends PayAppBaseVO { */ private PayMerchant payMerchant; - @Schema(title = "商户") + @Schema(description = "商户") @Data public static class PayMerchant { - @Schema(title = "商户编号", required = true, example = "1") + @Schema(description = "商户编号", required = true, example = "1") private Long id; - @Schema(title = "商户名称", required = true, example = "研发部") + @Schema(description = "商户名称", required = true, example = "研发部") private String name; } - @Schema(title = "渠道编码集合", required = true, example = "alipay_pc,alipay_wap...") + @Schema(description = "渠道编码集合", required = true, example = "alipay_pc,alipay_wap...") private Set channelCodes; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java index 04312cb1b..1aaadc78a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java @@ -8,32 +8,32 @@ import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 支付应用信息分页 Request VO") +@Schema(description = "管理后台 - 支付应用信息分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayAppPageReqVO extends PageParam { - @Schema(title = "应用名") + @Schema(description = "应用名") private String name; - @Schema(title = "开启状态") + @Schema(description = "开启状态") private Integer status; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; - @Schema(title = "支付结果的回调地址") + @Schema(description = "支付结果的回调地址") private String payNotifyUrl; - @Schema(title = "退款结果的回调地址") + @Schema(description = "退款结果的回调地址") private String refundNotifyUrl; - @Schema(title = "商户名称") + @Schema(description = "商户名称") private String merchantName; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java index c5fc4fb77..0bb0c5563 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java @@ -4,16 +4,16 @@ import lombok.*; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 支付应用信息 Response VO") +@Schema(description = "管理后台 - 支付应用信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayAppRespVO extends PayAppBaseVO { - @Schema(title = "应用编号", required = true) + @Schema(description = "应用编号", required = true) private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java index e55e86efb..2d940d5c2 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 支付应用信息更新 Request VO") +@Schema(description = "管理后台 - 支付应用信息更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayAppUpdateReqVO extends PayAppBaseVO { - @Schema(title = "应用编号", required = true) + @Schema(description = "应用编号", required = true) @NotNull(message = "应用编号不能为空") private Long id; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java index c5d257829..8454f5f2a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java @@ -5,15 +5,15 @@ import lombok.Data; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 应用更新状态 Request VO") +@Schema(description = "管理后台 - 应用更新状态 Request VO") @Data public class PayAppUpdateStatusReqVO { - @Schema(title = "商户编号", required = true, example = "1024") + @Schema(description = "商户编号", required = true, example = "1024") @NotNull(message = "商户编号不能为空") private Long id; - @Schema(title = "状态", required = true, example = "1", description = "见 SysCommonStatusEnum 枚举") + @Schema(description = "状态,见 SysCommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java index 3ff9f69b9..a8f0c1ec9 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java @@ -10,26 +10,26 @@ import javax.validation.constraints.*; @Data public class PayChannelBaseVO { - @Schema(title = "渠道编码", required = true) + @Schema(description = "渠道编码", required = true) @NotNull(message = "渠道编码不能为空") private String code; - @Schema(title = "开启状态", required = true) + @Schema(description = "开启状态", required = true) @NotNull(message = "开启状态不能为空") private Integer status; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; - @Schema(title = "渠道费率,单位:百分比", required = true) + @Schema(description = "渠道费率,单位:百分比", required = true) @NotNull(message = "渠道费率,单位:百分比不能为空") private Double feeRate; - @Schema(title = "商户编号", required = true) + @Schema(description = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long merchantId; - @Schema(title = "应用编号", required = true) + @Schema(description = "应用编号", required = true) @NotNull(message = "应用编号不能为空") private Long appId; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java index f2bda63fa..89547bc1e 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotBlank; -@Schema(title = "管理后台 - 支付渠道 创建 Request VO") +@Schema(description = "管理后台 - 支付渠道 创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayChannelCreateReqVO extends PayChannelBaseVO { - @Schema(title = "渠道配置的 json 字符串") + @Schema(description = "渠道配置的 json 字符串") @NotBlank(message = "渠道配置不能为空") private String config; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java index 091afc14e..3a7e16fb5 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java @@ -7,33 +7,33 @@ import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 支付渠道 Excel 导出 Request VO", description = "参数和 PayChannelPageReqVO 是一致的") +@Schema(description = "管理后台 - 支付渠道 Excel 导出 Request VO,参数和 PayChannelPageReqVO 是一致的") @Data public class PayChannelExportReqVO { - @Schema(title = "渠道编码") + @Schema(description = "渠道编码") private String code; - @Schema(title = "开启状态") + @Schema(description = "开启状态") private Integer status; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; - @Schema(title = "渠道费率,单位:百分比") + @Schema(description = "渠道费率,单位:百分比") private Double feeRate; - @Schema(title = "商户编号") + @Schema(description = "商户编号") private Long merchantId; - @Schema(title = "应用编号") + @Schema(description = "应用编号") private Long appId; - @Schema(title = "支付渠道配置") + @Schema(description = "支付渠道配置") private String config; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java index dd30097c5..00c724893 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java @@ -8,35 +8,35 @@ import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 支付渠道 分页 Request VO") +@Schema(description = "管理后台 - 支付渠道 分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayChannelPageReqVO extends PageParam { - @Schema(title = "渠道编码") + @Schema(description = "渠道编码") private String code; - @Schema(title = "开启状态") + @Schema(description = "开启状态") private Integer status; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; - @Schema(title = "渠道费率,单位:百分比") + @Schema(description = "渠道费率,单位:百分比") private Double feeRate; - @Schema(title = "商户编号") + @Schema(description = "商户编号") private Long merchantId; - @Schema(title = "应用编号") + @Schema(description = "应用编号") private Long appId; - @Schema(title = "支付渠道配置") + @Schema(description = "支付渠道配置") private String config; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java index 92c8f5714..5fa189e18 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java @@ -4,18 +4,18 @@ import lombok.*; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 支付渠道 Response VO") +@Schema(description = "管理后台 - 支付渠道 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayChannelRespVO extends PayChannelBaseVO { - @Schema(title = "商户编号", required = true) + @Schema(description = "商户编号", required = true) private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; - @Schema(title = "配置", required = true) + @Schema(description = "配置", required = true) private String config; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java index 94c322270..959c069b4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java @@ -3,17 +3,17 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 支付渠道 更新 Request VO") +@Schema(description = "管理后台 - 支付渠道 更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayChannelUpdateReqVO extends PayChannelBaseVO { - @Schema(title = "商户编号", required = true) + @Schema(description = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long id; - @Schema(title = "渠道配置的json字符串") + @Schema(description = "渠道配置的json字符串") @NotBlank(message = "渠道配置不能为空") private String config; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java index 71f8d0e61..dd8b3eddc 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java @@ -11,19 +11,19 @@ import javax.validation.constraints.NotNull; @Data public class PayMerchantBaseVO { - @Schema(title = "商户全称", required = true) + @Schema(description = "商户全称", required = true) @NotNull(message = "商户全称不能为空") private String name; - @Schema(title = "商户简称", required = true) + @Schema(description = "商户简称", required = true) @NotNull(message = "商户简称不能为空") private String shortName; - @Schema(title = "开启状态", required = true) + @Schema(description = "开启状态", required = true) @NotNull(message = "开启状态不能为空") private Integer status; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java index a61f728ab..f63aa123f 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - 支付商户信息创建 Request VO") +@Schema(description = "管理后台 - 支付商户信息创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java index 1a04a077d..4903531c9 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java @@ -7,27 +7,27 @@ import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 支付商户信息 Excel 导出 Request VO", description = "参数和 PayMerchantPageReqVO 是一致的") +@Schema(description = "管理后台 - 支付商户信息 Excel 导出 Request VO,参数和 PayMerchantPageReqVO 是一致的") @Data public class PayMerchantExportReqVO { - @Schema(title = "商户号") + @Schema(description = "商户号") private String no; - @Schema(title = "商户全称") + @Schema(description = "商户全称") private String name; - @Schema(title = "商户简称") + @Schema(description = "商户简称") private String shortName; - @Schema(title = "开启状态") + @Schema(description = "开启状态") private Integer status; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java index ec01270a5..0dccc4dab 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java @@ -8,29 +8,29 @@ import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 支付商户信息分页 Request VO") +@Schema(description = "管理后台 - 支付商户信息分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayMerchantPageReqVO extends PageParam { - @Schema(title = "商户号") + @Schema(description = "商户号") private String no; - @Schema(title = "商户全称") + @Schema(description = "商户全称") private String name; - @Schema(title = "商户简称") + @Schema(description = "商户简称") private String shortName; - @Schema(title = "开启状态") + @Schema(description = "开启状态") private Integer status; - @Schema(title = "备注") + @Schema(description = "备注") private String remark; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java index 54561c116..3e150f71c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java @@ -7,19 +7,19 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 支付商户信息 Response VO") +@Schema(description = "管理后台 - 支付商户信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayMerchantRespVO extends PayMerchantBaseVO { - @Schema(title = "商户编号", required = true) + @Schema(description = "商户编号", required = true) private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; - @Schema(title = "商户号", required = true, example = "M233666999") + @Schema(description = "商户号", required = true, example = "M233666999") private String no; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java index f6c509764..2fd70e2d9 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 支付商户信息更新 Request VO") +@Schema(description = "管理后台 - 支付商户信息更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayMerchantUpdateReqVO extends PayMerchantBaseVO { - @Schema(title = "商户编号", required = true) + @Schema(description = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long id; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java index 6fa637e7e..b42cd61f3 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java @@ -5,15 +5,15 @@ import lombok.Data; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 商户更新状态 Request VO") +@Schema(description = "管理后台 - 商户更新状态 Request VO") @Data public class PayMerchantUpdateStatusReqVO { - @Schema(title = "商户编号", required = true, example = "1024") + @Schema(description = "商户编号", required = true, example = "1024") @NotNull(message = "商户编号不能为空") private Long id; - @Schema(title = "状态", required = true, example = "1", description = "见 SysCommonStatusEnum 枚举") + @Schema(description = "状态,见 SysCommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java index ebf07630f..7991c7c7e 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java @@ -17,90 +17,90 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class PayOrderBaseVO { - @Schema(title = "商户编号", required = true) + @Schema(description = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long merchantId; - @Schema(title = "应用编号", required = true) + @Schema(description = "应用编号", required = true) @NotNull(message = "应用编号不能为空") private Long appId; - @Schema(title = "渠道编号") + @Schema(description = "渠道编号") private Long channelId; - @Schema(title = "渠道编码") + @Schema(description = "渠道编码") private String channelCode; - @Schema(title = "商户订单编号", required = true) + @Schema(description = "商户订单编号", required = true) @NotNull(message = "商户订单编号不能为空") private String merchantOrderId; - @Schema(title = "商品标题", required = true) + @Schema(description = "商品标题", required = true) @NotNull(message = "商品标题不能为空") private String subject; - @Schema(title = "商品描述", required = true) + @Schema(description = "商品描述", required = true) @NotNull(message = "商品描述不能为空") private String body; - @Schema(title = "异步通知地址", required = true) + @Schema(description = "异步通知地址", required = true) @NotNull(message = "异步通知地址不能为空") private String notifyUrl; - @Schema(title = "通知商户支付结果的回调状态", required = true) + @Schema(description = "通知商户支付结果的回调状态", required = true) @NotNull(message = "通知商户支付结果的回调状态不能为空") private Integer notifyStatus; - @Schema(title = "支付金额,单位:分", required = true) + @Schema(description = "支付金额,单位:分", required = true) @NotNull(message = "支付金额,单位:分不能为空") private Long amount; - @Schema(title = "渠道手续费,单位:百分比") + @Schema(description = "渠道手续费,单位:百分比") private Double channelFeeRate; - @Schema(title = "渠道手续金额,单位:分") + @Schema(description = "渠道手续金额,单位:分") private Long channelFeeAmount; - @Schema(title = "支付状态", required = true) + @Schema(description = "支付状态", required = true) @NotNull(message = "支付状态不能为空") private Integer status; - @Schema(title = "用户 IP", required = true) + @Schema(description = "用户 IP", required = true) @NotNull(message = "用户 IP不能为空") private String userIp; - @Schema(title = "订单失效时间", required = true) + @Schema(description = "订单失效时间", required = true) @NotNull(message = "订单失效时间不能为空") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime expireTime; - @Schema(title = "订单支付成功时间") + @Schema(description = "订单支付成功时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime successTime; - @Schema(title = "订单支付通知时间") + @Schema(description = "订单支付通知时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime notifyTime; - @Schema(title = "支付成功的订单拓展单编号") + @Schema(description = "支付成功的订单拓展单编号") private Long successExtensionId; - @Schema(title = "退款状态", required = true) + @Schema(description = "退款状态", required = true) @NotNull(message = "退款状态不能为空") private Integer refundStatus; - @Schema(title = "退款次数", required = true) + @Schema(description = "退款次数", required = true) @NotNull(message = "退款次数不能为空") private Integer refundTimes; - @Schema(title = "退款总金额,单位:分", required = true) + @Schema(description = "退款总金额,单位:分", required = true) @NotNull(message = "退款总金额,单位:分不能为空") private Long refundAmount; - @Schema(title = "渠道用户编号") + @Schema(description = "渠道用户编号") private String channelUserId; - @Schema(title = "渠道订单号") + @Schema(description = "渠道订单号") private String channelOrderNo; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java index 25ec3c9dc..6a1d2c8f6 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java @@ -7,25 +7,25 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 支付订单详细信息 Response VO") +@Schema(description = "管理后台 - 支付订单详细信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayOrderDetailsRespVO extends PayOrderBaseVO { - @Schema(title = "支付订单编号") + @Schema(description = "支付订单编号") private Long id; - @Schema(title = "商户名称") + @Schema(description = "商户名称") private String merchantName; - @Schema(title = "应用名称") + @Schema(description = "应用名称") private String appName; - @Schema(title = "渠道编号名称") + @Schema(description = "渠道编号名称") private String channelCodeName; - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime createTime; /** @@ -34,13 +34,13 @@ public class PayOrderDetailsRespVO extends PayOrderBaseVO { private PayOrderExtension payOrderExtension; @Data - @Schema(title = "支付订单扩展") + @Schema(description = "支付订单扩展") public static class PayOrderExtension { - @Schema(title = "支付订单号") + @Schema(description = "支付订单号") private String no; - @Schema(title = "支付异步通知的内容") + @Schema(description = "支付异步通知的内容") private String channelNotifyData; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java index cb08e04d4..a5783806c 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java @@ -8,84 +8,84 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 支付订单 Excel 导出 Request VO", description = "参数和 PayOrderPageReqVO 是一致的") +@Schema(description = "管理后台 - 支付订单 Excel 导出 Request VO,参数和 PayOrderPageReqVO 是一致的") @Data public class PayOrderExportReqVO { - @Schema(title = "商户编号") + @Schema(description = "商户编号") private Long merchantId; - @Schema(title = "应用编号") + @Schema(description = "应用编号") private Long appId; - @Schema(title = "渠道编号") + @Schema(description = "渠道编号") private Long channelId; - @Schema(title = "渠道编码") + @Schema(description = "渠道编码") private String channelCode; - @Schema(title = "商户订单编号") + @Schema(description = "商户订单编号") private String merchantOrderId; - @Schema(title = "商品标题") + @Schema(description = "商品标题") private String subject; - @Schema(title = "商品描述") + @Schema(description = "商品描述") private String body; - @Schema(title = "异步通知地址") + @Schema(description = "异步通知地址") private String notifyUrl; - @Schema(title = "通知商户支付结果的回调状态") + @Schema(description = "通知商户支付结果的回调状态") private Integer notifyStatus; - @Schema(title = "支付金额,单位:分") + @Schema(description = "支付金额,单位:分") private Long amount; - @Schema(title = "渠道手续费,单位:百分比") + @Schema(description = "渠道手续费,单位:百分比") private Double channelFeeRate; - @Schema(title = "渠道手续金额,单位:分") + @Schema(description = "渠道手续金额,单位:分") private Long channelFeeAmount; - @Schema(title = "支付状态") + @Schema(description = "支付状态") private Integer status; - @Schema(title = "用户 IP") + @Schema(description = "用户 IP") private String userIp; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "订单失效时间") + @Schema(description = "订单失效时间") private LocalDateTime[] expireTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "开始订单支付成功时间") + @Schema(description = "开始订单支付成功时间") private LocalDateTime[] successTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "开始订单支付通知时间") + @Schema(description = "开始订单支付通知时间") private LocalDateTime[] notifyTime; - @Schema(title = "支付成功的订单拓展单编号") + @Schema(description = "支付成功的订单拓展单编号") private Long successExtensionId; - @Schema(title = "退款状态") + @Schema(description = "退款状态") private Integer refundStatus; - @Schema(title = "退款次数") + @Schema(description = "退款次数") private Integer refundTimes; - @Schema(title = "退款总金额,单位:分") + @Schema(description = "退款总金额,单位:分") private Long refundAmount; - @Schema(title = "渠道用户编号") + @Schema(description = "渠道用户编号") private String channelUserId; - @Schema(title = "渠道订单号") + @Schema(description = "渠道订单号") private String channelOrderNo; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java index 795d2f804..8ca5f2162 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java @@ -7,28 +7,28 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 支付订单分页 Request VO") +@Schema(description = "管理后台 - 支付订单分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayOrderPageItemRespVO extends PayOrderBaseVO { - @Schema(title = "支付订单编号", required = true) + @Schema(description = "支付订单编号", required = true) private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; - @Schema(title = "商户名称") + @Schema(description = "商户名称") private String merchantName; - @Schema(title = "应用名称") + @Schema(description = "应用名称") private String appName; - @Schema(title = "渠道名称") + @Schema(description = "渠道名称") private String channelCodeName; - @Schema(title = "支付订单号") + @Schema(description = "支付订单号") private String no; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java index 61d0ab250..2ca72f9fc 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java @@ -11,86 +11,86 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 支付订单分页 Request VO") +@Schema(description = "管理后台 - 支付订单分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayOrderPageReqVO extends PageParam { - @Schema(title = "商户编号") + @Schema(description = "商户编号") private Long merchantId; - @Schema(title = "应用编号") + @Schema(description = "应用编号") private Long appId; - @Schema(title = "渠道编号") + @Schema(description = "渠道编号") private Long channelId; - @Schema(title = "渠道编码") + @Schema(description = "渠道编码") private String channelCode; - @Schema(title = "商户订单编号") + @Schema(description = "商户订单编号") private String merchantOrderId; - @Schema(title = "商品标题") + @Schema(description = "商品标题") private String subject; - @Schema(title = "商品描述") + @Schema(description = "商品描述") private String body; - @Schema(title = "异步通知地址") + @Schema(description = "异步通知地址") private String notifyUrl; - @Schema(title = "通知商户支付结果的回调状态") + @Schema(description = "通知商户支付结果的回调状态") private Integer notifyStatus; - @Schema(title = "支付金额,单位:分") + @Schema(description = "支付金额,单位:分") private Long amount; - @Schema(title = "渠道手续费,单位:百分比") + @Schema(description = "渠道手续费,单位:百分比") private Double channelFeeRate; - @Schema(title = "渠道手续金额,单位:分") + @Schema(description = "渠道手续金额,单位:分") private Long channelFeeAmount; - @Schema(title = "支付状态") + @Schema(description = "支付状态") private Integer status; - @Schema(title = "用户 IP") + @Schema(description = "用户 IP") private String userIp; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "订单失效时间") + @Schema(description = "订单失效时间") private LocalDateTime[] expireTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "订单支付成功时间") + @Schema(description = "订单支付成功时间") private LocalDateTime[] successTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "订单支付通知时间") + @Schema(description = "订单支付通知时间") private LocalDateTime[] notifyTime; - @Schema(title = "支付成功的订单拓展单编号") + @Schema(description = "支付成功的订单拓展单编号") private Long successExtensionId; - @Schema(title = "退款状态") + @Schema(description = "退款状态") private Integer refundStatus; - @Schema(title = "退款次数") + @Schema(description = "退款次数") private Integer refundTimes; - @Schema(title = "退款总金额,单位:分") + @Schema(description = "退款总金额,单位:分") private Long refundAmount; - @Schema(title = "渠道用户编号") + @Schema(description = "渠道用户编号") private String channelUserId; - @Schema(title = "渠道订单号") + @Schema(description = "渠道订单号") private String channelOrderNo; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java index 09c71e055..57794982d 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 支付订单 Response VO") +@Schema(description = "管理后台 - 支付订单 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayOrderRespVO extends PayOrderBaseVO { - @Schema(title = "支付订单编号", required = true) + @Schema(description = "支付订单编号", required = true) private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java index 5df3ffa06..54ac525d5 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java @@ -15,94 +15,94 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class PayRefundBaseVO { - @Schema(title = "商户编号", required = true) + @Schema(description = "商户编号", required = true) @NotNull(message = "商户编号不能为空") private Long merchantId; - @Schema(title = "应用编号", required = true) + @Schema(description = "应用编号", required = true) @NotNull(message = "应用编号不能为空") private Long appId; - @Schema(title = "渠道编号", required = true) + @Schema(description = "渠道编号", required = true) @NotNull(message = "渠道编号不能为空") private Long channelId; - @Schema(title = "渠道编码", required = true) + @Schema(description = "渠道编码", required = true) @NotNull(message = "渠道编码不能为空") private String channelCode; - @Schema(title = "支付订单编号 pay_order 表id", required = true) + @Schema(description = "支付订单编号 pay_order 表id", required = true) @NotNull(message = "支付订单编号 pay_order 表id不能为空") private Long orderId; - @Schema(title = "交易订单号 pay_extension 表no 字段", required = true) + @Schema(description = "交易订单号 pay_extension 表no 字段", required = true) @NotNull(message = "交易订单号 pay_extension 表no 字段不能为空") private String tradeNo; - @Schema(title = "商户订单编号(商户系统生成)", required = true) + @Schema(description = "商户订单编号(商户系统生成)", required = true) @NotNull(message = "商户订单编号(商户系统生成)不能为空") private String merchantOrderId; - @Schema(title = "商户退款订单号(商户系统生成)", required = true) + @Schema(description = "商户退款订单号(商户系统生成)", required = true) @NotNull(message = "商户退款订单号(商户系统生成)不能为空") private String merchantRefundNo; - @Schema(title = "异步通知商户地址", required = true) + @Schema(description = "异步通知商户地址", required = true) @NotNull(message = "异步通知商户地址不能为空") private String notifyUrl; - @Schema(title = "通知商户退款结果的回调状态", required = true) + @Schema(description = "通知商户退款结果的回调状态", required = true) @NotNull(message = "通知商户退款结果的回调状态不能为空") private Integer notifyStatus; - @Schema(title = "退款状态", required = true) + @Schema(description = "退款状态", required = true) @NotNull(message = "退款状态不能为空") private Integer status; - @Schema(title = "退款类型(部分退款,全部退款)", required = true) + @Schema(description = "退款类型(部分退款,全部退款)", required = true) @NotNull(message = "退款类型(部分退款,全部退款)不能为空") private Integer type; - @Schema(title = "支付金额,单位分", required = true) + @Schema(description = "支付金额,单位分", required = true) @NotNull(message = "支付金额,单位分不能为空") private Long payAmount; - @Schema(title = "退款金额,单位分", required = true) + @Schema(description = "退款金额,单位分", required = true) @NotNull(message = "退款金额,单位分不能为空") private Long refundAmount; - @Schema(title = "退款原因", required = true) + @Schema(description = "退款原因", required = true) @NotNull(message = "退款原因不能为空") private String reason; - @Schema(title = "用户 IP") + @Schema(description = "用户 IP") private String userIp; - @Schema(title = "渠道订单号,pay_order 中的channel_order_no 对应", required = true) + @Schema(description = "渠道订单号,pay_order 中的channel_order_no 对应", required = true) @NotNull(message = "渠道订单号,pay_order 中的channel_order_no 对应不能为空") private String channelOrderNo; - @Schema(title = "渠道退款单号,渠道返回") + @Schema(description = "渠道退款单号,渠道返回") private String channelRefundNo; - @Schema(title = "渠道调用报错时,错误码") + @Schema(description = "渠道调用报错时,错误码") private String channelErrorCode; - @Schema(title = "渠道调用报错时,错误信息") + @Schema(description = "渠道调用报错时,错误信息") private String channelErrorMsg; - @Schema(title = "支付渠道的额外参数") + @Schema(description = "支付渠道的额外参数") private String channelExtras; - @Schema(title = "退款失效时间") + @Schema(description = "退款失效时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime expireTime; - @Schema(title = "退款成功时间") + @Schema(description = "退款成功时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime successTime; - @Schema(title = "退款通知时间") + @Schema(description = "退款通知时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime notifyTime; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java index 7f100464e..86cf94636 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - 退款订单创建 Request VO") +@Schema(description = "管理后台 - 退款订单创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java index 9ad9fbd20..a02099946 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java @@ -8,31 +8,31 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 退款订单详情 Response VO") +@Schema(description = "管理后台 - 退款订单详情 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayRefundDetailsRespVO extends PayRefundBaseVO { - @Schema(title = "支付退款编号", required = true) + @Schema(description = "支付退款编号", required = true) private Long id; - @Schema(title = "商户名称") + @Schema(description = "商户名称") private String merchantName; - @Schema(title = "应用名称") + @Schema(description = "应用名称") private String appName; - @Schema(title = "渠道编号名称") + @Schema(description = "渠道编号名称") private String channelCodeName; @NotNull(message = "商品标题不能为空") private String subject; - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime createTime; - @Schema(title = "更新时间") + @Schema(description = "更新时间") private LocalDateTime updateTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java index bb1a25f91..bc7d7946b 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java @@ -8,87 +8,87 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 退款订单 Excel 导出 Request VO", description = "参数和 PayRefundPageReqVO 是一致的") +@Schema(description = "管理后台 - 退款订单 Excel 导出 Request VO,参数和 PayRefundPageReqVO 是一致的") @Data public class PayRefundExportReqVO { - @Schema(title = "商户编号") + @Schema(description = "商户编号") private Long merchantId; - @Schema(title = "应用编号") + @Schema(description = "应用编号") private Long appId; - @Schema(title = "渠道编号") + @Schema(description = "渠道编号") private Long channelId; - @Schema(title = "渠道编码") + @Schema(description = "渠道编码") private String channelCode; - @Schema(title = "支付订单编号 pay_order 表id") + @Schema(description = "支付订单编号 pay_order 表id") private Long orderId; - @Schema(title = "交易订单号 pay_extension 表no 字段") + @Schema(description = "交易订单号 pay_extension 表no 字段") private String tradeNo; - @Schema(title = "商户订单编号(商户系统生成)") + @Schema(description = "商户订单编号(商户系统生成)") private String merchantOrderId; - @Schema(title = "商户退款订单号(商户系统生成)") + @Schema(description = "商户退款订单号(商户系统生成)") private String merchantRefundNo; - @Schema(title = "异步通知商户地址") + @Schema(description = "异步通知商户地址") private String notifyUrl; - @Schema(title = "通知商户退款结果的回调状态") + @Schema(description = "通知商户退款结果的回调状态") private Integer notifyStatus; - @Schema(title = "退款状态") + @Schema(description = "退款状态") private Integer status; - @Schema(title = "退款类型(部分退款,全部退款)") + @Schema(description = "退款类型(部分退款,全部退款)") private Integer type; - @Schema(title = "支付金额,单位分") + @Schema(description = "支付金额,单位分") private Long payAmount; - @Schema(title = "退款金额,单位分") + @Schema(description = "退款金额,单位分") private Long refundAmount; - @Schema(title = "退款原因") + @Schema(description = "退款原因") private String reason; - @Schema(title = "用户 IP") + @Schema(description = "用户 IP") private String userIp; - @Schema(title = "渠道订单号,pay_order 中的channel_order_no 对应") + @Schema(description = "渠道订单号,pay_order 中的channel_order_no 对应") private String channelOrderNo; - @Schema(title = "渠道退款单号,渠道返回") + @Schema(description = "渠道退款单号,渠道返回") private String channelRefundNo; - @Schema(title = "渠道调用报错时,错误码") + @Schema(description = "渠道调用报错时,错误码") private String channelErrorCode; - @Schema(title = "渠道调用报错时,错误信息") + @Schema(description = "渠道调用报错时,错误信息") private String channelErrorMsg; - @Schema(title = "支付渠道的额外参数") + @Schema(description = "支付渠道的额外参数") private String channelExtras; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "退款失效时间") + @Schema(description = "退款失效时间") private LocalDateTime[] expireTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "退款成功时间") + @Schema(description = "退款成功时间") private LocalDateTime[] successTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "退款通知时间") + @Schema(description = "退款通知时间") private LocalDateTime[] notifyTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java index 192a11c44..df2d0aadd 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java @@ -7,25 +7,25 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 退款订单分页查询 Response VO") +@Schema(description = "管理后台 - 退款订单分页查询 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayRefundPageItemRespVO extends PayRefundBaseVO { - @Schema(title = "支付订单编号", required = true) + @Schema(description = "支付订单编号", required = true) private Long id; - @Schema(title = "商户名称") + @Schema(description = "商户名称") private String merchantName; - @Schema(title = "应用名称") + @Schema(description = "应用名称") private String appName; - @Schema(title = "渠道名称") + @Schema(description = "渠道名称") private String channelCodeName; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java index c126cfe0f..49d87f645 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java @@ -11,89 +11,89 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 退款订单分页 Request VO") +@Schema(description = "管理后台 - 退款订单分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayRefundPageReqVO extends PageParam { - @Schema(title = "商户编号") + @Schema(description = "商户编号") private Long merchantId; - @Schema(title = "应用编号") + @Schema(description = "应用编号") private Long appId; - @Schema(title = "渠道编号") + @Schema(description = "渠道编号") private Long channelId; - @Schema(title = "渠道编码") + @Schema(description = "渠道编码") private String channelCode; - @Schema(title = "支付订单编号 pay_order 表id") + @Schema(description = "支付订单编号 pay_order 表id") private Long orderId; - @Schema(title = "交易订单号 pay_extension 表no 字段") + @Schema(description = "交易订单号 pay_extension 表no 字段") private String tradeNo; - @Schema(title = "商户订单编号(商户系统生成)") + @Schema(description = "商户订单编号(商户系统生成)") private String merchantOrderId; - @Schema(title = "商户退款订单号(商户系统生成)") + @Schema(description = "商户退款订单号(商户系统生成)") private String merchantRefundNo; - @Schema(title = "异步通知商户地址") + @Schema(description = "异步通知商户地址") private String notifyUrl; - @Schema(title = "通知商户退款结果的回调状态") + @Schema(description = "通知商户退款结果的回调状态") private Integer notifyStatus; - @Schema(title = "退款状态") + @Schema(description = "退款状态") private Integer status; - @Schema(title = "退款类型(部分退款,全部退款)") + @Schema(description = "退款类型(部分退款,全部退款)") private Integer type; - @Schema(title = "支付金额,单位分") + @Schema(description = "支付金额,单位分") private Long payAmount; - @Schema(title = "退款金额,单位分") + @Schema(description = "退款金额,单位分") private Long refundAmount; - @Schema(title = "退款原因") + @Schema(description = "退款原因") private String reason; - @Schema(title = "用户 IP") + @Schema(description = "用户 IP") private String userIp; - @Schema(title = "渠道订单号,pay_order 中的channel_order_no 对应") + @Schema(description = "渠道订单号,pay_order 中的channel_order_no 对应") private String channelOrderNo; - @Schema(title = "渠道退款单号,渠道返回") + @Schema(description = "渠道退款单号,渠道返回") private String channelRefundNo; - @Schema(title = "渠道调用报错时,错误码") + @Schema(description = "渠道调用报错时,错误码") private String channelErrorCode; - @Schema(title = "渠道调用报错时,错误信息") + @Schema(description = "渠道调用报错时,错误信息") private String channelErrorMsg; - @Schema(title = "支付渠道的额外参数") + @Schema(description = "支付渠道的额外参数") private String channelExtras; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "退款失效时间") + @Schema(description = "退款失效时间") private LocalDateTime[] expireTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "退款成功时间") + @Schema(description = "退款成功时间") private LocalDateTime[] successTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "退款通知时间") + @Schema(description = "退款通知时间") private LocalDateTime[] notifyTime; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java index 6f040aafc..1374074e8 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 退款订单 Response VO") +@Schema(description = "管理后台 - 退款订单 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayRefundRespVO extends PayRefundBaseVO { - @Schema(title = "支付退款编号", required = true) + @Schema(description = "支付退款编号", required = true) private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java index 1cb8c7506..bb28fe2d0 100755 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java @@ -3,13 +3,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 退款订单更新 Request VO") +@Schema(description = "管理后台 - 退款订单更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class PayRefundUpdateReqVO extends PayRefundBaseVO { - @Schema(title = "支付退款编号", required = true) + @Schema(description = "支付退款编号", required = true) @NotNull(message = "支付退款编号不能为空") private Long id; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java index e2275f6e4..38f19c735 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java @@ -8,20 +8,20 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.Map; -@Schema(title = "用户 APP - 支付订单提交 Request VO") +@Schema(description = "用户 APP - 支付订单提交 Request VO") @Data @Accessors(chain = true) public class AppPayOrderSubmitReqVO { - @Schema(title = "支付单编号", required = true, example = "1024") + @Schema(description = "支付单编号", required = true, example = "1024") @NotNull(message = "支付单编号不能为空") private Long id; - @Schema(title = "支付渠道", required = true, example = "wx_pub") + @Schema(description = "支付渠道", required = true, example = "wx_pub") @NotEmpty(message = "支付渠道不能为空") private String channelCode; - @Schema(title = "支付渠道的额外参数", description = "例如说,微信公众号需要传递 openid 参数") + @Schema(description = "支付渠道的额外参数,例如说,微信公众号需要传递 openid 参数") private Map channelExtras; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java index ee33ef6ac..1eb4a852d 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java @@ -7,7 +7,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -@Schema(title = "用户 APP - 支付订单提交 Response VO") +@Schema(description = "用户 APP - 支付订单提交 Response VO") @Data @Accessors(chain = true) @Builder diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java index 6ea1528f1..09c31dae6 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java @@ -8,25 +8,25 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "用户 APP - 退款订单 Req VO") +@Schema(description = "用户 APP - 退款订单 Req VO") @Data @NoArgsConstructor @AllArgsConstructor public class AppPayRefundReqVO { - @Schema(title = "支付订单编号自增", required = true, example = "10") + @Schema(description = "支付订单编号自增", required = true, example = "10") @NotNull(message = "支付订单编号自增") private Long payOrderId; - @Schema(title = "退款金额", required = true, example = "1") + @Schema(description = "退款金额", required = true, example = "1") @NotNull(message = "退款金额") private Long amount; - @Schema(title = "退款原因", required = true, example = "不喜欢") + @Schema(description = "退款原因", required = true, example = "不喜欢") @NotEmpty(message = "退款原因") private String reason; - @Schema(title = "商户退款订单号", required = true, example = "MR202111180000000001") + @Schema(description = "商户退款订单号", required = true, example = "MR202111180000000001") //TODO 测试暂时模拟生成 //@NotEmpty(message = "商户退款订单号") private String merchantRefundId; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java index 21466c05d..3d2d65e53 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java @@ -7,7 +7,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -@Schema(title = "用户 APP - 提交退款订单 Response VO") +@Schema(description = "用户 APP - 提交退款订单 Response VO") @Data @Accessors(chain = true) @Builder @@ -15,7 +15,7 @@ import lombok.experimental.Accessors; @AllArgsConstructor public class AppPayRefundRespVO { - @Schema(title = "退款订单编号", required = true, example = "10") + @Schema(description = "退款订单编号", required = true, example = "10") private Long refundId; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java index c9e753c67..220a807f4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java @@ -9,18 +9,18 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "支付单的通知 Request VO", description = "业务方接入支付回调时,使用该 VO 对象") +@Schema(description = "支付单的通知 Request VO,业务方接入支付回调时,使用该 VO 对象") @Data @Builder @NoArgsConstructor @AllArgsConstructor public class PayNotifyOrderReqVO { - @Schema(title = "商户订单编号", required = true, example = "10") + @Schema(description = "商户订单编号", required = true, example = "10") @NotEmpty(message = "商户订单号不能为空") private String merchantOrderId; - @Schema(title = "支付订单编号", required = true, example = "20") + @Schema(description = "支付订单编号", required = true, example = "20") @NotNull(message = "支付订单编号不能为空") private Long payOrderId; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java index ab7d6ea03..7694d8403 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java @@ -9,22 +9,22 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "退款单的通知 Request VO", description = "业务方接入退款回调时,使用该 VO 对象") +@Schema(description = "退款单的通知 Request VO,业务方接入退款回调时,使用该 VO 对象") @Data @Builder @NoArgsConstructor @AllArgsConstructor public class PayRefundOrderReqVO { - @Schema(title = "商户退款单编号", required = true, example = "10") + @Schema(description = "商户退款单编号", required = true, example = "10") @NotEmpty(message = "商户退款单编号不能为空") private String merchantOrderId; - @Schema(title = "支付退款编号", required = true, example = "20") + @Schema(description = "支付退款编号", required = true, example = "20") @NotNull(message = "支付退款编号不能为空") private Long payRefundId; - @Schema(title = "退款状态(成功,失败)", required = true, example = "10") + @Schema(description = "退款状态(成功,失败)", required = true, example = "10") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java index 2f8ab7f36..757e7aef5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java @@ -14,42 +14,41 @@ import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; -@Schema(title = "管理后台 - 账号密码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") +@Schema(description = "管理后台 - 账号密码登录 Request VO,如果登录并绑定社交用户,需要传递 social 开头的参数") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthLoginReqVO { - @Schema(title = "账号", required = true, example = "yudaoyuanma") + @Schema(description = "账号", required = true, example = "yudaoyuanma") @NotEmpty(message = "登录账号不能为空") @Length(min = 4, max = 16, message = "账号长度为 4-16 位") @Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母") private String username; - @Schema(title = "密码", required = true, example = "buzhidao") + @Schema(description = "密码", required = true, example = "buzhidao") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; // ========== 图片验证码相关 ========== - @Schema(title = "验证码", required = true, - example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==", - description = "验证码开启时,需要传递") + @Schema(description = "验证码,验证码开启时,需要传递", required = true, + example = "PfcH6mgr8tpXuMWFjvW6YVaqrswIuwmWI5dsVZSg7sGpWtDCUbHuDEXl3cFB1+VvCC/rAkSwK8Fad52FSuncVg==") @NotEmpty(message = "验证码不能为空", groups = CodeEnableGroup.class) private String captchaVerification; // ========== 绑定社交登录时,需要传递如下参数 ========== - @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SysUserSocialTypeEnum 枚举值") + @Schema(description = "社交平台的类型,参见 SysUserSocialTypeEnum 枚举值", required = true, example = "10") @InEnum(SocialTypeEnum.class) private Integer socialType; - @Schema(title = "授权码", required = true, example = "1024") + @Schema(description = "授权码", required = true, example = "1024") private String socialCode; - @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(description = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") private String socialState; /** diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginRespVO.java index 2faf84567..79f745208 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginRespVO.java @@ -8,23 +8,23 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 登录 Response VO") +@Schema(description = "管理后台 - 登录 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthLoginRespVO { - @Schema(title = "用户编号", required = true, example = "1024") + @Schema(description = "用户编号", required = true, example = "1024") private Long userId; - @Schema(title = "访问令牌", required = true, example = "happy") + @Schema(description = "访问令牌", required = true, example = "happy") private String accessToken; - @Schema(title = "刷新令牌", required = true, example = "nice") + @Schema(description = "刷新令牌", required = true, example = "nice") private String refreshToken; - @Schema(title = "过期时间", required = true) + @Schema(description = "过期时间", required = true) private LocalDateTime expiresTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthMenuRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthMenuRespVO.java index 9af118f70..58948178f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthMenuRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthMenuRespVO.java @@ -8,35 +8,35 @@ import lombok.NoArgsConstructor; import java.util.List; -@Schema(title = "管理后台 - 登录用户的菜单信息 Response VO") +@Schema(description = "管理后台 - 登录用户的菜单信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthMenuRespVO { - @Schema(title = "菜单名称", required = true, example = "芋道") + @Schema(description = "菜单名称", required = true, example = "芋道") private Long id; - @Schema(title = "父菜单 ID", required = true, example = "1024") + @Schema(description = "父菜单 ID", required = true, example = "1024") private Long parentId; - @Schema(title = "菜单名称", required = true, example = "芋道") + @Schema(description = "菜单名称", required = true, example = "芋道") private String name; - @Schema(title = "路由地址", example = "post", description = "仅菜单类型为菜单或者目录时,才需要传") + @Schema(description = "路由地址,仅菜单类型为菜单或者目录时,才需要传", example = "post") private String path; - @Schema(title = "组件路径", example = "system/post/index", description = "仅菜单类型为菜单时,才需要传") + @Schema(description = "组件路径,仅菜单类型为菜单时,才需要传", example = "system/post/index") private String component; - @Schema(title = "菜单图标", example = "/menu/list", description = "仅菜单类型为菜单或者目录时,才需要传") + @Schema(description = "菜单图标,仅菜单类型为菜单或者目录时,才需要传", example = "/menu/list") private String icon; - @Schema(title = "是否可见", required = true, example = "false") + @Schema(description = "是否可见", required = true, example = "false") private Boolean visible; - @Schema(title = "是否缓存", required = true, example = "false") + @Schema(description = "是否缓存", required = true, example = "false") private Boolean keepAlive; /** diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java index cfe8725b0..957ca4b47 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthPermissionInfoRespVO.java @@ -8,36 +8,36 @@ import lombok.NoArgsConstructor; import java.util.Set; -@Schema(title = "管理后台 - 登录用户的权限信息 Response VO", description = "额外包括用户信息和角色列表") +@Schema(description = "管理后台 - 登录用户的权限信息 Response VO,额外包括用户信息和角色列表") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthPermissionInfoRespVO { - @Schema(title = "用户信息", required = true) + @Schema(description = "用户信息", required = true) private UserVO user; - @Schema(title = "角色标识数组", required = true) + @Schema(description = "角色标识数组", required = true) private Set roles; - @Schema(title = "操作权限数组", required = true) + @Schema(description = "操作权限数组", required = true) private Set permissions; - @Schema(title = "用户信息 VO") + @Schema(description = "用户信息 VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public static class UserVO { - @Schema(title = "用户编号", required = true, example = "1024") + @Schema(description = "用户编号", required = true, example = "1024") private Long id; - @Schema(title = "用户昵称", required = true, example = "芋道源码") + @Schema(description = "用户昵称", required = true, example = "芋道源码") private String nickname; - @Schema(title = "用户头像", required = true, example = "http://www.iocoder.cn/xx.jpg") + @Schema(description = "用户头像", required = true, example = "http://www.iocoder.cn/xx.jpg") private String avatar; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsLoginReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsLoginReqVO.java index 61e084254..5245b2f05 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsLoginReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsLoginReqVO.java @@ -9,19 +9,19 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; -@Schema(title = "管理后台 - 短信验证码的登录 Request VO") +@Schema(description = "管理后台 - 短信验证码的登录 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthSmsLoginReqVO { - @Schema(title = "手机号", required = true, example = "yudaoyuanma") + @Schema(description = "手机号", required = true, example = "yudaoyuanma") @NotEmpty(message = "手机号不能为空") @Mobile private String mobile; - @Schema(title = "短信验证码", required = true, example = "1024") + @Schema(description = "短信验证码", required = true, example = "1024") @NotEmpty(message = "验证码不能为空") private String code; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsSendReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsSendReqVO.java index 89b4cb97d..0f8ce8343 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsSendReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSmsSendReqVO.java @@ -12,19 +12,19 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 发送手机验证码 Request VO") +@Schema(description = "管理后台 - 发送手机验证码 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthSmsSendReqVO { - @Schema(title = "手机号", required = true, example = "yudaoyuanma") + @Schema(description = "手机号", required = true, example = "yudaoyuanma") @NotEmpty(message = "手机号不能为空") @Mobile private String mobile; - @Schema(title = "短信场景", required = true, example = "1") + @Schema(description = "短信场景", required = true, example = "1") @NotNull(message = "发送场景不能为空") @InEnum(SmsSceneEnum.class) private Integer scene; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSocialLoginReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSocialLoginReqVO.java index 10648edd3..9de058c12 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSocialLoginReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthSocialLoginReqVO.java @@ -11,23 +11,23 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 社交绑定登录 Request VO,使用 code 授权码 + 账号密码") +@Schema(description = "管理后台 - 社交绑定登录 Request VO,使用 code 授权码 + 账号密码") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class AuthSocialLoginReqVO { - @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 UserSocialTypeEnum 枚举值") + @Schema(description = "社交平台的类型,参见 UserSocialTypeEnum 枚举值", required = true, example = "10") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @Schema(title = "授权码", required = true, example = "1024") + @Schema(description = "授权码", required = true, example = "1024") @NotEmpty(message = "授权码不能为空") private String code; - @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(description = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") @NotEmpty(message = "state 不能为空") private String state; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptBaseVO.java index c07c45ffc..25f32c21a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptBaseVO.java @@ -14,31 +14,31 @@ import javax.validation.constraints.Size; @Data public class DeptBaseVO { - @Schema(title = "菜单名称", required = true, example = "芋道") + @Schema(description = "菜单名称", required = true, example = "芋道") @NotBlank(message = "部门名称不能为空") @Size(max = 30, message = "部门名称长度不能超过30个字符") private String name; - @Schema(title = "父菜单 ID", example = "1024") + @Schema(description = "父菜单 ID", example = "1024") private Long parentId; - @Schema(title = "显示顺序不能为空", required = true, example = "1024") + @Schema(description = "显示顺序不能为空", required = true, example = "1024") @NotNull(message = "显示顺序不能为空") private Integer sort; - @Schema(title = "负责人的用户编号", example = "2048") + @Schema(description = "负责人的用户编号", example = "2048") private Long leaderUserId; - @Schema(title = "联系电话", example = "15601691000") + @Schema(description = "联系电话", example = "15601691000") @Size(max = 11, message = "联系电话长度不能超过11个字符") private String phone; - @Schema(title = "邮箱", example = "yudao@iocoder.cn") + @Schema(description = "邮箱", example = "yudao@iocoder.cn") @Email(message = "邮箱格式不正确") @Size(max = 50, message = "邮箱长度不能超过50个字符") private String email; - @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") + @Schema(description = "状态,见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") // @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") private Integer status; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptCreateReqVO.java index 8db5621e0..66741f6da 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptCreateReqVO.java @@ -4,7 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 部门创建 Request VO") +@Schema(description = "管理后台 - 部门创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptListReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptListReqVO.java index 75de37bf1..469dc6ac6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptListReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptListReqVO.java @@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 部门列表 Request VO") +@Schema(description = "管理后台 - 部门列表 Request VO") @Data public class DeptListReqVO { - @Schema(title = "部门名称", example = "芋道", description = "模糊匹配") + @Schema(description = "部门名称,模糊匹配", example = "芋道") private String name; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptRespVO.java index bbc55e91c..7d8933a0c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptRespVO.java @@ -6,18 +6,18 @@ import lombok.EqualsAndHashCode; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 部门信息 Response VO") +@Schema(description = "管理后台 - 部门信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) public class DeptRespVO extends DeptBaseVO { - @Schema(title = "部门编号", required = true, example = "1024") + @Schema(description = "部门编号", required = true, example = "1024") private Long id; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", required = true, example = "1") private Integer status; - @Schema(title = "创建时间", required = true, example = "时间戳格式") + @Schema(description = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptSimpleRespVO.java index ad353fdd8..582eaae51 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptSimpleRespVO.java @@ -5,19 +5,19 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@Schema(title = "管理后台 - 部门精简信息 Response VO") +@Schema(description = "管理后台 - 部门精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class DeptSimpleRespVO { - @Schema(title = "部门编号", required = true, example = "1024") + @Schema(description = "部门编号", required = true, example = "1024") private Long id; - @Schema(title = "部门名称", required = true, example = "芋道") + @Schema(description = "部门名称", required = true, example = "芋道") private String name; - @Schema(title = "父部门 ID", required = true, example = "1024") + @Schema(description = "父部门 ID", required = true, example = "1024") private Long parentId; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptUpdateReqVO.java index ec40b6e7b..18d002438 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptUpdateReqVO.java @@ -6,12 +6,12 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 部门更新 Request VO") +@Schema(description = "管理后台 - 部门更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DeptUpdateReqVO extends DeptBaseVO { - @Schema(title = "部门编号", required = true, example = "1024") + @Schema(description = "部门编号", required = true, example = "1024") @NotNull(message = "部门编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostBaseVO.java index 2504f21e5..df3f10ec5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostBaseVO.java @@ -13,24 +13,24 @@ import javax.validation.constraints.Size; @Data public class PostBaseVO { - @Schema(title = "岗位名称", required = true, example = "小博主") + @Schema(description = "岗位名称", required = true, example = "小博主") @NotBlank(message = "岗位名称不能为空") @Size(max = 50, message = "岗位名称长度不能超过50个字符") private String name; - @Schema(title = "岗位编码", required = true, example = "yudao") + @Schema(description = "岗位编码", required = true, example = "yudao") @NotBlank(message = "岗位编码不能为空") @Size(max = 64, message = "岗位编码长度不能超过64个字符") private String code; - @Schema(title = "显示顺序不能为空", required = true, example = "1024") + @Schema(description = "显示顺序不能为空", required = true, example = "1024") @NotNull(message = "显示顺序不能为空") private Integer sort; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", required = true, example = "1") private Integer status; - @Schema(title = "备注", example = "快乐的备注") + @Schema(description = "备注", example = "快乐的备注") private String remark; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostCreateReqVO.java index 807454840..b2e52e174 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostCreateReqVO.java @@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@Schema(title = "管理后台 - 岗位创建 Request VO") +@Schema(description = "管理后台 - 岗位创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class PostCreateReqVO extends PostBaseVO { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostExportReqVO.java index 9e349ce12..8b7cc79a3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostExportReqVO.java @@ -3,17 +3,17 @@ package cn.iocoder.yudao.module.system.controller.admin.dept.vo.post; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 岗位导出 Request VO", description = "参数和 PostExcelVO 是一致的") +@Schema(description = "管理后台 - 岗位导出 Request VO,参数和 PostExcelVO 是一致的") @Data public class PostExportReqVO { - @Schema(title = "岗位编码", example = "yudao", description = "模糊匹配") + @Schema(description = "岗位编码,模糊匹配", example = "yudao") private String code; - @Schema(title = "岗位名称", example = "芋道", description = "模糊匹配") + @Schema(description = "岗位名称,模糊匹配", example = "芋道") private String name; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostListReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostListReqVO.java index 2450c39ee..abb166132 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostListReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostListReqVO.java @@ -4,15 +4,15 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@Schema(title = "管理后台 - 岗位列表 Request VO") +@Schema(description = "管理后台 - 岗位列表 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class PostListReqVO extends PostBaseVO { - @Schema(title = "岗位名称", example = "芋道", description = "模糊匹配") + @Schema(description = "岗位名称,模糊匹配", example = "芋道") private String name; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostPageReqVO.java index 3a027ea29..0806725f5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostPageReqVO.java @@ -5,18 +5,18 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@Schema(title = "管理后台 - 岗位分页 Request VO") +@Schema(description = "管理后台 - 岗位分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class PostPageReqVO extends PageParam { - @Schema(title = "岗位编码", example = "yudao", description = "模糊匹配") + @Schema(description = "岗位编码,模糊匹配", example = "yudao") private String code; - @Schema(title = "岗位名称", example = "芋道", description = "模糊匹配") + @Schema(description = "岗位名称,模糊匹配", example = "芋道") private String name; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostRespVO.java index acd66af5e..807abadeb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostRespVO.java @@ -6,15 +6,15 @@ import lombok.EqualsAndHashCode; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 岗位信息 Response VO") +@Schema(description = "管理后台 - 岗位信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) public class PostRespVO extends PostBaseVO { - @Schema(title = "岗位序号", required = true, example = "1024") + @Schema(description = "岗位序号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true, example = "时间戳格式") + @Schema(description = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostSimpleRespVO.java index b94398007..eeb613b40 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostSimpleRespVO.java @@ -5,16 +5,16 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@Schema(title = "管理后台 - 岗位精简信息 Response VO") +@Schema(description = "管理后台 - 岗位精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class PostSimpleRespVO { - @Schema(title = "岗位编号", required = true, example = "1024") + @Schema(description = "岗位编号", required = true, example = "1024") private Long id; - @Schema(title = "岗位名称", required = true, example = "芋道") + @Schema(description = "岗位名称", required = true, example = "芋道") private String name; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostUpdateReqVO.java index d32c8e8fa..e78c8160f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/post/PostUpdateReqVO.java @@ -6,12 +6,12 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 岗位更新 Request VO") +@Schema(description = "管理后台 - 岗位更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class PostUpdateReqVO extends PostBaseVO { - @Schema(title = "岗位编号", required = true, example = "1024") + @Schema(description = "岗位编号", required = true, example = "1024") @NotNull(message = "岗位编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataBaseVO.java index 79c32b9a8..90b5b9fea 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataBaseVO.java @@ -14,36 +14,36 @@ import javax.validation.constraints.Size; @Data public class DictDataBaseVO { - @Schema(title = "显示顺序不能为空", required = true, example = "1024") + @Schema(description = "显示顺序不能为空", required = true, example = "1024") @NotNull(message = "显示顺序不能为空") private Integer sort; - @Schema(title = "字典标签", required = true, example = "芋道") + @Schema(description = "字典标签", required = true, example = "芋道") @NotBlank(message = "字典标签不能为空") @Size(max = 100, message = "字典标签长度不能超过100个字符") private String label; - @Schema(title = "字典值", required = true, example = "iocoder") + @Schema(description = "字典值", required = true, example = "iocoder") @NotBlank(message = "字典键值不能为空") @Size(max = 100, message = "字典键值长度不能超过100个字符") private String value; - @Schema(title = "字典类型", required = true, example = "sys_common_sex") + @Schema(description = "字典类型", required = true, example = "sys_common_sex") @NotBlank(message = "字典类型不能为空") @Size(max = 100, message = "字典类型长度不能超过100个字符") private String dictType; - @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") + @Schema(description = "状态,见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") // @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") private Integer status; - @Schema(title = "颜色类型", example = "default", description = "default、primary、success、info、warning、danger") + @Schema(description = "颜色类型,default、primary、success、info、warning、danger", example = "default") private String colorType; - @Schema(title = "css 样式", example = "btn-visible") + @Schema(description = "css 样式", example = "btn-visible") private String cssClass; - @Schema(title = "备注", example = "我是一个角色") + @Schema(description = "备注", example = "我是一个角色") private String remark; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataCreateReqVO.java index b4fe37ba9..6f225eba4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataCreateReqVO.java @@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@Schema(title = "管理后台 - 字典数据创建 Request VO") +@Schema(description = "管理后台 - 字典数据创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictDataCreateReqVO extends DictDataBaseVO { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataExportReqVO.java index 94f1a4ffb..60e91db19 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataExportReqVO.java @@ -5,19 +5,19 @@ import lombok.Data; import javax.validation.constraints.Size; -@Schema(title = "管理后台 - 字典类型导出 Request VO") +@Schema(description = "管理后台 - 字典类型导出 Request VO") @Data public class DictDataExportReqVO { - @Schema(title = "字典标签", example = "芋道") + @Schema(description = "字典标签", example = "芋道") @Size(max = 100, message = "字典标签长度不能超过100个字符") private String label; - @Schema(title = "字典类型", example = "sys_common_sex", description = "模糊匹配") + @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex") @Size(max = 100, message = "字典类型类型长度不能超过100个字符") private String dictType; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataPageReqVO.java index a883c8048..bceec1600 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataPageReqVO.java @@ -7,20 +7,20 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.Size; -@Schema(title = "管理后台 - 字典类型分页列表 Request VO") +@Schema(description = "管理后台 - 字典类型分页列表 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictDataPageReqVO extends PageParam { - @Schema(title = "字典标签", example = "芋道") + @Schema(description = "字典标签", example = "芋道") @Size(max = 100, message = "字典标签长度不能超过100个字符") private String label; - @Schema(title = "字典类型", example = "sys_common_sex", description = "模糊匹配") + @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex") @Size(max = 100, message = "字典类型类型长度不能超过100个字符") private String dictType; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataRespVO.java index 72cb23cf7..b3afef470 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataRespVO.java @@ -8,17 +8,17 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 字典数据信息 Response VO") +@Schema(description = "管理后台 - 字典数据信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class DictDataRespVO extends DictDataBaseVO { - @Schema(title = "字典数据编号", required = true, example = "1024") + @Schema(description = "字典数据编号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true, example = "时间戳格式") + @Schema(description = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataSimpleRespVO.java index d61458446..31256e68d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataSimpleRespVO.java @@ -3,22 +3,22 @@ package cn.iocoder.yudao.module.system.controller.admin.dict.vo.data; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 数据字典精简 Response VO") +@Schema(description = "管理后台 - 数据字典精简 Response VO") @Data public class DictDataSimpleRespVO { - @Schema(title = "字典类型", required = true, example = "gender") + @Schema(description = "字典类型", required = true, example = "gender") private String dictType; - @Schema(title = "字典键值", required = true, example = "1") + @Schema(description = "字典键值", required = true, example = "1") private String value; - @Schema(title = "字典标签", required = true, example = "男") + @Schema(description = "字典标签", required = true, example = "男") private String label; - @Schema(title = "颜色类型", example = "default", description = "default、primary、success、info、warning、danger") + @Schema(description = "颜色类型,default、primary、success、info、warning、danger", example = "default") private String colorType; - @Schema(title = "css 样式", example = "btn-visible") + @Schema(description = "css 样式", example = "btn-visible") private String cssClass; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataUpdateReqVO.java index 9481ab1b4..ddbe8d734 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/data/DictDataUpdateReqVO.java @@ -6,12 +6,12 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 字典数据更新 Request VO") +@Schema(description = "管理后台 - 字典数据更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictDataUpdateReqVO extends DictDataBaseVO { - @Schema(title = "字典数据编号", required = true, example = "1024") + @Schema(description = "字典数据编号", required = true, example = "1024") @NotNull(message = "字典数据编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeBaseVO.java index d4e28e043..876eb8842 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeBaseVO.java @@ -14,16 +14,16 @@ import javax.validation.constraints.Size; @Data public class DictTypeBaseVO { - @Schema(title = "字典名称", required = true, example = "性别") + @Schema(description = "字典名称", required = true, example = "性别") @NotBlank(message = "字典名称不能为空") @Size(max = 100, message = "字典类型名称长度不能超过100个字符") private String name; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; - @Schema(title = "备注", example = "快乐的备注") + @Schema(description = "备注", example = "快乐的备注") private String remark; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeCreateReqVO.java index f7c158503..fc91e9197 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeCreateReqVO.java @@ -7,12 +7,12 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; -@Schema(title = "管理后台 - 字典类型创建 Request VO") +@Schema(description = "管理后台 - 字典类型创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictTypeCreateReqVO extends DictTypeBaseVO { - @Schema(title = "字典类型", required = true, example = "sys_common_sex") + @Schema(description = "字典类型", required = true, example = "sys_common_sex") @NotNull(message = "字典类型不能为空") @Size(max = 100, message = "字典类型类型长度不能超过100个字符") private String type; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeExportReqVO.java index 73d7093e6..b7d227ea3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeExportReqVO.java @@ -8,21 +8,21 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 字典类型分页列表 Request VO") +@Schema(description = "管理后台 - 字典类型分页列表 Request VO") @Data public class DictTypeExportReqVO { - @Schema(title = "字典类型名称", example = "芋道", description = "模糊匹配") + @Schema(description = "字典类型名称,模糊匹配", example = "芋道") private String name; - @Schema(title = "字典类型", example = "sys_common_sex", description = "模糊匹配") + @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex") private String type; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypePageReqVO.java index 1c7b48a91..336836f89 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypePageReqVO.java @@ -11,23 +11,23 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 字典类型分页列表 Request VO") +@Schema(description = "管理后台 - 字典类型分页列表 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictTypePageReqVO extends PageParam { - @Schema(title = "字典类型名称", example = "芋道", description = "模糊匹配") + @Schema(description = "字典类型名称,模糊匹配", example = "芋道") private String name; - @Schema(title = "字典类型", example = "sys_common_sex", description = "模糊匹配") + @Schema(description = "字典类型,模糊匹配", example = "sys_common_sex") @Size(max = 100, message = "字典类型类型长度不能超过100个字符") private String type; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeRespVO.java index cb39b1acf..06aeb469b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeRespVO.java @@ -8,20 +8,20 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 字典类型信息 Response VO") +@Schema(description = "管理后台 - 字典类型信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class DictTypeRespVO extends DictTypeBaseVO { - @Schema(title = "字典类型编号", required = true, example = "1024") + @Schema(description = "字典类型编号", required = true, example = "1024") private Long id; - @Schema(title = "字典类型", required = true, example = "sys_common_sex") + @Schema(description = "字典类型", required = true, example = "sys_common_sex") private String type; - @Schema(title = "创建时间", required = true, example = "时间戳格式") + @Schema(description = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeSimpleRespVO.java index b68f5ebf1..61ca6a7c9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeSimpleRespVO.java @@ -5,19 +5,19 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@Schema(title = "管理后台 - 字典类型精简信息 Response VO") +@Schema(description = "管理后台 - 字典类型精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class DictTypeSimpleRespVO { - @Schema(title = "字典类型编号", required = true, example = "1024") + @Schema(description = "字典类型编号", required = true, example = "1024") private Long id; - @Schema(title = "字典类型名称", required = true, example = "芋道") + @Schema(description = "字典类型名称", required = true, example = "芋道") private String name; - @Schema(title = "字典类型", required = true, example = "sys_common_sex") + @Schema(description = "字典类型", required = true, example = "sys_common_sex") private String type; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeUpdateReqVO.java index 579108d23..0a3120770 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/vo/type/DictTypeUpdateReqVO.java @@ -6,12 +6,12 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 字典类型更新 Request VO") +@Schema(description = "管理后台 - 字典类型更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class DictTypeUpdateReqVO extends DictTypeBaseVO { - @Schema(title = "字典类型编号", required = true, example = "1024") + @Schema(description = "字典类型编号", required = true, example = "1024") @NotNull(message = "字典类型编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeBaseVO.java index ac5c7445f..6425e106c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeBaseVO.java @@ -12,19 +12,19 @@ import javax.validation.constraints.NotNull; @Data public class ErrorCodeBaseVO { - @Schema(title = "应用名", required = true, example = "dashboard") + @Schema(description = "应用名", required = true, example = "dashboard") @NotNull(message = "应用名不能为空") private String applicationName; - @Schema(title = "错误码编码", required = true, example = "1234") + @Schema(description = "错误码编码", required = true, example = "1234") @NotNull(message = "错误码编码不能为空") private Integer code; - @Schema(title = "错误码错误提示", required = true, example = "帅气") + @Schema(description = "错误码错误提示", required = true, example = "帅气") @NotNull(message = "错误码错误提示不能为空") private String message; - @Schema(title = "备注", example = "哈哈哈") + @Schema(description = "备注", example = "哈哈哈") private String memo; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeCreateReqVO.java index 7d85826d1..0f859dbd9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeCreateReqVO.java @@ -5,7 +5,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 错误码创建 Request VO") +@Schema(description = "管理后台 - 错误码创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeExportReqVO.java index 90f5e739a..cb2488ee8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeExportReqVO.java @@ -8,24 +8,24 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 错误码 Excel 导出 Request VO", description = "参数和 InfErrorCodePageReqVO 是一致的") +@Schema(description = "管理后台 - 错误码 Excel 导出 Request VO,参数和 InfErrorCodePageReqVO 是一致的") @Data public class ErrorCodeExportReqVO { - @Schema(title = "错误码类型", example = "1") + @Schema(description = "错误码类型", example = "1") private Integer type; - @Schema(title = "应用名", example = "dashboard") + @Schema(description = "应用名", example = "dashboard") private String applicationName; - @Schema(title = "错误码编码", example = "1234") + @Schema(description = "错误码编码", example = "1234") private Integer code; - @Schema(title = "错误码错误提示", example = "帅气") + @Schema(description = "错误码错误提示", example = "帅气") private String message; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodePageReqVO.java index baeb1e203..8e5bbdb07 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodePageReqVO.java @@ -11,26 +11,26 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 错误码分页 Request VO") +@Schema(description = "管理后台 - 错误码分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ErrorCodePageReqVO extends PageParam { - @Schema(title = "错误码类型", example = "1", description = "参见 ErrorCodeTypeEnum 枚举类") + @Schema(description = "错误码类型,参见 ErrorCodeTypeEnum 枚举类", example = "1") private Integer type; - @Schema(title = "应用名", example = "dashboard") + @Schema(description = "应用名", example = "dashboard") private String applicationName; - @Schema(title = "错误码编码", example = "1234") + @Schema(description = "错误码编码", example = "1234") private Integer code; - @Schema(title = "错误码错误提示", example = "帅气") + @Schema(description = "错误码错误提示", example = "帅气") private String message; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeRespVO.java index 35712ad76..9fe447f90 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeRespVO.java @@ -7,19 +7,19 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 错误码 Response VO") +@Schema(description = "管理后台 - 错误码 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ErrorCodeRespVO extends ErrorCodeBaseVO { - @Schema(title = "错误码编号", required = true, example = "1024") + @Schema(description = "错误码编号", required = true, example = "1024") private Long id; - @Schema(title = "错误码类型", required = true, example = "1", description = "参见 ErrorCodeTypeEnum 枚举类") + @Schema(description = "错误码类型,参见 ErrorCodeTypeEnum 枚举类", required = true, example = "1") private Integer type; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeUpdateReqVO.java index cb0bb2055..64622acd2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/errorcode/vo/ErrorCodeUpdateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 错误码更新 Request VO") +@Schema(description = "管理后台 - 错误码更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class ErrorCodeUpdateReqVO extends ErrorCodeBaseVO { - @Schema(title = "错误码编号", required = true, example = "1024") + @Schema(description = "错误码编号", required = true, example = "1024") @NotNull(message = "错误码编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogBaseVO.java index 0e749c544..d5769c597 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogBaseVO.java @@ -15,28 +15,28 @@ import javax.validation.constraints.Size; @Data public class LoginLogBaseVO { - @Schema(title = "日志类型", required = true, example = "1", description = "参见 LoginLogTypeEnum 枚举类") + @Schema(description = "日志类型,参见 LoginLogTypeEnum 枚举类", required = true, example = "1") @NotNull(message = "日志类型不能为空") private Integer logType; - @Schema(title = "链路追踪编号", example = "89aca178-a370-411c-ae02-3f0d672be4ab") + @Schema(description = "链路追踪编号", example = "89aca178-a370-411c-ae02-3f0d672be4ab") @NotEmpty(message = "链路追踪编号不能为空") private String traceId; - @Schema(title = "用户账号", required = true, example = "yudao") + @Schema(description = "用户账号", required = true, example = "yudao") @NotBlank(message = "用户账号不能为空") @Size(max = 30, message = "用户账号长度不能超过30个字符") private String username; - @Schema(title = "登录结果", required = true, example = "1", description = "参见 LoginResultEnum 枚举类") + @Schema(description = "登录结果,参见 LoginResultEnum 枚举类", required = true, example = "1") @NotNull(message = "登录结果不能为空") private Integer result; - @Schema(title = "用户 IP", required = true, example = "127.0.0.1") + @Schema(description = "用户 IP", required = true, example = "127.0.0.1") @NotEmpty(message = "用户 IP 不能为空") private String userIp; - @Schema(title = "浏览器 UserAgent", example = "Mozilla/5.0") + @Schema(description = "浏览器 UserAgent", example = "Mozilla/5.0") private String userAgent; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogExportReqVO.java index c95be8148..a62d9da23 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogExportReqVO.java @@ -8,20 +8,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 登录日志分页列表 Request VO") +@Schema(description = "管理后台 - 登录日志分页列表 Request VO") @Data public class LoginLogExportReqVO { - @Schema(title = "用户 IP", example = "127.0.0.1", description = "模拟匹配") + @Schema(description = "用户 IP,模拟匹配", example = "127.0.0.1") private String userIp; - @Schema(title = "用户账号", example = "芋道", description = "模拟匹配") + @Schema(description = "用户账号,模拟匹配", example = "芋道") private String username; - @Schema(title = "操作状态", example = "true") + @Schema(description = "操作状态", example = "true") private Boolean status; - @Schema(title = "登录时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "登录时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogPageReqVO.java index 1767fd298..73f6d38a7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogPageReqVO.java @@ -10,21 +10,21 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 登录日志分页列表 Request VO") +@Schema(description = "管理后台 - 登录日志分页列表 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class LoginLogPageReqVO extends PageParam { - @Schema(title = "用户 IP", example = "127.0.0.1", description = "模拟匹配") + @Schema(description = "用户 IP,模拟匹配", example = "127.0.0.1") private String userIp; - @Schema(title = "用户账号", example = "芋道", description = "模拟匹配") + @Schema(description = "用户账号,模拟匹配", example = "芋道") private String username; - @Schema(title = "操作状态", example = "true") + @Schema(description = "操作状态", example = "true") private Boolean status; - @Schema(title = "登录时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "登录时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogRespVO.java index 4c57e0d59..a67d871ea 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/loginlog/LoginLogRespVO.java @@ -8,23 +8,23 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 登录日志 Response VO") +@Schema(description = "管理后台 - 登录日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class LoginLogRespVO extends LoginLogBaseVO { - @Schema(title = "日志编号", required = true, example = "1024") + @Schema(description = "日志编号", required = true, example = "1024") private Long id; - @Schema(title = "用户编号", example = "666") + @Schema(description = "用户编号", example = "666") private Long userId; - @Schema(title = "用户类型", required = true, example = "2", description = "参见 UserTypeEnum 枚举") + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", required = true, example = "2") @NotNull(message = "用户类型不能为空") private Integer userType; - @Schema(title = "登录时间", required = true) + @Schema(description = "登录时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogBaseVO.java index e36da5c07..e3187b0d5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogBaseVO.java @@ -15,71 +15,71 @@ import java.util.Map; @Data public class OperateLogBaseVO { - @Schema(title = "链路追踪编号", required = true, example = "89aca178-a370-411c-ae02-3f0d672be4ab") + @Schema(description = "链路追踪编号", required = true, example = "89aca178-a370-411c-ae02-3f0d672be4ab") @NotEmpty(message = "链路追踪编号不能为空") private String traceId; - @Schema(title = "用户编号", required = true, example = "1024") + @Schema(description = "用户编号", required = true, example = "1024") @NotNull(message = "用户编号不能为空") private Long userId; - @Schema(title = "操作模块", required = true, example = "订单") + @Schema(description = "操作模块", required = true, example = "订单") @NotEmpty(message = "操作模块不能为空") private String module; - @Schema(title = "操作名", required = true, example = "创建订单") + @Schema(description = "操作名", required = true, example = "创建订单") @NotEmpty(message = "操作名") private String name; - @Schema(title = "操作分类", required = true, example = "1", description = "参见 OperateLogTypeEnum 枚举类") + @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", required = true, example = "1") @NotNull(message = "操作分类不能为空") private Integer type; - @Schema(title = "操作明细", example = "修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。") + @Schema(description = "操作明细", example = "修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。") private String content; - @Schema(title = "拓展字段", example = "{'orderId': 1}") + @Schema(description = "拓展字段", example = "{'orderId': 1}") private Map exts; - @Schema(title = "请求方法名", required = true, example = "GET") + @Schema(description = "请求方法名", required = true, example = "GET") @NotEmpty(message = "请求方法名不能为空") private String requestMethod; - @Schema(title = "请求地址", required = true, example = "/xxx/yyy") + @Schema(description = "请求地址", required = true, example = "/xxx/yyy") @NotEmpty(message = "请求地址不能为空") private String requestUrl; - @Schema(title = "用户 IP", required = true, example = "127.0.0.1") + @Schema(description = "用户 IP", required = true, example = "127.0.0.1") @NotEmpty(message = "用户 IP 不能为空") private String userIp; - @Schema(title = "浏览器 UserAgent", required = true, example = "Mozilla/5.0") + @Schema(description = "浏览器 UserAgent", required = true, example = "Mozilla/5.0") @NotEmpty(message = "浏览器 UserAgent 不能为空") private String userAgent; - @Schema(title = "Java 方法名", required = true, example = "cn.iocoder.yudao.adminserver.UserController.save(...)") + @Schema(description = "Java 方法名", required = true, example = "cn.iocoder.yudao.adminserver.UserController.save(...)") @NotEmpty(message = "Java 方法名不能为空") private String javaMethod; - @Schema(title = "Java 方法的参数") + @Schema(description = "Java 方法的参数") private String javaMethodArgs; - @Schema(title = "开始时间", required = true) + @Schema(description = "开始时间", required = true) @NotNull(message = "开始时间不能为空") private LocalDateTime startTime; - @Schema(title = "执行时长,单位:毫秒", required = true) + @Schema(description = "执行时长,单位:毫秒", required = true) @NotNull(message = "执行时长不能为空") private Integer duration; - @Schema(title = "结果码", required = true) + @Schema(description = "结果码", required = true) @NotNull(message = "结果码不能为空") private Integer resultCode; - @Schema(title = "结果提示") + @Schema(description = "结果提示") private String resultMsg; - @Schema(title = "结果数据") + @Schema(description = "结果数据") private String resultData; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogExportReqVO.java index c323b2cb6..c12aca80e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogExportReqVO.java @@ -8,23 +8,23 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 操作日志分页列表 Request VO") +@Schema(description = "管理后台 - 操作日志分页列表 Request VO") @Data public class OperateLogExportReqVO { - @Schema(title = "操作模块", example = "订单", description = "模拟匹配") + @Schema(description = "操作模块,模拟匹配", example = "订单") private String module; - @Schema(title = "用户昵称", example = "芋道", description = "模拟匹配") + @Schema(description = "用户昵称,模拟匹配", example = "芋道") private String userNickname; - @Schema(title = "操作分类", example = "1", description = "参见 OperateLogTypeEnum 枚举类") + @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", example = "1") private Integer type; - @Schema(title = "操作状态", example = "true") + @Schema(description = "操作状态", example = "true") private Boolean success; - @Schema(title = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] startTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogPageReqVO.java index c6eed986e..13a23ac02 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogPageReqVO.java @@ -9,23 +9,23 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 操作日志分页列表 Request VO") +@Schema(description = "管理后台 - 操作日志分页列表 Request VO") @Data public class OperateLogPageReqVO extends PageParam { - @Schema(title = "操作模块", example = "订单", description = "模拟匹配") + @Schema(description = "操作模块,模拟匹配", example = "订单") private String module; - @Schema(title = "用户昵称", example = "芋道", description = "模拟匹配") + @Schema(description = "用户昵称,模拟匹配", example = "芋道") private String userNickname; - @Schema(title = "操作分类", example = "1", description = "参见 OperateLogTypeEnum 枚举类") + @Schema(description = "操作分类,参见 OperateLogTypeEnum 枚举类", example = "1") private Integer type; - @Schema(title = "操作状态", example = "true") + @Schema(description = "操作状态", example = "true") private Boolean success; - @Schema(title = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] startTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogRespVO.java index 139f1b20e..1e88408ff 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/vo/operatelog/OperateLogRespVO.java @@ -5,16 +5,16 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 操作日志 Response VO") +@Schema(description = "管理后台 - 操作日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class OperateLogRespVO extends OperateLogBaseVO { - @Schema(title = "日志编号", required = true, example = "1024") + @Schema(description = "日志编号", required = true, example = "1024") private Long id; - @Schema(title = "用户昵称", required = true, example = "芋艿") + @Schema(description = "用户昵称", required = true, example = "芋艿") private String userNickname; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeBaseVO.java index 218812656..0b90841be 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeBaseVO.java @@ -14,19 +14,19 @@ import javax.validation.constraints.Size; @Data public class NoticeBaseVO { - @Schema(title = "公告标题", required = true, example = "小博主") + @Schema(description = "公告标题", required = true, example = "小博主") @NotBlank(message = "公告标题不能为空") @Size(max = 50, message = "公告标题不能超过50个字符") private String title; - @Schema(title = "公告类型", required = true, example = "小博主") + @Schema(description = "公告类型", required = true, example = "小博主") @NotNull(message = "公告类型不能为空") private Integer type; - @Schema(title = "公告内容", required = true, example = "半生编码") + @Schema(description = "公告内容", required = true, example = "半生编码") private String content; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", required = true, example = "1") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeCreateReqVO.java index ceb834306..211f4f0cf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeCreateReqVO.java @@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@Schema(title = "管理后台 - 通知公告创建 Request VO") +@Schema(description = "管理后台 - 通知公告创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class NoticeCreateReqVO extends NoticeBaseVO { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticePageReqVO.java index 1939e288e..53ad45f56 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticePageReqVO.java @@ -5,15 +5,15 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@Schema(title = "管理后台 - 通知公告分页 Request VO") +@Schema(description = "管理后台 - 通知公告分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class NoticePageReqVO extends PageParam { - @Schema(title = "通知公告名称", example = "芋道", description = "模糊匹配") + @Schema(description = "通知公告名称,模糊匹配", example = "芋道") private String title; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeRespVO.java index 0e84852d0..7b83d9d15 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeRespVO.java @@ -6,15 +6,15 @@ import lombok.EqualsAndHashCode; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 通知公告信息 Response VO") +@Schema(description = "管理后台 - 通知公告信息 Response VO") @Data @EqualsAndHashCode(callSuper = true) public class NoticeRespVO extends NoticeBaseVO { - @Schema(title = "通知公告序号", required = true, example = "1024") + @Schema(description = "通知公告序号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true, example = "时间戳格式") + @Schema(description = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeUpdateReqVO.java index 89f80173d..af1d53ed1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeUpdateReqVO.java @@ -6,12 +6,12 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 岗位公告更新 Request VO") +@Schema(description = "管理后台 - 岗位公告更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class NoticeUpdateReqVO extends NoticeBaseVO { - @Schema(title = "岗位公告编号", required = true, example = "1024") + @Schema(description = "岗位公告编号", required = true, example = "1024") @NotNull(message = "岗位公告编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientBaseVO.java index aea3e059b..c0056ed3d 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientBaseVO.java @@ -18,60 +18,60 @@ import java.util.List; @Data public class OAuth2ClientBaseVO { - @Schema(title = "客户端编号", required = true, example = "tudou") + @Schema(description = "客户端编号", required = true, example = "tudou") @NotNull(message = "客户端编号不能为空") private String clientId; - @Schema(title = "客户端密钥", required = true, example = "fan") + @Schema(description = "客户端密钥", required = true, example = "fan") @NotNull(message = "客户端密钥不能为空") private String secret; - @Schema(title = "应用名", required = true, example = "土豆") + @Schema(description = "应用名", required = true, example = "土豆") @NotNull(message = "应用名不能为空") private String name; - @Schema(title = "应用图标", required = true, example = "https://www.iocoder.cn/xx.png") + @Schema(description = "应用图标", required = true, example = "https://www.iocoder.cn/xx.png") @NotNull(message = "应用图标不能为空") @URL(message = "应用图标的地址不正确") private String logo; - @Schema(title = "应用描述", example = "我是一个应用") + @Schema(description = "应用描述", example = "我是一个应用") private String description; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态,参见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; - @Schema(title = "访问令牌的有效期", required = true, example = "8640") + @Schema(description = "访问令牌的有效期", required = true, example = "8640") @NotNull(message = "访问令牌的有效期不能为空") private Integer accessTokenValiditySeconds; - @Schema(title = "刷新令牌的有效期", required = true, example = "8640000") + @Schema(description = "刷新令牌的有效期", required = true, example = "8640000") @NotNull(message = "刷新令牌的有效期不能为空") private Integer refreshTokenValiditySeconds; - @Schema(title = "可重定向的 URI 地址", required = true, example = "https://www.iocoder.cn") + @Schema(description = "可重定向的 URI 地址", required = true, example = "https://www.iocoder.cn") @NotNull(message = "可重定向的 URI 地址不能为空") private List<@NotEmpty(message = "重定向的 URI 不能为空") @URL(message = "重定向的 URI 格式不正确") String> redirectUris; - @Schema(title = "授权类型", required = true, example = "password", description = "参见 OAuth2GrantTypeEnum 枚举") + @Schema(description = "授权类型,参见 OAuth2GrantTypeEnum 枚举", required = true, example = "password") @NotNull(message = "授权类型不能为空") private List authorizedGrantTypes; - @Schema(title = "授权范围", example = "user_info") + @Schema(description = "授权范围", example = "user_info") private List scopes; - @Schema(title = "自动通过的授权范围", example = "user_info") + @Schema(description = "自动通过的授权范围", example = "user_info") private List autoApproveScopes; - @Schema(title = "权限", example = "system:user:query") + @Schema(description = "权限", example = "system:user:query") private List authorities; - @Schema(title = "资源", example = "1024") + @Schema(description = "资源", example = "1024") private List resourceIds; - @Schema(title = "附加信息", example = "{yunai: true}") + @Schema(description = "附加信息", example = "{yunai: true}") private String additionalInformation; @AssertTrue(message = "附加信息必须是 JSON 格式") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientCreateReqVO.java index 34c4350ba..b7b8ffc38 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientCreateReqVO.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - OAuth2 客户端创建 Request VO") +@Schema(description = "管理后台 - OAuth2 客户端创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientPageReqVO.java index c815331e9..66fd1f41b 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientPageReqVO.java @@ -4,16 +4,16 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; -@Schema(title = "管理后台 - OAuth2 客户端分页 Request VO") +@Schema(description = "管理后台 - OAuth2 客户端分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class OAuth2ClientPageReqVO extends PageParam { - @Schema(title = "应用名", example = "土豆", description = "模糊匹配") + @Schema(description = "应用名,模糊匹配", example = "土豆") private String name; - @Schema(title = "状态", example = "1", description = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态,参见 CommonStatusEnum 枚举", example = "1") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientRespVO.java index dc39d7c2a..28aff686c 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - OAuth2 客户端 Response VO") +@Schema(description = "管理后台 - OAuth2 客户端 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class OAuth2ClientRespVO extends OAuth2ClientBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientUpdateReqVO.java index 32968b4cd..ba76eaeb9 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/client/OAuth2ClientUpdateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - OAuth2 客户端更新 Request VO") +@Schema(description = "管理后台 - OAuth2 客户端更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class OAuth2ClientUpdateReqVO extends OAuth2ClientBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAccessTokenRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAccessTokenRespVO.java index 3c6412ae0..745095403 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAccessTokenRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAccessTokenRespVO.java @@ -6,29 +6,29 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@Schema(title = "管理后台 - 【开放接口】访问令牌 Response VO") +@Schema(description = "管理后台 - 【开放接口】访问令牌 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class OAuth2OpenAccessTokenRespVO { - @Schema(title = "访问令牌", required = true, example = "tudou") + @Schema(description = "访问令牌", required = true, example = "tudou") @JsonProperty("access_token") private String accessToken; - @Schema(title = "刷新令牌", required = true, example = "nice") + @Schema(description = "刷新令牌", required = true, example = "nice") @JsonProperty("refresh_token") private String refreshToken; - @Schema(title = "令牌类型", required = true, example = "bearer") + @Schema(description = "令牌类型", required = true, example = "bearer") @JsonProperty("token_type") private String tokenType; - @Schema(title = "过期时间", required = true, example = "42430", description = "单位:秒") + @Schema(description = "过期时间,单位:秒", required = true, example = "42430") @JsonProperty("expires_in") private Long expiresIn; - @Schema(title = "授权范围", example = "user_info", description = "如果多个授权范围,使用空格分隔") + @Schema(description = "授权范围,如果多个授权范围,使用空格分隔", example = "user_info") private String scope; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAuthorizeInfoRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAuthorizeInfoRespVO.java index 73a89817f..984f87916 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAuthorizeInfoRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenAuthorizeInfoRespVO.java @@ -8,7 +8,7 @@ import lombok.NoArgsConstructor; import java.util.List; -@Schema(title = "管理后台 - 授权页的信息 Response VO") +@Schema(description = "管理后台 - 授权页的信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @@ -19,7 +19,7 @@ public class OAuth2OpenAuthorizeInfoRespVO { */ private Client client; - @Schema(title = "scope 的选中信息", required = true, description = "使用 List 保证有序性,Key 是 scope,Value 为是否选中") + @Schema(description = "scope 的选中信息,使用 List 保证有序性,Key 是 scope,Value 为是否选中", required = true) private List> scopes; @Data @@ -27,10 +27,10 @@ public class OAuth2OpenAuthorizeInfoRespVO { @AllArgsConstructor public static class Client { - @Schema(title = "应用名", required = true, example = "土豆") + @Schema(description = "应用名", required = true, example = "土豆") private String name; - @Schema(title = "应用图标", required = true, example = "https://www.iocoder.cn/xx.png") + @Schema(description = "应用图标", required = true, example = "https://www.iocoder.cn/xx.png") private String logo; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenCheckTokenRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenCheckTokenRespVO.java index 3cf843f4f..d2dc8eb46 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenCheckTokenRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/open/OAuth2OpenCheckTokenRespVO.java @@ -8,33 +8,33 @@ import lombok.NoArgsConstructor; import java.util.List; -@Schema(title = "管理后台 - 【开放接口】校验令牌 Response VO") +@Schema(description = "管理后台 - 【开放接口】校验令牌 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class OAuth2OpenCheckTokenRespVO { - @Schema(title = "用户编号", required = true, example = "666") + @Schema(description = "用户编号", required = true, example = "666") @JsonProperty("user_id") private Long userId; - @Schema(title = "用户类型", required = true, example = "2", description = "参见 UserTypeEnum 枚举") + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", required = true, example = "2") @JsonProperty("user_type") private Integer userType; - @Schema(title = "租户编号", required = true, example = "1024") + @Schema(description = "租户编号", required = true, example = "1024") @JsonProperty("tenant_id") private Long tenantId; - @Schema(title = "客户端编号", required = true, example = "car") + @Schema(description = "客户端编号", required = true, example = "car") @JsonProperty("client_id") private String clientId; - @Schema(title = "授权范围", required = true, example = "user_info") + @Schema(description = "授权范围", required = true, example = "user_info") private List scopes; - @Schema(title = "访问令牌", required = true, example = "tudou") + @Schema(description = "访问令牌", required = true, example = "tudou") @JsonProperty("access_token") private String accessToken; - @Schema(title = "过期时间", required = true, example = "1593092157", description = "时间戳 / 1000,即单位:秒") + @Schema(description = "过期时间,时间戳 / 1000,即单位:秒", required = true, example = "1593092157") private Long exp; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenPageReqVO.java index 7bd1fa5d3..1a54fdcb6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenPageReqVO.java @@ -5,18 +5,18 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@Schema(title = "管理后台 - 访问令牌分页 Request VO") +@Schema(description = "管理后台 - 访问令牌分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class OAuth2AccessTokenPageReqVO extends PageParam { - @Schema(title = "用户编号", required = true, example = "666") + @Schema(description = "用户编号", required = true, example = "666") private Long userId; - @Schema(title = "用户类型", required = true, example = "2", description = "参见 UserTypeEnum 枚举") + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", required = true, example = "2") private Integer userType; - @Schema(title = "客户端编号", required = true, example = "2") + @Schema(description = "客户端编号", required = true, example = "2") private String clientId; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenRespVO.java index b7b258ca2..125e37f46 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/token/OAuth2AccessTokenRespVO.java @@ -7,34 +7,34 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 访问令牌 Response VO") +@Schema(description = "管理后台 - 访问令牌 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class OAuth2AccessTokenRespVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @Schema(title = "访问令牌", required = true, example = "tudou") + @Schema(description = "访问令牌", required = true, example = "tudou") private String accessToken; - @Schema(title = "刷新令牌", required = true, example = "nice") + @Schema(description = "刷新令牌", required = true, example = "nice") private String refreshToken; - @Schema(title = "用户编号", required = true, example = "666") + @Schema(description = "用户编号", required = true, example = "666") private Long userId; - @Schema(title = "用户类型", required = true, example = "2", description = "参见 UserTypeEnum 枚举") + @Schema(description = "用户类型,参见 UserTypeEnum 枚举", required = true, example = "2") private Integer userType; - @Schema(title = "客户端编号", required = true, example = "2") + @Schema(description = "客户端编号", required = true, example = "2") private String clientId; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; - @Schema(title = "过期时间", required = true) + @Schema(description = "过期时间", required = true) private LocalDateTime expiresTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java index ab561607b..0a1002f7c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java @@ -7,30 +7,30 @@ import lombok.NoArgsConstructor; import java.util.List; -@Schema(title = "管理后台 - OAuth2 获得用户基本信息 Response VO") +@Schema(description = "管理后台 - OAuth2 获得用户基本信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class OAuth2UserInfoRespVO { - @Schema(title = "用户编号", required = true, example = "1") + @Schema(description = "用户编号", required = true, example = "1") private Long id; - @Schema(title = "用户账号", required = true, example = "芋艿") + @Schema(description = "用户账号", required = true, example = "芋艿") private String username; - @Schema(title = "用户昵称", required = true, example = "芋道") + @Schema(description = "用户昵称", required = true, example = "芋道") private String nickname; - @Schema(title = "用户邮箱", example = "yudao@iocoder.cn") + @Schema(description = "用户邮箱", example = "yudao@iocoder.cn") private String email; - @Schema(title = "手机号码", example = "15601691300") + @Schema(description = "手机号码", example = "15601691300") private String mobile; - @Schema(title = "用户性别", example = "1", description = "参见 SexEnum 枚举类") + @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1") private Integer sex; - @Schema(title = "用户头像", example = "https://www.iocoder.cn/xxx.png") + @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") private String avatar; /** @@ -43,26 +43,26 @@ public class OAuth2UserInfoRespVO { */ private List posts; - @Schema(title = "部门") + @Schema(description = "部门") @Data public static class Dept { - @Schema(title = "部门编号", required = true, example = "1") + @Schema(description = "部门编号", required = true, example = "1") private Long id; - @Schema(title = "部门名称", required = true, example = "研发部") + @Schema(description = "部门名称", required = true, example = "研发部") private String name; } - @Schema(title = "岗位") + @Schema(description = "岗位") @Data public static class Post { - @Schema(title = "岗位编号", required = true, example = "1") + @Schema(description = "岗位编号", required = true, example = "1") private Long id; - @Schema(title = "岗位名称", required = true, example = "开发") + @Schema(description = "岗位名称", required = true, example = "开发") private String name; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java index 5d7c9c267..739b12d6b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/vo/user/OAuth2UserUpdateReqVO.java @@ -9,26 +9,26 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.Email; import javax.validation.constraints.Size; -@Schema(title = "管理后台 - OAuth2 更新用户基本信息 Request VO") +@Schema(description = "管理后台 - OAuth2 更新用户基本信息 Request VO") @Data @NoArgsConstructor @AllArgsConstructor public class OAuth2UserUpdateReqVO { - @Schema(title = "用户昵称", required = true, example = "芋艿") + @Schema(description = "用户昵称", required = true, example = "芋艿") @Size(max = 30, message = "用户昵称长度不能超过 30 个字符") private String nickname; - @Schema(title = "用户邮箱", example = "yudao@iocoder.cn") + @Schema(description = "用户邮箱", example = "yudao@iocoder.cn") @Email(message = "邮箱格式不正确") @Size(max = 50, message = "邮箱长度不能超过 50 个字符") private String email; - @Schema(title = "手机号码", example = "15601691300") + @Schema(description = "手机号码", example = "15601691300") @Length(min = 11, max = 11, message = "手机号长度必须 11 位") private String mobile; - @Schema(title = "用户性别", example = "1", description = "参见 SexEnum 枚举类") + @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1") private Integer sex; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuBaseVO.java index a316ad577..3b89c7515 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuBaseVO.java @@ -14,46 +14,46 @@ import javax.validation.constraints.Size; @Data public class MenuBaseVO { - @Schema(title = "菜单名称", required = true, example = "芋道") + @Schema(description = "菜单名称", required = true, example = "芋道") @NotBlank(message = "菜单名称不能为空") @Size(max = 50, message = "菜单名称长度不能超过50个字符") private String name; - @Schema(title = "权限标识", example = "sys:menu:add", description = "仅菜单类型为按钮时,才需要传递") + @Schema(description = "权限标识,仅菜单类型为按钮时,才需要传递", example = "sys:menu:add") @Size(max = 100) private String permission; - @Schema(title = "类型", required = true, example = "1", description = "参见 MenuTypeEnum 枚举类") + @Schema(description = "类型,参见 MenuTypeEnum 枚举类", required = true, example = "1") @NotNull(message = "菜单类型不能为空") private Integer type; - @Schema(title = "显示顺序不能为空", required = true, example = "1024") + @Schema(description = "显示顺序不能为空", required = true, example = "1024") @NotNull(message = "显示顺序不能为空") private Integer sort; - @Schema(title = "父菜单 ID", required = true, example = "1024") + @Schema(description = "父菜单 ID", required = true, example = "1024") @NotNull(message = "父菜单 ID 不能为空") private Long parentId; - @Schema(title = "路由地址", example = "post", description = "仅菜单类型为菜单或者目录时,才需要传") + @Schema(description = "路由地址,仅菜单类型为菜单或者目录时,才需要传", example = "post") @Size(max = 200, message = "路由地址不能超过200个字符") private String path; - @Schema(title = "菜单图标", example = "/menu/list", description = "仅菜单类型为菜单或者目录时,才需要传") + @Schema(description = "菜单图标,仅菜单类型为菜单或者目录时,才需要传", example = "/menu/list") private String icon; - @Schema(title = "组件路径", example = "system/post/index", description = "仅菜单类型为菜单时,才需要传") + @Schema(description = "组件路径,仅菜单类型为菜单时,才需要传", example = "system/post/index") @Size(max = 200, message = "组件路径不能超过255个字符") private String component; - @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") + @Schema(description = "状态,见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; - @Schema(title = "是否可见", example = "false") + @Schema(description = "是否可见", example = "false") private Boolean visible; - @Schema(title = "是否缓存", example = "false") + @Schema(description = "是否缓存", example = "false") private Boolean keepAlive; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuCreateReqVO.java index 3930c8116..56721b7fe 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuCreateReqVO.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -@Schema(title = "管理后台 - 菜单创建 Request VO") +@Schema(description = "管理后台 - 菜单创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class MenuCreateReqVO extends MenuBaseVO { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java index 0f1410878..ce6cf5dbd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuListReqVO.java @@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(title = "管理后台 - 菜单列表 Request VO") +@Schema(description = "管理后台 - 菜单列表 Request VO") @Data public class MenuListReqVO { - @Schema(title = "菜单名称", example = "芋道", description = "模糊匹配") + @Schema(description = "菜单名称,模糊匹配", example = "芋道") private String name; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuRespVO.java index 0d5e9b2e1..f85532639 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuRespVO.java @@ -8,20 +8,20 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 菜单信息 Response VO") +@Schema(description = "管理后台 - 菜单信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class MenuRespVO extends MenuBaseVO { - @Schema(title = "菜单编号", required = true, example = "1024") + @Schema(description = "菜单编号", required = true, example = "1024") private Long id; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", required = true, example = "1") private Integer status; - @Schema(title = "创建时间", required = true, example = "时间戳格式") + @Schema(description = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuSimpleRespVO.java index 53a10ed2b..bc8665ec1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuSimpleRespVO.java @@ -7,22 +7,22 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 菜单精简信息 Response VO") +@Schema(description = "管理后台 - 菜单精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class MenuSimpleRespVO { - @Schema(title = "菜单编号", required = true, example = "1024") + @Schema(description = "菜单编号", required = true, example = "1024") private Long id; - @Schema(title = "菜单名称", required = true, example = "芋道") + @Schema(description = "菜单名称", required = true, example = "芋道") private String name; - @Schema(title = "父菜单 ID", required = true, example = "1024") + @Schema(description = "父菜单 ID", required = true, example = "1024") private Long parentId; - @Schema(title = "类型", required = true, example = "1", description = "参见 MenuTypeEnum 枚举类") + @Schema(description = "类型,参见 MenuTypeEnum 枚举类", required = true, example = "1") private Integer type; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuUpdateReqVO.java index 01783beff..9346be045 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/menu/MenuUpdateReqVO.java @@ -5,12 +5,12 @@ import lombok.*; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 菜单更新 Request VO") +@Schema(description = "管理后台 - 菜单更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class MenuUpdateReqVO extends MenuBaseVO { - @Schema(title = "菜单编号", required = true, example = "1024") + @Schema(description = "菜单编号", required = true, example = "1024") @NotNull(message = "菜单编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleDataScopeReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleDataScopeReqVO.java index 9d3c126df..3d6449c99 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleDataScopeReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleDataScopeReqVO.java @@ -7,20 +7,20 @@ import javax.validation.constraints.NotNull; import java.util.Collections; import java.util.Set; -@Schema(title = "管理后台 - 赋予角色数据权限 Request VO") +@Schema(description = "管理后台 - 赋予角色数据权限 Request VO") @Data public class PermissionAssignRoleDataScopeReqVO { - @Schema(title = "角色编号", required = true, example = "1") + @Schema(description = "角色编号", required = true, example = "1") @NotNull(message = "角色编号不能为空") private Long roleId; - @Schema(title = "数据范围", required = true, example = "1", description = "参见 DataScopeEnum 枚举类") + @Schema(description = "数据范围,参见 DataScopeEnum 枚举类", required = true, example = "1") @NotNull(message = "数据范围不能为空") // TODO 这里要多一个枚举校验 private Integer dataScope; - @Schema(title = "部门编号列表", example = "1,3,5", description = "只有范围类型为 DEPT_CUSTOM 时,该字段才需要") + @Schema(description = "部门编号列表,只有范围类型为 DEPT_CUSTOM 时,该字段才需要", example = "1,3,5") private Set dataScopeDeptIds = Collections.emptySet(); // 兜底 } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleMenuReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleMenuReqVO.java index 70a33591d..393ab47b2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleMenuReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignRoleMenuReqVO.java @@ -7,15 +7,15 @@ import javax.validation.constraints.NotNull; import java.util.Collections; import java.util.Set; -@Schema(title = "管理后台 - 赋予角色菜单 Request VO") +@Schema(description = "管理后台 - 赋予角色菜单 Request VO") @Data public class PermissionAssignRoleMenuReqVO { - @Schema(title = "角色编号", required = true, example = "1") + @Schema(description = "角色编号", required = true, example = "1") @NotNull(message = "角色编号不能为空") private Long roleId; - @Schema(title = "菜单编号列表", example = "1,3,5") + @Schema(description = "菜单编号列表", example = "1,3,5") private Set menuIds = Collections.emptySet(); // 兜底 } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignUserRoleReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignUserRoleReqVO.java index bcb4d46bf..74971401f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignUserRoleReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/permission/PermissionAssignUserRoleReqVO.java @@ -7,15 +7,15 @@ import javax.validation.constraints.NotNull; import java.util.Collections; import java.util.Set; -@Schema(title = "管理后台 - 赋予用户角色 Request VO") +@Schema(description = "管理后台 - 赋予用户角色 Request VO") @Data public class PermissionAssignUserRoleReqVO { - @Schema(title = "用户编号", required = true, example = "1") + @Schema(description = "用户编号", required = true, example = "1") @NotNull(message = "用户编号不能为空") private Long userId; - @Schema(title = "角色编号列表", example = "1,3,5") + @Schema(description = "角色编号列表", example = "1,3,5") private Set roleIds = Collections.emptySet(); // 兜底 } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleBaseVO.java index ee320c01b..84acfad92 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleBaseVO.java @@ -14,21 +14,21 @@ import javax.validation.constraints.Size; @Data public class RoleBaseVO { - @Schema(title = "角色名称", required = true, example = "管理员") + @Schema(description = "角色名称", required = true, example = "管理员") @NotBlank(message = "角色名称不能为空") @Size(max = 30, message = "角色名称长度不能超过30个字符") private String name; @NotBlank(message = "角色标志不能为空") @Size(max = 100, message = "角色标志长度不能超过100个字符") - @Schema(title = "角色编码", required = true, example = "ADMIN") + @Schema(description = "角色编码", required = true, example = "ADMIN") private String code; - @Schema(title = "显示顺序不能为空", required = true, example = "1024") + @Schema(description = "显示顺序不能为空", required = true, example = "1024") @NotNull(message = "显示顺序不能为空") private Integer sort; - @Schema(title = "备注", example = "我是一个角色") + @Schema(description = "备注", example = "我是一个角色") private String remark; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleCreateReqVO.java index 0f21c3c2f..ab4523f15 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleCreateReqVO.java @@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@Schema(title = "管理后台 - 角色创建 Request VO") +@Schema(description = "管理后台 - 角色创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class RoleCreateReqVO extends RoleBaseVO { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleExportReqVO.java index a16deff7a..f13e91f33 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleExportReqVO.java @@ -8,20 +8,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 角色分页 Request VO") +@Schema(description = "管理后台 - 角色分页 Request VO") @Data public class RoleExportReqVO { - @Schema(title = "角色名称", example = "芋道", description = "模糊匹配") + @Schema(description = "角色名称,模糊匹配", example = "芋道") private String name; - @Schema(title = "角色标识", example = "yudao", description = "模糊匹配") + @Schema(description = "角色标识,模糊匹配", example = "yudao") private String code; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; - @Schema(title = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "开始时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RolePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RolePageReqVO.java index b37cdb485..cc0f0040d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RolePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RolePageReqVO.java @@ -10,21 +10,21 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 角色分页 Request VO") +@Schema(description = "管理后台 - 角色分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class RolePageReqVO extends PageParam { - @Schema(title = "角色名称", example = "芋道", description = "模糊匹配") + @Schema(description = "角色名称,模糊匹配", example = "芋道") private String name; - @Schema(title = "角色标识", example = "yudao", description = "模糊匹配") + @Schema(description = "角色标识,模糊匹配", example = "yudao") private String code; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; - @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleRespVO.java index 654eff898..b4090f40e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleRespVO.java @@ -9,29 +9,29 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; import java.util.Set; -@Schema(title = "管理后台 - 角色信息 Response VO") +@Schema(description = "管理后台 - 角色信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class RoleRespVO extends RoleBaseVO { - @Schema(title = "角色编号", required = true, example = "1") + @Schema(description = "角色编号", required = true, example = "1") private Long id; - @Schema(title = "数据范围", required = true, example = "1", description = "参见 DataScopeEnum 枚举类") + @Schema(description = "数据范围,参见 DataScopeEnum 枚举类", required = true, example = "1") private Integer dataScope; - @Schema(title = "数据范围(指定部门数组)", example = "1") + @Schema(description = "数据范围(指定部门数组)", example = "1") private Set dataScopeDeptIds; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", required = true, example = "1") private Integer status; - @Schema(title = "角色类型", required = true, example = "1", description = "参见 RoleTypeEnum 枚举类") + @Schema(description = "角色类型,参见 RoleTypeEnum 枚举类", required = true, example = "1") private Integer type; - @Schema(title = "创建时间", required = true, example = "时间戳格式") + @Schema(description = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleSimpleRespVO.java index a7fced888..d0404da61 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleSimpleRespVO.java @@ -5,16 +5,16 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@Schema(title = "管理后台 - 角色精简信息 Response VO") +@Schema(description = "管理后台 - 角色精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class RoleSimpleRespVO { - @Schema(title = "角色编号", required = true, example = "1024") + @Schema(description = "角色编号", required = true, example = "1024") private Long id; - @Schema(title = "角色名称", required = true, example = "芋道") + @Schema(description = "角色名称", required = true, example = "芋道") private String name; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateReqVO.java index 5c02ff2d9..367fcf943 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateReqVO.java @@ -6,12 +6,12 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 角色更新 Request VO") +@Schema(description = "管理后台 - 角色更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class RoleUpdateReqVO extends RoleBaseVO { - @Schema(title = "角色编号", required = true, example = "1024") + @Schema(description = "角色编号", required = true, example = "1024") @NotNull(message = "角色编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateStatusReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateStatusReqVO.java index ed4a72604..5f51b5757 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateStatusReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/vo/role/RoleUpdateStatusReqVO.java @@ -7,15 +7,15 @@ import lombok.Data; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 角色更新状态 Request VO") +@Schema(description = "管理后台 - 角色更新状态 Request VO") @Data public class RoleUpdateStatusReqVO { - @Schema(title = "角色编号", required = true, example = "1024") + @Schema(description = "角色编号", required = true, example = "1024") @NotNull(message = "角色编号不能为空") private Long id; - @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") + @Schema(description = "状态,见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") private Integer status; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordBaseVO.java index f7539f944..408e952de 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordBaseVO.java @@ -13,19 +13,19 @@ import java.util.List; @Data public class SensitiveWordBaseVO { - @Schema(title = "敏感词", required = true, example = "敏感词") + @Schema(description = "敏感词", required = true, example = "敏感词") @NotNull(message = "敏感词不能为空") private String name; - @Schema(title = "标签", required = true, example = "短信,评论") + @Schema(description = "标签", required = true, example = "短信,评论") @NotNull(message = "标签不能为空") private List tags; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; - @Schema(title = "描述", example = "污言秽语") + @Schema(description = "描述", example = "污言秽语") private String description; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordCreateReqVO.java index bc833d276..2e2e89df5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordCreateReqVO.java @@ -5,7 +5,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 敏感词创建 Request VO") +@Schema(description = "管理后台 - 敏感词创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExportReqVO.java index 7df2b7aa7..f5f3c4442 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordExportReqVO.java @@ -8,21 +8,21 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 敏感词 Excel 导出 Request VO", description = "参数和 SensitiveWordPageReqVO 是一致的") +@Schema(description = "管理后台 - 敏感词 Excel 导出 Request VO,参数和 SensitiveWordPageReqVO 是一致的") @Data public class SensitiveWordExportReqVO { - @Schema(title = "敏感词", example = "敏感词") + @Schema(description = "敏感词", example = "敏感词") private String name; - @Schema(title = "标签", example = "短信,评论") + @Schema(description = "标签", example = "短信,评论") private String tag; - @Schema(title = "状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java index f913b9270..173162194 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordPageReqVO.java @@ -11,23 +11,23 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 敏感词分页 Request VO") +@Schema(description = "管理后台 - 敏感词分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SensitiveWordPageReqVO extends PageParam { - @Schema(title = "敏感词", example = "敏感词") + @Schema(description = "敏感词", example = "敏感词") private String name; - @Schema(title = "标签", example = "短信,评论") + @Schema(description = "标签", example = "短信,评论") private String tag; - @Schema(title = "状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordRespVO.java index f97333f58..28849b408 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 敏感词 Response VO") +@Schema(description = "管理后台 - 敏感词 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SensitiveWordRespVO extends SensitiveWordBaseVO { - @Schema(title = "编号", required = true, example = "1") + @Schema(description = "编号", required = true, example = "1") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordUpdateReqVO.java index 2dc0ad37b..58828115e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/vo/SensitiveWordUpdateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 敏感词更新 Request VO") +@Schema(description = "管理后台 - 敏感词更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SensitiveWordUpdateReqVO extends SensitiveWordBaseVO { - @Schema(title = "编号", required = true, example = "1") + @Schema(description = "编号", required = true, example = "1") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelBaseVO.java index c63d4545e..6c97f06de 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelBaseVO.java @@ -12,25 +12,25 @@ import javax.validation.constraints.NotNull; @Data public class SmsChannelBaseVO { - @Schema(title = "短信签名", required = true, example = "芋道源码") + @Schema(description = "短信签名", required = true, example = "芋道源码") @NotNull(message = "短信签名不能为空") private String signature; - @Schema(title = "启用状态", required = true, example = "1") + @Schema(description = "启用状态", required = true, example = "1") @NotNull(message = "启用状态不能为空") private Integer status; - @Schema(title = "备注", example = "好吃!") + @Schema(description = "备注", example = "好吃!") private String remark; - @Schema(title = "短信 API 的账号", required = true, example = "yudao") + @Schema(description = "短信 API 的账号", required = true, example = "yudao") @NotNull(message = "短信 API 的账号不能为空") private String apiKey; - @Schema(title = "短信 API 的密钥", example = "yuanma") + @Schema(description = "短信 API 的密钥", example = "yuanma") private String apiSecret; - @Schema(title = "短信发送回调 URL", example = "http://www.iocoder.cn") + @Schema(description = "短信发送回调 URL", example = "http://www.iocoder.cn") @URL(message = "回调 URL 格式不正确") private String callbackUrl; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelCreateReqVO.java index b8940af40..31671a572 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelCreateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 短信渠道创建 Request VO") +@Schema(description = "管理后台 - 短信渠道创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsChannelCreateReqVO extends SmsChannelBaseVO { - @Schema(title = "渠道编码", required = true, example = "YUN_PIAN", description = "参见 SmsChannelEnum 枚举类") + @Schema(description = "渠道编码,参见 SmsChannelEnum 枚举类", required = true, example = "YUN_PIAN") @NotNull(message = "渠道编码不能为空") private String code; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelPageReqVO.java index 9b79a3170..a0c5baaf6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelPageReqVO.java @@ -11,20 +11,20 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 短信渠道分页 Request VO") +@Schema(description = "管理后台 - 短信渠道分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsChannelPageReqVO extends PageParam { - @Schema(title = "任务状态", example = "1") + @Schema(description = "任务状态", example = "1") private Integer status; - @Schema(title = "短信签名", example = "芋道源码", description = "模糊匹配") + @Schema(description = "短信签名,模糊匹配", example = "芋道源码") private String signature; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelRespVO.java index 04b8d95e1..27b09d60b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelRespVO.java @@ -7,19 +7,19 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 短信渠道 Response VO") +@Schema(description = "管理后台 - 短信渠道 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsChannelRespVO extends SmsChannelBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @Schema(title = "渠道编码", required = true, example = "YUN_PIAN", description = "参见 SmsChannelEnum 枚举类") + @Schema(description = "渠道编码,参见 SmsChannelEnum 枚举类", required = true, example = "YUN_PIAN") private String code; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelSimpleRespVO.java index 57c4c3fb9..b9a3f46c0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelSimpleRespVO.java @@ -5,19 +5,19 @@ import lombok.Data; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 短信渠道精简 Response VO") +@Schema(description = "管理后台 - 短信渠道精简 Response VO") @Data public class SmsChannelSimpleRespVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; - @Schema(title = "短信签名", required = true, example = "芋道源码") + @Schema(description = "短信签名", required = true, example = "芋道源码") @NotNull(message = "短信签名不能为空") private String signature; - @Schema(title = "渠道编码", required = true, example = "YUN_PIAN", description = "参见 SmsChannelEnum 枚举类") + @Schema(description = "渠道编码,参见 SmsChannelEnum 枚举类", required = true, example = "YUN_PIAN") private String code; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelUpdateReqVO.java index 0d4606821..3379649f1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/channel/SmsChannelUpdateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 短信渠道更新 Request VO") +@Schema(description = "管理后台 - 短信渠道更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsChannelUpdateReqVO extends SmsChannelBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExportReqVO.java index 57093888d..739e630eb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogExportReqVO.java @@ -8,31 +8,31 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 短信日志 Excel 导出 Request VO", description = "参数和 SmsLogPageReqVO 是一致的") +@Schema(description = "管理后台 - 短信日志 Excel 导出 Request VO,参数和 SmsLogPageReqVO 是一致的") @Data public class SmsLogExportReqVO { - @Schema(title = "短信渠道编号", example = "10") + @Schema(description = "短信渠道编号", example = "10") private Long channelId; - @Schema(title = "模板编号", example = "20") + @Schema(description = "模板编号", example = "20") private Long templateId; - @Schema(title = "手机号", example = "15601691300") + @Schema(description = "手机号", example = "15601691300") private String mobile; - @Schema(title = "发送状态", example = "1") + @Schema(description = "发送状态", example = "1") private Integer sendStatus; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "开始发送时间") + @Schema(description = "开始发送时间") private LocalDateTime[] sendTime; - @Schema(title = "接收状态", example = "0") + @Schema(description = "接收状态", example = "0") private Integer receiveStatus; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "开始接收时间") + @Schema(description = "开始接收时间") private LocalDateTime[] receiveTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java index ce00897dd..0da70bd12 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogPageReqVO.java @@ -11,33 +11,33 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 短信日志分页 Request VO") +@Schema(description = "管理后台 - 短信日志分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsLogPageReqVO extends PageParam { - @Schema(title = "短信渠道编号", example = "10") + @Schema(description = "短信渠道编号", example = "10") private Long channelId; - @Schema(title = "模板编号", example = "20") + @Schema(description = "模板编号", example = "20") private Long templateId; - @Schema(title = "手机号", example = "15601691300") + @Schema(description = "手机号", example = "15601691300") private String mobile; - @Schema(title = "发送状态", example = "1", description = "参见 SmsSendStatusEnum 枚举类") + @Schema(description = "发送状态,参见 SmsSendStatusEnum 枚举类", example = "1") private Integer sendStatus; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "发送时间") + @Schema(description = "发送时间") private LocalDateTime[] sendTime; - @Schema(title = "接收状态", example = "0", description = "参见 SmsReceiveStatusEnum 枚举类") + @Schema(description = "接收状态,参见 SmsReceiveStatusEnum 枚举类", example = "0") private Integer receiveStatus; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "接收时间") + @Schema(description = "接收时间") private LocalDateTime[] receiveTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogRespVO.java index 98ec37f94..2780b5de1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/log/SmsLogRespVO.java @@ -6,83 +6,83 @@ import lombok.Data; import java.time.LocalDateTime; import java.util.Map; -@Schema(title = "管理后台 - 短信日志 Response VO") +@Schema(description = "管理后台 - 短信日志 Response VO") @Data public class SmsLogRespVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @Schema(title = "短信渠道编号", required = true, example = "10") + @Schema(description = "短信渠道编号", required = true, example = "10") private Long channelId; - @Schema(title = "短信渠道编码", required = true, example = "ALIYUN") + @Schema(description = "短信渠道编码", required = true, example = "ALIYUN") private String channelCode; - @Schema(title = "模板编号", required = true, example = "20") + @Schema(description = "模板编号", required = true, example = "20") private Long templateId; - @Schema(title = "模板编码", required = true, example = "test-01") + @Schema(description = "模板编码", required = true, example = "test-01") private String templateCode; - @Schema(title = "短信类型", required = true, example = "1") + @Schema(description = "短信类型", required = true, example = "1") private Integer templateType; - @Schema(title = "短信内容", required = true, example = "你好,你的验证码是 1024") + @Schema(description = "短信内容", required = true, example = "你好,你的验证码是 1024") private String templateContent; - @Schema(title = "短信参数", required = true, example = "name,code") + @Schema(description = "短信参数", required = true, example = "name,code") private Map templateParams; - @Schema(title = "短信 API 的模板编号", required = true, example = "SMS_207945135") + @Schema(description = "短信 API 的模板编号", required = true, example = "SMS_207945135") private String apiTemplateId; - @Schema(title = "手机号", required = true, example = "15601691300") + @Schema(description = "手机号", required = true, example = "15601691300") private String mobile; - @Schema(title = "用户编号", example = "10") + @Schema(description = "用户编号", example = "10") private Long userId; - @Schema(title = "用户类型", example = "1") + @Schema(description = "用户类型", example = "1") private Integer userType; - @Schema(title = "发送状态", required = true, example = "1") + @Schema(description = "发送状态", required = true, example = "1") private Integer sendStatus; - @Schema(title = "发送时间") + @Schema(description = "发送时间") private LocalDateTime sendTime; - @Schema(title = "发送结果的编码", example = "0") + @Schema(description = "发送结果的编码", example = "0") private Integer sendCode; - @Schema(title = "发送结果的提示", example = "成功") + @Schema(description = "发送结果的提示", example = "成功") private String sendMsg; - @Schema(title = "短信 API 发送结果的编码", example = "SUCCESS") + @Schema(description = "短信 API 发送结果的编码", example = "SUCCESS") private String apiSendCode; - @Schema(title = "短信 API 发送失败的提示", example = "成功") + @Schema(description = "短信 API 发送失败的提示", example = "成功") private String apiSendMsg; - @Schema(title = "短信 API 发送返回的唯一请求 ID", example = "3837C6D3-B96F-428C-BBB2-86135D4B5B99") + @Schema(description = "短信 API 发送返回的唯一请求 ID", example = "3837C6D3-B96F-428C-BBB2-86135D4B5B99") private String apiRequestId; - @Schema(title = "短信 API 发送返回的序号", example = "62923244790") + @Schema(description = "短信 API 发送返回的序号", example = "62923244790") private String apiSerialNo; - @Schema(title = "接收状态", required = true, example = "0") + @Schema(description = "接收状态", required = true, example = "0") private Integer receiveStatus; - @Schema(title = "接收时间") + @Schema(description = "接收时间") private LocalDateTime receiveTime; - @Schema(title = "API 接收结果的编码", example = "DELIVRD") + @Schema(description = "API 接收结果的编码", example = "DELIVRD") private String apiReceiveCode; - @Schema(title = "API 接收结果的说明", example = "用户接收成功") + @Schema(description = "API 接收结果的说明", example = "用户接收成功") private String apiReceiveMsg; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateBaseVO.java index 664d52948..dc33b45c0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateBaseVO.java @@ -11,34 +11,34 @@ import javax.validation.constraints.NotNull; @Data public class SmsTemplateBaseVO { - @Schema(title = "短信类型", required = true, example = "1", description = "参见 SmsTemplateTypeEnum 枚举类") + @Schema(description = "短信类型,参见 SmsTemplateTypeEnum 枚举类", required = true, example = "1") @NotNull(message = "短信类型不能为空") private Integer type; - @Schema(title = "开启状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "开启状态,参见 CommonStatusEnum 枚举类", required = true, example = "1") @NotNull(message = "开启状态不能为空") private Integer status; - @Schema(title = "模板编码", required = true, example = "test_01") + @Schema(description = "模板编码", required = true, example = "test_01") @NotNull(message = "模板编码不能为空") private String code; - @Schema(title = "模板名称", required = true, example = "yudao") + @Schema(description = "模板名称", required = true, example = "yudao") @NotNull(message = "模板名称不能为空") private String name; - @Schema(title = "模板内容", required = true, example = "你好,{name}。你长的太{like}啦!") + @Schema(description = "模板内容", required = true, example = "你好,{name}。你长的太{like}啦!") @NotNull(message = "模板内容不能为空") private String content; - @Schema(title = "备注", example = "哈哈哈") + @Schema(description = "备注", example = "哈哈哈") private String remark; - @Schema(title = "短信 API 的模板编号", required = true, example = "4383920") + @Schema(description = "短信 API 的模板编号", required = true, example = "4383920") @NotNull(message = "短信 API 的模板编号不能为空") private String apiTemplateId; - @Schema(title = "短信渠道编号", required = true, example = "10") + @Schema(description = "短信渠道编号", required = true, example = "10") @NotNull(message = "短信渠道编号不能为空") private Long channelId; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateCreateReqVO.java index 9546b83e7..737a16a45 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateCreateReqVO.java @@ -4,7 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 短信模板创建 Request VO") +@Schema(description = "管理后台 - 短信模板创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExportReqVO.java index 0f84463af..93d157340 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateExportReqVO.java @@ -8,30 +8,30 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 短信模板 Excel 导出 Request VO", description = "参数和 SmsTemplatePageReqVO 是一致的") +@Schema(description = "管理后台 - 短信模板 Excel 导出 Request VO,参数和 SmsTemplatePageReqVO 是一致的") @Data public class SmsTemplateExportReqVO { - @Schema(title = "短信签名", example = "1") + @Schema(description = "短信签名", example = "1") private Integer type; - @Schema(title = "开启状态", example = "1") + @Schema(description = "开启状态", example = "1") private Integer status; - @Schema(title = "模板编码", example = "test_01", description = "模糊匹配") + @Schema(description = "模板编码,模糊匹配", example = "test_01") private String code; - @Schema(title = "模板内容", example = "你好,{name}。你长的太{like}啦!", description = "模糊匹配") + @Schema(description = "模板内容,模糊匹配", example = "你好,{name}。你长的太{like}啦!") private String content; - @Schema(title = "短信 API 的模板编号", example = "4383920", description = "模糊匹配") + @Schema(description = "短信 API 的模板编号,模糊匹配", example = "4383920") private String apiTemplateId; - @Schema(title = "短信渠道编号", example = "10") + @Schema(description = "短信渠道编号", example = "10") private Long channelId; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplatePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplatePageReqVO.java index 3cb26d228..89ae459f5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplatePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplatePageReqVO.java @@ -11,32 +11,32 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 短信模板分页 Request VO") +@Schema(description = "管理后台 - 短信模板分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsTemplatePageReqVO extends PageParam { - @Schema(title = "短信签名", example = "1") + @Schema(description = "短信签名", example = "1") private Integer type; - @Schema(title = "开启状态", example = "1") + @Schema(description = "开启状态", example = "1") private Integer status; - @Schema(title = "模板编码", example = "test_01", description = "模糊匹配") + @Schema(description = "模板编码,模糊匹配", example = "test_01") private String code; - @Schema(title = "模板内容", example = "你好,{name}。你长的太{like}啦!", description = "模糊匹配") + @Schema(description = "模板内容,模糊匹配", example = "你好,{name}。你长的太{like}啦!") private String content; - @Schema(title = "短信 API 的模板编号", example = "4383920", description = "模糊匹配") + @Schema(description = "短信 API 的模板编号,模糊匹配", example = "4383920") private String apiTemplateId; - @Schema(title = "短信渠道编号", example = "10") + @Schema(description = "短信渠道编号", example = "10") private Long channelId; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateRespVO.java index 853056b16..e1874ce67 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateRespVO.java @@ -8,22 +8,22 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@Schema(title = "管理后台 - 短信模板 Response VO") +@Schema(description = "管理后台 - 短信模板 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsTemplateRespVO extends SmsTemplateBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @Schema(title = "短信渠道编码", required = true, example = "ALIYUN") + @Schema(description = "短信渠道编码", required = true, example = "ALIYUN") private String channelCode; - @Schema(title = "参数数组", example = "name,code") + @Schema(description = "参数数组", example = "name,code") private List params; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateSendReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateSendReqVO.java index f8ca2a0e0..11561fae9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateSendReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateSendReqVO.java @@ -6,19 +6,19 @@ import lombok.Data; import javax.validation.constraints.NotNull; import java.util.Map; -@Schema(title = "管理后台 - 短信模板的发送 Request VO") +@Schema(description = "管理后台 - 短信模板的发送 Request VO") @Data public class SmsTemplateSendReqVO { - @Schema(title = "手机号", required = true, example = "15601691300") + @Schema(description = "手机号", required = true, example = "15601691300") @NotNull(message = "手机号不能为空") private String mobile; - @Schema(title = "模板编码", required = true, example = "test_01") + @Schema(description = "模板编码", required = true, example = "test_01") @NotNull(message = "模板编码不能为空") private String templateCode; - @Schema(title = "模板参数") + @Schema(description = "模板参数") private Map templateParams; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateUpdateReqVO.java index 44531e799..6cfcdfe5f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/vo/template/SmsTemplateUpdateReqVO.java @@ -7,13 +7,13 @@ import lombok.ToString; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 短信模板更新 Request VO") +@Schema(description = "管理后台 - 短信模板更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class SmsTemplateUpdateReqVO extends SmsTemplateBaseVO { - @Schema(title = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserBindReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserBindReqVO.java index 54d52e1f0..c4d36e986 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserBindReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserBindReqVO.java @@ -11,23 +11,23 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 社交绑定 Request VO,使用 code 授权码") +@Schema(description = "管理后台 - 社交绑定 Request VO,使用 code 授权码") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class SocialUserBindReqVO { - @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 UserSocialTypeEnum 枚举值") + @Schema(description = "社交平台的类型,参见 UserSocialTypeEnum 枚举值", required = true, example = "10") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @Schema(title = "授权码", required = true, example = "1024") + @Schema(description = "授权码", required = true, example = "1024") @NotEmpty(message = "授权码不能为空") private String code; - @Schema(title = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + @Schema(description = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") @NotEmpty(message = "state 不能为空") private String state; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserUnbindReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserUnbindReqVO.java index 933e06d9b..aa293ca5c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserUnbindReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/SocialUserUnbindReqVO.java @@ -11,19 +11,19 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 取消社交绑定 Request VO") +@Schema(description = "管理后台 - 取消社交绑定 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @Builder public class SocialUserUnbindReqVO { - @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 UserSocialTypeEnum 枚举值") + @Schema(description = "社交平台的类型,参见 UserSocialTypeEnum 枚举值", required = true, example = "10") @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") private Integer type; - @Schema(title = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") + @Schema(description = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") @NotEmpty(message = "社交用户的 openid 不能为空") private String openid; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageBaseVO.java index d4ff85926..53adc072f 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageBaseVO.java @@ -13,18 +13,18 @@ import java.util.Set; @Data public class TenantPackageBaseVO { - @Schema(title = "套餐名", required = true, example = "VIP") + @Schema(description = "套餐名", required = true, example = "VIP") @NotNull(message = "套餐名不能为空") private String name; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态,参见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; - @Schema(title = "备注", example = "好") + @Schema(description = "备注", example = "好") private String remark; - @Schema(title = "关联的菜单编号", required = true) + @Schema(description = "关联的菜单编号", required = true) @NotNull(message = "关联的菜单编号不能为空") private Set menuIds; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageCreateReqVO.java index 46f544fa6..255971447 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageCreateReqVO.java @@ -5,7 +5,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(title = "管理后台 - 租户套餐创建 Request VO") +@Schema(description = "管理后台 - 租户套餐创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java index 984dafb39..525a5da73 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackagePageReqVO.java @@ -11,22 +11,22 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 租户套餐分页 Request VO") +@Schema(description = "管理后台 - 租户套餐分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantPackagePageReqVO extends PageParam { - @Schema(title = "套餐名", example = "VIP") + @Schema(description = "套餐名", example = "VIP") private String name; - @Schema(title = "状态", example = "1") + @Schema(description = "状态", example = "1") private Integer status; - @Schema(title = "备注", example = "好") + @Schema(description = "备注", example = "好") private String remark; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java index e1734cd7b..f1a0d2f46 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageRespVO.java @@ -7,16 +7,16 @@ import lombok.ToString; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 租户套餐 Response VO") +@Schema(description = "管理后台 - 租户套餐 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantPackageRespVO extends TenantPackageBaseVO { - @Schema(title = "套餐编号", required = true, example = "1024") + @Schema(description = "套餐编号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java index 112495807..feeff1fe8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageSimpleRespVO.java @@ -5,15 +5,15 @@ import lombok.Data; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 租户套餐精简 Response VO") +@Schema(description = "管理后台 - 租户套餐精简 Response VO") @Data public class TenantPackageSimpleRespVO { - @Schema(title = "套餐编号", required = true, example = "1024") + @Schema(description = "套餐编号", required = true, example = "1024") @NotNull(message = "套餐编号不能为空") private Long id; - @Schema(title = "套餐名", required = true, example = "VIP") + @Schema(description = "套餐名", required = true, example = "VIP") @NotNull(message = "套餐名不能为空") private String name; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageUpdateReqVO.java index 4e4a9cdfc..a91f2fb3d 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/packages/TenantPackageUpdateReqVO.java @@ -4,13 +4,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 租户套餐更新 Request VO") +@Schema(description = "管理后台 - 租户套餐更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantPackageUpdateReqVO extends TenantPackageBaseVO { - @Schema(title = "套餐编号", required = true, example = "1024") + @Schema(description = "套餐编号", required = true, example = "1024") @NotNull(message = "套餐编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java index 4a1570135..4673e2990 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantBaseVO.java @@ -13,33 +13,33 @@ import java.time.LocalDateTime; @Data public class TenantBaseVO { - @Schema(title = "租户名", required = true, example = "芋道") + @Schema(description = "租户名", required = true, example = "芋道") @NotNull(message = "租户名不能为空") private String name; - @Schema(title = "联系人", required = true, example = "芋艿") + @Schema(description = "联系人", required = true, example = "芋艿") @NotNull(message = "联系人不能为空") private String contactName; - @Schema(title = "联系手机", example = "15601691300") + @Schema(description = "联系手机", example = "15601691300") private String contactMobile; - @Schema(title = "租户状态", required = true, example = "1") + @Schema(description = "租户状态", required = true, example = "1") @NotNull(message = "租户状态") private Integer status; - @Schema(title = "绑定域名", example = "https://www.iocoder.cn") + @Schema(description = "绑定域名", example = "https://www.iocoder.cn") private String domain; - @Schema(title = "租户套餐编号", required = true, example = "1024") + @Schema(description = "租户套餐编号", required = true, example = "1024") @NotNull(message = "租户套餐编号不能为空") private Long packageId; - @Schema(title = "过期时间", required = true) + @Schema(description = "过期时间", required = true) @NotNull(message = "过期时间不能为空") private LocalDateTime expireTime; - @Schema(title = "账号数量", required = true, example = "1024") + @Schema(description = "账号数量", required = true, example = "1024") @NotNull(message = "账号数量不能为空") private Integer accountCount; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantCreateReqVO.java index 209643cea..8db44c2c1 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantCreateReqVO.java @@ -9,19 +9,19 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; -@Schema(title = "管理后台 - 租户创建 Request VO") +@Schema(description = "管理后台 - 租户创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantCreateReqVO extends TenantBaseVO { - @Schema(title = "用户账号", required = true, example = "yudao") + @Schema(description = "用户账号", required = true, example = "yudao") @NotBlank(message = "用户账号不能为空") @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成") @Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符") private String username; - @Schema(title = "密码", required = true, example = "123456") + @Schema(description = "密码", required = true, example = "123456") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantExportReqVO.java index 92e365912..706337276 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantExportReqVO.java @@ -8,24 +8,24 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 租户 Excel 导出 Request VO", description = "参数和 TenantPageReqVO 是一致的") +@Schema(description = "管理后台 - 租户 Excel 导出 Request VO,参数和 TenantPageReqVO 是一致的") @Data public class TenantExportReqVO { - @Schema(title = "租户名", example = "芋道") + @Schema(description = "租户名", example = "芋道") private String name; - @Schema(title = "联系人", example = "芋艿") + @Schema(description = "联系人", example = "芋艿") private String contactName; - @Schema(title = "联系手机", example = "15601691300") + @Schema(description = "联系手机", example = "15601691300") private String contactMobile; - @Schema(title = "租户状态(0正常 1停用)", example = "1") + @Schema(description = "租户状态(0正常 1停用)", example = "1") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java index 501d75a77..512a4a761 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantPageReqVO.java @@ -11,26 +11,26 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 租户分页 Request VO") +@Schema(description = "管理后台 - 租户分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantPageReqVO extends PageParam { - @Schema(title = "租户名", example = "芋道") + @Schema(description = "租户名", example = "芋道") private String name; - @Schema(title = "联系人", example = "芋艿") + @Schema(description = "联系人", example = "芋艿") private String contactName; - @Schema(title = "联系手机", example = "15601691300") + @Schema(description = "联系手机", example = "15601691300") private String contactMobile; - @Schema(title = "租户状态(0正常 1停用)", example = "1") + @Schema(description = "租户状态(0正常 1停用)", example = "1") private Integer status; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(title = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java index bbd3932c9..10e1aa552 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantRespVO.java @@ -5,16 +5,16 @@ import lombok.*; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 租户 Response VO") +@Schema(description = "管理后台 - 租户 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantRespVO extends TenantBaseVO { - @Schema(title = "租户编号", required = true, example = "1024") + @Schema(description = "租户编号", required = true, example = "1024") private Long id; - @Schema(title = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantUpdateReqVO.java index dd8be9659..1969fe302 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/vo/tenant/TenantUpdateReqVO.java @@ -4,13 +4,13 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.*; -@Schema(title = "管理后台 - 租户更新 Request VO") +@Schema(description = "管理后台 - 租户更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class TenantUpdateReqVO extends TenantBaseVO { - @Schema(title = "租户编号", required = true, example = "1024") + @Schema(description = "租户编号", required = true, example = "1024") @NotNull(message = "租户编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java index 4a0dd9b9d..9e8298f45 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileRespVO.java @@ -15,22 +15,22 @@ import java.util.List; @EqualsAndHashCode(callSuper = true) @NoArgsConstructor @AllArgsConstructor -@Schema(title = "管理后台 - 用户个人中心信息 Response VO") +@Schema(description = "管理后台 - 用户个人中心信息 Response VO") public class UserProfileRespVO extends UserBaseVO { - @Schema(title = "用户编号", required = true, example = "1") + @Schema(description = "用户编号", required = true, example = "1") private Long id; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", required = true, example = "1") private Integer status; - @Schema(title = "最后登录 IP", required = true, example = "192.168.1.1") + @Schema(description = "最后登录 IP", required = true, example = "192.168.1.1") private String loginIp; - @Schema(title = "最后登录时间", required = true, example = "时间戳格式") + @Schema(description = "最后登录时间", required = true, example = "时间戳格式") private LocalDateTime loginDate; - @Schema(title = "创建时间", required = true, example = "时间戳格式") + @Schema(description = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; /** @@ -52,50 +52,50 @@ public class UserProfileRespVO extends UserBaseVO { */ private List socialUsers; - @Schema(title = "角色") + @Schema(description = "角色") @Data public static class Role { - @Schema(title = "角色编号", required = true, example = "1") + @Schema(description = "角色编号", required = true, example = "1") private Long id; - @Schema(title = "角色名称", required = true, example = "普通角色") + @Schema(description = "角色名称", required = true, example = "普通角色") private String name; } - @Schema(title = "部门") + @Schema(description = "部门") @Data public static class Dept { - @Schema(title = "部门编号", required = true, example = "1") + @Schema(description = "部门编号", required = true, example = "1") private Long id; - @Schema(title = "部门名称", required = true, example = "研发部") + @Schema(description = "部门名称", required = true, example = "研发部") private String name; } - @Schema(title = "岗位") + @Schema(description = "岗位") @Data public static class Post { - @Schema(title = "岗位编号", required = true, example = "1") + @Schema(description = "岗位编号", required = true, example = "1") private Long id; - @Schema(title = "岗位名称", required = true, example = "开发") + @Schema(description = "岗位名称", required = true, example = "开发") private String name; } - @Schema(title = "社交用户") + @Schema(description = "社交用户") @Data public static class SocialUser { - @Schema(title = "社交平台的类型", required = true, example = "10", description = "参见 SocialTypeEnum 枚举类") + @Schema(description = "社交平台的类型,参见 SocialTypeEnum 枚举类", required = true, example = "10") private Integer type; - @Schema(title = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") + @Schema(description = "社交用户的 openid", required = true, example = "IPRmJ0wvBptiPIlGEZiPewGwiEiE") private String openid; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdatePasswordReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdatePasswordReqVO.java index 94684ce6c..d784537cf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdatePasswordReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdatePasswordReqVO.java @@ -6,16 +6,16 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotEmpty; -@Schema(title = "管理后台 - 用户个人中心更新密码 Request VO") +@Schema(description = "管理后台 - 用户个人中心更新密码 Request VO") @Data public class UserProfileUpdatePasswordReqVO { - @Schema(title = "旧密码", required = true, example = "123456") + @Schema(description = "旧密码", required = true, example = "123456") @NotEmpty(message = "旧密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String oldPassword; - @Schema(title = "新密码", required = true, example = "654321") + @Schema(description = "新密码", required = true, example = "654321") @NotEmpty(message = "新密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String newPassword; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java index e9696add5..727f28178 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java @@ -7,23 +7,23 @@ import javax.validation.constraints.Email; import javax.validation.constraints.Size; -@Schema(title = "管理后台 - 用户个人信息更新 Request VO") +@Schema(description = "管理后台 - 用户个人信息更新 Request VO") @Data public class UserProfileUpdateReqVO { - @Schema(title = "用户昵称", required = true, example = "芋艿") + @Schema(description = "用户昵称", required = true, example = "芋艿") @Size(max = 30, message = "用户昵称长度不能超过 30 个字符") private String nickname; - @Schema(title = "用户邮箱", example = "yudao@iocoder.cn") + @Schema(description = "用户邮箱", example = "yudao@iocoder.cn") @Email(message = "邮箱格式不正确") @Size(max = 50, message = "邮箱长度不能超过 50 个字符") private String email; - @Schema(title = "手机号码", example = "15601691300") + @Schema(description = "手机号码", example = "15601691300") private String mobile; - @Schema(title = "用户性别", example = "1", description = "参见 SexEnum 枚举类") + @Schema(description = "用户性别-参见 SexEnum 枚举类", example = "1") private Integer sex; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserBaseVO.java index ea9fff93b..93467b2ab 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserBaseVO.java @@ -17,38 +17,38 @@ import java.util.Set; @Data public class UserBaseVO { - @Schema(title = "用户账号", required = true, example = "yudao") + @Schema(description = "用户账号", required = true, example = "yudao") @NotBlank(message = "用户账号不能为空") @Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成") @Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符") private String username; - @Schema(title = "用户昵称", required = true, example = "芋艿") + @Schema(description = "用户昵称", required = true, example = "芋艿") @Size(max = 30, message = "用户昵称长度不能超过30个字符") private String nickname; - @Schema(title = "备注", example = "我是一个用户") + @Schema(description = "备注", example = "我是一个用户") private String remark; - @Schema(title = "部门ID", example = "我是一个用户") + @Schema(description = "部门ID", example = "我是一个用户") private Long deptId; - @Schema(title = "岗位编号数组", example = "1") + @Schema(description = "岗位编号数组", example = "1") private Set postIds; - @Schema(title = "用户邮箱", example = "yudao@iocoder.cn") + @Schema(description = "用户邮箱", example = "yudao@iocoder.cn") @Email(message = "邮箱格式不正确") @Size(max = 50, message = "邮箱长度不能超过 50 个字符") private String email; - @Schema(title = "手机号码", example = "15601691300") + @Schema(description = "手机号码", example = "15601691300") @Mobile private String mobile; - @Schema(title = "用户性别", example = "1", description = "参见 SexEnum 枚举类") + @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1") private Integer sex; - @Schema(title = "用户头像", example = "https://www.iocoder.cn/xxx.png") + @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") private String avatar; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserCreateReqVO.java index 940ad80a3..1a80ac2d0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserCreateReqVO.java @@ -7,12 +7,12 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotEmpty; -@Schema(title = "管理后台 - 用户创建 Request VO") +@Schema(description = "管理后台 - 用户创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class UserCreateReqVO extends UserBaseVO { - @Schema(title = "密码", required = true, example = "123456") + @Schema(description = "密码", required = true, example = "123456") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserExportReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserExportReqVO.java index 356db6444..5d9464b79 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserExportReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserExportReqVO.java @@ -10,26 +10,26 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 用户导出 Request VO", description = "参数和 UserPageReqVO 是一致的") +@Schema(description = "管理后台 - 用户导出 Request VO,参数和 UserPageReqVO 是一致的") @Data @NoArgsConstructor @AllArgsConstructor public class UserExportReqVO { - @Schema(title = "用户账号", example = "yudao", description = "模糊匹配") + @Schema(description = "用户账号,模糊匹配", example = "yudao") private String username; - @Schema(title = "手机号码", example = "yudao", description = "模糊匹配") + @Schema(description = "手机号码,模糊匹配", example = "yudao") private String mobile; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; - @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; - @Schema(title = "部门编号", example = "1024", description = "同时筛选子部门") + @Schema(description = "部门编号,同时筛选子部门", example = "1024") private Long deptId; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportRespVO.java index 36ffa2f71..c0dcd09aa 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserImportRespVO.java @@ -7,18 +7,18 @@ import lombok.Data; import java.util.List; import java.util.Map; -@Schema(title = "管理后台 - 用户导入 Response VO") +@Schema(description = "管理后台 - 用户导入 Response VO") @Data @Builder public class UserImportRespVO { - @Schema(title = "创建成功的用户名数组", required = true) + @Schema(description = "创建成功的用户名数组", required = true) private List createUsernames; - @Schema(title = "更新成功的用户名数组", required = true) + @Schema(description = "更新成功的用户名数组", required = true) private List updateUsernames; - @Schema(title = "导入失败的用户集合", required = true, description = "key 为用户名,value 为失败原因") + @Schema(description = "导入失败的用户集合,key 为用户名,value 为失败原因", required = true) private Map failureUsernames; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageItemRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageItemRespVO.java index 21f72b090..52ae7b7ea 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageItemRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageItemRespVO.java @@ -6,7 +6,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -@Schema(title = "管理后台 - 用户分页时的信息 Response VO", description = "相比用户基本信息来说,会多部门信息") +@Schema(description = "管理后台 - 用户分页时的信息 Response VO,相比用户基本信息来说,会多部门信息") @Data @NoArgsConstructor @AllArgsConstructor @@ -18,14 +18,14 @@ public class UserPageItemRespVO extends UserRespVO { */ private Dept dept; - @Schema(title = "部门") + @Schema(description = "部门") @Data public static class Dept { - @Schema(title = "部门编号", required = true, example = "1") + @Schema(description = "部门编号", required = true, example = "1") private Long id; - @Schema(title = "部门名称", required = true, example = "研发部") + @Schema(description = "部门名称", required = true, example = "研发部") private String name; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java index 193a74807..4e6a42541 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java @@ -12,27 +12,27 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(title = "管理后台 - 用户分页 Request VO") +@Schema(description = "管理后台 - 用户分页 Request VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class UserPageReqVO extends PageParam { - @Schema(title = "用户账号", example = "yudao", description = "模糊匹配") + @Schema(description = "用户账号,模糊匹配", example = "yudao") private String username; - @Schema(title = "手机号码", example = "yudao", description = "模糊匹配") + @Schema(description = "手机号码,模糊匹配", example = "yudao") private String mobile; - @Schema(title = "展示状态", example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1") private Integer status; - @Schema(title = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") + @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; - @Schema(title = "部门编号", example = "1024", description = "同时筛选子部门") + @Schema(description = "部门编号,同时筛选子部门", example = "1024") private Long deptId; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java index 68208729c..93a53b74e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserRespVO.java @@ -6,26 +6,26 @@ import lombok.*; import java.time.LocalDateTime; -@Schema(title = "管理后台 - 用户信息 Response VO") +@Schema(description = "管理后台 - 用户信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class UserRespVO extends UserBaseVO { - @Schema(title = "用户编号", required = true, example = "1") + @Schema(description = "用户编号", required = true, example = "1") private Long id; - @Schema(title = "状态", required = true, example = "1", description = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态,参见 CommonStatusEnum 枚举类", required = true, example = "1") private Integer status; - @Schema(title = "最后登录 IP", required = true, example = "192.168.1.1") + @Schema(description = "最后登录 IP", required = true, example = "192.168.1.1") private String loginIp; - @Schema(title = "最后登录时间", required = true, example = "时间戳格式") + @Schema(description = "最后登录时间", required = true, example = "时间戳格式") private LocalDateTime loginDate; - @Schema(title = "创建时间", required = true, example = "时间戳格式") + @Schema(description = "创建时间", required = true, example = "时间戳格式") private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSimpleRespVO.java index 0a2daaf6f..61460c065 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSimpleRespVO.java @@ -5,16 +5,16 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@Schema(title = "用户精简信息 Response VO") +@Schema(description = "用户精简信息 Response VO") @Data @NoArgsConstructor @AllArgsConstructor public class UserSimpleRespVO { - @Schema(title = "用户编号", required = true, example = "1024") + @Schema(description = "用户编号", required = true, example = "1024") private Long id; - @Schema(title = "用户昵称", required = true, example = "芋道") + @Schema(description = "用户昵称", required = true, example = "芋道") private String nickname; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdatePasswordReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdatePasswordReqVO.java index 44e5eb3f7..786fca8ca 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdatePasswordReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdatePasswordReqVO.java @@ -7,15 +7,15 @@ import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 用户更新密码 Request VO") +@Schema(description = "管理后台 - 用户更新密码 Request VO") @Data public class UserUpdatePasswordReqVO { - @Schema(title = "用户编号", required = true, example = "1024") + @Schema(description = "用户编号", required = true, example = "1024") @NotNull(message = "用户编号不能为空") private Long id; - @Schema(title = "密码", required = true, example = "123456") + @Schema(description = "密码", required = true, example = "123456") @NotEmpty(message = "密码不能为空") @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateReqVO.java index f5d4cc92f..d11a6e493 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateReqVO.java @@ -6,12 +6,12 @@ import lombok.EqualsAndHashCode; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 用户更新 Request VO") +@Schema(description = "管理后台 - 用户更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) public class UserUpdateReqVO extends UserBaseVO { - @Schema(title = "用户编号", required = true, example = "1024") + @Schema(description = "用户编号", required = true, example = "1024") @NotNull(message = "用户编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateStatusReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateStatusReqVO.java index 11b9afd2f..0f8e21d0c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateStatusReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserUpdateStatusReqVO.java @@ -5,15 +5,15 @@ import lombok.Data; import javax.validation.constraints.NotNull; -@Schema(title = "管理后台 - 用户更新状态 Request VO") +@Schema(description = "管理后台 - 用户更新状态 Request VO") @Data public class UserUpdateStatusReqVO { - @Schema(title = "用户编号", required = true, example = "1024") + @Schema(description = "用户编号", required = true, example = "1024") @NotNull(message = "角色编号不能为空") private Long id; - @Schema(title = "状态", required = true, example = "1", description = "见 CommonStatusEnum 枚举") + @Schema(description = "状态,见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") // @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") private Integer status; diff --git a/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/vo/AppShopOrderCreateRespVO.java b/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/vo/AppShopOrderCreateRespVO.java index 6879beab4..0a8c30b36 100644 --- a/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/vo/AppShopOrderCreateRespVO.java +++ b/yudao-server/src/main/java/cn/iocoder/yudao/module/shop/controller/app/vo/AppShopOrderCreateRespVO.java @@ -5,16 +5,16 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; -@Schema(title = "用户 APP - 商城订单创建 Response VO") +@Schema(description = "用户 APP - 商城订单创建 Response VO") @Data @Builder @AllArgsConstructor public class AppShopOrderCreateRespVO { - @Schema(title = "商城订单编号", required = true, example = "1024") + @Schema(description = "商城订单编号", required = true, example = "1024") private Long id; - @Schema(title = "支付订单编号", required = true, example = "2048") + @Schema(description = "支付订单编号", required = true, example = "2048") private Long payOrderId; } diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 7918d443c..583a58563 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -34,6 +34,10 @@ spring: redis: time-to-live: 1h # 设置过期时间为 1 小时 +springdoc: + swagger-ui: + path: /swagger-ui + # 工作流 Flowable 配置 flowable: # 1. false: 默认值,Flowable 启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常 diff --git a/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue b/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue index 574e9ddd2..5d4697c1a 100644 --- a/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue +++ b/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue @@ -8,5 +8,5 @@ import { ref } from 'vue' import { IFrame } from '@/components/IFrame' const BASE_URL = import.meta.env.VITE_BASE_URL -const src = ref(BASE_URL + '/swagger-ui') +const src = ref(BASE_URL + '/doc.html') From 683b49a8a49d6e1833b230431fddc5ef48acb1ed Mon Sep 17 00:00:00 2001 From: xingyu Date: Thu, 22 Dec 2022 00:49:23 +0800 Subject: [PATCH 05/59] =?UTF-8?q?feat:=20springdoc=20=E5=BC=80=E5=90=AF?= =?UTF-8?q?=E8=AE=A4=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/YudaoSwaggerAutoConfiguration.java | 27 ++++++++++++++++--- .../src/main/resources/application.yaml | 1 + 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index 4bb2d77ac..9e05fe3a0 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -6,7 +6,10 @@ import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; -import org.springdoc.core.GroupedOpenApi; +import org.springdoc.core.*; +import org.springdoc.core.customizers.OpenApiBuilderCustomizer; +import org.springdoc.core.customizers.ServerBaseUrlCustomizer; +import org.springdoc.core.providers.JavadocProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -15,6 +18,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.http.HttpHeaders; import java.util.Arrays; +import java.util.List; +import java.util.Optional; /** * Swagger3 自动配置类 @@ -38,17 +43,17 @@ public class YudaoSwaggerAutoConfiguration { .license(new License().name("MIT").url("https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE")); //鉴权组件(随便起名的) SecurityScheme securityScheme = new SecurityScheme() - .type(SecurityScheme.Type.OAUTH2) + .type(SecurityScheme.Type.APIKEY) .scheme("bearer")//固定写法 .bearerFormat("JWT") .in(SecurityScheme.In.HEADER) .name(HttpHeaders.AUTHORIZATION); Components components = new Components() - .addSecuritySchemes("bearer", securityScheme); + .addSecuritySchemes("Bearer", securityScheme); //鉴权限制要求(随便起名的) SecurityRequirement securityRequirement = new SecurityRequirement() - .addList("bearer", Arrays.asList("read", "write")); + .addList(HttpHeaders.AUTHORIZATION, Arrays.asList("read", "write")); return new OpenAPI() .info(info) @@ -56,6 +61,20 @@ public class YudaoSwaggerAutoConfiguration { .addSecurityItem(securityRequirement); } + /** + * 自定义 openapi 处理器 + */ + @Bean + public OpenAPIService openApiBuilder(Optional openAPI, + SecurityService securityParser, + SpringDocConfigProperties springDocConfigProperties, + PropertyResolverUtils propertyResolverUtils, + Optional> openApiBuilderCustomisers, + Optional> serverBaseUrlCustomisers, + Optional javadocProvider) { + return new OpenAPIService(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers, javadocProvider); + } + @Bean public GroupedOpenApi appApi() { return GroupedOpenApi.builder() diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 583a58563..22e32d931 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -35,6 +35,7 @@ spring: time-to-live: 1h # 设置过期时间为 1 小时 springdoc: + show-actuator: true swagger-ui: path: /swagger-ui From df2c137fe2d92132948970eb6a984a3466f0d727 Mon Sep 17 00:00:00 2001 From: dengxiaobing <657563945@qq.com> Date: Fri, 30 Dec 2022 10:04:20 +0800 Subject: [PATCH 06/59] =?UTF-8?q?=E6=B8=85=E7=90=86=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=20sql=20=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 4 +- sql/postgresql/ruoyi-vue-pro.sql | 4 +- sql/sqlserver/ruoyi-vue-pro.sql | 4 +- .../src/test/resources/sql/clean.sql | 6 +- .../src/test/resources/sql/create_tables.sql | 13 ----- .../src/test/resources/sql/clean.sql | 5 +- .../src/test/resources/sql/create_tables.sql | 1 - .../src/test/resources/sql/create_tables.sql | 13 ----- .../src/test/resources/sql/clean.sql | 5 +- .../src/test/resources/sql/create_tables.sql | 58 ------------------- 10 files changed, 15 insertions(+), 98 deletions(-) diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index 39cb52afe..be1aa16eb 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -2463,7 +2463,7 @@ CREATE TABLE `system_tenant` ( `package_id` bigint NOT NULL COMMENT '租户套餐编号', `expire_time` datetime NOT NULL COMMENT '过期时间', `account_count` int NOT NULL COMMENT '账号数量', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '创建者', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', @@ -2490,7 +2490,7 @@ CREATE TABLE `system_tenant_package` ( `status` tinyint NOT NULL DEFAULT 0 COMMENT '租户状态(0正常 1停用)', `remark` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '备注', `menu_ids` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '关联的菜单编号', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '创建者', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', diff --git a/sql/postgresql/ruoyi-vue-pro.sql b/sql/postgresql/ruoyi-vue-pro.sql index 7484486c2..c16a51f75 100644 --- a/sql/postgresql/ruoyi-vue-pro.sql +++ b/sql/postgresql/ruoyi-vue-pro.sql @@ -3817,7 +3817,7 @@ CREATE TABLE "system_tenant" ( "package_id" int8 NOT NULL, "expire_time" timestamp(6) NOT NULL, "account_count" int4 NOT NULL, - "creator" varchar(64) COLLATE "pg_catalog"."default" NOT NULL, + "creator" varchar(64) COLLATE "pg_catalog"."default", "create_time" timestamp(6) NOT NULL, "updater" varchar(64) COLLATE "pg_catalog"."default", "update_time" timestamp(6) NOT NULL, @@ -3860,7 +3860,7 @@ CREATE TABLE "system_tenant_package" ( "status" int2 NOT NULL, "remark" varchar(256) COLLATE "pg_catalog"."default", "menu_ids" varchar(2048) COLLATE "pg_catalog"."default" NOT NULL, - "creator" varchar(64) COLLATE "pg_catalog"."default" NOT NULL, + "creator" varchar(64) COLLATE "pg_catalog"."default", "create_time" timestamp(6) NOT NULL, "updater" varchar(64) COLLATE "pg_catalog"."default", "update_time" timestamp(6) NOT NULL, diff --git a/sql/sqlserver/ruoyi-vue-pro.sql b/sql/sqlserver/ruoyi-vue-pro.sql index 386e9bd2e..dd728f2c7 100644 --- a/sql/sqlserver/ruoyi-vue-pro.sql +++ b/sql/sqlserver/ruoyi-vue-pro.sql @@ -10600,7 +10600,7 @@ CREATE TABLE [dbo].[system_tenant] ( [package_id] bigint NOT NULL, [expire_time] datetime2(7) NOT NULL, [account_count] int NOT NULL, - [creator] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, + [creator] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [create_time] datetime2(7) NOT NULL, [updater] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [update_time] datetime2(7) NOT NULL, @@ -10761,7 +10761,7 @@ CREATE TABLE [dbo].[system_tenant_package] ( [status] tinyint NOT NULL, [remark] nvarchar(256) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [menu_ids] nvarchar(2048) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, - [creator] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, + [creator] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [create_time] datetime2(7) NOT NULL, [updater] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [update_time] datetime2(7) NOT NULL, diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/clean.sql b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/clean.sql index eb05d3d5a..3dc20f7ba 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/clean.sql @@ -1,12 +1,10 @@ DELETE FROM "infra_config"; +DELETE FROM "infra_file_config"; DELETE FROM "infra_file"; DELETE FROM "infra_job"; DELETE FROM "infra_job_log"; DELETE FROM "infra_api_access_log"; DELETE FROM "infra_api_error_log"; -DELETE FROM "infra_api_access_log"; -DELETE FROM "infra_file"; -DELETE FROM "infra_api_error_log"; -DELETE FROM "infra_test_demo"; DELETE FROM "infra_file_config"; +DELETE FROM "infra_test_demo"; DELETE FROM "infra_data_source_config"; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql index 5825e0fef..e490b8779 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql @@ -85,19 +85,6 @@ CREATE TABLE IF NOT EXISTS "infra_job_log" ( PRIMARY KEY ("id") )COMMENT='定时任务日志表'; -CREATE TABLE IF NOT EXISTS "inf_file" ( - "id" varchar(188) NOT NULL, - "type" varchar(63) DEFAULT NULL, - "content" blob NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint not null default '0', - PRIMARY KEY ("id") - ) COMMENT '文件表'; - CREATE TABLE IF NOT EXISTS "infra_api_access_log" ( "id" bigint not null GENERATED BY DEFAULT AS IDENTITY, "trace_id" varchar(64) not null default '', diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql index aad191337..3acd7a48e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql @@ -1,3 +1,6 @@ DELETE FROM "product_sku"; +DELETE FROM "product_spu"; +DELETE FROM "product_category"; + + -DELETE FROM "product_spu"; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql index 9d26cc733..6b0ffc7c7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql @@ -21,7 +21,6 @@ CREATE TABLE IF NOT EXISTS `product_sku` ( PRIMARY KEY (`id`) ) COMMENT '商品sku'; - CREATE TABLE IF NOT EXISTS `product_spu` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', diff --git a/yudao-module-member/yudao-module-member-biz/src/test/resources/sql/create_tables.sql b/yudao-module-member/yudao-module-member-biz/src/test/resources/sql/create_tables.sql index b0347b058..9724c80d6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-member/yudao-module-member-biz/src/test/resources/sql/create_tables.sql @@ -17,19 +17,6 @@ CREATE TABLE IF NOT EXISTS "member_user" ( PRIMARY KEY ("id") ) COMMENT '会员表'; --- inf 开头的 DB -CREATE TABLE IF NOT EXISTS "inf_file" ( - "id" varchar(188) NOT NULL, - "type" varchar(63) DEFAULT NULL, - "content" blob NOT NULL, - "creator" varchar(64) DEFAULT '', - "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '文件表'; - CREATE TABLE IF NOT EXISTS "member_address" ( "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, "user_id" bigint(20) NOT NULL, diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql index b13b191db..dac3d6870 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql @@ -4,10 +4,11 @@ DELETE FROM "system_role"; DELETE FROM "system_role_menu"; DELETE FROM "system_menu"; DELETE FROM "system_user_role"; -DELETE FROM "system_user_post"; DELETE FROM "system_dict_type"; DELETE FROM "system_user_session"; DELETE FROM "system_post"; +DELETE FROM "system_user_post"; +DELETE FROM "system_notice"; DELETE FROM "system_login_log"; DELETE FROM "system_operate_log"; DELETE FROM "system_users"; @@ -24,4 +25,4 @@ DELETE FROM "system_oauth2_client"; DELETE FROM "system_oauth2_approve"; DELETE FROM "system_oauth2_access_token"; DELETE FROM "system_oauth2_refresh_token"; -DELETE FROM "system_oauth2_code"; +DELETE FROM "system_oauth2_code"; \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql index 7590e57a3..f50c27a57 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql @@ -162,7 +162,6 @@ CREATE TABLE IF NOT EXISTS `system_user_post`( PRIMARY KEY (`id`) ) COMMENT ='用户岗位表'; - CREATE TABLE IF NOT EXISTS "system_notice" ( "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "title" varchar(50) NOT NULL COMMENT '公告标题', @@ -250,63 +249,6 @@ CREATE TABLE IF NOT EXISTS "system_users" ( primary key ("id") ) comment '用户信息表'; -CREATE TABLE IF NOT EXISTS "inf_api_access_log" ( - "id" bigint not null GENERATED BY DEFAULT AS IDENTITY, - "trace_id" varchar(64) not null default '', - "user_id" bigint not null default '0', - "user_type" tinyint not null default '0', - "application_name" varchar(50) not null, - "request_method" varchar(16) not null default '', - "request_url" varchar(255) not null default '', - "request_params" varchar(8000) not null default '', - "user_ip" varchar(50) not null, - "user_agent" varchar(512) not null, - "begin_time" timestamp not null, - "end_time" timestamp not null, - "duration" integer not null, - "result_code" integer not null default '0', - "result_msg" varchar(512) default '', - "creator" varchar(64) default '', - "create_time" timestamp not null default current_timestamp, - "updater" varchar(64) default '', - "update_time" timestamp not null default current_timestamp, - "deleted" bit not null default false, - "tenant_id" bigint not null default '0', - primary key ("id") -) COMMENT 'API 访问日志表'; - -CREATE TABLE IF NOT EXISTS "inf_api_error_log" ( - "id" bigint not null GENERATED BY DEFAULT AS IDENTITY, - "trace_id" varchar(64) not null, - "user_id" bigint not null default '0', - "user_type" tinyint not null default '0', - "application_name" varchar(50) not null, - "request_method" varchar(16) not null, - "request_url" varchar(255) not null, - "request_params" varchar(8000) not null, - "user_ip" varchar(50) not null, - "user_agent" varchar(512) not null, - "exception_time" timestamp not null, - "exception_name" varchar(128) not null default '', - "exception_message" clob not null, - "exception_root_cause_message" clob not null, - "exception_stack_trace" clob not null, - "exception_class_name" varchar(512) not null, - "exception_file_name" varchar(512) not null, - "exception_method_name" varchar(512) not null, - "exception_line_number" integer not null, - "process_status" tinyint not null, - "process_time" timestamp default null, - "process_user_id" bigint default '0', - "creator" varchar(64) default '', - "create_time" timestamp not null default current_timestamp, - "updater" varchar(64) default '', - "update_time" timestamp not null default current_timestamp, - "deleted" bit not null default false, - "tenant_id" bigint not null default '0', - primary key ("id") -) COMMENT '系统异常日志'; - CREATE TABLE IF NOT EXISTS "system_sms_channel" ( "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "signature" varchar(10) NOT NULL, From 854ba3315ccfc0080850dcac6e81bee03c3e17fc Mon Sep 17 00:00:00 2001 From: xingyu Date: Wed, 4 Jan 2023 10:57:19 +0800 Subject: [PATCH 07/59] marge master --- yudao-module-mall/pom.xml | 29 - .../yudao-module-product-api/pom.xml | 34 -- .../module/product/api/package-info.java | 4 - .../api/property/ProductPropertyValueApi.java | 23 - .../ProductPropertyValueDetailRespDTO.java | 33 -- .../module/product/api/sku/ProductSkuApi.java | 40 -- .../api/sku/dto/ProductSkuRespDTO.java | 95 --- .../sku/dto/ProductSkuUpdateStockReqDTO.java | 47 -- .../module/product/api/spu/ProductSpuApi.java | 24 - .../api/spu/dto/ProductSpuRespDTO.java | 127 ---- .../product/enums/ErrorCodeConstants.java | 45 -- .../ProductCommentAuditStatusEnum.java | 38 -- .../enums/delivery/DeliveryTypeEnum.java | 38 -- .../enums/group/ProductGroupStyleEnum.java | 38 -- .../enums/spu/ProductSpuSpecTypeEnum.java | 37 -- .../enums/spu/ProductSpuStatusEnum.java | 48 -- .../yudao-module-product-biz/pom.xml | 62 -- .../module/product/api/package-info.java | 1 - .../property/ProductPropertyValueApiImpl.java | 31 - .../product/api/sku/ProductSkuApiImpl.java | 49 -- .../product/api/spu/ProductSpuApiImpl.java | 38 -- .../admin/brand/ProductBrandController.java | 82 --- .../admin/brand/vo/ProductBrandBaseVO.java | 33 -- .../brand/vo/ProductBrandCreateReqVO.java | 11 - .../admin/brand/vo/ProductBrandListReqVO.java | 13 - .../admin/brand/vo/ProductBrandPageReqVO.java | 30 - .../admin/brand/vo/ProductBrandRespVO.java | 22 - .../brand/vo/ProductBrandUpdateReqVO.java | 16 - .../category/ProductCategoryController.java | 76 --- .../category/vo/ProductCategoryBaseVO.java | 37 -- .../vo/ProductCategoryCreateReqVO.java | 11 - .../category/vo/ProductCategoryListReqVO.java | 13 - .../category/vo/ProductCategoryRespVO.java | 19 - .../vo/ProductCategoryUpdateReqVO.java | 16 - .../property/ProductPropertyController.java | 99 ---- .../ProductPropertyValueController.java | 70 --- .../vo/ProductPropertyViewRespVO.java | 0 .../ProductPropertyAndValueRespVO.java | 35 -- .../vo/property/ProductPropertyBaseVO.java | 22 - .../property/ProductPropertyCreateReqVO.java | 15 - .../vo/property/ProductPropertyListReqVO.java | 15 - .../vo/property/ProductPropertyPageReqVO.java | 30 - .../vo/property/ProductPropertyRespVO.java | 22 - .../property/ProductPropertyUpdateReqVO.java | 20 - .../vo/value/ProductPropertyValueBaseVO.java | 27 - .../ProductPropertyValueCreateReqVO.java | 12 - .../ProductPropertyValueDetailRespVO.java | 23 - .../value/ProductPropertyValuePageReqVO.java | 24 - .../vo/value/ProductPropertyValueRespVO.java | 22 - .../ProductPropertyValueUpdateReqVO.java | 17 - .../admin/sku/ProductSkuController.java | 57 -- .../admin/sku/vo/ProductSkuBaseVO.java | 75 --- .../sku/vo/ProductSkuCreateOrUpdateReqVO.java | 21 - .../admin/sku/vo/ProductSkuOptionRespVO.java | 30 - .../admin/sku/vo/ProductSkuRespVO.java | 28 - .../admin/spu/ProductSpuController.http | 4 - .../admin/spu/ProductSpuController.java | 101 ---- .../admin/spu/vo/ProductSpuBaseVO.java | 76 --- .../admin/spu/vo/ProductSpuCreateReqVO.java | 24 - .../admin/spu/vo/ProductSpuDetailRespVO.java | 38 -- .../admin/spu/vo/ProductSpuPageReqVO.java | 45 -- .../admin/spu/vo/ProductSpuRespVO.java | 40 -- .../admin/spu/vo/ProductSpuSimpleRespVO.java | 26 - .../admin/spu/vo/ProductSpuUpdateReqVO.java | 29 - .../app/category/AppCategoryController.java | 38 -- .../app/category/vo/AppCategoryRespVO.java | 28 - .../controller/app/property/package-info.java | 4 - .../property/vo/property/package-info.java | 4 - .../AppProductPropertyValueDetailRespVO.java | 23 - .../app/spu/AppProductSpuController.http | 8 - .../app/spu/AppProductSpuController.java | 78 --- .../app/spu/vo/AppProductSpuDetailRespVO.java | 92 --- .../spu/vo/AppProductSpuPageItemRespVO.java | 40 -- .../app/spu/vo/AppProductSpuPageReqVO.java | 44 -- .../app/spu/vo/AppSpuPageReqVO.java | 0 .../app/spu/vo/AppSpuPageRespVO.java | 0 .../controller/app/spu/vo/AppSpuRespVO.java | 0 .../convert/brand/ProductBrandConvert.java | 33 -- .../category/ProductCategoryConvert.java | 32 - .../property/ProductPropertyConvert.java | 48 -- .../ProductPropertyValueConvert.java | 55 -- .../convert/sku/ProductSkuConvert.java | 93 --- .../convert/spu/ProductSpuConvert.java | 108 ---- .../dal/dataobject/brand/ProductBrandDO.java | 53 -- .../category/ProductCategoryDO.java | 67 --- .../dataobject/comment/ProductCommentDO.java | 129 ----- .../delivery/DeliveryTemplateDO.java | 30 - .../favorite/ProductFavoriteDO.java | 45 -- .../dataobject/group/ProductGroupBindDO.java | 43 -- .../dal/dataobject/group/ProductGroupDO.java | 63 -- .../property/ProductPropertyDO.java | 38 -- .../property/ProductPropertyValueDO.java | 46 -- .../dataobject/search/ProductHotSearchDO.java | 38 -- .../product/dal/dataobject/shop/ShopDO.java | 26 - .../dal/dataobject/sku/ProductSkuDO.java | 137 ----- .../dal/dataobject/spu/ProductSpuDO.java | 212 ------- .../dal/mysql/brand/ProductBrandMapper.java | 34 -- .../mysql/category/ProductCategoryMapper.java | 33 -- .../mysql/property/ProductPropertyMapper.java | 32 - .../property/ProductPropertyValueMapper.java | 43 -- .../dal/mysql/sku/ProductSkuMapper.java | 75 --- .../dal/mysql/spu/ProductSpuMapper.java | 75 --- .../yudao/module/product/package-info.java | 8 - .../service/brand/ProductBrandService.java | 79 --- .../brand/ProductBrandServiceImpl.java | 117 ---- .../category/ProductCategoryService.java | 78 --- .../category/ProductCategoryServiceImpl.java | 138 ----- .../property/ProductPropertyService.java | 72 --- .../property/ProductPropertyServiceImpl.java | 113 ---- .../property/ProductPropertyValueService.java | 90 --- .../ProductPropertyValueServiceImpl.java | 127 ---- .../bo/ProductPropertyValueDetailRespBO.java | 33 -- .../service/sku/ProductSkuService.java | 122 ---- .../service/sku/ProductSkuServiceImpl.java | 214 ------- .../service/spu/ProductSpuService.java | 101 ---- .../service/spu/ProductSpuServiceImpl.java | 180 ------ .../brand/ProductBrandServiceImplTest.java | 133 ----- .../ProductCategoryServiceImplTest.java | 145 ----- .../service/sku/ProductSkuServiceTest.java | 171 ------ .../spu/ProductSpuServiceImplTest.java | 359 ------------ .../test/resources/application-unit-test.yaml | 50 -- .../src/test/resources/logback.xml | 4 - .../src/test/resources/sql/clean.sql | 3 - .../src/test/resources/sql/create_tables.sql | 69 --- .../yudao-module-promotion-api/pom.xml | 33 -- .../promotion/api/coupon/CouponApi.java | 21 - .../api/coupon/dto/CouponUseReqDTO.java | 33 -- .../module/promotion/api/package-info.java | 4 - .../module/promotion/api/price/PriceApi.java | 21 - .../api/price/dto/CouponMeetRespDTO.java | 35 -- .../api/price/dto/PriceCalculateReqDTO.java | 56 -- .../api/price/dto/PriceCalculateRespDTO.java | 257 -------- .../promotion/enums/ErrorCodeConstants.java | 60 -- .../common/PromotionActivityStatusEnum.java | 39 -- .../common/PromotionConditionTypeEnum.java | 37 -- .../common/PromotionDiscountTypeEnum.java | 38 -- .../enums/common/PromotionLevelEnum.java | 40 -- .../common/PromotionProductScopeEnum.java | 38 -- .../enums/common/PromotionTypeEnum.java | 40 -- .../enums/coupon/CouponStatusEnum.java | 39 -- .../enums/coupon/CouponTakeTypeEnum.java | 37 -- .../CouponTemplateValidityTypeEnum.java | 38 -- .../yudao-module-promotion-biz/pom.xml | 77 --- .../promotion/api/coupon/CouponApiImpl.java | 27 - .../promotion/api/discount/package-info.java | 1 - .../promotion/api/price/PriceApiImpl.java | 26 - .../admin/banner/BannerController.java | 71 --- .../admin/banner/vo/BannerBaseVO.java | 42 -- .../admin/banner/vo/BannerCreateReqVO.java | 18 - .../admin/banner/vo/BannerPageReqVO.java | 37 -- .../admin/banner/vo/BannerRespVO.java | 25 - .../admin/banner/vo/BannerUpdateReqVO.java | 23 - .../admin/coupon/CouponController.java | 75 --- .../coupon/CouponTemplateController.java | 79 --- .../admin/coupon/vo/coupon/CouponBaseVO.java | 103 ---- .../vo/coupon/CouponPageItemRespVO.java | 17 - .../coupon/vo/coupon/CouponPageReqVO.java | 33 -- .../admin/coupon/vo/coupon/CouponRespVO.java | 22 - .../vo/template/CouponTemplateBaseVO.java | 154 ----- .../template/CouponTemplateCreateReqVO.java | 13 - .../vo/template/CouponTemplatePageReqVO.java | 33 -- .../vo/template/CouponTemplateRespVO.java | 34 -- .../template/CouponTemplateUpdateReqVO.java | 20 - .../CouponTemplateUpdateStatusReqVO.java | 23 - .../discount/DiscountActivityController.java | 87 --- .../discount/vo/DiscountActivityBaseVO.java | 81 --- .../vo/DiscountActivityCreateReqVO.java | 24 - .../vo/DiscountActivityDetailRespVO.java | 20 - .../vo/DiscountActivityPageReqVO.java | 30 - .../discount/vo/DiscountActivityRespVO.java | 27 - .../vo/DiscountActivityUpdateReqVO.java | 30 - .../reward/RewardActivityController.java | 83 --- .../admin/reward/vo/RewardActivityBaseVO.java | 98 ---- .../reward/vo/RewardActivityCreateReqVO.java | 11 - .../reward/vo/RewardActivityPageReqVO.java | 18 - .../admin/reward/vo/RewardActivityRespVO.java | 25 - .../reward/vo/RewardActivityUpdateReqVO.java | 16 - .../seckill/SeckillActivityController.java | 96 --- .../admin/seckill/SeckillTimeController.java | 72 --- .../vo/activity/SeckillActivityBaseVO.java | 66 --- .../activity/SeckillActivityCreateReqVO.java | 38 -- .../activity/SeckillActivityDetailRespVO.java | 21 - .../vo/activity/SeckillActivityPageReqVO.java | 37 -- .../vo/activity/SeckillActivityRespVO.java | 42 -- .../activity/SeckillActivityUpdateReqVO.java | 42 -- .../seckill/vo/time/SeckillTimeBaseVO.java | 28 - .../vo/time/SeckillTimeCreateReqVO.java | 12 - .../seckill/vo/time/SeckillTimePageReqVO.java | 30 - .../seckill/vo/time/SeckillTimeRespVO.java | 26 - .../vo/time/SeckillTimeUpdateReqVO.java | 21 - .../app/AppMarketTestController.java | 24 - .../app/banner/AppBannerController.java | 42 -- .../convert/banner/BannerConvert.java | 34 -- .../convert/coupon/CouponConvert.java | 21 - .../convert/coupon/CouponTemplateConvert.java | 29 - .../discount/DiscountActivityConvert.java | 102 ---- .../promotion/convert/price/PriceConvert.java | 49 -- .../convert/reward/RewardActivityConvert.java | 29 - .../SeckillActivityConvert.java | 83 --- .../seckilltime/SeckillTimeConvert.java | 34 -- .../dal/dataobject/banner/BannerDO.java | 53 -- .../dal/dataobject/coupon/CouponDO.java | 139 ----- .../dataobject/coupon/CouponTemplateDO.java | 162 ------ .../discount/DiscountActivityDO.java | 55 -- .../discount/DiscountProductDO.java | 65 --- .../dataobject/reward/RewardActivityDO.java | 133 ----- .../seckillactivity/SeckillActivityDO.java | 78 --- .../seckillactivity/SeckillProductDO.java | 65 --- .../seckill/seckilltime/SeckillTimeDO.java | 47 -- .../dal/mysql/banner/BannerMapper.java | 26 - .../dal/mysql/coupon/CouponMapper.java | 52 -- .../mysql/coupon/CouponTemplateMapper.java | 30 - .../discount/DiscountActivityMapper.java | 30 - .../mysql/discount/DiscountProductMapper.java | 26 - .../mysql/reward/RewardActivityMapper.java | 38 -- .../SeckillActivityMapper.java | 26 - .../seckillactivity/SeckillProductMapper.java | 35 -- .../seckilltime/SeckillTimeMapper.java | 37 -- .../yudao/module/promotion/package-info.java | 8 - .../service/banner/BannerService.java | 63 -- .../service/banner/BannerServiceImpl.java | 78 --- .../service/coupon/CouponService.java | 70 --- .../service/coupon/CouponServiceImpl.java | 123 ---- .../service/coupon/CouponTemplateService.java | 72 --- .../coupon/CouponTemplateServiceImpl.java | 94 --- .../discount/DiscountActivityService.java | 86 --- .../discount/DiscountActivityServiceImpl.java | 196 ------- .../discount/bo/DiscountProductDetailBO.java | 50 -- .../promotion/service/price/PriceService.java | 32 - .../service/price/PriceServiceImpl.java | 547 ------------------ .../service/reward/RewardActivityService.java | 73 --- .../reward/RewardActivityServiceImpl.java | 169 ------ .../SeckillActivityService.java | 80 --- .../SeckillActivityServiceImpl.java | 226 -------- .../seckilltime/SeckillTimeService.java | 76 --- .../seckilltime/SeckillTimeServiceImpl.java | 124 ---- .../module/promotion/util/PromotionUtils.java | 32 - .../mapper/coupon/CouponTemplateMapper.xml | 11 - .../coupon/CouponTemplateServiceImplTest.java | 147 ----- .../DiscountActivityServiceImplTest.java | 210 ------- .../service/price/PriceServiceTest.java | 506 ---------------- .../reward/RewardActivityServiceImplTest.java | 218 ------- .../SeckillActivityServiceImplTest.java | 170 ------ .../SeckillTimeServiceImplTest.java | 189 ------ .../test/resources/application-unit-test.yaml | 49 -- .../src/test/resources/logback.xml | 4 - .../src/test/resources/sql/clean.sql | 6 - .../src/test/resources/sql/create_tables.sql | 124 ---- .../yudao-module-trade-api/pom.xml | 26 - .../trade/enums/ErrorCodeConstants.java | 49 -- .../aftersale/TradeAfterSaleStatusEnum.java | 67 --- .../aftersale/TradeAfterSaleTypeEnum.java | 37 -- .../aftersale/TradeAfterSaleWayEnum.java | 37 -- .../order/TradeOrderAfterSaleStatusEnum.java | 38 -- .../enums/order/TradeOrderCancelTypeEnum.java | 39 -- .../order/TradeOrderDeliveryStatusEnum.java | 28 - .../TradeOrderItemAfterSaleStatusEnum.java | 52 -- .../enums/order/TradeOrderStatusEnum.java | 118 ---- .../trade/enums/order/TradeOrderTypeEnum.java | 39 -- .../yudao-module-trade-biz/pom.xml | 94 --- .../aftersale/TradeAfterSaleController.http | 4 - .../aftersale/TradeAfterSaleController.java | 113 ---- .../aftersale/vo/TradeAfterSaleBaseVO.java | 119 ---- .../vo/TradeAfterSaleDisagreeReqVO.java | 22 - .../aftersale/vo/TradeAfterSalePageReqVO.java | 50 -- .../vo/TradeAfterSaleRefuseReqVO.java | 21 - .../vo/TradeAfterSaleRespPageItemVO.java | 36 -- .../vo/log/TradeAfterSaleLogRespVO.java | 51 -- .../admin/base/member/package-info.java | 4 - .../base/member/user/MemberUserRespVO.java | 20 - .../controller/admin/base/package-info.java | 4 - .../ProductPropertyValueDetailRespVO.java | 23 - .../admin/order/TradeOrderController.http | 9 - .../admin/order/TradeOrderController.java | 93 --- .../admin/order/vo/TradeOrderBaseVO.java | 145 ----- .../order/vo/TradeOrderDeliveryReqVO.java | 26 - .../order/vo/TradeOrderDetailRespVO.java | 39 -- .../admin/order/vo/TradeOrderItemBaseVO.java | 70 --- .../order/vo/TradeOrderPageItemRespVO.java | 33 -- .../admin/order/vo/TradeOrderPageReqVO.java | 54 -- .../AppTradeAfterSaleController.java | 50 -- .../vo/AppTradeAfterSaleCreateReqVO.java | 41 -- .../vo/AppTradeAfterSaleDeliveryReqVO.java | 31 - .../controller/app/base/package-info.java | 4 - .../AppProductPropertyValueDetailRespVO.java | 22 - .../app/base/sku/AppProductSkuBaseRespVO.java | 34 -- .../app/base/spu/AppProductSpuBaseRespVO.java | 24 - .../app/cart/TradeCartController.http | 47 -- .../app/cart/TradeCartController.java | 84 --- .../app/cart/vo/AppTradeCartDetailRespVO.java | 117 ---- .../vo/AppTradeCartItemAddCountReqVO.java | 22 - .../vo/AppTradeCartItemUpdateCountReqVO.java | 22 - .../AppTradeCartItemUpdateSelectedReqVO.java | 21 - .../app/order/AppTradeOrderController.http | 37 -- .../app/order/AppTradeOrderController.java | 102 ---- .../order/vo/AppTradeOrderCreateReqVO.java | 52 -- .../order/vo/AppTradeOrderDetailRespVO.java | 150 ----- .../vo/AppTradeOrderGetCreateInfoRespVO.java | 168 ------ .../order/vo/AppTradeOrderPageItemRespVO.java | 66 --- .../app/order/vo/AppTradeOrderPageReqVO.java | 18 - .../app/order/vo/TradeOrderItemRespVO.java | 0 .../app/order/vo/TradeOrderRespVO.java | 0 .../module/trade/controller/package-info.java | 6 - .../aftersale/TradeAfterSaleConvert.java | 89 --- .../trade/convert/cart/TradeCartConvert.java | 45 -- .../convert/order/TradeOrderConvert.java | 241 -------- .../aftersale/TradeAfterSaleDO.java | 201 ------- .../aftersale/TradeAfterSaleLogDO.java | 83 --- .../dal/dataobject/cart/TradeCartItemDO.java | 90 --- .../dal/dataobject/order/TradeOrderDO.java | 257 -------- .../dataobject/order/TradeOrderItemDO.java | 190 ------ .../aftersale/TradeAfterSaleLogMapper.java | 9 - .../mysql/aftersale/TradeAfterSaleMapper.java | 35 -- .../dal/mysql/cart/TradeCartItemMapper.java | 47 -- .../dal/mysql/order/TradeOrderItemMapper.java | 27 - .../dal/mysql/order/TradeOrderMapper.java | 46 -- .../module/trade/dal/mysql/package-info.java | 4 - .../order/config/TradeOrderConfig.java | 14 - .../order/config/TradeOrderProperties.java | 33 -- .../yudao/module/trade/package-info.java | 8 - .../aftersale/TradeAfterSaleService.java | 94 --- .../aftersale/TradeAfterSaleServiceImpl.java | 392 ------------- .../trade/service/cart/TradeCartService.java | 66 --- .../service/cart/TradeCartServiceImpl.java | 184 ------ .../service/order/TradeOrderService.java | 142 ----- .../service/order/TradeOrderServiceImpl.java | 530 ----------------- .../aftersale/TradeAfterSaleServiceTest.java | 154 ----- .../service/order/TradeOrderServiceTest.java | 320 ---------- .../test/resources/application-unit-test.yaml | 53 -- .../src/test/resources/logback.xml | 4 - .../src/test/resources/sql/clean.sql | 4 - .../src/test/resources/sql/create_tables.sql | 128 ---- .../admin/notify/PayNotifyController.java | 10 +- .../controller/admin/ip/AreaController.java | 14 +- .../admin/ip/vo/AreaNodeRespVO.java | 9 +- 335 files changed, 16 insertions(+), 21122 deletions(-) delete mode 100644 yudao-module-mall/pom.xml delete mode 100644 yudao-module-mall/yudao-module-product-api/pom.xml delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/dto/ProductPropertyValueDetailRespDTO.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuUpdateStockReqDTO.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentAuditStatusEnum.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/pom.xml delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/propertyvalue/ProductPropertyValueConvert.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/bo/ProductPropertyValueDetailRespBO.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImplTest.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java delete mode 100755 yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql delete mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql delete mode 100644 yudao-module-mall/yudao-module-promotion-api/pom.xml delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponUseReqDTO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/CouponMeetRespDTO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionDiscountTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponStatusEnum.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTakeTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTemplateValidityTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/pom.xml delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityPageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/reward/RewardActivityConvert.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountActivityMapper.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImplTest.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java delete mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql delete mode 100644 yudao-module-mall/yudao-module-trade-api/pom.xml delete mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java delete mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java delete mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleWayEnum.java delete mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java delete mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java delete mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java delete mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java delete mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/pom.xml delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDisagreeReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRefuseReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespPageItemVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/TradeAfterSaleLogRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/package-info.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/user/MemberUserRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/product/property/ProductPropertyValueDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.http delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java delete mode 100755 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/package-info.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleLogMapper.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/package-info.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/package-info.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/logback.xml delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/clean.sql delete mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql diff --git a/yudao-module-mall/pom.xml b/yudao-module-mall/pom.xml deleted file mode 100644 index 37484f00c..000000000 --- a/yudao-module-mall/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - yudao - cn.iocoder.boot - ${revision} - - 4.0.0 - - yudao-module-mall - pom - - ${project.artifactId} - - - 商城大模块,由 product 商品、promotion 营销、trade 交易等组成 - - - yudao-module-promotion-api - yudao-module-promotion-biz - yudao-module-product-api - yudao-module-product-biz - yudao-module-trade-api - yudao-module-trade-biz - - - diff --git a/yudao-module-mall/yudao-module-product-api/pom.xml b/yudao-module-mall/yudao-module-product-api/pom.xml deleted file mode 100644 index 123e7c334..000000000 --- a/yudao-module-mall/yudao-module-product-api/pom.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - 4.0.0 - - cn.iocoder.boot - yudao-module-mall - ${revision} - - - yudao-module-product-api - jar - - ${project.artifactId} - - product 模块 API,暴露给其它模块调用 - - - - - cn.iocoder.boot - yudao-common - - - - - org.springframework.boot - spring-boot-starter-validation - true - - - - diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java deleted file mode 100644 index b19092853..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 占位 - */ -package cn.iocoder.yudao.module.product.api; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java deleted file mode 100644 index 83269f91d..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.module.product.api.property; - -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; - -import java.util.Collection; -import java.util.List; - -/** - * 商品属性值 API 接口 - * - * @author 芋道源码 - */ -public interface ProductPropertyValueApi { - - /** - * 根据编号数组,获得属性值列表 - * - * @param ids 编号数组 - * @return 属性值明细列表 - */ - List getPropertyValueDetailList(Collection ids); - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/dto/ProductPropertyValueDetailRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/dto/ProductPropertyValueDetailRespDTO.java deleted file mode 100644 index 2a1ab71a9..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/dto/ProductPropertyValueDetailRespDTO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.product.api.property.dto; - -import lombok.Data; - -/** - * 商品属性项的明细 Response DTO - * - * @author 芋道源码 - */ -@Data -public class ProductPropertyValueDetailRespDTO { - - /** - * 属性的编号 - */ - private Long propertyId; - - /** - * 属性的名称 - */ - private String propertyName; - - /** - * 属性值的编号 - */ - private Long valueId; - - /** - * 属性值的名称 - */ - private String valueName; - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java deleted file mode 100644 index d5d93dc37..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.product.api.sku; - -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; - -import java.util.Collection; -import java.util.List; - -/** - * 商品 SKU API 接口 - * - * @author LeeYan9 - * @since 2022-08-26 - */ -public interface ProductSkuApi { - - /** - * 查询 SKU 信息 - * - * @param id SKU 编号 - * @return SKU 信息 - */ - ProductSkuRespDTO getSku(Long id); - - /** - * 批量查询 SKU 数组 - * - * @param ids SKU 编号列表 - * @return SKU 数组 - */ - List getSkuList(Collection ids); - - /** - * 更新 SKU 库存 - * - * @param updateStockReqDTO 更新请求 - */ - void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO); - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java deleted file mode 100644 index aaaf767f2..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java +++ /dev/null @@ -1,95 +0,0 @@ -package cn.iocoder.yudao.module.product.api.sku.dto; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import lombok.Data; - -import java.util.List; - -/** - * 商品 SKU 信息 Response DTO - * - * @author LeeYan9 - * @since 2022-08-26 - */ -@Data -public class ProductSkuRespDTO { - - /** - * 商品 SKU 编号,自增 - */ - private Long id; - /** - * SPU 编号 - */ - private Long spuId; - /** - * SPU 名字 - */ - private String spuName; - - /** - * 属性数组,JSON 格式 - */ - private List properties; - /** - * 销售价格,单位:分 - */ - private Integer price; - /** - * 市场价,单位:分 - */ - private Integer marketPrice; - /** - * 成本价,单位:分 - */ - private Integer costPrice; - /** - * SKU 的条形码 - */ - private String barCode; - /** - * 图片地址 - */ - private String picUrl; - /** - * SKU 状态 - *

- * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - /** - * 库存 - */ - private Integer stock; - /** - * 预警预存 - */ - private Integer warnStock; - /** - * 商品重量,单位:kg 千克 - */ - private Double weight; - /** - * 商品体积,单位:m^3 平米 - */ - private Double volume; - - /** - * 商品属性 - */ - @Data - public static class Property { - - /** - * 属性编号 - */ - private Long propertyId; - /** - * 属性值编号 - */ - private Long valueId; - - } - - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuUpdateStockReqDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuUpdateStockReqDTO.java deleted file mode 100644 index 345c17cbd..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuUpdateStockReqDTO.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.module.product.api.sku.dto; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotNull; -import java.util.List; - -/** - * 商品 SKU 更新库存 Request DTO - * - * @author LeeYan9 - * @since 2022-08-26 - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class ProductSkuUpdateStockReqDTO { - - /** - * 商品 SKU - */ - @NotNull(message = "商品 SKU 不能为空") - private List items; - - @Data - public static class Item { - - /** - * 商品 SKU 编号 - */ - @NotNull(message = "商品 SKU 编号不能为空") - private Long id; - - /** - * 库存变化数量 - * - * 正数:增加库存 - * 负数:扣减库存 - */ - @NotNull(message = "库存变化数量不能为空") - private Integer incrCount; - - } - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java deleted file mode 100644 index 8ba0fba7d..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.product.api.spu; - -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; - -import java.util.Collection; -import java.util.List; - -/** - * 商品 SPU API 接口 - * - * @author LeeYan9 - * @since 2022-08-26 - */ -public interface ProductSpuApi { - - /** - * 批量查询 SPU 数组 - * - * @param ids SPU 编号列表 - * @return SPU 数组 - */ - List getSpuList(Collection ids); - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java deleted file mode 100644 index 45d42f41b..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java +++ /dev/null @@ -1,127 +0,0 @@ -package cn.iocoder.yudao.module.product.api.spu.dto; - -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import lombok.Data; - -import java.util.List; - -// TODO @LeeYan9: ProductSpuRespDTO -/** - * 商品 SPU 信息 Response DTO - * - * @author LeeYan9 - * @since 2022-08-26 - */ -@Data -public class ProductSpuRespDTO { - - /** - * 商品 SPU 编号,自增 - */ - private Long id; - - // ========== 基本信息 ========= - - /** - * 商品名称 - */ - private String name; - /** - * 商品编码 - */ - private String code; - /** - * 促销语 - */ - private String sellPoint; - /** - * 商品详情 - */ - private String description; - /** - * 商品分类编号 - */ - private Long categoryId; - /** - * 商品品牌编号 - */ - private Long brandId; - /** - * 商品图片的数组 - *

- * 1. 第一张图片将作为商品主图,支持同时上传多张图; - * 2. 建议使用尺寸 800x800 像素以上、大小不超过 1M 的正方形图片; - * 3. 至少 1 张,最多上传 10 张 - */ - private List picUrls; - /** - * 商品视频 - */ - private String videoUrl; - - /** - * 排序字段 - */ - private Integer sort; - /** - * 商品状态 - *

- * 枚举 {@link ProductSpuStatusEnum} - */ - private Integer status; - - // ========== SKU 相关字段 ========= - - /** - * 规格类型 - *

- * 枚举 {@link ProductSpuSpecTypeEnum} - */ - private Integer specType; - /** - * 最小价格,单位使用:分 - *

- * 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最小值 - */ - private Integer minPrice; - /** - * 最大价格,单位使用:分 - *

- * 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最大值 - */ - private Integer maxPrice; - /** - * 市场价,单位使用:分 - *

- * 基于其对应的 {@link ProductSkuRespDTO#getMarketPrice()} 最大值 - */ - private Integer marketPrice; - /** - * 总库存 - *

- * 基于其对应的 {@link ProductSkuRespDTO#getStock()} 求和 - */ - private Integer totalStock; - /** - * 是否展示库存 - */ - private Boolean showStock; - - // ========== 统计相关字段 ========= - - /** - * 商品销量 - */ - private Integer salesCount; - /** - * 虚拟销量 - */ - private Integer virtualSalesCount; - /** - * 商品点击量 - */ - private Integer clickCount; - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java deleted file mode 100644 index 4adad0afc..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.iocoder.yudao.module.product.enums; - -import cn.iocoder.yudao.framework.common.exception.ErrorCode; - -/** - * Product 错误码枚举类 - * - * product 系统,使用 1-008-000-000 段 - */ -public interface ErrorCodeConstants { - - // ========== 商品分类相关 1008001000 ============ - ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在"); - ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在"); - ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类"); - ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除"); - ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用"); - - // ========== 商品品牌相关编号 1008002000 ========== - ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在"); - ErrorCode BRAND_DISABLED = new ErrorCode(1008002001, "品牌不存在"); - ErrorCode BRAND_NAME_EXISTS = new ErrorCode(1008002002, "品牌名称已存在"); - - // ========== 商品属性项 1008003000 ========== - ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "属性项不存在"); - ErrorCode PROPERTY_EXISTS = new ErrorCode(1008003001, "属性项的名称已存在"); - ErrorCode PROPERTY_DELETE_FAIL_VALUE_EXISTS = new ErrorCode(1008003002, "属性项下存在属性值,无法删除"); - - // ========== 商品属性值 1008004000 ========== - ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "属性值不存在"); - ErrorCode PROPERTY_VALUE_EXISTS = new ErrorCode(1008004001, "属性值的名称已存在"); - - // ========== 商品 SPU 1008005000 ========== - ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在"); - ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第三级的商品分类下"); - ErrorCode SPU_NOT_ENABLE = new ErrorCode(1008005002, "商品 SPU 不处于上架状态"); - - // ========== 商品 SKU 1008006000 ========== - ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在"); - ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1008006001, "商品 SKU 的属性组合存在重复"); - ErrorCode SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1008006002, "一个 SPU 下的每个 SKU,其属性项必须一致"); - ErrorCode SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU,必须不重复"); - ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足"); - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentAuditStatusEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentAuditStatusEnum.java deleted file mode 100644 index 276839daf..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentAuditStatusEnum.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.product.enums.comment; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 商品评论的审批状态枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum ProductCommentAuditStatusEnum implements IntArrayValuable { - - NONE(1, "待审核"), - APPROVE(2, "审批通过"), - REJECT(2, "审批不通过"),; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductCommentAuditStatusEnum::getStatus).toArray(); - - /** - * 审批状态 - */ - private final Integer status; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java deleted file mode 100644 index da322ff24..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.product.enums.delivery; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 配送方式枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum DeliveryTypeEnum implements IntArrayValuable { - - // TODO 芋艿:英文单词,需要再想下; - EXPRESS(1, "快递发货"), - USER(2, "用户自提"),; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeliveryTypeEnum::getMode).toArray(); - - /** - * 配送方式 - */ - private final Integer mode; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java deleted file mode 100644 index c5e55e8e4..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.product.enums.group; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 商品分组的样式枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum ProductGroupStyleEnum implements IntArrayValuable { - - ONE(1, "每列一个"), - TWO(2, "每列两个"), - THREE(2, "每列三个"),; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductGroupStyleEnum::getStyle).toArray(); - - /** - * 列表样式 - */ - private final Integer style; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java deleted file mode 100644 index fbc227b53..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.product.enums.spu; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 商品 SPU 规格类型 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum ProductSpuSpecTypeEnum implements IntArrayValuable { - - RECYCLE(1, "统一规格"), - DISABLE(2, "多规格"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuSpecTypeEnum::getType).toArray(); - - /** - * 规格类型 - */ - private final Integer type; - /** - * 规格名称 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java deleted file mode 100644 index 2223cf23d..000000000 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java +++ /dev/null @@ -1,48 +0,0 @@ -package cn.iocoder.yudao.module.product.enums.spu; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 商品 SPU 状态 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum ProductSpuStatusEnum implements IntArrayValuable { - - RECYCLE(-1, "回收站"), - DISABLE(0, "下架"), - ENABLE(1, "上架"),; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuStatusEnum::getStatus).toArray(); - - /** - * 状态 - */ - private final Integer status; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - - /** - * 判断是否处于【上架】状态 - * - * @param status 状态 - * @return 是否处于【上架】状态 - */ - public static boolean isEnable(Integer status) { - return ENABLE.getStatus().equals(status); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/pom.xml b/yudao-module-mall/yudao-module-product-biz/pom.xml deleted file mode 100644 index e89ed105e..000000000 --- a/yudao-module-mall/yudao-module-product-biz/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - cn.iocoder.boot - yudao-module-mall - ${revision} - - 4.0.0 - yudao-module-product-biz - jar - - ${project.artifactId} - - product 模块,主要实现商品相关功能 - 例如:品牌、商品分类、spu、sku等功能。 - - - - - cn.iocoder.boot - yudao-module-product-api - ${revision} - - - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-operatelog - - - - - cn.iocoder.boot - yudao-spring-boot-starter-web - - - cn.iocoder.boot - yudao-spring-boot-starter-security - - - - - cn.iocoder.boot - yudao-spring-boot-starter-mybatis - - - - - cn.iocoder.boot - yudao-spring-boot-starter-test - - - - - cn.iocoder.boot - yudao-spring-boot-starter-excel - - - - diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java deleted file mode 100644 index 162453c3c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.module.product.api; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java deleted file mode 100644 index 9aab9e560..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.product.api.property; - -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; -import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; - -/** - * 商品属性值 API 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class ProductPropertyValueApiImpl implements ProductPropertyValueApi { - - @Resource - private ProductPropertyValueService productPropertyValueService; - - @Override - public List getPropertyValueDetailList(Collection ids) { - return ProductPropertyValueConvert.INSTANCE.convertList02( - productPropertyValueService.getPropertyValueDetailList(ids)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java deleted file mode 100644 index 89913c70e..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.yudao.module.product.api.sku; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * TODO LeeYan9: 类注释; - * @author LeeYan9 - * @since 2022-09-06 - */ -@Service -@Validated -public class ProductSkuApiImpl implements ProductSkuApi { - - @Resource - private ProductSkuService productSkuService; - - @Override - public ProductSkuRespDTO getSku(Long id) { - // TODO TODO LeeYan9: 需要实现 - return null; - } - - @Override - public List getSkuList(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return Collections.emptyList(); - } - List skus = productSkuService.getSkuList(ids); - return ProductSkuConvert.INSTANCE.convertList04(skus); - } - - @Override - public void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO) { - productSkuService.updateSkuStock(updateStockReqDTO); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java deleted file mode 100644 index 4d880e662..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.product.api.spu; - -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * TODO LeeYan9: 类注释; - * - * @author LeeYan9 - * @since 2022-09-06 - */ -@Service -@Validated -public class ProductSpuApiImpl implements ProductSpuApi { - - @Resource - private ProductSpuMapper productSpuMapper; - - @Override - public List getSpuList(Collection spuIds) { - // TODO TODO LeeYan9: AllEmpty? - if (CollectionUtils.isAnyEmpty(spuIds)) { - return Collections.emptyList(); - } - List productSpuDOList = productSpuMapper.selectBatchIds(spuIds); - return ProductSpuConvert.INSTANCE.convertList2(productSpuDOList); - } -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java deleted file mode 100644 index 8427449f7..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java +++ /dev/null @@ -1,82 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.brand; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*; -import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; -import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.Comparator; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - 商品品牌") -@RestController -@RequestMapping("/product/brand") -@Validated -public class ProductBrandController { - - @Resource - private ProductBrandService brandService; - - @PostMapping("/create") - @Operation(summary = "创建品牌") - @PreAuthorize("@ss.hasPermission('product:brand:create')") - public CommonResult createBrand(@Valid @RequestBody ProductBrandCreateReqVO createReqVO) { - return success(brandService.createBrand(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新品牌") - @PreAuthorize("@ss.hasPermission('product:brand:update')") - public CommonResult updateBrand(@Valid @RequestBody ProductBrandUpdateReqVO updateReqVO) { - brandService.updateBrand(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除品牌") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('product:brand:delete')") - public CommonResult deleteBrand(@RequestParam("id") Long id) { - brandService.deleteBrand(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得品牌") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('product:brand:query')") - public CommonResult getBrand(@RequestParam("id") Long id) { - ProductBrandDO brand = brandService.getBrand(id); - return success(ProductBrandConvert.INSTANCE.convert(brand)); - } - - @GetMapping("/page") - @Operation(summary = "获得品牌分页") - @PreAuthorize("@ss.hasPermission('product:brand:query')") - public CommonResult> getBrandPage(@Valid ProductBrandPageReqVO pageVO) { - PageResult pageResult = brandService.getBrandPage(pageVO); - return success(ProductBrandConvert.INSTANCE.convertPage(pageResult)); - } - - @GetMapping("/list") - @Operation(summary = "获得品牌列表") - @PreAuthorize("@ss.hasPermission('product:brand:query')") - public CommonResult> getBrandList(@Valid ProductBrandListReqVO listVO) { - List list = brandService.getBrandList(listVO); - list.sort(Comparator.comparing(ProductBrandDO::getSort)); - return success(ProductBrandConvert.INSTANCE.convertList(list)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java deleted file mode 100644 index 033199d9f..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.brand.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotNull; - -/** -* 商品品牌 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class ProductBrandBaseVO { - - @Schema(description = "品牌名称", required = true, example = "芋道") - @NotNull(message = "品牌名称不能为空") - private String name; - - @Schema(description = "品牌图片", required = true) - @NotNull(message = "品牌图片不能为空") - private String picUrl; - - @Schema(description = "品牌排序", required = true, example = "1") - @NotNull(message = "品牌排序不能为空") - private Integer sort; - - @Schema(description = "品牌描述", example = "描述") - private String description; - - @Schema(description = "状态", required = true, example = "0") - @NotNull(message = "状态不能为空") - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java deleted file mode 100644 index 2ab9c354a..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java +++ /dev/null @@ -1,11 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.brand.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -@Schema(description = "管理后台 - 商品品牌创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductBrandCreateReqVO extends ProductBrandBaseVO { - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java deleted file mode 100644 index 63305810c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java +++ /dev/null @@ -1,13 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.brand.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - 商品品牌分页 Request VO") -@Data -public class ProductBrandListReqVO { - - @Schema(description = "品牌名称", example = "芋道") - private String name; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java deleted file mode 100644 index e90744a10..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.brand.vo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - 商品品牌分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductBrandPageReqVO extends PageParam { - - @Schema(description = "品牌名称", example = "芋道") - private String name; - - @Schema(description = "状态-参考 CommonStatusEnum 枚举", example = "0") - private Integer status; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(description = "创建时间") - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java deleted file mode 100644 index b68fbc5be..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.brand.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 品牌 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductBrandRespVO extends ProductBrandBaseVO { - - @Schema(description = "品牌编号", required = true, example = "1") - private Long id; - - @Schema(description = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java deleted file mode 100644 index 15648164f..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java +++ /dev/null @@ -1,16 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.brand.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import javax.validation.constraints.*; - -@Schema(description = "管理后台 - 商品品牌更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductBrandUpdateReqVO extends ProductBrandBaseVO { - - @Schema(description = "品牌编号", required = true, example = "1") - @NotNull(message = "品牌编号不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java deleted file mode 100644 index c51498d3b..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java +++ /dev/null @@ -1,76 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.Comparator; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - 商品分类") -@RestController -@RequestMapping("/product/category") -@Validated -public class ProductCategoryController { - - @Resource - private ProductCategoryService categoryService; - - @PostMapping("/create") - @Operation(summary = "创建商品分类") - @PreAuthorize("@ss.hasPermission('product:category:create')") - public CommonResult createCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) { - return success(categoryService.createCategory(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新商品分类") - @PreAuthorize("@ss.hasPermission('product:category:update')") - public CommonResult updateCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) { - categoryService.updateCategory(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除商品分类") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('product:category:delete')") - public CommonResult deleteCategory(@RequestParam("id") Long id) { - categoryService.deleteCategory(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得商品分类") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('product:category:query')") - public CommonResult getCategory(@RequestParam("id") Long id) { - ProductCategoryDO category = categoryService.getCategory(id); - return success(ProductCategoryConvert.INSTANCE.convert(category)); - } - - @GetMapping("/list") - @Operation(summary = "获得商品分类列表") - @PreAuthorize("@ss.hasPermission('product:category:query')") - public CommonResult> getCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) { - List list = categoryService.getEnableCategoryList(treeListReqVO); - list.sort(Comparator.comparing(ProductCategoryDO::getSort)); - return success(ProductCategoryConvert.INSTANCE.convertList(list)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java deleted file mode 100644 index c2276e9ac..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; - -/** -* 商品分类 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class ProductCategoryBaseVO { - - @Schema(description = "父分类编号", required = true, example = "1") - @NotNull(message = "父分类编号不能为空") - private Long parentId; - - @Schema(description = "分类名称", required = true, example = "办公文具") - @NotBlank(message = "分类名称不能为空") - private String name; - - @Schema(description = "分类图片", required = true) - @NotBlank(message = "分类图片不能为空") - private String picUrl; - - @Schema(description = "分类排序", required = true, example = "1") - private Integer sort; - - @Schema(description = "分类描述", required = true, example = "描述") - private String description; - - @Schema(description = "开启状态", required = true, example = "0") - @NotNull(message = "开启状态不能为空") - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java deleted file mode 100644 index 577b9e774..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java +++ /dev/null @@ -1,11 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -@Schema(description = "管理后台 - 商品分类创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO { - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java deleted file mode 100644 index 9c9439d3e..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java +++ /dev/null @@ -1,13 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - 商品分类列表查询 Request VO") -@Data -public class ProductCategoryListReqVO { - - @Schema(description = "分类名称", example = "办公文具") - private String name; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java deleted file mode 100644 index 4e2b64188..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 商品分类 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductCategoryRespVO extends ProductCategoryBaseVO { - - @Schema(description = "分类编号", required = true, example = "2") - private Long id; - - @Schema(description = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java deleted file mode 100644 index 01deb165c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java +++ /dev/null @@ -1,16 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import javax.validation.constraints.*; - -@Schema(description = "管理后台 - 商品分类更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO { - - @Schema(description = "分类编号", required = true, example = "2") - @NotNull(message = "分类编号不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java deleted file mode 100644 index 8f5120723..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java +++ /dev/null @@ -1,99 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*; -import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.Collections; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - 商品属性项") -@RestController -@RequestMapping("/product/property") -@Validated -public class ProductPropertyController { - - @Resource - private ProductPropertyService productPropertyService; - @Resource - private ProductPropertyValueService productPropertyValueService; - - @PostMapping("/create") - @Operation(summary = "创建属性项") - @PreAuthorize("@ss.hasPermission('product:property:create')") - public CommonResult createProperty(@Valid @RequestBody ProductPropertyCreateReqVO createReqVO) { - return success(productPropertyService.createProperty(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新属性项") - @PreAuthorize("@ss.hasPermission('product:property:update')") - public CommonResult updateProperty(@Valid @RequestBody ProductPropertyUpdateReqVO updateReqVO) { - productPropertyService.updateProperty(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除属性项") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('product:property:delete')") - public CommonResult deleteProperty(@RequestParam("id") Long id) { - productPropertyService.deleteProperty(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得属性项") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult getProperty(@RequestParam("id") Long id) { - return success(ProductPropertyConvert.INSTANCE.convert(productPropertyService.getProperty(id))); - } - - @GetMapping("/list") - @Operation(summary = "获得属性项列表") - @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult> getPropertyList(@Valid ProductPropertyListReqVO listReqVO) { - return success(ProductPropertyConvert.INSTANCE.convertList(productPropertyService.getPropertyList(listReqVO))); - } - - @GetMapping("/page") - @Operation(summary = "获得属性项分页") - @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) { - return success(ProductPropertyConvert.INSTANCE.convertPage(productPropertyService.getPropertyPage(pageVO))); - } - - @GetMapping("/get-value-list") - @Operation(summary = "获得属性项列表") - @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult> getPropertyAndValueList(@Valid ProductPropertyListReqVO listReqVO) { - // 查询属性项 - List keys = productPropertyService.getPropertyList(listReqVO); - if (CollUtil.isEmpty(keys)) { - return success(Collections.emptyList()); - } - // 查询属性值 - List values = productPropertyValueService.getPropertyValueListByPropertyId( - convertSet(keys, ProductPropertyDO::getId)); - return success(ProductPropertyConvert.INSTANCE.convertList(keys, values)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java deleted file mode 100644 index 5c377220a..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java +++ /dev/null @@ -1,70 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - 商品属性值") -@RestController -@RequestMapping("/product/property/value") -@Validated -public class ProductPropertyValueController { - - @Resource - private ProductPropertyValueService productPropertyValueService; - - @PostMapping("/create") - @Operation(summary = "创建属性值") - @PreAuthorize("@ss.hasPermission('product:property:create')") - public CommonResult createProperty(@Valid @RequestBody ProductPropertyValueCreateReqVO createReqVO) { - return success(productPropertyValueService.createPropertyValue(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新属性值") - @PreAuthorize("@ss.hasPermission('product:property:update')") - public CommonResult updateProperty(@Valid @RequestBody ProductPropertyValueUpdateReqVO updateReqVO) { - productPropertyValueService.updatePropertyValue(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除属性值") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('product:property:delete')") - public CommonResult deleteProperty(@RequestParam("id") Long id) { - productPropertyValueService.deletePropertyValue(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得属性值") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult getProperty(@RequestParam("id") Long id) { - return success(ProductPropertyValueConvert.INSTANCE.convert(productPropertyValueService.getPropertyValue(id))); - } - - @GetMapping("/page") - @Operation(summary = "获得属性值分页") - @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult> getPropertyValuePage(@Valid ProductPropertyValuePageReqVO pageVO) { - return success(ProductPropertyValueConvert.INSTANCE.convertPage(productPropertyValueService.getPropertyValuePage(pageVO))); - } -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/ProductPropertyViewRespVO.java deleted file mode 100644 index e69de29bb..000000000 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java deleted file mode 100644 index ec569d1f3..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.util.List; - -@Schema(description = "管理后台 - 商品属性项 + 属性值 Response VO") -@Data -public class ProductPropertyAndValueRespVO { - - @ApiModelProperty(value = "属性项的编号", required = true, example = "1024") - private Long id; - - @ApiModelProperty(value = "属性项的名称", required = true, example = "颜色") - private String name; - - /** - * 属性值的集合 - */ - private List values; - - @ApiModel("管理后台 - 属性值的简单 Response VO") - @Data - public static class Value { - - @Schema(description = "属性值的编号", required = true, example = "2048") - private Long id; - - @Schema(description = "属性值的名称", required = true, example = "红色") - private String name; - - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java deleted file mode 100644 index 1f05af4b2..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotBlank; - -/** - * 商品属性项 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class ProductPropertyBaseVO { - - @Schema(description = "名称", required = true, example = "颜色") - @NotBlank(message = "名称不能为空") - private String name; - - @Schema(description = "备注", example = "颜色") - private String remark; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java deleted file mode 100644 index b854dd73c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - 属性项创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyCreateReqVO extends ProductPropertyBaseVO { - - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java deleted file mode 100644 index 242caff84..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.ToString; - -@Schema(description = "管理后台 - 属性项 List Request VO") -@Data -@ToString(callSuper = true) -public class ProductPropertyListReqVO { - - @Schema(description = "名称", example = "颜色") - private String name; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java deleted file mode 100644 index a725e2076..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - 属性项 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyPageReqVO extends PageParam { - - @Schema(description = "名称", example = "颜色") - private String name; - - @Schema(description = "状态-参见 CommonStatusEnum 枚举", required = true, example = "1") - private Integer status; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(description = "创建时间") - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java deleted file mode 100644 index b33e615fc..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 属性项 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyRespVO extends ProductPropertyBaseVO { - - @Schema(description = "编号", required = true, example = "1024") - private Long id; - - @Schema(description = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java deleted file mode 100644 index 33ba8f2c1..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.constraints.NotNull; - -@Schema(description = "管理后台 - 属性项更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyUpdateReqVO extends ProductPropertyBaseVO { - - @Schema(description = "主键", required = true, example = "1") - @NotNull(message = "主键不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java deleted file mode 100644 index da3bf5068..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -/** -* 属性值 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class ProductPropertyValueBaseVO { - - @Schema(description = "属性项的编号", required = true, example = "1024") - @NotNull(message = "属性项的编号不能为空") - private Long propertyId; - - @Schema(description = "名称", required = true, example = "红色") - @NotEmpty(message = "名称名字不能为空") - private String name; - - @Schema(description = "备注", example = "颜色") - private String remark; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java deleted file mode 100644 index a643927ae..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java +++ /dev/null @@ -1,12 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -@Schema(description = "管理后台 - 商品属性值创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyValueCreateReqVO extends ProductPropertyValueBaseVO { - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java deleted file mode 100644 index 55bae16df..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -@ApiModel("管理后台 - 商品属性值的明细 Response VO") -@Data -public class ProductPropertyValueDetailRespVO { - - @ApiModelProperty(value = "属性的编号", required = true, example = "1") - private Long propertyId; - - @ApiModelProperty(value = "属性的名称", required = true, example = "颜色") - private String propertyName; - - @ApiModelProperty(value = "属性值的编号", required = true, example = "1024") - private Long valueId; - - @ApiModelProperty(value = "属性值的名称", required = true, example = "红色") - private String valueName; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java deleted file mode 100644 index e484324f0..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - 商品属性值分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyValuePageReqVO extends PageParam { - - @Schema(description = "属性项的编号", example = "1024") - private String propertyId; - - @Schema(description = "名称", example = "红色") - private String name; - - @Schema(description = "状态 - 参见 CommonStatusEnum 枚举", required = true, example = "1") - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java deleted file mode 100644 index dac075b86..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 商品属性值 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyValueRespVO extends ProductPropertyValueBaseVO { - - @Schema(description = "编号", required = true, example = "10") - private Long id; - - @Schema(description = "创建时间") - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java deleted file mode 100644 index e23b8927c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import javax.validation.constraints.*; - -@Schema(description = "管理后台 - 商品属性值更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyValueUpdateReqVO extends ProductPropertyValueBaseVO { - - @Schema(description = "主键", required = true, example = "1024") - @NotNull(message = "主键不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java deleted file mode 100755 index 6c8601782..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java +++ /dev/null @@ -1,57 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.sku; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO; -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; -import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - 商品 sku") -@RestController -@RequestMapping("/product/sku") -@Validated -public class ProductSkuController { - - @Resource - private ProductSkuService productSkuService; - @Resource - private ProductSpuService productSpuService; - - @GetMapping("/get-option-list") - @Operation(summary = "获得商品 SKU 选项的列表") -// @PreAuthorize("@ss.hasPermission('product:sku:query')") - public CommonResult> getSkuOptionList() { - // 获得 SKU 列表 - List skus = productSkuService.getSkuList(); - if (CollUtil.isEmpty(skus)) { - return success(Collections.emptyList()); - } - - // 获得对应的 SPU 映射 - Map spuMap = productSpuService.getSpuMap(convertSet(skus, ProductSkuDO::getSpuId)); - // 转换为返回结果 - List skuVOs = ProductSkuConvert.INSTANCE.convertList05(skus); - skuVOs.forEach(sku -> MapUtils.findAndThen(spuMap, sku.getSpuId(), - spu -> sku.setSpuId(spu.getId()).setSpuName(spu.getName()))); - return success(skuVOs); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java deleted file mode 100755 index 7c1117d57..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java +++ /dev/null @@ -1,75 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.sku.vo; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -/** -* 商品 SKU Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class ProductSkuBaseVO { - - @Schema(description = "商品 SKU 名字", required = true, example = "芋道") - @NotEmpty(message = "商品 SKU 名字不能为空") - private String name; - - @Schema(description = "销售价格,单位:分", required = true, example = "1024", notes = "单位:分") - @NotNull(message = "销售价格,单位:分不能为空") - private Integer price; - - @Schema(description = "市场价", example = "1024", notes = "单位:分") - private Integer marketPrice; - - @Schema(description = "成本价", example = "1024", notes = "单位:分") - private Integer costPrice; - - @Schema(description = "条形码", example = "haha") - private String barCode; - - @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") - @NotNull(message = "图片地址不能为空") - private String picUrl; - - @Schema(description = "SKU 状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") - @NotNull(message = "SKU 状态不能为空") - @InEnum(CommonStatusEnum.class) - private Integer status; - - @Schema(description = "库存", required = true, example = "1") - @NotNull(message = "库存不能为空") - private Integer stock; - - @Schema(description = "预警预存", example = "1") - private Integer warnStock; - - @Schema(description = "商品重量 - 单位:kg 千克", example = "1") - private Double weight; - - @Schema(description = "商品体积 - 单位:m^3 平米", example = "1024") - private Double volume; - - @ApiModel("商品属性") - @Data - @AllArgsConstructor - @NoArgsConstructor - public static class Property { - - @Schema(description = "属性编号", required = true, example = "1") - @NotNull(message = "属性编号不能为空") - private Long propertyId; - - @Schema(description = "属性值编号", required = true, example = "1024") - @NotNull(message = "属性值编号不能为空") - private Long valueId; - - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java deleted file mode 100755 index 496475f99..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.sku.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.List; - -@Schema(description = "管理后台 - 商品 SKU 创建/更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO { - - /** - * 属性数组 - */ - private List properties; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java deleted file mode 100644 index 1522ca59e..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.sku.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - 商品 SKU 选项 Response VO,用于前端 SELECT 选项") -@Data -public class ProductSkuOptionRespVO { - - @Schema(description = "主键", required = true, example = "1024") - private Long id; - - @Schema(description = "商品 SKU 名字", example = "红色") - private String name; - - @Schema(description = "销售价格,单位:分", required = true, example = "100") - private String price; - - @Schema(description = "库存", required = true, example = "100") - private Integer stock; - - // ========== 商品 SPU 信息 ========== - - @Schema(description = "商品 SPU 编号", required = true, example = "1") - private Long spuId; - - @Schema(description = "商品 SPU 名字", required = true, example = "iPhone 11") - private String spuName; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java deleted file mode 100755 index 95e394ada..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.sku.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; -import java.util.List; - -@Schema(description = "管理后台 - 商品 SKU Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductSkuRespVO extends ProductSkuBaseVO { - - @Schema(description = "主键", required = true, example = "1024") - private Long id; - - @Schema(description = "创建时间") - private LocalDateTime createTime; - - /** - * 属性数组 - */ - private List properties; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http deleted file mode 100644 index 4ab7b4f71..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http +++ /dev/null @@ -1,4 +0,0 @@ -### 获得商品 SPU 明细 -GET {{baseUrl}}/product/spu/get-detail?id=4 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java deleted file mode 100755 index 10da8104f..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ /dev/null @@ -1,101 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.spu; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; -import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; -import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; - -@Tag(name = "管理后台 - 商品 SPU") -@RestController -@RequestMapping("/product/spu") -@Validated -public class ProductSpuController { - - @Resource - private ProductSpuService productSpuService; - @Resource - private ProductSkuService productSkuService; - @Resource - private ProductPropertyValueService productPropertyValueService; - - @PostMapping("/create") - @Operation(summary = "创建商品 SPU") - @PreAuthorize("@ss.hasPermission('product:spu:create')") - public CommonResult createProductSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) { - return success(productSpuService.createSpu(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新商品 SPU") - @PreAuthorize("@ss.hasPermission('product:spu:update')") - public CommonResult updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) { - productSpuService.updateSpu(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除商品 SPU") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('product:spu:delete')") - public CommonResult deleteSpu(@RequestParam("id") Long id) { - productSpuService.deleteSpu(id); - return success(true); - } - - @GetMapping("/get-detail") - @Operation(summary = "获得商品 SPU 明细") - @Parameter(name = "id", value = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult getSpuDetail(@RequestParam("id") Long id) { - // 获得商品 SPU - ProductSpuDO spu = productSpuService.getSpu(id); - if (spu == null) { - throw exception(SPU_NOT_EXISTS); - } - - // 查询商品 SKU - List skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(), null); - // 查询商品属性 - List propertyValues = productPropertyValueService - .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); - // 拼接 - return success(ProductSpuConvert.INSTANCE.convert03(spu, skus, propertyValues)); - } - - @GetMapping("/get-simple-list") - @Operation(summary = "获得商品 SPU 精简列表") - @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult> getSpuSimpleList() { - List list = productSpuService.getSpuList(); - return success(ProductSpuConvert.INSTANCE.convertList02(list)); - } - - @GetMapping("/page") - @Operation(summary = "获得商品 SPU 分页") - @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { - return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO))); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java deleted file mode 100755 index 22d1d3025..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ /dev/null @@ -1,76 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.spu.vo; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.util.List; - -/** - * 商品 SPU Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class ProductSpuBaseVO { - - @Schema(description = = "商品名称", required = true, example = "芋道") - @NotEmpty(message = "商品名称不能为空") - private String name; - - @Schema(description = = "商品编码", example = "yudaoyuanma") - private String code; - - @Schema(description = = "促销语", example = "好吃!") - private String sellPoint; - - @Schema(description = = "商品详情", required = true, example = "我是商品描述") - @NotNull(message = "商品详情不能为空") - private String description; - - @Schema(description = = "商品分类编号", required = true, example = "1") - @NotNull(message = "商品分类编号不能为空") - private Long categoryId; - - @Schema(description = = "商品品牌编号", example = "1") - private Long brandId; - - @Schema(description = = "商品图片的数组", required = true) - @NotNull(message = "商品图片的数组不能为空") - private List picUrls; - - @Schema(description = = "商品视频", required = true) - private String videoUrl; - - @Schema(description = = "排序字段", required = true, example = "1") - private Integer sort; - - @Schema(description = = "商品状态 参见 ProductSpuStatusEnum 枚举类", required = true, example = "1") - @NotNull(message = "商品状态不能为空") - @InEnum(ProductSpuStatusEnum.class) - private Integer status; - - // ========== SKU 相关字段 ========= - - @Schema(description = = "规格类型 参见 ProductSpuSpecTypeEnum 枚举类", required = true, example = "1") - @NotNull(message = "规格类型不能为空") - @InEnum(ProductSpuSpecTypeEnum.class) - private Integer specType; - - @Schema(description = = "是否展示库存", required = true, example = "true") - @NotNull(message = "是否展示库存不能为空") - private Boolean showStock; - - @Schema(description = = "市场价", example = "1024") - private Integer marketPrice; - - // ========== 统计相关字段 ========= - - @Schema(description = = "虚拟销量", required = true, example = "1024") - @NotNull(message = "虚拟销量不能为空") - private Integer virtualSalesCount; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java deleted file mode 100755 index c75ed4d2e..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.spu.vo; - -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.Valid; -import java.util.List; - -@Schema(description = "管理后台 - 商品 SPU 创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductSpuCreateReqVO extends ProductSpuBaseVO { - - /** - * SKU 数组 - */ - @Valid - private List skus; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java deleted file mode 100644 index a8cf9f5b9..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.spu.vo; - -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.List; - -@Schema(description = "管理后台 - 商品 SPU 详细 Response VO 包括关联的 SKU 等信息") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductSpuDetailRespVO extends ProductSpuRespVO { - - // ========== SKU 相关字段 ========= - - /** - * SKU 数组 - */ - private List skus; - - @Schema(description = "管理后台 - 商品 SKU 详细 Response VO") - @Data - @EqualsAndHashCode(callSuper = true) - @ToString(callSuper = true) - public static class Sku extends ProductSkuBaseVO { - - /** - * 属性数组 - */ - private List properties; - - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java deleted file mode 100755 index d4714328f..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.spu.vo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - 商品 SPU 分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductSpuPageReqVO extends PageParam { - - @Schema(description = "商品名称", example = "yutou") - private String name; - - @Schema(description = "商品编码", example = "yudaoyuanma") - private String code; - - @Schema(description = "分类编号", example = "1") - private Long categoryId; - - @Schema(description = "商品品牌编号", example = "1") - private Long brandId; - - @Schema(description = "上下架状态 参见 ProductSpuStatusEnum 枚举值", example = "1") - private Integer status; - - @Schema(description = "销量最小值", example = "1") - private Integer salesCountMin; - - @Schema(description = "销量最大值", example = "1024") - private Integer salesCountMax; - - @Schema(description = "市场价最小值", example = "1") - private Integer marketPriceMin; - - @Schema(description = "市场价最大值", example = "1024") - private Integer marketPriceMax; - - @Schema(description = "是否库存告警", example = "true") - private Boolean alarmStock; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java deleted file mode 100755 index 49303a7a3..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.spu.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 商品 SPU Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductSpuRespVO extends ProductSpuBaseVO { - - @Schema(description = "主键", required = true, example = "1") - private Long id; - - @Schema(description = "创建时间") - private LocalDateTime createTime; - - // ========== SKU 相关字段 ========= - - @ApiModelProperty(value = "库存", required = true, example = "true") - private Integer totalStock; - - @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024") - private Integer minPrice; - - @ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024") - private Integer maxPrice; - - @ApiModelProperty(value = "商品销量", example = "1024") - private Integer salesCount; - - // ========== 统计相关字段 ========= - - @ApiModelProperty(value = "点击量", example = "1024") - private Integer clickCount; -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java deleted file mode 100755 index 9cc7bf169..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.spu.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - 商品 SPU 精简 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductSpuSimpleRespVO extends ProductSpuBaseVO { - - @Schema(description = "主键", required = true, example = "1") - private Long id; - - @Schema(description = "商品名称", required = true, example = "芋道") - private String name; - - @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") - private Integer minPrice; - - @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") - private Integer maxPrice; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java deleted file mode 100755 index 6ea84fb9e..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.spu.vo; - -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; -import java.util.List; - -@Schema(description = "管理后台 - 商品 SPU 更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductSpuUpdateReqVO extends ProductSpuBaseVO { - - @Schema(description = "商品编号", required = true, example = "1") - @NotNull(message = "商品编号不能为空") - private Long id; - - /** - * SKU 数组 - */ - @Valid - private List skus; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java deleted file mode 100644 index 79f066de4..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.category; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRespVO; -import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import java.util.Comparator; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "用户 APP - 商品分类") -@RestController -@RequestMapping("/product/category") -@Validated -public class AppCategoryController { - - @Resource - private ProductCategoryService categoryService; - - @GetMapping("/list") - @Operation(summary = "获得商品分类列表") - public CommonResult> getProductCategoryList() { - List list = categoryService.getEnableCategoryList(); - list.sort(Comparator.comparing(ProductCategoryDO::getSort)); - return success(ProductCategoryConvert.INSTANCE.convertList03(list)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java deleted file mode 100644 index 1dca05a3a..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.category.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; - -@Data -@Schema(description = "用户 APP - 商品分类 Response VO") -public class AppCategoryRespVO { - - @Schema(description = "分类编号", required = true, example = "2") - private Long id; - - @Schema(description = "父分类编号", required = true, example = "1") - @NotNull(message = "父分类编号不能为空") - private Long parentId; - - @Schema(description = "分类名称", required = true, example = "办公文具") - @NotBlank(message = "分类名称不能为空") - private String name; - - @Schema(description = "分类图片", required = true) - @NotBlank(message = "分类图片不能为空") - private String picUrl; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java deleted file mode 100644 index 379e85180..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 占位符,无时间作用,避免 package 缩进 - */ -package cn.iocoder.yudao.module.product.controller.app.property; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java deleted file mode 100644 index 6538bea3c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 占位符,无时间作用,避免 package 缩进 - */ -package cn.iocoder.yudao.module.product.controller.app.property.vo.property; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java deleted file mode 100644 index 516dd077f..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.property.vo.value; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -@ApiModel("用户 App - 商品属性值的明细 Response VO") -@Data -public class AppProductPropertyValueDetailRespVO { - - @ApiModelProperty(value = "属性的编号", required = true, example = "1") - private Long propertyId; - - @ApiModelProperty(value = "属性的名称", required = true, example = "颜色") - private String propertyName; - - @ApiModelProperty(value = "属性值的编号", required = true, example = "1024") - private Long valueId; - - @ApiModelProperty(value = "属性值的名称", required = true, example = "红色") - private String valueName; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http deleted file mode 100644 index 04df7bfec..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http +++ /dev/null @@ -1,8 +0,0 @@ -### 获得订单交易的分页 TODO -GET {{appApi}}/product/spu/page?pageNo=1&pageSize=10 -Authorization: Bearer {{appToken}} -tenant-id: {{appTenentId}} - -### 获得商品 SPU 明细 -GET {{appApi}}/product/spu/get-detail?id=4 -tenant-id: {{appTenentId}} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java deleted file mode 100644 index b2f8b495d..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ /dev/null @@ -1,78 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.spu; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; -import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; -import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; - -@Tag(name = "用户 APP - 商品spu") -@RestController -@RequestMapping("/product/spu") -@Validated -public class AppProductSpuController { - - @Resource - private ProductSpuService productSpuService; - @Resource - private ProductSkuService productSkuService; - @Resource - private ProductPropertyValueService productPropertyValueService; - - @GetMapping("/page") - @Operation(summary = "获得商品 SPU 分页") - public CommonResult> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { - PageResult pageResult = productSpuService.getSpuPage(pageVO, ProductSpuStatusEnum.ENABLE.getStatus()); - return success(ProductSpuConvert.INSTANCE.convertPage02(pageResult)); - } - - @GetMapping("/get-detail") - @Operation(summary = "获得商品 SPU 明细") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) - public CommonResult getSpuDetail(@RequestParam("id") Long id) { - // 获得商品 SPU - ProductSpuDO spu = productSpuService.getSpu(id); - if (spu == null) { - throw exception(SPU_NOT_EXISTS); - } - if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { - throw exception(SPU_NOT_ENABLE); - } - - // 查询商品 SKU - List skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(), - CommonStatusEnum.ENABLE.getStatus()); - // 查询商品属性 - List propertyValues = productPropertyValueService - .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); - // 拼接 - return success(ProductSpuConvert.INSTANCE.convert(spu, skus, propertyValues)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java deleted file mode 100644 index 699ca1caa..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java +++ /dev/null @@ -1,92 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.spu.vo; - -import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; - -@ApiModel("用户 App - 商品 SPU 明细 Response VO") -@Data -public class AppProductSpuDetailRespVO { - - @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") - private Long id; - - // ========== 基本信息 ========= - - @ApiModelProperty(value = "商品名称", required = true, example = "芋道") - private String name; - - @ApiModelProperty(value = "促销语", example = "好吃!") - private String sellPoint; - - @ApiModelProperty(value = "商品详情", required = true, example = "我是商品描述") - private String description; - - @ApiModelProperty(value = "商品分类编号", required = true, example = "1") - private Long categoryId; - - @ApiModelProperty(value = "商品图片的数组", required = true) - private List picUrls; - - @ApiModelProperty(value = "商品视频", required = true) - private String videoUrl; - - // ========== SKU 相关字段 ========= - - @ApiModelProperty(value = "规格类型", required = true, example = "1", notes = "参见 ProductSpuSpecTypeEnum 枚举类") - private Integer specType; - - @ApiModelProperty(value = "是否展示库存", required = true, example = "true") - private Boolean showStock; - - @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024") - private Integer minPrice; - - @ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024") - private Integer maxPrice; - - /** - * SKU 数组 - */ - private List skus; - - // ========== 统计相关字段 ========= - - @ApiModelProperty(value = "商品销量", required = true, example = "1024") - private Integer salesCount; - - @ApiModel("用户 App - 商品 SPU 明细的 SKU 信息") - @Data - public static class Sku { - - @ApiModelProperty(value = "商品 SKU 编号", example = "1") - private Long id; - - /** - * 商品属性数组 - */ - private List properties; - - @ApiModelProperty(value = "销售价格,单位:分", required = true, example = "1024", notes = "单位:分") - private Integer price; - - @ApiModelProperty(value = "市场价", example = "1024", notes = "单位:分") - private Integer marketPrice; - - @ApiModelProperty(value = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") - private String picUrl; - - @ApiModelProperty(value = "库存", required = true, example = "1") - private Integer stock; - - @ApiModelProperty(value = "商品重量", example = "1", notes = "单位:kg 千克") - private Double weight; - - @ApiModelProperty(value = "商品体积", example = "1024", notes = "单位:m^3 平米") - private Double volume; - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java deleted file mode 100644 index 60fc9235e..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.spu.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.util.List; - -@ApiModel("用户 App - 商品 SPU 分页项 Response VO") -@Data -public class AppProductSpuPageItemRespVO { - - @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") - private Long id; - - @ApiModelProperty(value = "商品名称", required = true, example = "芋道") - @NotEmpty(message = "商品名称不能为空") - private String name; - - @ApiModelProperty(value = "分类编号", required = true) - @NotNull(message = "分类编号不能为空") - private Long categoryId; - - @ApiModelProperty(value = "商品图片的数组", required = true) - private List picUrls; - - @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024") - private Integer minPrice; - - @ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024") - private Integer maxPrice; - - // ========== 统计相关字段 ========= - - @ApiModelProperty(value = "商品销量", example = "1024") - private Integer salesCount; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java deleted file mode 100644 index f19a7c21a..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.spu.vo; - -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.constraints.AssertTrue; - -@ApiModel("用户 App - 商品 SPU 分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class AppProductSpuPageReqVO extends PageParam { - - public static final String SORT_FIELD_PRICE = "price"; - public static final String SORT_FIELD_SALES_COUNT = "salesCount"; - - @ApiModelProperty(value = "分类编号", example = "1") - private Long categoryId; - - @ApiModelProperty(value = "关键字", example = "好看") - private String keyword; - - @ApiModelProperty(value = "排序字段", example = "price", notes = "参见 AppSpuPageReqVO.SORT_FIELD_XXX 常量") - private String sortField; - - @ApiModelProperty(value = "排序方式", example = "true", notes = "true - 升序;false - 降序") - private Boolean sortAsc; - - @AssertTrue(message = "排序字段不合法") - @JsonIgnore - public boolean isSortFieldValid() { - if (StrUtil.isEmpty(sortField)) { - return true; - } - return StrUtil.equalsAny(sortField, SORT_FIELD_PRICE, SORT_FIELD_SALES_COUNT); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageReqVO.java deleted file mode 100644 index e69de29bb..000000000 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuPageRespVO.java deleted file mode 100644 index e69de29bb..000000000 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java deleted file mode 100644 index e69de29bb..000000000 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java deleted file mode 100644 index a318e9128..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.product.convert.brand; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandRespVO; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -/** - * 品牌 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface ProductBrandConvert { - - ProductBrandConvert INSTANCE = Mappers.getMapper(ProductBrandConvert.class); - - ProductBrandDO convert(ProductBrandCreateReqVO bean); - - ProductBrandDO convert(ProductBrandUpdateReqVO bean); - - ProductBrandRespVO convert(ProductBrandDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java deleted file mode 100644 index ae01ca9d5..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.product.convert.category; - -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRespVO; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -/** - * 商品分类 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface ProductCategoryConvert { - - ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class); - - ProductCategoryDO convert(ProductCategoryCreateReqVO bean); - - ProductCategoryDO convert(ProductCategoryUpdateReqVO bean); - - ProductCategoryRespVO convert(ProductCategoryDO bean); - - List convertList(List list); - - List convertList03(List list); -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java deleted file mode 100644 index 211bcc293..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java +++ /dev/null @@ -1,48 +0,0 @@ -package cn.iocoder.yudao.module.product.convert.property; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; -import java.util.Map; - -/** - * 属性项 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface ProductPropertyConvert { - - ProductPropertyConvert INSTANCE = Mappers.getMapper(ProductPropertyConvert.class); - - ProductPropertyDO convert(ProductPropertyCreateReqVO bean); - - ProductPropertyDO convert(ProductPropertyUpdateReqVO bean); - - ProductPropertyRespVO convert(ProductPropertyDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - default List convertList(List keys, List values) { - Map> valueMap = CollectionUtils.convertMultiMap(values, ProductPropertyValueDO::getPropertyId); - return CollectionUtils.convertList(keys, key -> { - ProductPropertyAndValueRespVO respVO = convert02(key); - respVO.setValues(convertList02(valueMap.get(key.getId()))); - return respVO; - }); - } - ProductPropertyAndValueRespVO convert02(ProductPropertyDO bean); - List convertList02(List list); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/propertyvalue/ProductPropertyValueConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/propertyvalue/ProductPropertyValueConvert.java deleted file mode 100644 index d6167c174..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/propertyvalue/ProductPropertyValueConvert.java +++ /dev/null @@ -1,55 +0,0 @@ -package cn.iocoder.yudao.module.product.convert.propertyvalue; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * 属性值 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface ProductPropertyValueConvert { - - ProductPropertyValueConvert INSTANCE = Mappers.getMapper(ProductPropertyValueConvert.class); - - ProductPropertyValueDO convert(ProductPropertyValueCreateReqVO bean); - - ProductPropertyValueDO convert(ProductPropertyValueUpdateReqVO bean); - - ProductPropertyValueRespVO convert(ProductPropertyValueDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - default List convertList(List values, List keys) { - Map keyMap = convertMap(keys, ProductPropertyDO::getId); - return CollectionUtils.convertList(values, value -> { - ProductPropertyValueDetailRespBO valueDetail = new ProductPropertyValueDetailRespBO() - .setValueId(value.getId()).setValueName(value.getName()); - // 设置属性项 - MapUtils.findAndThen(keyMap, value.getPropertyId(), - key -> valueDetail.setPropertyId(key.getId()).setPropertyName(key.getName())); - return valueDetail; - }); - } - - List convertList02(List list); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java deleted file mode 100755 index f397dfc48..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java +++ /dev/null @@ -1,93 +0,0 @@ -package cn.iocoder.yudao.module.product.convert.sku; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.*; -import java.util.stream.Collectors; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * 商品 SKU Convert - * - * @author 芋道源码 - */ -@Mapper -public interface ProductSkuConvert { - - ProductSkuConvert INSTANCE = Mappers.getMapper(ProductSkuConvert.class); - - ProductSkuDO convert(ProductSkuCreateOrUpdateReqVO bean); - - ProductSkuRespVO convert(ProductSkuDO bean); - - List convertList(List list); - - List convertList06(List list); - - default List convertList06(List list, Long spuId, String spuName) { - List result = convertList06(list); - result.forEach(item -> item.setSpuId(spuId).setSpuName(spuName)); - return result; - } - - ProductSkuRespDTO convert02(ProductSkuDO bean); - - List convertList03(List list); - - List convertList04(List list); - - List convertList05(List skus); - - /** - * 获得 SPU 的库存变化 Map - * - * @param items SKU 库存变化 - * @param skus SKU 列表 - * @return SPU 的库存变化 Map - */ - default Map convertSpuStockMap(List items, - List skus) { - Map skuIdAndSpuIdMap = convertMap(skus, ProductSkuDO::getId, ProductSkuDO::getSpuId); // SKU 与 SKU 编号的 Map 关系 - Map spuIdAndStockMap = new HashMap<>(); // SPU 的库存变化 Map 关系 - items.forEach(item -> { - Long spuId = skuIdAndSpuIdMap.get(item.getId()); - if (spuId == null) { - return; - } - Integer stock = spuIdAndStockMap.getOrDefault(spuId, 0) + item.getIncrCount(); - spuIdAndStockMap.put(spuId, stock); - }); - return spuIdAndStockMap; - } - - default Collection convertPropertyValueIds(List list) { - if (CollUtil.isEmpty(list)) { - return new HashSet<>(); - } - return list.stream().filter(item -> item.getProperties() != null) - .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 - .map(ProductSkuDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 - .collect(Collectors.toSet()); - } - - default String buildPropertyKey(ProductSkuDO bean) { - if (CollUtil.isEmpty(bean.getProperties())) { - return StrUtil.EMPTY; - } - List properties = new ArrayList<>(bean.getProperties()); - properties.sort(Comparator.comparing(ProductSkuDO.Property::getValueId)); - return properties.stream().map(m -> String.valueOf(m.getValueId())).collect(Collectors.joining()); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java deleted file mode 100755 index fcf6d6436..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ /dev/null @@ -1,108 +0,0 @@ -package cn.iocoder.yudao.module.product.convert.spu; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; -import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static cn.hutool.core.util.ObjectUtil.defaultIfNull; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * 商品 SPU Convert - * - * @author 芋道源码 - */ -@Mapper -public interface ProductSpuConvert { - - ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class); - - ProductSpuDO convert(ProductSpuCreateReqVO bean); - - ProductSpuDO convert(ProductSpuUpdateReqVO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean); - - List convertList2(List list); - - List convertList02(List list); - - default AppProductSpuDetailRespVO convert(ProductSpuDO spu, List skus, - List propertyValues) { - AppProductSpuDetailRespVO spuVO = convert02(spu) - .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)); - spuVO.setSkus(convertList03(skus)); - // 处理商品属性 - Map propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); - for (int i = 0; i < skus.size(); i++) { - List properties = skus.get(i).getProperties(); - if (CollUtil.isEmpty(properties)) { - continue; - } - AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); - sku.setProperties(new ArrayList<>(properties.size())); - // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 - properties.forEach(property -> { - ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); - if (propertyValue == null) { - return; - } - sku.getProperties().add(convert03(propertyValue)); - }); - } - return spuVO; - } - AppProductSpuDetailRespVO convert02(ProductSpuDO spu); - List convertList03(List skus); - AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue); - - PageResult convertPage02(PageResult page); - - default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List skus, - List propertyValues) { - ProductSpuDetailRespVO spuVO = convert03(spu); - spuVO.setSkus(convertList04(skus)); - // 处理商品属性 - Map propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); - for (int i = 0; i < skus.size(); i++) { - List properties = skus.get(i).getProperties(); - if (CollUtil.isEmpty(properties)) { - continue; - } - ProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); - sku.setProperties(new ArrayList<>(properties.size())); - // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 - properties.forEach(property -> { - ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); - if (propertyValue == null) { - return; - } - sku.getProperties().add(convert04(propertyValue)); - }); - } - return spuVO; - } - ProductSpuDetailRespVO convert03(ProductSpuDO spu); - List convertList04(List skus); - ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java deleted file mode 100644 index 9775f36a5..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java +++ /dev/null @@ -1,53 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.brand; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商品品牌 DO - * - * @author 芋道源码 - */ -@TableName("product_brand") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductBrandDO extends BaseDO { - - /** - * 品牌编号 - */ - @TableId - private Long id; - /** - * 品牌名称 - */ - private String name; - /** - * 品牌图片 - */ - private String picUrl; - /** - * 品牌排序 - */ - private Integer sort; - /** - * 品牌描述 - */ - private String description; - /** - * 状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - - // TODO 芋艿:firstLetter 首字母 - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java deleted file mode 100644 index 93ec925a9..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java +++ /dev/null @@ -1,67 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.category; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商品分类 DO - * - * 商品分类一共两类: - * 1)一级分类:{@link #parentId} 等于 0 - * 2)二级 + 三级分类:{@link #parentId} 不等于 0 - * - * @author 芋道源码 - */ -@TableName("product_category") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductCategoryDO extends BaseDO { - - /** - * 父分类编号 - 根分类 - */ - public static final Long PARENT_ID_NULL = 0L; - - /** - * 分类编号 - */ - @TableId - private Long id; - /** - * 父分类编号 - */ - private Long parentId; - /** - * 分类名称 - */ - private String name; - /** - * 分类图片 - * - * 一级分类:推荐 200 x 100 分辨率 - * 二级 + 三级分类:推荐 100 x 100 分辨率 - */ - private String picUrl; - /** - * 分类排序 - */ - private Integer sort; - /** - * 分类描述 - */ - private String description; - /** - * 开启状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java deleted file mode 100644 index c14808f22..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java +++ /dev/null @@ -1,129 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.comment; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.enums.comment.ProductCommentAuditStatusEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import lombok.*; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * 商品评论 DO - * - * @author 芋道源码 - */ -@TableName("product_comment") -@KeySequence("product_comment_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductCommentDO extends BaseDO { - - /** - * 评论编号,主键自增 - */ - @TableId - private Long id; - /** - * 商品 SPU 编号 - * - * 关联 {@link ProductSpuDO#getId()} - */ - private Long spuId; - /** - * 交易订单编号 - * - * 关联 TradeOrderDO 的 id 编号 - */ - private Long orderId; - /** - * 交易订单项编号 - * - * 关联 TradeOrderItemDO 的 id 编号 - */ - private Long orderItemId; - /** - * 审核状态 - * - * 枚举 {@link ProductCommentAuditStatusEnum} - */ - private Integer auditStatus; - - /** - * 用户编号 - * - * 关联 MemberUserDO 的 id 编号 - */ - private Long userId; - /** - * 用户 IP - */ - private String userIp; - /** - * 是否匿名 - */ - private Boolean anonymous; - /** - * 评论内容 - */ - private String content; - /** - * 评论图片地址数组 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private List picUrls; - /** - * 描述相符星级 - * - * 1-5 星 - */ - private Integer descriptionScore; - /** - * 商品评论星级 - * - * 1-5 星 - */ - private Integer productScore; - /** - * 服务评论星级 - * - * 1-5 星 - */ - private Integer serviceScore; - /** - * 物流评论星级 - * - * 1-5 星 - */ - private Integer expressComment; - - /** - * 商家是否回复 - */ - private Boolean replied; - /** - * 商家回复内容 - */ - private String replyContent; - /** - * 商家回复时间 - */ - private LocalDateTime replyTime; - - /** - * 有用的计数 - * - * 其他用户看到评论时,可点击「有用」按钮 - */ - private Integer usefulCount; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java deleted file mode 100644 index 70445dc01..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.delivery; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 配送模板 SPU DO - * - * @author 芋道源码 - */ -@TableName("delivery_template") -@KeySequence("delivery_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class DeliveryTemplateDO extends BaseDO { - - /** - * 编号,自增 - */ - @TableId - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java deleted file mode 100644 index 54d4b31ac..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.favorite; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商品收藏 DO - * - * @author 芋道源码 - */ -@TableName("product_favorite") -@KeySequence("product_favorite_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductFavoriteDO extends BaseDO { - - /** - * 编号,主键自增 - */ - @TableId - private Long id; - /** - * 用户编号 - * - * 关联 MemberUserDO 的 id 编号 - */ - private Long userId; - /** - * 商品 SPU 编号 - * - * 关联 {@link ProductSpuDO#getId()} - */ - private Long spuId; - - // TODO 芋艿:type 1 收藏;2 点赞 - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java deleted file mode 100644 index 2e3b63e59..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.group; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商品分组的绑定 DO - * - * @author 芋道源码 - */ -@TableName("product_group_bind") -@KeySequence("product_group_bind_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductGroupBindDO extends BaseDO { - - /** - * 编号,自增 - */ - @TableId - private Long id; - /** - * 商品分组编号 - * - * 关联 {@link ProductGroupDO#getId()} - */ - private Long groupId; - /** - * 商品 SPU 编号 - * - * 关联 {@link ProductSpuDO#getId()} - */ - private Long spuId; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java deleted file mode 100644 index 605e8c38a..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java +++ /dev/null @@ -1,63 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.group; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.product.enums.group.ProductGroupStyleEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商品分组 DO - * - * @author 芋道源码 - */ -@TableName("product_group") -@KeySequence("product_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductGroupDO extends BaseDO { - - /** - * 商品分组编号,自增 - */ - @TableId - private Long id; - /** - * 分组名称 - */ - private String name; - /** - * 状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - /** - * 商品数量 - */ - private Integer count; - /** - * 排序 - */ - private Integer sort; - /** - * 风格,用于 APP 首页展示商品的样式 - * - * 枚举 {@link ProductGroupStyleEnum} - */ - private Integer style; - /** - * 是否默认 - * - * true - 系统默认,不允许删除 - * false - 自定义,允许删除 - */ - private Boolean defaulted; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java deleted file mode 100644 index 2976674c1..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.property; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商品属性项 DO - * - * @author 芋道源码 - */ -@TableName("product_property") -@KeySequence("product_property_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductPropertyDO extends BaseDO { - - /** - * 主键 - */ - @TableId - private Long id; - /** - * 名称 - */ - private String name; - /** - * 备注 - */ - private String remark; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java deleted file mode 100644 index d73fe06b2..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.property; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - - -/** - * 商品属性值 DO - * - * @author 芋道源码 - */ -@TableName("product_property_value") -@KeySequence("product_property_value_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductPropertyValueDO extends BaseDO { - - /** - * 主键 - */ - @TableId - private Long id; - /** - * 属性项的编号 - * - * 关联 {@link ProductPropertyDO#getId()} - */ - private Long propertyId; - /** - * 名称 - */ - private String name; - /** - * 备注 - * - */ - private String remark; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java deleted file mode 100644 index 3d5cf9101..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.search; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商品热搜关键字 DO - * - * @author 芋道源码 - */ -@TableName("product_hot_search") -@KeySequence("product_hot_search_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductHotSearchDO extends BaseDO { - - /** - * 编号,主键自增 - */ - @TableId - private Long id; - /** - * 关键字 - */ - private String name; - /** - * 内容 - */ - private String content; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java deleted file mode 100644 index 1c702da91..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.shop; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -// TODO 芋艿:待设计 -/** - * 店铺 DO - * - * @author 芋道源码 - */ -@TableName("shop") -@KeySequence("shop_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ShopDO extends BaseDO { - - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java deleted file mode 100755 index 3836f20e5..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java +++ /dev/null @@ -1,137 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.sku; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; -import lombok.*; - -import java.util.List; - -/** - * 商品 SKU DO - * - * @author 芋道源码 - */ -@TableName(value = "product_sku",autoResultMap = true) -@KeySequence("product_sku_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductSkuDO extends BaseDO { - - /** - * 商品 SKU 编号,自增 - */ - @TableId - private Long id; - /** - * SPU 编号 - *

- * 关联 {@link ProductSpuDO#getId()} - */ - private Long spuId; - /** - * SPU 名字 - * - * 冗余 {@link ProductSkuDO#getSpuName()} - */ - private String spuName; - /** - * 属性数组,JSON 格式 - */ - @TableField(typeHandler = PropertyTypeHandler.class) - private List properties; - /** - * 销售价格,单位:分 - */ - private Integer price; - /** - * 市场价,单位:分 - */ - private Integer marketPrice; - /** - * 成本价,单位:分 - */ - private Integer costPrice; - /** - * SKU 的条形码 - */ - private String barCode; - /** - * 图片地址 - */ - private String picUrl; - /** - * SKU 状态 - *

- * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - /** - * 库存 - */ - private Integer stock; - /** - * 预警预存 - */ - private Integer warnStock; - /** - * 商品重量,单位:kg 千克 - */ - private Double weight; - /** - * 商品体积,单位:m^3 平米 - */ - private Double volume; - - /** - * 商品属性 - */ - @Data - @NoArgsConstructor - @AllArgsConstructor - public static class Property { - - /** - * 属性编号 - *

- * 关联 {@link ProductPropertyDO#getId()} - */ - private Long propertyId; - /** - * 属性值编号 - *

- * 关联 {@link ProductPropertyValueDO#getId()} - */ - private Long valueId; - - } - - // TODO @芋艿:可以找一些新的思路 - public static class PropertyTypeHandler extends AbstractJsonTypeHandler { - - @Override - protected Object parse(String json) { - return JsonUtils.parseArray(json, Property.class); - } - - @Override - protected String toJson(Object obj) { - return JsonUtils.toJsonString(obj); - } - - } - -} - diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java deleted file mode 100755 index 93c47d4af..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ /dev/null @@ -1,212 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.dataobject.spu; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import lombok.*; - -import java.util.List; - -/** - * 商品 SPU DO - * - * @author 芋道源码 - */ -@TableName(value = "product_spu", autoResultMap = true) -@KeySequence("product_spu_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductSpuDO extends BaseDO { - - /** - * 商品 SPU 编号,自增 - */ - @TableId - private Long id; - - // ========== 基本信息 ========= - - /** - * 商品名称 - */ - private String name; - /** - * 商品编码 - */ - private String code; - /** - * 促销语 - */ - private String sellPoint; - /** - * 商品详情 - */ - private String description; - /** - * 商品分类编号 - * - * 关联 {@link ProductCategoryDO#getId()} - */ - private Long categoryId; - /** - * 商品品牌编号 - * - * 关联 {@link ProductBrandDO#getId()} - */ - private Long brandId; - /** - * 商品图片的数组 - * - * 1. 第一张图片将作为商品主图,支持同时上传多张图; - * 2. 建议使用尺寸 800x800 像素以上、大小不超过 1M 的正方形图片; - * 3. 至少 1 张,最多上传 10 张 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private List picUrls; - /** - * 商品视频 - */ - private String videoUrl; - - /** - * 排序字段 - */ - private Integer sort; - /** - * 商品状态 - * - * 枚举 {@link ProductSpuStatusEnum} - */ - private Integer status; - - // ========== SKU 相关字段 ========= - - /** - * 规格类型 - * - * 枚举 {@link ProductSpuSpecTypeEnum} - */ - private Integer specType; - /** - * 最小价格,单位使用:分 - * - * 基于其对应的 {@link ProductSkuDO#getPrice()} 最小值 - */ - private Integer minPrice; - /** - * 最大价格,单位使用:分 - * - * 基于其对应的 {@link ProductSkuDO#getPrice()} 最大值 - */ - private Integer maxPrice; - /** - * 市场价,单位使用:分 - * - * 基于其对应的 {@link ProductSkuDO#getMarketPrice()} 最大值 - */ - private Integer marketPrice; - /** - * 总库存 - * - * 基于其对应的 {@link ProductSkuDO#getStock()} 求和 - */ - private Integer totalStock; - /** - * 是否展示库存 - */ - private Boolean showStock; - - // ========== 统计相关字段 ========= - - /** - * 商品销量 - */ - private Integer salesCount; - /** - * 虚拟销量 - */ - private Integer virtualSalesCount; - /** - * 商品点击量 - */ - private Integer clickCount; - - // ========== 物流相关字段 ========= - - // TODO 芋艿:稍后完善物流的字段 -// /** -// * 配送方式 -// * -// * 枚举 {@link DeliveryModeEnum} -// */ -// private Integer deliveryMode; -// /** -// * 配置模板编号 -// * -// * 关联 {@link DeliveryTemplateDO#getId()} -// */ -// private Long deliveryTemplateId; - - // TODO ========== 待定字段:yv ========= - // TODO vip_price 会员价格 - // TODO postage 邮费 - // TODO is_postage 是否包邮 - // TODO unit_name 单位 - // TODO is_new 商户是否代理 - // TODO give_integral 获得积分 - // TODO is_integral 是开启积分兑换 - // TODO integral 所需积分 - // TODO is_seckill 秒杀状态 - // TODO is_bargain 砍价状态 - // TODO code_path 产品二维码地址 - // TODO is_sub 是否分佣 - - // TODO ↓↓ 芋艿 ↓↓ 看起来走分组更合适? - // TODO is_hot 是否热卖 - // TODO is_benefit 是否优惠 - // TODO is_best 是否精品 - // TODO is_new 是否新品 - // TODO is_good 是否优品推荐 - - // TODO ========== 待定字段:cf ========= - // TODO source_link 淘宝京东1688类型 - // TODO activity 活动显示排序 0=默认 1=秒 2=砍价 3=拼团 - - // TODO ========== 待定字段:lf ========= - - // TODO free_shipping_type:运费类型:1-包邮;2-统一运费;3-运费模板 - // TODO free_shipping:统一运费金额 - // TODO free_shipping_template_id:运费模板 - // TODO is_commission:分销佣金:1-开启;0-不开启;first_ratio second_ratio three_ratio - // TODO is_share_bouns:区域股东分红:1-开启;0-不开启;region_ratio;shareholder_ratio - - // TODO is_new:新品推荐:1-是;0-否 - // TODO is_best:好物优选:1-是;0-否 - // TODO is_like:猜你喜欢:1-是;0-否 - - // TODO is_team:是否开启拼团[0=否, 1=是] - // TODO is_integral:积分抵扣:1-开启;0-不开启 - // TODO is_member:会员价:1-开启;0-不开启 - // TODO give_integral_type:赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分 - // TODO give_integral:赠送积分; - - // TODO poster:商品自定义海报 - - // TODO ========== 待定字段:laoji ========= - // TODO productType 1 - 普通商品 2 - 预售商品;可能和 type 合并不错 - // TODO productUnit 商品单位 - // TODO extJson 扩展信息;例如说,预售商品的信息 - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java deleted file mode 100644 index a62df7dc8..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.brand; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -@Mapper -public interface ProductBrandMapper extends BaseMapperX { - - default PageResult selectPage(ProductBrandPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(ProductBrandDO::getName, reqVO.getName()) - .eqIfPresent(ProductBrandDO::getStatus, reqVO.getStatus()) - .betweenIfPresent(ProductBrandDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(ProductBrandDO::getId)); - } - - - default List selectList(ProductBrandListReqVO reqVO) { - return selectList(new LambdaQueryWrapperX() - .likeIfPresent(ProductBrandDO::getName, reqVO.getName())); - } - - default ProductBrandDO selectByName(String name) { - return selectOne(ProductBrandDO::getName, name); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java deleted file mode 100644 index 8130d5a46..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.category; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -/** - * 商品分类 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface ProductCategoryMapper extends BaseMapperX { - - default List selectList(ProductCategoryListReqVO listReqVO) { - return selectList(new LambdaQueryWrapperX() - .likeIfPresent(ProductCategoryDO::getName, listReqVO.getName()) - .orderByDesc(ProductCategoryDO::getId)); - } - - default Long selectCountByParentId(Long parentId) { - return selectCount(ProductCategoryDO::getParentId, parentId); - } - - default List selectListByStatus(Integer status) { - return selectList(ProductCategoryDO::getStatus, status); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java deleted file mode 100644 index 26f8d5239..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.property; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyListReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -@Mapper -public interface ProductPropertyMapper extends BaseMapperX { - - default PageResult selectPage(ProductPropertyPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(ProductPropertyDO::getName, reqVO.getName()) - .betweenIfPresent(ProductPropertyDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(ProductPropertyDO::getId)); - } - - default ProductPropertyDO selectByName(String name) { - return selectOne(ProductPropertyDO::getName, name); - } - - default List selectList(ProductPropertyListReqVO listReqVO) { - return selectList(new LambdaQueryWrapperX() - .eqIfPresent(ProductPropertyDO::getName, listReqVO.getName())); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java deleted file mode 100644 index 402df51e7..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.property; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -@Mapper -public interface ProductPropertyValueMapper extends BaseMapperX { - - default List selectListByPropertyId(Collection propertyIds) { - return selectList(new LambdaQueryWrapperX() - .inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds)); - } - - default ProductPropertyValueDO selectByName(Long propertyId, String name) { - return selectOne(new LambdaQueryWrapperX() - .eq(ProductPropertyValueDO::getPropertyId, propertyId) - .eq(ProductPropertyValueDO::getName, name)); - } - - default void deleteByPropertyId(Long propertyId) { - delete(new LambdaQueryWrapperX() - .eq(ProductPropertyValueDO::getPropertyId, propertyId)); - } - - default PageResult selectPage(ProductPropertyValuePageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(ProductPropertyValueDO::getPropertyId, reqVO.getPropertyId()) - .likeIfPresent(ProductPropertyValueDO::getName, reqVO.getName()) - .orderByDesc(ProductPropertyValueDO::getId)); - } - - default Integer selectCountByPropertyId(Long propertyId) { - return selectCount(ProductPropertyValueDO::getPropertyId, propertyId).intValue(); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java deleted file mode 100755 index 56bc54499..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java +++ /dev/null @@ -1,75 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.sku; - -import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * 商品 SKU Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface ProductSkuMapper extends BaseMapperX { - - default List selectListBySpuId(Long spuId) { - return selectList(ProductSkuDO::getSpuId, spuId); - } - - default List selectListBySpuIdAndStatus(Long spuId, - Integer status) { - return selectList(new LambdaQueryWrapperX() - .eq(ProductSkuDO::getSpuId, spuId) - .eqIfPresent(ProductSkuDO::getStatus, status)); - } - - default List selectListBySpuId(Collection spuIds) { - return selectList(ProductSkuDO::getSpuId, spuIds); - } - - default void deleteBySpuId(Long spuId) { - delete(new LambdaQueryWrapperX().eq(ProductSkuDO::getSpuId, spuId)); - } - - /** - * 更新 SKU 库存(增加) - * - * @param id 编号 - * @param incrCount 增加库存(正数) - */ - default void updateStockIncr(Long id, Integer incrCount) { - Assert.isTrue(incrCount > 0); - LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() - .setSql(" stock = stock + " + incrCount) - .eq(ProductSkuDO::getId, id); - update(null, lambdaUpdateWrapper); - } - - /** - * 更新 SKU 库存(减少) - * - * @param id 编号 - * @param incrCount 减少库存(负数) - * @return 更新条数 - */ - default int updateStockDecr(Long id, Integer incrCount) { - Assert.isTrue(incrCount < 0); - LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() - .setSql(" stock = stock + " + incrCount) // 负数,所以使用 + 号 - .eq(ProductSkuDO::getId, id) - .ge(ProductSkuDO::getStock, -incrCount); // cas 逻辑 - return update(null, updateWrapper); - } - - default List selectListByAlarmStock(){ - return selectList(new QueryWrapper().apply("stock <= warn_stock")); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java deleted file mode 100755 index 57a3125d8..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ /dev/null @@ -1,75 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.spu; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Objects; -import java.util.Set; - -/** - * 商品spu Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface ProductSpuMapper extends BaseMapperX { - - default PageResult selectPage(ProductSpuPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) - .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) - .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) - .leIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMax()) - .geIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMin()) - .leIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMax()) - .geIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMin()) - .orderByDesc(ProductSpuDO::getSort)); - } - - default PageResult selectPage(ProductSpuPageReqVO reqVO, Set alarmStockSpuIds) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) - .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) - .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) - .leIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMax()) - .geIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMin()) - .leIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMax()) - .geIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMin()) - .inIfPresent(ProductSpuDO::getId, alarmStockSpuIds) // 库存告警 - .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) - .orderByDesc(ProductSpuDO::getSort)); - } - - default PageResult selectPage(AppProductSpuPageReqVO pageReqVO, Integer status) { - LambdaQueryWrapperX query = new LambdaQueryWrapperX() - .eqIfPresent(ProductSpuDO::getCategoryId, pageReqVO.getCategoryId()) - .eqIfPresent(ProductSpuDO::getStatus, status); - // 排序逻辑 - if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_PRICE)) { - query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getMaxPrice); - } else if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { - query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getSalesCount); - } - return selectPage(pageReqVO, query); - } - - /** - * 更新商品 SPU 库存 - * - * @param id 商品 SPU 编号 - * @param incrCount 增加的库存数量 - */ - default void updateStock(Long id, Integer incrCount) { - LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() - .setSql(" total_stock = total_stock +" + incrCount) // 负数,所以使用 + 号 - .eq(ProductSpuDO::getId, id); - update(null, updateWrapper); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java deleted file mode 100644 index 01967857e..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * trade 模块,主要实现交易相关功能 - * 例如:订单、退款、购物车等功能。 - * - * 1. Controller URL:以 /product/ 开头,避免和其它 Module 冲突 - * 2. DataObject 表名:以 product_ 开头,方便在数据库中区分 - */ -package cn.iocoder.yudao.module.product; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java deleted file mode 100644 index a90ec8a87..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java +++ /dev/null @@ -1,79 +0,0 @@ -package cn.iocoder.yudao.module.product.service.brand; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*; -import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; - -/** - * 商品品牌 Service 接口 - * - * @author 芋道源码 - */ -public interface ProductBrandService { - - /** - * 创建品牌 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createBrand(@Valid ProductBrandCreateReqVO createReqVO); - - /** - * 更新品牌 - * - * @param updateReqVO 更新信息 - */ - void updateBrand(@Valid ProductBrandUpdateReqVO updateReqVO); - - /** - * 删除品牌 - * - * @param id 编号 - */ - void deleteBrand(Long id); - - /** - * 获得品牌 - * - * @param id 编号 - * @return 品牌 - */ - ProductBrandDO getBrand(Long id); - - /** - * 获得品牌列表 - * - * @param ids 编号 - * @return 品牌列表 - */ - List getBrandList(Collection ids); - - /** - * 获得品牌列表 - * - * @param listReqVO 请求参数 - * @return 品牌列表 - */ - List getBrandList(ProductBrandListReqVO listReqVO); - - /** - * 验证选择的商品分类是否合法 - * - * @param id 分类编号 - */ - void validateProductBrand(Long id); - - /** - * 获得品牌分页 - * - * @param pageReqVO 分页查询 - * @return 品牌分页 - */ - PageResult getBrandPage(ProductBrandPageReqVO pageReqVO); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java deleted file mode 100644 index c7a3e5198..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java +++ /dev/null @@ -1,117 +0,0 @@ -package cn.iocoder.yudao.module.product.service.brand; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; -import cn.iocoder.yudao.module.product.dal.mysql.brand.ProductBrandMapper; -import com.google.common.annotations.VisibleForTesting; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; - -/** - * 品牌 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class ProductBrandServiceImpl implements ProductBrandService { - - @Resource - private ProductBrandMapper brandMapper; - - @Override - public Long createBrand(ProductBrandCreateReqVO createReqVO) { - // 校验 - validateBrandNameUnique(null, createReqVO.getName()); - - // 插入 - ProductBrandDO brand = ProductBrandConvert.INSTANCE.convert(createReqVO); - brandMapper.insert(brand); - // 返回 - return brand.getId(); - } - - @Override - public void updateBrand(ProductBrandUpdateReqVO updateReqVO) { - // 校验存在 - validateBrandExists(updateReqVO.getId()); - validateBrandNameUnique(updateReqVO.getId(), updateReqVO.getName()); - // 更新 - ProductBrandDO updateObj = ProductBrandConvert.INSTANCE.convert(updateReqVO); - brandMapper.updateById(updateObj); - } - - @Override - public void deleteBrand(Long id) { - // 校验存在 - validateBrandExists(id); - // 删除 - brandMapper.deleteById(id); - } - - private void validateBrandExists(Long id) { - if (brandMapper.selectById(id) == null) { - throw exception(BRAND_NOT_EXISTS); - } - } - - @VisibleForTesting - public void validateBrandNameUnique(Long id, String name) { - ProductBrandDO brand = brandMapper.selectByName(name); - if (brand == null) { - return; - } - // 如果 id 为空,说明不用比较是否为相同 id 的字典类型 - if (id == null) { - throw exception(BRAND_NAME_EXISTS); - } - if (!brand.getId().equals(id)) { - throw exception(BRAND_NAME_EXISTS); - } - } - - @Override - public ProductBrandDO getBrand(Long id) { - return brandMapper.selectById(id); - } - - @Override - public List getBrandList(Collection ids) { - return brandMapper.selectBatchIds(ids); - } - - @Override - public List getBrandList(ProductBrandListReqVO listReqVO) { - return brandMapper.selectList(listReqVO); - } - - @Override - public void validateProductBrand(Long id) { - ProductBrandDO brand = brandMapper.selectById(id); - if (brand == null) { - throw exception(BRAND_NOT_EXISTS); - } - if (brand.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { - throw exception(BRAND_DISABLED); - } - } - - @Override - public PageResult getBrandPage(ProductBrandPageReqVO pageReqVO) { - return brandMapper.selectPage(pageReqVO); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java deleted file mode 100644 index 32a4c030d..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java +++ /dev/null @@ -1,78 +0,0 @@ -package cn.iocoder.yudao.module.product.service.category; - -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; - -import javax.validation.Valid; -import java.util.List; - -/** - * 商品分类 Service 接口 - * - * @author 芋道源码 - */ -public interface ProductCategoryService { - - /** - * 创建商品分类 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createCategory(@Valid ProductCategoryCreateReqVO createReqVO); - - /** - * 更新商品分类 - * - * @param updateReqVO 更新信息 - */ - void updateCategory(@Valid ProductCategoryUpdateReqVO updateReqVO); - - /** - * 删除商品分类 - * - * @param id 编号 - */ - void deleteCategory(Long id); - - /** - * 获得商品分类 - * - * @param id 编号 - * @return 商品分类 - */ - ProductCategoryDO getCategory(Long id); - - /** - * 校验商品分类 - * - * @param id 分类编号 - */ - void validateCategory(Long id); - - /** - * 获得商品分类的层级 - * - * @param id 编号 - * @return 商品分类的层级 - */ - Integer getCategoryLevel(Long id); - - /** - * 获得商品分类列表 - * - * @param listReqVO 查询条件 - * @return 商品分类列表 - */ - List getEnableCategoryList(ProductCategoryListReqVO listReqVO); - - /** - * 获得开启状态的商品分类列表 - * - * @return 商品分类列表 - */ - List getEnableCategoryList(); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java deleted file mode 100644 index f0d10b8b8..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ /dev/null @@ -1,138 +0,0 @@ -package cn.iocoder.yudao.module.product.service.category; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.List; -import java.util.Objects; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; - -/** - * 商品分类 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class ProductCategoryServiceImpl implements ProductCategoryService { - - @Resource - private ProductCategoryMapper productCategoryMapper; - - @Override - public Long createCategory(ProductCategoryCreateReqVO createReqVO) { - // 校验父分类存在 - validateParentProductCategory(createReqVO.getParentId()); - - // 插入 - ProductCategoryDO category = ProductCategoryConvert.INSTANCE.convert(createReqVO); - productCategoryMapper.insert(category); - // 返回 - return category.getId(); - } - - @Override - public void updateCategory(ProductCategoryUpdateReqVO updateReqVO) { - // 校验分类是否存在 - validateProductCategoryExists(updateReqVO.getId()); - // 校验父分类存在 - validateParentProductCategory(updateReqVO.getParentId()); - - // 更新 - ProductCategoryDO updateObj = ProductCategoryConvert.INSTANCE.convert(updateReqVO); - productCategoryMapper.updateById(updateObj); - } - - @Override - public void deleteCategory(Long id) { - // 校验分类是否存在 - validateProductCategoryExists(id); - // 校验是否还有子分类 - if (productCategoryMapper.selectCountByParentId(id) > 0) { - throw exception(CATEGORY_EXISTS_CHILDREN); - } - // TODO 芋艿 补充只有不存在商品才可以删除 - // 删除 - productCategoryMapper.deleteById(id); - } - - private void validateParentProductCategory(Long id) { - // 如果是根分类,无需验证 - if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { - return; - } - // 父分类不存在 - ProductCategoryDO category = productCategoryMapper.selectById(id); - if (category == null) { - throw exception(CATEGORY_PARENT_NOT_EXISTS); - } - // 父分类不能是二级分类 - if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { - throw exception(CATEGORY_PARENT_NOT_FIRST_LEVEL); - } - } - - private void validateProductCategoryExists(Long id) { - ProductCategoryDO category = productCategoryMapper.selectById(id); - if (category == null) { - throw exception(CATEGORY_NOT_EXISTS); - } - } - - @Override - public ProductCategoryDO getCategory(Long id) { - return productCategoryMapper.selectById(id); - } - - @Override - public void validateCategory(Long id) { - ProductCategoryDO category = productCategoryMapper.selectById(id); - if (category == null) { - throw exception(CATEGORY_NOT_EXISTS); - } - if (Objects.equals(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { - throw exception(CATEGORY_DISABLED, category.getName()); - } - } - - @Override - public Integer getCategoryLevel(Long id) { - if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { - return 0; - } - int level = 1; - for (int i = 0; i < 100; i++) { - ProductCategoryDO category = productCategoryMapper.selectById(id); - // 如果没有父节点,break 结束 - if (category == null - || Objects.equals(category.getParentId(), ProductCategoryDO.PARENT_ID_NULL)) { - break; - } - // 继续递归父节点 - level++; - id = category.getParentId(); - } - return level; - } - - @Override - public List getEnableCategoryList(ProductCategoryListReqVO listReqVO) { - return productCategoryMapper.selectList(listReqVO); - } - - @Override - public List getEnableCategoryList() { - return productCategoryMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java deleted file mode 100644 index 564bc82a9..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java +++ /dev/null @@ -1,72 +0,0 @@ -package cn.iocoder.yudao.module.product.service.property; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; - -/** - * 商品属性项 Service 接口 - * - * @author 芋道源码 - */ -public interface ProductPropertyService { - - /** - * 创建属性项 - * 注意,如果已经存在该属性项,直接返回它的编号即可 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createProperty(@Valid ProductPropertyCreateReqVO createReqVO); - - /** - * 更新属性项 - * - * @param updateReqVO 更新信息 - */ - void updateProperty(@Valid ProductPropertyUpdateReqVO updateReqVO); - - /** - * 删除属性项 - * - * @param id 编号 - */ - void deleteProperty(Long id); - - /** - * 获得属性项列表 - * @param listReqVO 集合查询 - * @return 属性项集合 - */ - List getPropertyList(ProductPropertyListReqVO listReqVO); - - /** - * 获取属性名称分页 - * - * @param pageReqVO 分页条件 - * @return 属性项分页 - */ - PageResult getPropertyPage(ProductPropertyPageReqVO pageReqVO); - - /** - * 获得指定编号的属性项 - * - * @param id 编号 - * @return 属性项 - */ - ProductPropertyDO getProperty(Long id); - - /** - * 根据属性项的编号的集合,获得对应的属性项数组 - * - * @param ids 属性项的编号的集合 - * @return 属性项数组 - */ - List getPropertyList(Collection ids); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java deleted file mode 100644 index 328c343d6..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java +++ /dev/null @@ -1,113 +0,0 @@ -package cn.iocoder.yudao.module.product.service.property; - -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyListReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyMapper; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; - -/** - * 商品属性项 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class ProductPropertyServiceImpl implements ProductPropertyService { - - @Resource - private ProductPropertyMapper productPropertyMapper; - - @Resource - @Lazy // 延迟加载,解决循环依赖问题 - private ProductPropertyValueService productPropertyValueService; - - @Override - @Transactional(rollbackFor = Exception.class) - public Long createProperty(ProductPropertyCreateReqVO createReqVO) { - // 如果已经添加过该属性项,直接返回 - ProductPropertyDO dbProperty = productPropertyMapper.selectByName(createReqVO.getName()); - if (dbProperty != null) { - return dbProperty.getId(); - } - - // 插入 - ProductPropertyDO property = ProductPropertyConvert.INSTANCE.convert(createReqVO); - productPropertyMapper.insert(property); - // 返回 - return property.getId(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateProperty(ProductPropertyUpdateReqVO updateReqVO) { - validatePropertyExists(updateReqVO.getId()); - // 校验名字重复 - ProductPropertyDO productPropertyDO = productPropertyMapper.selectByName(updateReqVO.getName()); - if (productPropertyDO != null && - ObjUtil.notEqual(productPropertyDO.getId(), updateReqVO.getId())) { - throw exception(PROPERTY_EXISTS); - } - - // 更新 - ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO); - productPropertyMapper.updateById(updateObj); - } - - @Override - public void deleteProperty(Long id) { - // 校验存在 - validatePropertyExists(id); - // 校验其下是否有规格值 - if (productPropertyValueService.getPropertyValueCountByPropertyId(id) > 0) { - throw exception(PROPERTY_DELETE_FAIL_VALUE_EXISTS); - } - - // 删除 - productPropertyMapper.deleteById(id); - // 同步删除属性值 - productPropertyValueService.deletePropertyValueByPropertyId(id); - } - - private void validatePropertyExists(Long id) { - if (productPropertyMapper.selectById(id) == null) { - throw exception(PROPERTY_NOT_EXISTS); - } - } - - @Override - public List getPropertyList(ProductPropertyListReqVO listReqVO) { - return productPropertyMapper.selectList(listReqVO); - } - - @Override - public PageResult getPropertyPage(ProductPropertyPageReqVO pageReqVO) { - return productPropertyMapper.selectPage(pageReqVO); - } - - @Override - public ProductPropertyDO getProperty(Long id) { - return productPropertyMapper.selectById(id); - } - - @Override - public List getPropertyList(Collection ids) { - return productPropertyMapper.selectBatchIds(ids); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java deleted file mode 100644 index 553e2578d..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java +++ /dev/null @@ -1,90 +0,0 @@ -package cn.iocoder.yudao.module.product.service.property; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; - -import java.util.Collection; -import java.util.List; - -/** - * 商品属性值 Service 接口 - * - * @author LuoWenFeng - */ -public interface ProductPropertyValueService { - - /** - * 创建属性值 - * 注意,如果已经存在该属性值,直接返回它的编号即可 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO); - - /** - * 更新属性值 - * - * @param updateReqVO 更新信息 - */ - void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO); - - /** - * 删除属性值 - * - * @param id 编号 - */ - void deletePropertyValue(Long id); - - /** - * 获得属性值 - * - * @param id 编号 - * @return 属性值 - */ - ProductPropertyValueDO getPropertyValue(Long id); - - /** - * 根据属性项编号数组,获得属性值列表 - * - * @param propertyIds 属性项目编号数组 - * @return 属性值列表 - */ - List getPropertyValueListByPropertyId(Collection propertyIds); - - /** - * 根据编号数组,获得属性值列表 - * - * @param ids 编号数组 - * @return 属性值明细列表 - */ - List getPropertyValueDetailList(Collection ids); - - /** - * 根据属性项编号,活的属性值数量 - * - * @param propertyId 属性项编号数 - * @return 属性值数量 - */ - Integer getPropertyValueCountByPropertyId(Long propertyId); - - /** - * 获取属性值的分页 - * - * @param pageReqVO 查询条件 - * @return 属性值的分页 - */ - PageResult getPropertyValuePage(ProductPropertyValuePageReqVO pageReqVO); - - /** - * 删除指定属性项编号下的属性值们 - * - * @param propertyId 属性项的编号 - */ - void deletePropertyValueByPropertyId(Long propertyId); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java deleted file mode 100644 index e5bc6874b..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -package cn.iocoder.yudao.module.product.service.property; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyValueMapper; -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_EXISTS; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_NOT_EXISTS; - -/** - * 商品属性值 Service 实现类 - * - * @author LuoWenFeng - */ -@Service -@Validated -public class ProductPropertyValueServiceImpl implements ProductPropertyValueService { - - @Resource - private ProductPropertyValueMapper productPropertyValueMapper; - - @Resource - @Lazy // 延迟加载,避免循环依赖 - private ProductPropertyService productPropertyService; - - @Override - public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) { - // 如果已经添加过该属性值,直接返回 - ProductPropertyValueDO dbValue = productPropertyValueMapper.selectByName( - createReqVO.getPropertyId(), createReqVO.getName()); - if (dbValue != null) { - return dbValue.getId(); - } - - // 新增 - ProductPropertyValueDO value = ProductPropertyValueConvert.INSTANCE.convert(createReqVO); - productPropertyValueMapper.insert(value); - return value.getId(); - } - - @Override - public void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO) { - validatePropertyValueExists(updateReqVO.getId()); - // 校验名字唯一 - ProductPropertyValueDO productPropertyValueDO = productPropertyValueMapper.selectByName - (updateReqVO.getPropertyId(), updateReqVO.getName()); - if (productPropertyValueDO != null && !productPropertyValueDO.getId().equals(updateReqVO.getId())) { - throw exception(PROPERTY_VALUE_EXISTS); - } - - // 更新 - ProductPropertyValueDO updateObj = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO); - productPropertyValueMapper.updateById(updateObj); - } - - @Override - public void deletePropertyValue(Long id) { - validatePropertyValueExists(id); - productPropertyValueMapper.deleteById(id); - } - - private void validatePropertyValueExists(Long id) { - if (productPropertyValueMapper.selectById(id) == null) { - throw exception(PROPERTY_VALUE_NOT_EXISTS); - } - } - - @Override - public ProductPropertyValueDO getPropertyValue(Long id) { - return productPropertyValueMapper.selectById(id); - } - - @Override - public List getPropertyValueListByPropertyId(Collection propertyIds) { - return productPropertyValueMapper.selectListByPropertyId(propertyIds); - } - - @Override - public List getPropertyValueDetailList(Collection ids) { - // 获得属性值列表 - if (CollUtil.isEmpty(ids)) { - return Collections.emptyList(); - } - List values = productPropertyValueMapper.selectBatchIds(ids); - if (CollUtil.isEmpty(values)) { - return Collections.emptyList(); - } - // 获得属性项列表 - List keys = productPropertyService.getPropertyList( - convertSet(values, ProductPropertyValueDO::getPropertyId)); - // 组装明细 - return ProductPropertyValueConvert.INSTANCE.convertList(values, keys); - } - - @Override - public Integer getPropertyValueCountByPropertyId(Long propertyId) { - return productPropertyValueMapper.selectCountByPropertyId(propertyId); - } - - @Override - public PageResult getPropertyValuePage(ProductPropertyValuePageReqVO pageReqVO) { - return productPropertyValueMapper.selectPage(pageReqVO); - } - - @Override - public void deletePropertyValueByPropertyId(Long propertyId) { - productPropertyValueMapper.deleteByPropertyId(propertyId); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/bo/ProductPropertyValueDetailRespBO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/bo/ProductPropertyValueDetailRespBO.java deleted file mode 100644 index 6776731f9..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/bo/ProductPropertyValueDetailRespBO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.product.service.property.bo; - -import lombok.Data; - -/** - * 商品属性项的明细 Response BO - * - * @author 芋道源码 - */ -@Data -public class ProductPropertyValueDetailRespBO { - - /** - * 属性的编号 - */ - private Long propertyId; - - /** - * 属性的名称 - */ - private String propertyName; - - /** - * 属性值的编号 - */ - private Long valueId; - - /** - * 属性值的名称 - */ - private String valueName; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java deleted file mode 100755 index 621e12d9f..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ /dev/null @@ -1,122 +0,0 @@ -package cn.iocoder.yudao.module.product.service.sku; - -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import org.springframework.lang.Nullable; - -import java.util.Collection; -import java.util.List; - -/** - * 商品 SKU Service 接口 - * - * @author 芋道源码 - */ -public interface ProductSkuService { - - /** - * 删除商品 SKU - * - * @param id 编号 - */ - void deleteSku(Long id); - - /** - * 获得商品 SKU 信息 - * - * @param id 编号 - * @return 商品 SKU 信息 - */ - ProductSkuDO getSku(Long id); - - /** - * 获得商品 SKU 列表 - * - * @return 商品sku列表 - */ - List getSkuList(); - - /** - * 获得商品 SKU 列表 - * - * @param ids 编号 - * @return 商品sku列表 - */ - List getSkuList(Collection ids); - - /** - * 对 sku 的组合的属性等进行合法性校验 - * - * @param list sku组合的集合 - */ - void validateSkuList(List list, Integer specType); - - /** - * 批量创建 SKU - * - * @param spuId 商品 SPU 编号 - * @param spuName 商品 SPU 名称 - * @param list SKU 对象集合 - */ - void createSkuList(Long spuId, String spuName, List list); - - /** - * 根据 SPU 编号,批量更新它的 SKU 信息 - * - * @param spuId SPU 编码 - * @param spuName 商品 SPU 名称 - * @param skus SKU 的集合 - */ - void updateSkuList(Long spuId, String spuName, List skus); - - /** - * 更新 SKU 库存(增量) - * - * 如果更新的库存不足,会抛出异常 - * - * @param updateStockReqDTO 更行请求 - */ - void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO); - - /** - * 获得商品 SKU 集合 - * - * @param spuId spu 编号 - * @return 商品sku 集合 - */ - List getSkuListBySpuId(Long spuId); - - /** - * 基于 SPU 编号和状态,获得商品 SKU 集合 - * - * @param spuId SPU 编号 - * @param status 状态 - * @return 商品 SKU 集合 - */ - List getSkuListBySpuIdAndStatus(Long spuId, - @Nullable Integer status); - - /** - * 获得 spu 对应的 SKU 集合 - * - * @param spuIds spu 编码集合 - * @return 商品 sku 集合 - */ - List getSkuListBySpuId(List spuIds); - - /** - * 通过 spuId 删除 sku 信息 - * - * @param spuId spu 编码 - */ - void deleteSkuBySpuId(Long spuId); - - /** - * 获得库存预警的 SKU 数组 - * - * @return SKU 数组 - */ - List getSkuListByAlarmStock(); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java deleted file mode 100755 index 1ab2523cc..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ /dev/null @@ -1,214 +0,0 @@ -package cn.iocoder.yudao.module.product.service.sku; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper; -import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.*; -import java.util.stream.Collectors; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; - -/** - * 商品 SKU Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class ProductSkuServiceImpl implements ProductSkuService { - - @Resource - private ProductSkuMapper productSkuMapper; - - @Resource - @Lazy // 循环依赖,避免报错 - private ProductSpuService productSpuService; - @Resource - private ProductPropertyService productPropertyService; - @Resource - private ProductPropertyValueService productPropertyValueService; - - @Override - public void deleteSku(Long id) { - // 校验存在 - validateSkuExists(id); - // 删除 - productSkuMapper.deleteById(id); - } - - private void validateSkuExists(Long id) { - if (productSkuMapper.selectById(id) == null) { - throw exception(SKU_NOT_EXISTS); - } - } - - @Override - public ProductSkuDO getSku(Long id) { - return productSkuMapper.selectById(id); - } - - @Override - public List getSkuList() { - return productSkuMapper.selectList(); - } - - @Override - public List getSkuList(Collection ids) { - return productSkuMapper.selectBatchIds(ids); - } - - @Override - public void validateSkuList(List skus, Integer specType) { - // 非多规格,不需要校验 - if (ObjectUtil.notEqual(specType, ProductSpuSpecTypeEnum.DISABLE.getType())) { - return; - } - - // 1、校验属性项存在 - Set propertyIds = skus.stream().filter(p -> p.getProperties() != null) - .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 - .map(ProductSkuBaseVO.Property::getPropertyId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 - .collect(Collectors.toSet()); - List propertyList = productPropertyService.getPropertyList(propertyIds); - if (propertyList.size() != propertyIds.size()) { - throw exception(PROPERTY_NOT_EXISTS); - } - - // 2. 校验,一个 SKU 下,没有重复的属性。校验方式是,遍历每个 SKU ,看看是否有重复的属性 propertyId - Map propertyValueMap = convertMap(productPropertyValueService.getPropertyValueListByPropertyId(propertyIds), ProductPropertyValueDO::getId); - skus.forEach(sku -> { - Set skuPropertyIds = convertSet(sku.getProperties(), propertyItem -> propertyValueMap.get(propertyItem.getValueId()).getPropertyId()); - if (skuPropertyIds.size() != sku.getProperties().size()) { - throw exception(SKU_PROPERTIES_DUPLICATED); - } - }); - - // 3. 再校验,每个 Sku 的属性值的数量,是一致的。 - int attrValueIdsSize = skus.get(0).getProperties().size(); - for (int i = 1; i < skus.size(); i++) { - if (attrValueIdsSize != skus.get(i).getProperties().size()) { - throw exception(ErrorCodeConstants.SPU_ATTR_NUMBERS_MUST_BE_EQUALS); - } - } - - // 4. 最后校验,每个 Sku 之间不是重复的 - Set> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的. - for (ProductSkuCreateOrUpdateReqVO sku : skus) { - if (!skuAttrValues.add(convertSet(sku.getProperties(), ProductSkuBaseVO.Property::getValueId))) { // 添加失败,说明重复 - throw exception(ErrorCodeConstants.SPU_SKU_NOT_DUPLICATE); - } - } - } - - @Override - public void createSkuList(Long spuId, String spuName, List skuCreateReqList) { - productSkuMapper.insertBatch(ProductSkuConvert.INSTANCE.convertList06(skuCreateReqList, spuId, spuName)); - } - - @Override - public List getSkuListBySpuId(Long spuId) { - return productSkuMapper.selectListBySpuId(spuId); - } - - @Override - public List getSkuListBySpuIdAndStatus(Long spuId, Integer status) { - return productSkuMapper.selectListBySpuIdAndStatus(spuId, status); - } - - @Override - public List getSkuListBySpuId(List spuIds) { - return productSkuMapper.selectListBySpuId(spuIds); - } - - @Override - public void deleteSkuBySpuId(Long spuId) { - productSkuMapper.deleteBySpuId(spuId); - } - - @Override - public List getSkuListByAlarmStock() { - return productSkuMapper.selectListByAlarmStock(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateSkuList(Long spuId, String spuName, List skus) { - // 构建属性与 SKU 的映射关系; - Map existsSkuMap = convertMap(productSkuMapper.selectListBySpuId(spuId), - ProductSkuConvert.INSTANCE::buildPropertyKey, ProductSkuDO::getId); - - // 拆分三个集合,新插入的、需要更新的、需要删除的 - List insertSkus = new ArrayList<>(); - List updateSkus = new ArrayList<>(); - List allUpdateSkus = ProductSkuConvert.INSTANCE.convertList06(skus, null, spuName); - allUpdateSkus.forEach(sku -> { - String propertiesKey = ProductSkuConvert.INSTANCE.buildPropertyKey(sku); - // 1、找得到的,进行更新 - Long existsSkuId = existsSkuMap.remove(propertiesKey); - if (existsSkuId != null) { - sku.setId(existsSkuId); - updateSkus.add(sku); - return; - } - // 2、找不到,进行插入 - sku.setSpuId(spuId); - insertSkus.add(sku); - }); - - // 执行最终的批量操作 - if (CollUtil.isNotEmpty(insertSkus)) { - productSkuMapper.insertBatch(insertSkus); - } - if (CollUtil.isNotEmpty(updateSkus)) { - updateSkus.forEach(sku -> productSkuMapper.updateById(sku)); - } - if (CollUtil.isNotEmpty(existsSkuMap)) { - productSkuMapper.deleteBatchIds(existsSkuMap.values()); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO) { - // 更新 SKU 库存 - updateStockReqDTO.getItems().forEach(item -> { - if (item.getIncrCount() > 0) { - productSkuMapper.updateStockIncr(item.getId(), item.getIncrCount()); - } else if (item.getIncrCount() < 0) { - int updateStockIncr = productSkuMapper.updateStockDecr(item.getId(), item.getIncrCount()); - if (updateStockIncr == 0) { - throw exception(SKU_STOCK_NOT_ENOUGH); - } - } - }); - - // 更新 SPU 库存 - List skus = productSkuMapper.selectBatchIds( - convertSet(updateStockReqDTO.getItems(), ProductSkuUpdateStockReqDTO.Item::getId)); - Map spuStockIncrCounts = ProductSkuConvert.INSTANCE.convertSpuStockMap( - updateStockReqDTO.getItems(), skus); - productSpuService.updateSpuStock(spuStockIncrCounts); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java deleted file mode 100755 index 0ae7359eb..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ /dev/null @@ -1,101 +0,0 @@ -package cn.iocoder.yudao.module.product.service.spu; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * 商品 SPU Service 接口 - * - * @author 芋道源码 - */ -public interface ProductSpuService { - - /** - * 创建商品 SPU - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createSpu(@Valid ProductSpuCreateReqVO createReqVO); - - /** - * 更新商品 SPU - * - * @param updateReqVO 更新信息 - */ - void updateSpu(@Valid ProductSpuUpdateReqVO updateReqVO); - - /** - * 删除商品 SPU - * - * @param id 编号 - */ - void deleteSpu(Long id); - - /** - * 获得商品 SPU - * - * @param id 编号 - * @return 商品 SPU - */ - ProductSpuDO getSpu(Long id); - - /** - * 获得商品 SPU 列表 - * - * @param ids 编号数组 - * @return 商品 SPU 列表 - */ - List getSpuList(Collection ids); - - /** - * 获得商品 SPU 映射 - * - * @param ids 编号数组 - * @return 商品 SPU 映射 - */ - default Map getSpuMap(Collection ids) { - return convertMap(getSpuList(ids), ProductSpuDO::getId); - } - - /** - * 获得所有商品 SPU 列表 - * - * @return 商品 SPU 列表 - */ - List getSpuList(); - - /** - * 获得商品 SPU 分页 - * - * @param pageReqVO 分页查询 - * @return 商品spu分页 - */ - PageResult getSpuPage(ProductSpuPageReqVO pageReqVO); - - /** - * 获得商品 SPU 分页 - * - * @param pageReqVO 分页查询 - * @param status 状态 - * @return 商品 SPU 分页 - */ - PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO, Integer status); - - /** - * 更新商品 SPU 库存(增量) - * - * @param stockIncrCounts SPU 编号与库存变化(增量)的映射 - */ - void updateSpuStock(Map stockIncrCounts); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java deleted file mode 100755 index 0dd9cdf55..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ /dev/null @@ -1,180 +0,0 @@ -package cn.iocoder.yudao.module.product.service.spu; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; -import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; -import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR; - -/** - * 商品 SPU Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class ProductSpuServiceImpl implements ProductSpuService { - - @Resource - private ProductSpuMapper productSpuMapper; - - @Resource - @Lazy // 循环依赖,避免报错 - private ProductSkuService productSkuService; - @Resource - private ProductBrandService brandService; - @Resource - private ProductCategoryService categoryService; - - @Override - @Transactional(rollbackFor = Exception.class) - public Long createSpu(ProductSpuCreateReqVO createReqVO) { - // 校验分类 - validateCategory(createReqVO.getCategoryId()); - // 校验品牌 - brandService.validateProductBrand(createReqVO.getBrandId()); - // 校验SKU - List skuSaveReqList = createReqVO.getSkus(); - productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); - - // 插入 SPU - ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); - initSpuFromSkus(spu, skuSaveReqList); - productSpuMapper.insert(spu); - // 插入 SKU - productSkuService.createSkuList(spu.getId(), spu.getName(), skuSaveReqList); - // 返回 - return spu.getId(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateSpu(ProductSpuUpdateReqVO updateReqVO) { - // 校验 SPU 是否存在 - validateSpuExists(updateReqVO.getId()); - // 校验分类 - validateCategory(updateReqVO.getCategoryId()); - // 校验品牌 - brandService.validateProductBrand(updateReqVO.getBrandId()); - // 校验SKU - List skuSaveReqList = updateReqVO.getSkus(); - productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType()); - - // 更新 SPU - ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); - initSpuFromSkus(updateObj, skuSaveReqList); - productSpuMapper.updateById(updateObj); - // 批量更新 SKU - productSkuService.updateSkuList(updateObj.getId(), updateObj.getName(), updateReqVO.getSkus()); - } - - /** - * 基于 SKU 的信息,初始化 SPU 的信息 - * 主要是计数相关的字段,例如说市场价、最大最小价、库存等等 - * - * @param spu 商品 SPU - * @param skus 商品 SKU 数组 - */ - private void initSpuFromSkus(ProductSpuDO spu, List skus) { - spu.setMarketPrice(getMaxValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); - spu.setMaxPrice(getMaxValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); - spu.setMinPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); - spu.setTotalStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); - } - - /** - * 校验商品分类是否合法 - * - * @param id 商品分类编号 - */ - private void validateCategory(Long id) { - categoryService.validateCategory(id); - // 校验层级 - if (categoryService.getCategoryLevel(id) != 3) { - throw exception(SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void deleteSpu(Long id) { - // 校验存在 - validateSpuExists(id); - // 删除 SPU - productSpuMapper.deleteById(id); - // 删除关联的 SKU - productSkuService.deleteSkuBySpuId(id); - } - - private void validateSpuExists(Long id) { - if (productSpuMapper.selectById(id) == null) { - throw exception(SPU_NOT_EXISTS); - } - } - - @Override - public ProductSpuDO getSpu(Long id) { - return productSpuMapper.selectById(id); - } - - @Override - public List getSpuList(Collection ids) { - return productSpuMapper.selectBatchIds(ids); - } - - @Override - public List getSpuList() { - return productSpuMapper.selectList(); - } - - @Override - public PageResult getSpuPage(ProductSpuPageReqVO pageReqVO) { - // 库存告警的 SPU 编号的集合 - Set alarmStockSpuIds = null; - if (Boolean.TRUE.equals(pageReqVO.getAlarmStock())) { - alarmStockSpuIds = CollectionUtils.convertSet(productSkuService.getSkuListByAlarmStock(), ProductSkuDO::getSpuId); - if (CollUtil.isEmpty(alarmStockSpuIds)) { - return PageResult.empty(); - } - } - // 分页查询 - return productSpuMapper.selectPage(pageReqVO, alarmStockSpuIds); - } - - @Override - public PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO, Integer status) { - return productSpuMapper.selectPage(pageReqVO, status); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateSpuStock(Map stockIncrCounts) { - stockIncrCounts.forEach((id, incCount) -> productSpuMapper.updateStock(id, incCount)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImplTest.java deleted file mode 100644 index 1b5c68ba4..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImplTest.java +++ /dev/null @@ -1,133 +0,0 @@ -package cn.iocoder.yudao.module.product.service.brand; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; -import cn.iocoder.yudao.module.product.dal.mysql.brand.ProductBrandMapper; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.BRAND_NOT_EXISTS; -import static org.junit.jupiter.api.Assertions.*; - -/** -* {@link ProductBrandServiceImpl} 的单元测试类 -* -* @author 芋道源码 -*/ -@Import(ProductBrandServiceImpl.class) -public class ProductBrandServiceImplTest extends BaseDbUnitTest { - - @Resource - private ProductBrandServiceImpl brandService; - - @Resource - private ProductBrandMapper brandMapper; - - @Test - public void testCreateBrand_success() { - // 准备参数 - ProductBrandCreateReqVO reqVO = randomPojo(ProductBrandCreateReqVO.class); - - // 调用 - Long brandId = brandService.createBrand(reqVO); - // 断言 - assertNotNull(brandId); - // 校验记录的属性是否正确 - ProductBrandDO brand = brandMapper.selectById(brandId); - assertPojoEquals(reqVO, brand); - } - - @Test - public void testUpdateBrand_success() { - // mock 数据 - ProductBrandDO dbBrand = randomPojo(ProductBrandDO.class); - brandMapper.insert(dbBrand);// @Sql: 先插入出一条存在的数据 - // 准备参数 - ProductBrandUpdateReqVO reqVO = randomPojo(ProductBrandUpdateReqVO.class, o -> { - o.setId(dbBrand.getId()); // 设置更新的 ID - }); - - // 调用 - brandService.updateBrand(reqVO); - // 校验是否更新正确 - ProductBrandDO brand = brandMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, brand); - } - - @Test - public void testUpdateBrand_notExists() { - // 准备参数 - ProductBrandUpdateReqVO reqVO = randomPojo(ProductBrandUpdateReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> brandService.updateBrand(reqVO), BRAND_NOT_EXISTS); - } - - @Test - public void testDeleteBrand_success() { - // mock 数据 - ProductBrandDO dbBrand = randomPojo(ProductBrandDO.class); - brandMapper.insert(dbBrand);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbBrand.getId(); - - // 调用 - brandService.deleteBrand(id); - // 校验数据不存在了 - assertNull(brandMapper.selectById(id)); - } - - @Test - public void testDeleteBrand_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> brandService.deleteBrand(id), BRAND_NOT_EXISTS); - } - - @Test - public void testGetBrandPage() { - // mock 数据 - ProductBrandDO dbBrand = randomPojo(ProductBrandDO.class, o -> { // 等会查询到 - o.setName("芋道源码"); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setCreateTime(buildTime(2022, 2, 1)); - }); - brandMapper.insert(dbBrand); - // 测试 name 不匹配 - brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setName("源码"))); - // 测试 status 不匹配 - brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); - // 测试 createTime 不匹配 - brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setCreateTime(buildTime(2022, 3, 1)))); - // 准备参数 - ProductBrandPageReqVO reqVO = new ProductBrandPageReqVO(); - reqVO.setName("芋道"); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2022, 1, 1), buildTime(2022, 2, 25)})); - - // 调用 - PageResult pageResult = brandService.getBrandPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbBrand, pageResult.getList().get(0)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java deleted file mode 100644 index a2963d498..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java +++ /dev/null @@ -1,145 +0,0 @@ -package cn.iocoder.yudao.module.product.service.category; - -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS; -import static org.junit.jupiter.api.Assertions.*; - -/** - * {@link ProductCategoryServiceImpl} 的单元测试类 - * - * @author 芋道源码 - */ -@Import(ProductCategoryServiceImpl.class) -public class ProductCategoryServiceImplTest extends BaseDbUnitTest { - - @Resource - private ProductCategoryServiceImpl productCategoryService; - - @Resource - private ProductCategoryMapper productCategoryMapper; - - @Test - public void testCreateCategory_success() { - // 准备参数 - ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class); - // mock 父类 - ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> o.setId(reqVO.getParentId())); - productCategoryMapper.insert(parentProductCategory); - - // 调用 - Long categoryId = productCategoryService.createCategory(reqVO); - // 断言 - assertNotNull(categoryId); - // 校验记录的属性是否正确 - ProductCategoryDO category = productCategoryMapper.selectById(categoryId); - assertPojoEquals(reqVO, category); - } - - @Test - public void testUpdateCategory_success() { - // mock 数据 - ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class); - productCategoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据 - // 准备参数 - ProductCategoryUpdateReqVO reqVO = randomPojo(ProductCategoryUpdateReqVO.class, o -> { - o.setId(dbCategory.getId()); // 设置更新的 ID - }); - // mock 父类 - ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> o.setId(reqVO.getParentId())); - productCategoryMapper.insert(parentProductCategory); - - // 调用 - productCategoryService.updateCategory(reqVO); - // 校验是否更新正确 - ProductCategoryDO category = productCategoryMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, category); - } - - @Test - public void testUpdateCategory_notExists() { - // 准备参数 - ProductCategoryUpdateReqVO reqVO = randomPojo(ProductCategoryUpdateReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> productCategoryService.updateCategory(reqVO), CATEGORY_NOT_EXISTS); - } - - @Test - public void testDeleteCategory_success() { - // mock 数据 - ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class); - productCategoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbCategory.getId(); - - // 调用 - productCategoryService.deleteCategory(id); - // 校验数据不存在了 - assertNull(productCategoryMapper.selectById(id)); - } - - @Test - public void testDeleteCategory_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> productCategoryService.deleteCategory(id), CATEGORY_NOT_EXISTS); - } - - @Test - public void testGetCategoryLevel() { - // mock 数据 - ProductCategoryDO category1 = randomPojo(ProductCategoryDO.class, - o -> o.setParentId(ProductCategoryDO.PARENT_ID_NULL)); - productCategoryMapper.insert(category1); - ProductCategoryDO category2 = randomPojo(ProductCategoryDO.class, - o -> o.setParentId(category1.getId())); - productCategoryMapper.insert(category2); - ProductCategoryDO category3 = randomPojo(ProductCategoryDO.class, - o -> o.setParentId(category2.getId())); - productCategoryMapper.insert(category3); - - // 调用,并断言 - assertEquals(productCategoryService.getCategoryLevel(category1.getId()), 1); - assertEquals(productCategoryService.getCategoryLevel(category2.getId()), 2); - assertEquals(productCategoryService.getCategoryLevel(category3.getId()), 3); - } - - @Test - public void testGetCategoryList() { - // mock 数据 - ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class, o -> { // 等会查询到 - o.setName("奥特曼"); - }); - productCategoryMapper.insert(dbCategory); - // 测试 name 不匹配 - productCategoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName("奥特块"))); - // 准备参数 - ProductCategoryListReqVO reqVO = new ProductCategoryListReqVO(); - reqVO.setName("特曼"); - - // 调用 - List list = productCategoryService.getEnableCategoryList(reqVO); - // 断言 - assertEquals(1, list.size()); - assertPojoEquals(dbCategory, list.get(0)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java deleted file mode 100644 index ec088cfdd..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java +++ /dev/null @@ -1,171 +0,0 @@ -package cn.iocoder.yudao.module.product.service.sku; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.framework.test.core.util.AssertUtils; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.util.Arrays; -import java.util.List; - -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; -import static java.util.Collections.singletonList; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.verify; - -/** - * {@link ProductSkuServiceImpl} 的单元测试 - * - * @author 芋道源码 - */ -@Import(ProductSkuServiceImpl.class) -public class ProductSkuServiceTest extends BaseDbUnitTest { - - @Resource - private ProductSkuService productSkuService; - - @Resource - private ProductSkuMapper productSkuMapper; - - @MockBean - private ProductSpuService productSpuService; - @MockBean - private ProductPropertyService productPropertyService; - @MockBean - private ProductPropertyValueService productPropertyValueService; - - @Test - public void testUpdateSkuList() { - // mock 数据 - ProductSkuDO sku01 = randomPojo(ProductSkuDO.class, o -> { // 测试更新 - o.setSpuId(1L); - o.setProperties(singletonList(new ProductSkuDO.Property(10L, 20L))); - }); - productSkuMapper.insert(sku01); - ProductSkuDO sku02 = randomPojo(ProductSkuDO.class, o -> { // 测试删除 - o.setSpuId(1L); - o.setProperties(singletonList(new ProductSkuDO.Property(10L, 30L))); - }); - productSkuMapper.insert(sku02); - // 准备参数 - Long spuId = 1L; - String spuName = "测试商品"; - List skus = Arrays.asList( - randomPojo(ProductSkuCreateOrUpdateReqVO.class, o -> { // 测试更新 - o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property(10L, 20L))); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - }), - randomPojo(ProductSkuCreateOrUpdateReqVO.class, o -> { // 测试新增 - o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property(10L, 40L))); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - }) - ); - - // 调用 - productSkuService.updateSkuList(spuId, spuName, skus); - // 断言 - List dbSkus = productSkuMapper.selectListBySpuId(spuId); - assertEquals(dbSkus.size(), 2); - // 断言更新的 - assertEquals(dbSkus.get(0).getId(), sku01.getId()); - assertPojoEquals(dbSkus.get(0), skus.get(0), "properties"); - assertEquals(skus.get(0).getProperties().size(), 1); - assertPojoEquals(dbSkus.get(0).getProperties().get(0), skus.get(0).getProperties().get(0)); - // 断言新增的 - assertNotEquals(dbSkus.get(1).getId(), sku02.getId()); - assertPojoEquals(dbSkus.get(1), skus.get(1), "properties"); - assertEquals(skus.get(1).getProperties().size(), 1); - assertPojoEquals(dbSkus.get(1).getProperties().get(0), skus.get(1).getProperties().get(0)); - } - - @Test - public void testUpdateSkuStock_incrSuccess() { - // 准备参数 - ProductSkuUpdateStockReqDTO updateStockReqDTO = new ProductSkuUpdateStockReqDTO() - .setItems(singletonList(new ProductSkuUpdateStockReqDTO.Item().setId(1L).setIncrCount(10))); - // mock 数据 - productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> o.setId(1L).setSpuId(10L).setStock(20))); - - // 调用 - productSkuService.updateSkuStock(updateStockReqDTO); - // 断言 - ProductSkuDO sku = productSkuMapper.selectById(1L); - assertEquals(sku.getStock(), 30); - verify(productSpuService).updateSpuStock(argThat(spuStockIncrCounts -> { - assertEquals(spuStockIncrCounts.size(), 1); - assertEquals(spuStockIncrCounts.get(10L), 10); - return true; - })); - } - - @Test - public void testUpdateSkuStock_decrSuccess() { - // 准备参数 - ProductSkuUpdateStockReqDTO updateStockReqDTO = new ProductSkuUpdateStockReqDTO() - .setItems(singletonList(new ProductSkuUpdateStockReqDTO.Item().setId(1L).setIncrCount(-10))); - // mock 数据 - productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> o.setId(1L).setSpuId(10L).setStock(20))); - - // 调用 - productSkuService.updateSkuStock(updateStockReqDTO); - // 断言 - ProductSkuDO sku = productSkuMapper.selectById(1L); - assertEquals(sku.getStock(), 10); - verify(productSpuService).updateSpuStock(argThat(spuStockIncrCounts -> { - assertEquals(spuStockIncrCounts.size(), 1); - assertEquals(spuStockIncrCounts.get(10L), -10); - return true; - })); - } - - @Test - public void testUpdateSkuStock_decrFail() { - // 准备参数 - ProductSkuUpdateStockReqDTO updateStockReqDTO = new ProductSkuUpdateStockReqDTO() - .setItems(singletonList(new ProductSkuUpdateStockReqDTO.Item().setId(1L).setIncrCount(-30))); - // mock 数据 - productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> o.setId(1L).setSpuId(10L).setStock(20))); - - // 调用并断言 - AssertUtils.assertServiceException(() -> productSkuService.updateSkuStock(updateStockReqDTO), - SKU_STOCK_NOT_ENOUGH); - } - - @Test - public void testDeleteSku_success() { - // mock 数据 - ProductSkuDO dbSku = randomPojo(ProductSkuDO.class); - productSkuMapper.insert(dbSku);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbSku.getId(); - - // 调用 - productSkuService.deleteSku(id); - // 校验数据不存在了 - assertNull(productSkuMapper.selectById(id)); - } - - @Test - public void testDeleteSku_notExists() { - // 准备参数 - Long id = 1L; - - // 调用, 并断言异常 - assertServiceException(() -> productSkuService.deleteSku(id), SKU_NOT_EXISTS); - } -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java deleted file mode 100755 index 1e029570c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ /dev/null @@ -1,359 +0,0 @@ -package cn.iocoder.yudao.module.product.service.spu; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.framework.common.exception.ServiceException; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO; -import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; -import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; -import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; -import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.product.service.brand.ProductBrandServiceImpl; -import cn.iocoder.yudao.module.product.service.category.ProductCategoryServiceImpl; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuServiceImpl; -import com.google.common.collect.Lists; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static org.junit.jupiter.api.Assertions.assertEquals; - -// TODO @芋艿:review 下单元测试 - -/** - * {@link ProductSpuServiceImpl} 的单元测试类 - * - * @author 芋道源码 - */ -@Import(ProductSpuServiceImpl.class) -@Disabled // TODO 芋艿:临时去掉 -public class ProductSpuServiceImplTest extends BaseDbUnitTest { - - @Resource - private ProductSpuServiceImpl productSpuService; - - @Resource - private ProductSpuMapper productSpuMapper; - - @MockBean - private ProductSkuServiceImpl productSkuService; - @MockBean - private ProductCategoryServiceImpl categoryService; - @MockBean - private ProductBrandServiceImpl brandService; - @MockBean - private ProductPropertyService productPropertyService; - @MockBean - private ProductPropertyValueService productPropertyValueService; - - public String generateNo() { - return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999); - } - - public Long generateId() { - return RandomUtil.randomLong(100000, 999999); - } - - @Test - public void testCreateSpu_success() { - // 准备参数 - ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class, o -> { - o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()); - o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - }); - - // 校验SKU - List skuCreateReqList = createReqVO.getSkus(); - - Long spu = productSpuService.createSpu(createReqVO); - ProductSpuDO productSpuDO = productSpuMapper.selectById(spu); - - createReqVO.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); -// createReqVO.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); -// createReqVO.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); -// createReqVO.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); - - assertPojoEquals(createReqVO, productSpuDO); - - } - - @Test - public void testUpdateSpu_success() { - // 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); - productSpuMapper.insert(createReqVO); - // 准备参数 - ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { - o.setId(createReqVO.getId()); // 设置更新的 ID - o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()); - o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()); - }); - // 调用 - productSpuService.updateSpu(reqVO); - - List skuCreateReqList = reqVO.getSkus(); - reqVO.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); -// reqVO.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); -// reqVO.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); -// reqVO.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); - - // 校验是否更新正确 - ProductSpuDO spu = productSpuMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, spu); - } - - @Test - public void testValidateSpuExists_exception() { - ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { - o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()); - o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()); - }); - // 调用 - Assertions.assertThrows(ServiceException.class, () -> productSpuService.updateSpu(reqVO)); - } - - @Test - void deleteSpu() { - // 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); - productSpuMapper.insert(createReqVO); - - // 调用 - productSpuService.deleteSpu(createReqVO.getId()); - - Assertions.assertNull(productSpuMapper.selectById(createReqVO.getId())); - } - - @Test - void getSpu() { - // 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); - productSpuMapper.insert(createReqVO); - - ProductSpuDO spu = productSpuService.getSpu(createReqVO.getId()); - assertPojoEquals(createReqVO, spu); - } - - @Test - void getSpuList() { - // 准备参数 - ArrayList createReqVO = Lists.newArrayList(randomPojo(ProductSpuDO.class), randomPojo(ProductSpuDO.class)); - productSpuMapper.insertBatch(createReqVO); - - // 调用 - List spuList = productSpuService.getSpuList(createReqVO.stream().map(ProductSpuDO::getId).collect(Collectors.toList())); - Assertions.assertIterableEquals(createReqVO, spuList); - } - - @Test - void getSpuPage_alarmStock_empty() { - // 调用 - ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - productSpuPageReqVO.setAlarmStock(true); - - PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); - - PageResult result = PageResult.empty(); - Assertions.assertIterableEquals(result.getList(), spuPage.getList()); - assertEquals(spuPage.getTotal(), result.getTotal()); - } - - @Test - void getSpuPage_alarmStock() { - // mock 数据 - Long brandId = generateId(); - Long categoryId = generateId(); - String code = generateNo(); - - // 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o->{ - o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - o.setTotalStock(500); - o.setMinPrice(1); - o.setMaxPrice(50); - o.setMarketPrice(25); - o.setSpecType(ProductSpuSpecTypeEnum.RECYCLE.getType()); - o.setBrandId(brandId); - o.setCategoryId(categoryId); - o.setClickCount(100); - o.setCode(code); - o.setDescription("测试商品"); - o.setPicUrls(new ArrayList<>()); - o.setName("测试"); - o.setSalesCount(100); - o.setSellPoint("超级加倍"); - o.setShowStock(true); - o.setVideoUrl(""); - }); - productSpuMapper.insert(createReqVO); - - Set alarmStockSpuIds = SetUtils.asSet(createReqVO.getId()); - - List productSpuDOS = Arrays.asList(randomPojo(ProductSkuDO.class, o -> { - o.setSpuId(createReqVO.getId()); - }), randomPojo(ProductSkuDO.class, o -> { - o.setSpuId(createReqVO.getId()); - })); - - Mockito.when(productSkuService.getSkuListByAlarmStock()).thenReturn(productSpuDOS); - - // 调用 - ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - productSpuPageReqVO.setAlarmStock(true); - PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); - - PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, alarmStockSpuIds)); - Assertions.assertIterableEquals(result.getList(), spuPage.getList()); - assertEquals(spuPage.getTotal(), result.getTotal()); - } - - @Test - void getSpuPage() { - // mock 数据 - Long brandId = generateId(); - Long categoryId = generateId(); - - // 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o->{ - o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - o.setTotalStock(1); - o.setMinPrice(1); - o.setMaxPrice(1); - o.setMarketPrice(1); - o.setSpecType(ProductSpuSpecTypeEnum.RECYCLE.getType()); - o.setBrandId(brandId); - o.setCategoryId(categoryId); - o.setClickCount(1); - o.setCode(generateNo()); - o.setDescription("测试商品"); - o.setPicUrls(new ArrayList<>()); - o.setName("测试"); - o.setSalesCount(1); - o.setSellPoint("卖点"); - o.setShowStock(true); - }); - - // 准备参数 - productSpuMapper.insert(createReqVO); - // 测试 status 不匹配 - productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()))); - productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setStatus(ProductSpuStatusEnum.RECYCLE.getStatus()))); - // 测试 SpecType 不匹配 - productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()))); - // 测试 BrandId 不匹配 - productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setBrandId(generateId()))); - // 测试 CategoryId 不匹配 - productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setCategoryId(generateId()))); - - // 调用 - ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); - productSpuPageReqVO.setAlarmStock(false); - productSpuPageReqVO.setBrandId(brandId); - productSpuPageReqVO.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); - productSpuPageReqVO.setCategoryId(categoryId); - - PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); - - PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, (Set) null)); - assertEquals(result, spuPage); - } - - @Test - void testGetSpuPage() { -// 准备参数 - ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o -> { - o.setCategoryId(2L); - }); - productSpuMapper.insert(createReqVO); - - // 调用 - AppProductSpuPageReqVO appSpuPageReqVO = new AppProductSpuPageReqVO(); - appSpuPageReqVO.setCategoryId(2L); - -// PageResult spuPage = productSpuService.getSpuPage(appSpuPageReqVO); -// -// PageResult result = productSpuMapper.selectPage( -// ProductSpuConvert.INSTANCE.convert(appSpuPageReqVO)); -// -// List collect = result.getList() -// .stream() -// .map(ProductSpuConvert.INSTANCE::convertAppResp) -// .collect(Collectors.toList()); -// -// Assertions.assertIterableEquals(collect, spuPage.getList()); -// assertEquals(spuPage.getTotal(), result.getTotal()); - } - - - /** - * 生成笛卡尔积 - * - * @param data 数据 - * @return 笛卡尔积 - */ - public static List> cartesianProduct(List> data) { - List> res = null; // 结果集(当前为第N个List,则该处存放的就为前N-1个List的笛卡尔积集合) - for (List list : data) { // 遍历数据 - List> temp = new ArrayList<>(); // 临时结果集,存放本次循环后生成的笛卡尔积集合 - if (res == null) { // 结果集为null表示第一次循环既list为第一个List - for (T t : list) { // 便利第一个List - // 利用stream生成List,第一个List的笛卡尔积集合约等于自己本身(需要创建一个List并把对象添加到当中),存放到临时结果集 - temp.add(Stream.of(t).collect(Collectors.toList())); - } - res = temp; // 将临时结果集赋值给结果集 - continue; // 跳过本次循环 - } - // 不为第一个List,计算前面的集合(笛卡尔积)和当前List的笛卡尔积集合 - for (T t : list) { // 便利 - for (List rl : res) { // 便利前面的笛卡尔积集合 - // 利用stream生成List - temp.add(Stream.concat(rl.stream(), Stream.of(t)).collect(Collectors.toList())); - } - } - res = temp; // 将临时结果集赋值给结果集 - } - // 返回结果 - return res; - } - - @Test - public void testUpdateSpuStock() { - // 准备参数 - Map stockIncrCounts = MapUtil.builder(1L, 10).put(2L, -20).build(); - // mock 方法(数据) - productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> o.setId(1L).setTotalStock(20))); - productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> o.setId(2L).setTotalStock(30))); - - // 调用 - productSpuService.updateSpuStock(stockIncrCounts); - // 断言 - assertEquals(productSpuService.getSpu(1L).getTotalStock(), 30); - assertEquals(productSpuService.getSpu(2L).getTotalStock(), 10); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index 31e5ae5c9..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,50 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis-plus: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - -# Resilience4j 配置项 - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml b/yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml deleted file mode 100644 index daf756bff..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql deleted file mode 100644 index aad191337..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql +++ /dev/null @@ -1,3 +0,0 @@ -DELETE FROM "product_sku"; - -DELETE FROM "product_spu"; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql deleted file mode 100644 index 9d26cc733..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ /dev/null @@ -1,69 +0,0 @@ -CREATE TABLE IF NOT EXISTS `product_sku` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `spu_id` bigint NOT NULL COMMENT 'spu编号', - `spu_name` varchar DEFAULT NULL COMMENT '商品 SPU 名字', - `properties` varchar DEFAULT NULL COMMENT '规格值数组-json格式, [{propertId: , valueId: }, {propertId: , valueId: }]', - `price` int NOT NULL DEFAULT '-1' COMMENT '销售价格,单位:分', - `market_price` int DEFAULT NULL COMMENT '市场价', - `cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分', - `pic_url` varchar NOT NULL COMMENT '图片地址', - `stock` int DEFAULT NULL COMMENT '库存', - `warn_stock` int DEFAULT NULL COMMENT '预警库存', - `volume` double DEFAULT NULL COMMENT '商品体积', - `weight` double DEFAULT NULL COMMENT '商品重量', - `bar_code` varchar DEFAULT NULL COMMENT '条形码', - `status` tinyint DEFAULT NULL COMMENT '状态: 0-正常 1-禁用', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar DEFAULT NULL COMMENT '创建人', - `updater` varchar DEFAULT NULL COMMENT '更新人', - `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', - PRIMARY KEY (`id`) -) COMMENT '商品sku'; - - -CREATE TABLE IF NOT EXISTS `product_spu` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', - `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', - `brand_id` bigint DEFAULT NULL COMMENT '商品品牌编号', - `category_id` bigint NOT NULL COMMENT '分类id', - `spec_type` int NOT NULL COMMENT '规格类型:0 单规格 1 多规格', - `code` varchar(128) DEFAULT NULL COMMENT '商品编码', - `name` varchar(128) NOT NULL COMMENT '商品名称', - `sell_point` varchar(128) DEFAULT NULL COMMENT '卖点', - `description` text COMMENT '描述', - `pic_urls` varchar(1024) DEFAULT '' COMMENT '商品轮播图地址数组,以逗号分隔最多上传15张', - `video_url` varchar(128) DEFAULT NULL COMMENT '商品视频', - `market_price` int DEFAULT NULL COMMENT '市场价,单位使用:分', - `min_price` int DEFAULT NULL COMMENT '最小价格,单位使用:分', - `max_price` int DEFAULT NULL COMMENT '最大价格,单位使用:分', - `total_stock` int NOT NULL DEFAULT '0' COMMENT '总库存', - `show_stock` int DEFAULT '0' COMMENT '是否展示库存', - `sales_count` int DEFAULT '0' COMMENT '商品销量', - `virtual_sales_count` int DEFAULT '0' COMMENT '虚拟销量', - `click_count` int DEFAULT '0' COMMENT '商品点击量', - `status` bit(1) DEFAULT NULL COMMENT '上下架状态: 0 上架(开启) 1 下架(禁用)-1 回收', - `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar DEFAULT NULL COMMENT '创建人', - `updater` varchar DEFAULT NULL COMMENT '更新人', - `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', -PRIMARY KEY (`id`) -) COMMENT '商品spu'; - -CREATE TABLE IF NOT EXISTS `product_category` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号', - `parent_id` bigint DEFAULT NULL COMMENT '父分类编号', - `name` varchar(128) NOT NULL COMMENT '分类名称', - `description` varchar(128) NOT NULL COMMENT '分类描述', - `pic_url` varchar DEFAULT NULL COMMENT '分类图片', - `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', - `status` bit(1) DEFAULT NULL COMMENT '状态', - `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `creator` varchar DEFAULT NULL COMMENT '创建人', - `updater` varchar DEFAULT NULL COMMENT '更新人', - `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', - PRIMARY KEY (`id`) -) COMMENT '商品分类'; diff --git a/yudao-module-mall/yudao-module-promotion-api/pom.xml b/yudao-module-mall/yudao-module-promotion-api/pom.xml deleted file mode 100644 index 510b17bee..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/pom.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - cn.iocoder.boot - yudao-module-mall - ${revision} - - 4.0.0 - yudao-module-promotion-api - jar - - ${project.artifactId} - - market 模块 API,暴露给其它模块调用 - - - - - cn.iocoder.boot - yudao-common - - - - - org.springframework.boot - spring-boot-starter-validation - true - - - - diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java deleted file mode 100644 index f99ff815f..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.coupon; - -import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; - -import javax.validation.Valid; - -/** - * 优惠劵 API 接口 - * - * @author 芋道源码 - */ -public interface CouponApi { - - /** - * 使用优惠劵 - * - * @param useReqDTO 使用请求 - */ - void useCoupon(@Valid CouponUseReqDTO useReqDTO); - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponUseReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponUseReqDTO.java deleted file mode 100644 index 9323ab553..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponUseReqDTO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.coupon.dto; - -import lombok.Data; - -import javax.validation.constraints.NotNull; - -/** - * 优惠劵使用 Request DTO - * - * @author 芋道源码 - */ -@Data -public class CouponUseReqDTO { - - /** - * 优惠劵编号 - */ - @NotNull(message = "优惠劵编号不能为空") - private Long id; - - /** - * 用户编号 - */ - @NotNull(message = "用户编号不能为空") - private Long userId; - - /** - * 订单编号 - */ - @NotNull(message = "订单编号不能为空") - private Long orderId; - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java deleted file mode 100644 index 08e1020a6..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 占位 - */ -package cn.iocoder.yudao.module.promotion.api; diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java deleted file mode 100644 index b36c938bc..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.price; - -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; - -/** - * 价格 API 接口 - * - * @author 芋道源码 - */ -public interface PriceApi { - - /** - * 计算商品的价格 - * - * @param calculateReqDTO 价格请求 - * @return 价格相应 - */ - PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/CouponMeetRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/CouponMeetRespDTO.java deleted file mode 100644 index 310959e2c..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/CouponMeetRespDTO.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.price.dto; - -import lombok.Data; - -/** - * 优惠劵的匹配信息 Response DTO - * - * why 放在 price 包下?主要获取的时候,需要涉及到较多的价格计算逻辑,放在 price 可以更好的复用逻辑 - * - * @author 芋道源码 - */ -@Data -public class CouponMeetRespDTO { - - /** - * 优惠劵编号 - */ - private Long id; - - // ========== 非优惠劵的基本信息字段 ========== - /** - * 是否匹配 - */ - private Boolean meet; - /** - * 不匹配的提示,即 {@link #meet} = true 才有值 - * - * 例如说: - * 1. 所结算商品没有符合条件的商品 - * 2. 差 XXX 元可用优惠劵 - * 3. 优惠劵未到使用时间 - */ - private String meetTip; - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java deleted file mode 100644 index 01f0ac220..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java +++ /dev/null @@ -1,56 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.price.dto; - -import lombok.Data; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import java.util.List; - -/** - * 价格计算 Request DTO - * - * @author 芋道源码 - */ -@Data -public class PriceCalculateReqDTO { - - /** - * 用户编号 - * - * 对应 MemberUserDO 的 id 编号 - */ - private Long userId; - - /** - * 优惠劵编号 - */ - private Long couponId; - - /** - * 商品 SKU 数组 - */ - @NotNull(message = "商品数组不能为空") - private List items; - - /** - * 商品 SKU - */ - @Data - public static class Item { - - /** - * SKU 编号 - */ - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - /** - * SKU 数量 - */ - @NotNull(message = "商品 SKU 数量不能为空") - @Min(value = 0L, message = "商品 SKU 数量必须大于等于 0") // 可传递 0 数量,用于购物车未选中的情况 - private Integer count; - - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java deleted file mode 100644 index cda6d99d6..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java +++ /dev/null @@ -1,257 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.price.dto; - -import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; -import lombok.Data; - -import java.util.List; - -/** - * 价格计算 Response DTO - * - * 整体设计,参考 taobao 的技术文档: - * 1. 订单管理 - * 2. 常用订单金额说明 - * - * 举个例子:订单图 - * 输入: - * 1. 订单实付: trade.payment = 198.00;订单邮费:5 元; - * 2. 商品级优惠 圣诞价: 省 29.00 元 和 圣诞价:省 150.00 元; 订单级优惠,圣诞 2:省 5.00 元; - * 分摊: - * 1. 商品 1:原价 108 元,优惠 29 元,子订单实付 79 元,分摊主订单优惠 1.99 元; - * 2. 商品 2:原价 269 元,优惠 150 元,子订单实付 119 元,分摊主订单优惠 3.01 元; - * - * @author 芋道源码 - */ -@Data -public class PriceCalculateRespDTO { - - /** - * 订单 - */ - private Order order; - - /** - * 营销活动数组 - * - * 只对应 {@link Order#items} 商品匹配的活动 - */ - private List promotions; - - /** - * 订单 - */ - @Data - public static class Order { - - /** - * 商品原价(总),单位:分 - * - * 基于 {@link OrderItem#getOriginalPrice()} 求和 - * - * 对应 taobao 的 trade.total_fee 字段 - */ - private Integer originalPrice; - /** - * 订单原价(总),单位:分 - * - * 基于 {@link OrderItem#getPayPrice()} 求和 - * 和 {@link #originalPrice} 的差异:去除商品级优惠 - */ - private Integer orderPrice; - /** - * 订单优惠(总),单位:分 - * - * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。 - * - * 对应 taobao 的 order.discount_fee 字段 - */ - private Integer discountPrice; - /** - * 优惠劵减免金额(总),单位:分 - * - * 对应 taobao 的 trade.coupon_fee 字段 - */ - private Integer couponPrice; - /** - * 积分减免金额(总),单位:分 - * - * 对应 taobao 的 trade.point_fee 字段 - */ - private Integer pointPrice; - /** - * 运费金额,单位:分 - */ - private Integer deliveryPrice; - /** - * 最终购买金额(总),单位:分 - * - * = {@link OrderItem#getPayPrice()} 求和 - * - {@link #couponPrice} - * - {@link #pointPrice} - * + {@link #deliveryPrice} - * - {@link #discountPrice} - */ - private Integer payPrice; - /** - * 商品 SKU 数组 - */ - private List items; - - // ========== 营销基本信息 ========== - /** - * 优惠劵编号 - */ - private Long couponId; - - } - - /** - * 订单商品 SKU - */ - @Data - public static class OrderItem { - - /** - * SPU 编号 - */ - private Long spuId; - /** - * SKU 编号 - */ - private Long skuId; - /** - * 购买数量 - */ - private Integer count; - - /** - * 商品原价(总),单位:分 - * - * = {@link #originalUnitPrice} * {@link #getCount()} - */ - private Integer originalPrice; - /** - * 商品原价(单),单位:分 - * - * 对应 ProductSkuDO 的 price 字段 - * 对应 taobao 的 order.price 字段 - */ - private Integer originalUnitPrice; - /** - * 商品优惠(总),单位:分 - * - * 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元 - * - * 对应 taobao 的 order.discount_fee 字段 - */ - private Integer discountPrice; - /** - * 子订单实付金额,不算主订单分摊金额,单位:分 - * - * = {@link #originalPrice} - * - {@link #discountPrice} - * - * 对应 taobao 的 order.payment 字段 - */ - private Integer payPrice; - - /** - * 子订单分摊金额(总),单位:分 - * 需要分摊 {@link Order#discountPrice}、{@link Order#couponPrice}、{@link Order#pointPrice} - * - * 对应 taobao 的 order.part_mjz_discount 字段 - * 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。 - */ - private Integer orderPartPrice; - /** - * 分摊后子订单实付金额(总),单位:分 - * - * = {@link #payPrice} - * - {@link #orderPartPrice} - * - * 对应 taobao 的 divide_order_fee 字段 - */ - private Integer orderDividePrice; - - } - - /** - * 营销明细 - */ - @Data - public static class Promotion { - - /** - * 营销编号 - * - * 例如说:营销活动的编号、优惠劵的编号 - */ - private Long id; - /** - * 营销名字 - */ - private String name; - /** - * 营销类型 - * - * 枚举 {@link PromotionTypeEnum} - */ - private Integer type; - /** - * 营销级别 - * - * 枚举 {@link PromotionLevelEnum} - */ - private Integer level; - /** - * 计算时的原价(总),单位:分 - */ - private Integer originalPrice; - /** - * 计算时的优惠(总),单位:分 - */ - private Integer discountPrice; - /** - * 匹配的商品 SKU 数组 - */ - private List items; - - // ========== 匹配情况 ========== - - /** - * 是否满足优惠条件 - */ - private Boolean meet; - /** - * 满足条件的提示 - * - * 如果 {@link #meet} = true 满足,则提示“圣诞价:省 150.00 元” - * 如果 {@link #meet} = false 不满足,则提示“购满 85 元,可减 40 元” - */ - private String meetTip; - - } - - /** - * 营销匹配的商品 SKU - */ - @Data - public static class PromotionItem { - - /** - * 商品 SKU 编号 - */ - private Long skuId; - /** - * 计算时的原价(总),单位:分 - */ - private Integer originalPrice; - /** - * 计算时的优惠(总),单位:分 - */ - private Integer discountPrice; - - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java deleted file mode 100644 index 47ce28b4b..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java +++ /dev/null @@ -1,60 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums; - -import cn.iocoder.yudao.framework.common.exception.ErrorCode; - -/** - * promotion 错误码枚举类 - * - * market 系统,使用 1-003-000-000 段 - */ -public interface ErrorCodeConstants { - - // ========== 促销活动相关 1003001000 ============ - ErrorCode DISCOUNT_ACTIVITY_NOT_EXISTS = new ErrorCode(1003001000, "限时折扣活动不存在"); - ErrorCode DISCOUNT_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003006001, "存在商品参加了其它限时折扣活动"); - ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "限时折扣活动已关闭,不能修改"); - ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "限时折扣活动未关闭,不能删除"); - ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "限时折扣活动已关闭,不能重复关闭"); - ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "限时折扣活动已结束,不能关闭"); - - // ========== Banner 相关 1003002000 ============ - ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1003002000, "Banner 不存在"); - - // ========== Coupon 相关 1003003000 ============ - ErrorCode COUPON_NO_MATCH_SPU = new ErrorCode(1003003000, "优惠劵没有可使用的商品!"); - ErrorCode COUPON_NO_MATCH_MIN_PRICE = new ErrorCode(1003003000, "所结算的商品中未满足使用的金额"); - - // ========== 优惠劵模板 1003004000 ========== - ErrorCode COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1003004000, "优惠劵模板不存在"); - ErrorCode COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL = new ErrorCode(1003004001, "发放数量不能小于已领取数量({})"); - - // ========== 优惠劵模板 1003005000 ========== - ErrorCode COUPON_NOT_EXISTS = new ErrorCode(1003005000, "优惠券不存在"); - ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1003005001, "回收优惠劵失败,优惠劵已被使用"); - ErrorCode COUPON_STATUS_NOT_UNUSED = new ErrorCode(1006003003, "优惠劵不处于待使用状态"); - ErrorCode COUPON_VALID_TIME_NOT_NOW = new ErrorCode(1006003004, "优惠券不在使用时间范围内"); - - // ========== 满减送活动 1003006000 ========== - ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1003006000, "满减送活动不存在"); - ErrorCode REWARD_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003006001, "存在商品参加了其它满减送活动"); - ErrorCode REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "满减送活动已关闭,不能修改"); - ErrorCode REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "满减送活动未关闭,不能删除"); - ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "满减送活动已关闭,不能重复关闭"); - ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "满减送活动已结束,不能关闭"); - - // ========== Price 相关 1003007000 ============ - ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1003007000, "支付价格计算异常,原因:价格小于等于 0"); - - // ========== 秒杀活动 1003008000 ========== - ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1003008000, "秒杀活动不存在"); - ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003008002, "存在商品参加了其它秒杀活动"); - ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003008003, "秒杀活动已关闭,不能修改"); - ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1003008004, "秒杀活动未关闭或未结束,不能删除"); - ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003008005, "秒杀活动已关闭,不能重复关闭"); - ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003008006, "秒杀活动已结束,不能关闭"); - - // ========== 秒杀时段 1003009000 ========== - ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1003009000, "秒杀时段不存在"); - ErrorCode SECKILL_TIME_CONFLICTS = new ErrorCode(1003009001, "秒杀时段冲突"); - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java deleted file mode 100644 index db79f871b..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 促销活动的状态枚举 - * - * @author 芋道源码 - */ -@AllArgsConstructor -@Getter -public enum PromotionActivityStatusEnum implements IntArrayValuable { - - WAIT(10, "未开始"), - RUN(20, "进行中"), - END(30, "已结束"), - CLOSE(40, "已关闭"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionActivityStatusEnum::getStatus).toArray(); - - /** - * 状态值 - */ - private final Integer status; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java deleted file mode 100644 index 05e62e399..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 营销的条件类型枚举 - * - * @author 芋道源码 - */ -@AllArgsConstructor -@Getter -public enum PromotionConditionTypeEnum implements IntArrayValuable { - - PRICE(10, "满 N 元"), - COUNT(20, "满 N 件"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionConditionTypeEnum::getType).toArray(); - - /** - * 类型值 - */ - private final Integer type; - /** - * 类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionDiscountTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionDiscountTypeEnum.java deleted file mode 100644 index 7da6b4b08..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionDiscountTypeEnum.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 优惠类型枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PromotionDiscountTypeEnum implements IntArrayValuable { - - PRICE(1, "满减"), // 具体金额 - PERCENT(2, "折扣"), // 百分比 - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionDiscountTypeEnum::getType).toArray(); - - /** - * 优惠类型 - */ - private final Integer type; - /** - * 名字 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java deleted file mode 100644 index ed0564a70..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 营销的级别枚举 - * - * 参考有赞:营销级别 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PromotionLevelEnum implements IntArrayValuable { - - ORDER(1, "订单级"), // 多个商品,进行组合后优惠。例如说:满减送、打包一口价、第二件半价 - SKU(2, "商品级"), // 单个商品,直接优惠。例如说:限时折扣、会员折扣 - COUPON(3, "优惠劵"), // 多个商品,进行组合后优惠。例如说:优惠劵 - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionLevelEnum::getLevel).toArray(); - - /** - * 级别值 - */ - private final Integer level; - /** - * 类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java deleted file mode 100644 index 0a7a4994d..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 营销的商品范围枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PromotionProductScopeEnum implements IntArrayValuable { - - ALL(1, "全部商品参与"), - SPU(2, "指定商品参与"), - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionProductScopeEnum::getScope).toArray(); - - /** - * 范围值 - */ - private final Integer scope; - /** - * 范围名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java deleted file mode 100644 index eea48f7dc..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 营销类型枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PromotionTypeEnum implements IntArrayValuable { - - DISCOUNT_ACTIVITY(1, "限时折扣"), - REWARD_ACTIVITY(2, "满减送"), - - MEMBER(3, "会员折扣"), - COUPON(4, "优惠劵") - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray(); - - /** - * 类型值 - */ - private final Integer type; - /** - * 类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponStatusEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponStatusEnum.java deleted file mode 100644 index 320345d85..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponStatusEnum.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.coupon; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 优惠劵状态枚举 - * - * @author 芋道源码 - */ -@AllArgsConstructor -@Getter -public enum CouponStatusEnum implements IntArrayValuable { - - UNUSED(1, "未使用"), - USED(2, "已使用"), - EXPIRE(3, "已过期"), - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponStatusEnum::getStatus).toArray(); - - /** - * 值 - */ - private final Integer status; - /** - * 名字 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTakeTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTakeTypeEnum.java deleted file mode 100644 index ce7974142..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTakeTypeEnum.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.coupon; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 优惠劵领取方式 - * - * @author 芋道源码 - */ -@AllArgsConstructor -@Getter -public enum CouponTakeTypeEnum implements IntArrayValuable { - - BY_USER(1, "直接领取"), // 用户可在首页、每日领劵直接领取 - BY_ADMIN(2, "指定发放"), // 后台指定会员赠送优惠劵 - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponTakeTypeEnum::getValue).toArray(); - - /** - * 值 - */ - private final Integer value; - /** - * 名字 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTemplateValidityTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTemplateValidityTypeEnum.java deleted file mode 100644 index 391515de3..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTemplateValidityTypeEnum.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.coupon; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 优惠劵模板的有限期类型的枚举 - * - * @author 芋道源码 - */ -@AllArgsConstructor -@Getter -public enum CouponTemplateValidityTypeEnum implements IntArrayValuable { - - DATE(1, "固定日期"), - TERM(2, "领取之后"), - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponTemplateValidityTypeEnum::getType).toArray(); - - /** - * 值 - */ - private final Integer type; - /** - * 名字 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/pom.xml b/yudao-module-mall/yudao-module-promotion-biz/pom.xml deleted file mode 100644 index 266cb1511..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/pom.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - cn.iocoder.boot - yudao-module-mall - ${revision} - - 4.0.0 - jar - yudao-module-promotion-biz - - ${project.artifactId} - - - market模块,主要实现营销相关功能 - 例如:营销活动、banner广告、优惠券、优惠码等功能。 - - - - - cn.iocoder.boot - yudao-module-promotion-api - ${revision} - - - cn.iocoder.boot - yudao-module-product-api - ${revision} - - - cn.iocoder.boot - yudao-module-member-api - ${revision} - - - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-operatelog - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-weixin - - - - - cn.iocoder.boot - yudao-spring-boot-starter-web - - - cn.iocoder.boot - yudao-spring-boot-starter-security - - - - - cn.iocoder.boot - yudao-spring-boot-starter-mybatis - - - - - cn.iocoder.boot - yudao-spring-boot-starter-test - - - - - cn.iocoder.boot - yudao-spring-boot-starter-excel - - - - diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java deleted file mode 100644 index 349eba1ff..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.coupon; - - -import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; -import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; - -/** - * 优惠劵 API 实现类 - * - * @author 芋道源码 - */ -@Service -public class CouponApiImpl implements CouponApi { - - @Resource - private CouponService couponService; - - @Override - public void useCoupon(CouponUseReqDTO useReqDTO) { - couponService.useCoupon(useReqDTO.getId(), useReqDTO.getUserId(), - useReqDTO.getOrderId()); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java deleted file mode 100644 index 4e3ce77a8..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.discount; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java deleted file mode 100644 index 3c415f1c4..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.price; - -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.promotion.service.price.PriceService; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; - -/** - * 价格 API 实现类 - * - * @author 芋道源码 - */ -@Service -public class PriceApiImpl implements PriceApi { - - @Resource - private PriceService priceService; - - @Override - public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { - return priceService.calculatePrice(calculateReqDTO); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java deleted file mode 100644 index f052a3349..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java +++ /dev/null @@ -1,71 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.banner; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.*; -import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; -import cn.iocoder.yudao.module.promotion.service.banner.BannerService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - Banner 管理") -@RestController -@RequestMapping("/market/banner") -@Validated -public class BannerController { - - @Resource - private BannerService bannerService; - - @PostMapping("/create") - @Operation(summary = "创建 Banner") - @PreAuthorize("@ss.hasPermission('market:banner:create')") - public CommonResult createBanner(@Valid @RequestBody BannerCreateReqVO createReqVO) { - return success(bannerService.createBanner(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新 Banner") - @PreAuthorize("@ss.hasPermission('market:banner:update')") - public CommonResult updateBanner(@Valid @RequestBody BannerUpdateReqVO updateReqVO) { - bannerService.updateBanner(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除 Banner") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('market:banner:delete')") - public CommonResult deleteBanner(@RequestParam("id") Long id) { - bannerService.deleteBanner(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得 Banner") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('market:banner:query')") - public CommonResult getBanner(@RequestParam("id") Long id) { - BannerDO banner = bannerService.getBanner(id); - return success(BannerConvert.INSTANCE.convert(banner)); - } - - @GetMapping("/page") - @Operation(summary = "获得 Banner 分页") - @PreAuthorize("@ss.hasPermission('market:banner:query')") - public CommonResult> getBannerPage(@Valid BannerPageReqVO pageVO) { - PageResult pageResult = bannerService.getBannerPage(pageVO); - return success(BannerConvert.INSTANCE.convertPage(pageResult)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java deleted file mode 100644 index 6c72155f4..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotNull; - -/** - * Banner Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - * @author xia - */ -@Data -public class BannerBaseVO { - - @Schema(description = "标题", required = true) - @NotNull(message = "标题不能为空") - private String title; - - @Schema(description = "跳转链接", required = true) - @NotNull(message = "跳转链接不能为空") - private String url; - - @Schema(description = "图片地址", required = true) - @NotNull(message = "图片地址不能为空") - private String picUrl; - - @Schema(description = "排序", required = true) - @NotNull(message = "排序不能为空") - private Integer sort; - - @Schema(description = "状态", required = true) - @NotNull(message = "状态不能为空") - @InEnum(CommonStatusEnum.class) - private Integer status; - - @Schema(description = "备注") - private String memo; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java deleted file mode 100644 index eefdd175a..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -/** - * @author xia - */ -@Schema(description = "管理后台 - Banner 创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class BannerCreateReqVO extends BannerBaseVO { - - - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java deleted file mode 100644 index b97008ccd..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -/** - * @author xia - */ -@Schema(description = "管理后台 - Banner 分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class BannerPageReqVO extends PageParam { - - @Schema(description = "标题") - private String title; - - - @Schema(description = "状态") - @InEnum(CommonStatusEnum.class) - private Integer status; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Schema(description = "创建时间") - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java deleted file mode 100644 index fb0010669..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.ToString; - -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; - -/** - * @author xia - */ -@Schema(description = "管理后台 - Banner Response VO") -@Data -@ToString(callSuper = true) -public class BannerRespVO extends BannerBaseVO { - - @Schema(description = "banner编号", required = true) - @NotNull(message = "banner编号不能为空") - private Long id; - - @Schema(description = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java deleted file mode 100644 index 033b6054d..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.constraints.NotNull; - -/** - * @author xia - */ -@Schema(description = "管理后台 - Banner更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class BannerUpdateReqVO extends BannerBaseVO { - - @Schema(description = "banner 编号", required = true) - @NotNull(message = "banner 编号不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java deleted file mode 100755 index b6b87b567..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java +++ /dev/null @@ -1,75 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; -import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; -import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.Map; -import java.util.Set; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -@Tag(name = "管理后台 - 优惠劵") -@RestController -@RequestMapping("/promotion/coupon") -@Validated -public class CouponController { - - @Resource - private CouponService couponService; - @Resource - private MemberUserApi memberUserApi; - -// @GetMapping("/get") -// @Operation(summary = "获得优惠劵") -// @Parameter(name = "id", description = "编号", required = true, example = "1024") -// @PreAuthorize("@ss.hasPermission('promotion:coupon:query')") -// public CommonResult getCoupon(@RequestParam("id") Long id) { -// CouponDO coupon = couponService.getCoupon(id); -// return success(CouponConvert.INSTANCE.convert(coupon)); -// } - - @DeleteMapping("/delete") - @Operation(summary = "回收优惠劵") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('promotion:coupon:delete')") - public CommonResult deleteCoupon(@RequestParam("id") Long id) { - couponService.deleteCoupon(id); - return success(true); - } - - @GetMapping("/page") - @Operation(summary = "获得优惠劵分页") - @PreAuthorize("@ss.hasPermission('promotion:coupon:query')") - public CommonResult> getCouponPage(@Valid CouponPageReqVO pageVO) { - PageResult pageResult = couponService.getCouponPage(pageVO); - PageResult pageResulVO = CouponConvert.INSTANCE.convertPage(pageResult); - if (CollUtil.isEmpty(pageResulVO.getList())) { - return success(pageResulVO); - } - // 读取用户信息,进行拼接 - Set userIds = convertSet(pageResult.getList(), CouponDO::getUserId); - Map userMap = memberUserApi.getUserMap(userIds); - pageResulVO.getList().forEach(itemRespVO -> MapUtils.findAndThen(userMap, itemRespVO.getUserId(), - userRespDTO -> itemRespVO.setNickname(userRespDTO.getNickname()))); - return success(pageResulVO); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java deleted file mode 100755 index df5b16986..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java +++ /dev/null @@ -1,79 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.*; -import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; -import cn.iocoder.yudao.module.promotion.service.coupon.CouponTemplateService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - 优惠劵模板") -@RestController -@RequestMapping("/promotion/coupon-template") -@Validated -public class CouponTemplateController { - - @Resource - private CouponTemplateService couponTemplateService; - - @PostMapping("/create") - @Operation(summary = "创建优惠劵模板") - @PreAuthorize("@ss.hasPermission('promotion:coupon-template:create')") - public CommonResult createCouponTemplate(@Valid @RequestBody CouponTemplateCreateReqVO createReqVO) { - return success(couponTemplateService.createCouponTemplate(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新优惠劵模板") - @PreAuthorize("@ss.hasPermission('promotion:coupon-template:update')") - public CommonResult updateCouponTemplate(@Valid @RequestBody CouponTemplateUpdateReqVO updateReqVO) { - couponTemplateService.updateCouponTemplate(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @Operation(summary = "更新优惠劵模板状态") - @PreAuthorize("@ss.hasPermission('promotion:coupon-template:update')") - public CommonResult updateCouponTemplateStatus(@Valid @RequestBody CouponTemplateUpdateStatusReqVO reqVO) { - couponTemplateService.updateCouponTemplateStatus(reqVO.getId(), reqVO.getStatus()); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除优惠劵模板") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('promotion:coupon-template:delete')") - public CommonResult deleteCouponTemplate(@RequestParam("id") Long id) { - couponTemplateService.deleteCouponTemplate(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得优惠劵模板") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('promotion:coupon-template:query')") - public CommonResult getCouponTemplate(@RequestParam("id") Long id) { - CouponTemplateDO couponTemplate = couponTemplateService.getCouponTemplate(id); - return success(CouponTemplateConvert.INSTANCE.convert(couponTemplate)); - } - - @GetMapping("/page") - @Operation(summary = "获得优惠劵模板分页") - @PreAuthorize("@ss.hasPermission('promotion:coupon-template:query')") - public CommonResult> getCouponTemplatePage(@Valid CouponTemplatePageReqVO pageVO) { - PageResult pageResult = couponTemplateService.getCouponTemplatePage(pageVO); - return success(CouponTemplateConvert.INSTANCE.convertPage(pageResult)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java deleted file mode 100755 index 43611a903..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java +++ /dev/null @@ -1,103 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; -import com.fasterxml.jackson.annotation.JsonFormat; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; - -/** -* 优惠劵 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class CouponBaseVO { - - // ========== 基本信息 BEGIN ========== - @Schema(description = "优惠劵模板编号", required = true, example = "1024") - @NotNull(message = "优惠劵模板编号不能为空") - private Integer templateId; - - @Schema(description = "优惠劵名", required = true, example = "春节送送送") - @NotNull(message = "优惠劵名不能为空") - private String name; - - @Schema(description = "优惠码状态,参见 CouponStatusEnum 枚举", required = true, example = "1") - private Integer status; - - // ========== 基本信息 END ========== - - // ========== 领取情况 BEGIN ========== - @Schema(description = "用户编号", required = true, example = "1") - @NotNull(message = "用户编号不能为空") - private Long userId; - - @Schema(description = "领取方式,参见 CouponTakeTypeEnum 枚举类", required = true, example = "1") - @NotNull(message = "领取方式不能为空") - private Integer takeType; - // ========== 领取情况 END ========== - - // ========== 使用规则 BEGIN ========== - @Schema(description = "是否设置满多少金额可用,单位:分;0 - 不限制", required = true, example = "100") - @NotNull(message = "是否设置满多少金额可用不能为空") - private Integer usePrice; - - @Schema(description = "固定日期 - 生效开始时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) - private LocalDateTime validStartTime; - - @Schema(description = "固定日期 - 生效结束时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) - private LocalDateTime validEndTime; - - @Schema(description = "商品范围,参见 PromotionProductScopeEnum 枚举类", required = true, example = "1") - @NotNull(message = "商品范围不能为空") - @InEnum(PromotionProductScopeEnum.class) - private Integer productScope; - - @Schema(description = "商品 SPU 编号的数组", example = "1,3") - private List productSpuIds; - // ========== 使用规则 END ========== - - // ========== 使用效果 BEGIN ========== - @Schema(description = "优惠类型,参见 PromotionDiscountTypeEnum 枚举", required = true, example = "1") - @NotNull(message = "优惠类型不能为空") - @InEnum(PromotionDiscountTypeEnum.class) - private Integer discountType; - - @Schema(description = "折扣百分比,例如说,80% 为 80", example = "80") - private Integer discountPercent; - - @Schema(description = "优惠金额,单位:分", example = "10") - @Min(value = 0, message = "优惠金额需要大于等于 0") - private Integer discountPrice; - - @Schema(description = "折扣上限,单位:分,仅在 discountType 为 PERCENT 使用", example = "100") - private Integer discountLimitPrice; - // ========== 使用效果 END ========== - - // ========== 使用情况 BEGIN ========== - - @Schema(description = "使用订单号", example = "4096") - private Long useOrderId; - - @Schema(description = "使用时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) - private LocalDateTime useTime; - - // ========== 使用情况 END ========== - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java deleted file mode 100755 index 118736ef6..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - 优惠劵分页的每一项 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CouponPageItemRespVO extends CouponRespVO { - - @Schema(description = "用户昵称", example = "老芋艿") - private String nickname; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java deleted file mode 100755 index e74f6327d..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - 优惠劵分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CouponPageReqVO extends PageParam { - - @Schema(description = "优惠劵模板编号", example = "2048") - private Long templateId; - - @Schema(description = "优惠码状态,参见 CouponStatusEnum 枚举", example = "1") - private Integer status; - - @Schema(description = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; - - @Schema(description = "用户昵称,模糊匹配", example = "芋艿") - private String nickname; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java deleted file mode 100755 index 68f0bc44e..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 优惠劵 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CouponRespVO extends CouponBaseVO { - - @Schema(description = "优惠劵编号", required = true, example = "1024") - private Long id; - - @Schema(description = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java deleted file mode 100755 index 0100c91c6..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java +++ /dev/null @@ -1,154 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import javax.validation.constraints.AssertTrue; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Objects; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; - -/** -* 优惠劵模板 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class CouponTemplateBaseVO { - - @Schema(description = "优惠劵名", required = true, example = "春节送送送") - @NotNull(message = "优惠劵名不能为空") - private String name; - - @Schema(description = "发行总量,-1 - 则表示不限制发放数量", required = true, example = "1024") - @NotNull(message = "发行总量不能为空") - private Integer totalCount; - - @Schema(description = "每人限领个数,-1 - 则表示不限制", required = true, example = "66") - @NotNull(message = "每人限领个数不能为空") - private Integer takeLimitCount; - - @Schema(description = "领取方式,参见 CouponTakeTypeEnum 枚举类", required = true, example = "1") - @NotNull(message = "领取方式不能为空") - private Integer takeType; - - @Schema(description = "是否设置满多少金额可用,单位:分;0 - 不限制", required = true, example = "100") - @NotNull(message = "是否设置满多少金额可用不能为空") - private Integer usePrice; - - @Schema(description = "商品范围,参见 PromotionProductScopeEnum 枚举类", required = true, example = "1") - @NotNull(message = "商品范围不能为空") - @InEnum(PromotionProductScopeEnum.class) - private Integer productScope; - - @Schema(description = "商品 SPU 编号的数组", example = "1,3") - private List productSpuIds; - - @Schema(description = "生效日期类型", required = true, example = "1") - @NotNull(message = "生效日期类型不能为空") - @InEnum(CouponTemplateValidityTypeEnum.class) - private Integer validityType; - - @Schema(description = "固定日期 - 生效开始时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) - private LocalDateTime validStartTime; - - @Schema(description = "固定日期 - 生效结束时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) - private LocalDateTime validEndTime; - - @Schema(description = "领取日期 - 开始天数") - @Min(value = 0L, message = "开始天数必须大于 0") - private Integer fixedStartTerm; - - @Schema(description = "领取日期 - 结束天数") - @Min(value = 1L, message = "开始天数必须大于 1") - private Integer fixedEndTerm; - - @Schema(description = "优惠类型,参见 PromotionDiscountTypeEnum 枚举", required = true, example = "1") - @NotNull(message = "优惠类型不能为空") - @InEnum(PromotionDiscountTypeEnum.class) - private Integer discountType; - - @Schema(description = "折扣百分比,例如说,80% 为 80", example = "80") - private Integer discountPercent; - - @Schema(description = "优惠金额,单位:分", example = "10") - @Min(value = 0, message = "优惠金额需要大于等于 0") - private Integer discountPrice; - - @Schema(description = "折扣上限,单位:分,仅在 discountType 为 PERCENT 使用", example = "100") - private Integer discountLimitPrice; - - @AssertTrue(message = "商品 SPU 编号的数组不能为空") - @JsonIgnore - public boolean isProductSpuIdsValid() { - return Objects.equals(productScope, PromotionProductScopeEnum.ALL.getScope()) // 全部范围时,可以为空 - || CollUtil.isNotEmpty(productSpuIds); - } - - @AssertTrue(message = "生效开始时间不能为空") - @JsonIgnore - public boolean isValidStartTimeValid() { - return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.DATE.getType()) - || validStartTime != null; - } - - @AssertTrue(message = "生效结束时间不能为空") - @JsonIgnore - public boolean isValidEndTimeValid() { - return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.DATE.getType()) - || validEndTime != null; - } - - @AssertTrue(message = "开始天数不能为空") - @JsonIgnore - public boolean isFixedStartTermValid() { - return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.TERM.getType()) - || fixedStartTerm != null; - } - - @AssertTrue(message = "结束天数不能为空") - @JsonIgnore - public boolean isFixedEndTermValid() { - return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.TERM.getType()) - || fixedEndTerm != null; - } - - @AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99") - @JsonIgnore - public boolean isDiscountPercentValid() { - return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType()) - || (discountPercent != null && discountPercent >= 1 && discountPercent<= 99); - } - - @AssertTrue(message = "优惠金额不能为空") - @JsonIgnore - public boolean isDiscountPriceValid() { - return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType()) - || discountPrice != null; - } - - @AssertTrue(message = "折扣上限不能为空") - @JsonIgnore - public boolean isDiscountLimitPriceValid() { - return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType()) - || discountLimitPrice != null; - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java deleted file mode 100755 index 7b24dbbdb..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java +++ /dev/null @@ -1,13 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - 优惠劵模板创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CouponTemplateCreateReqVO extends CouponTemplateBaseVO { - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java deleted file mode 100755 index bcbafcd06..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - 优惠劵模板分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CouponTemplatePageReqVO extends PageParam { - - @Schema(description = "优惠劵名", example = "你好") - private String name; - - @Schema(description = "状态,参见 CommonStatusEnum 枚举类", example = "1") - private Integer status; - - @Schema(description = "优惠类型,参见 PromotionDiscountTypeEnum 枚举", example = "1") - private Integer discountType; - - @Schema(description = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java deleted file mode 100755 index b90407b43..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 优惠劵模板 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CouponTemplateRespVO extends CouponTemplateBaseVO { - - @Schema(description = "模板编号", required = true, example = "1024") - private Long id; - - @Schema(description = "状态", required = true, example = "1") - @InEnum(CommonStatusEnum.class) - private Integer status; - - @Schema(description = "领取优惠券的数量", required = true, example = "1024") - private Integer takeCount; - - @Schema(description = "使用优惠券的次数", required = true, example = "2048") - private Integer useCount; - - @Schema(description = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java deleted file mode 100755 index 922e4f057..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.constraints.NotNull; - -@Schema(description = "管理后台 - 优惠劵模板更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CouponTemplateUpdateReqVO extends CouponTemplateBaseVO { - - @Schema(description = "模板编号", required = true, example = "1024") - @NotNull(message = "模板编号不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java deleted file mode 100644 index f12f6b756..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotNull; - -@Schema(description = "管理后台 - 优惠劵模板更新状态 Request VO") -@Data -public class CouponTemplateUpdateStatusReqVO { - - @Schema(description = "优惠劵模板编号", required = true, example = "1024") - @NotNull(message = "优惠劵模板编号不能为空") - private Long id; - - @Schema(description = "状态,见 CommonStatusEnum 枚举", required = true, example = "1") - @NotNull(message = "状态不能为空") - @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java deleted file mode 100755 index 08d4dc10e..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java +++ /dev/null @@ -1,87 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.discount; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*; -import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; -import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - 限时折扣活动") -@RestController -@RequestMapping("/promotion/discount-activity") -@Validated -public class DiscountActivityController { - - @Resource - private DiscountActivityService discountActivityService; - - @PostMapping("/create") - @Operation(summary = "创建限时折扣活动") - @PreAuthorize("@ss.hasPermission('promotion:discount-activity:create')") - public CommonResult createDiscountActivity(@Valid @RequestBody DiscountActivityCreateReqVO createReqVO) { - return success(discountActivityService.createDiscountActivity(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新限时折扣活动") - @PreAuthorize("@ss.hasPermission('promotion:discount-activity:update')") - public CommonResult updateDiscountActivity(@Valid @RequestBody DiscountActivityUpdateReqVO updateReqVO) { - discountActivityService.updateDiscountActivity(updateReqVO); - return success(true); - } - - @PutMapping("/close") - @Operation(summary = "关闭限时折扣活动") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('promotion:discount-activity:close')") - public CommonResult closeRewardActivity(@RequestParam("id") Long id) { - discountActivityService.closeRewardActivity(id); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除限时折扣活动") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('promotion:discount-activity:delete')") - public CommonResult deleteDiscountActivity(@RequestParam("id") Long id) { - discountActivityService.deleteDiscountActivity(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得限时折扣活动") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')") - public CommonResult getDiscountActivity(@RequestParam("id") Long id) { - DiscountActivityDO discountActivity = discountActivityService.getDiscountActivity(id); - if (discountActivity == null) { - return success(null); - } - // 拼接结果 - List discountProducts = discountActivityService.getDiscountProductsByActivityId(id); - return success(DiscountActivityConvert.INSTANCE.convert(discountActivity, discountProducts)); - } - - @GetMapping("/page") - @Operation(summary = "获得限时折扣活动分页") - @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')") - public CommonResult> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) { - PageResult pageResult = discountActivityService.getDiscountActivityPage(pageVO); - return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java deleted file mode 100755 index d30df6c1c..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java +++ /dev/null @@ -1,81 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; - -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import javax.validation.constraints.AssertTrue; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -/** -* 限时折扣活动 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class DiscountActivityBaseVO { - - @Schema(description = "活动标题", required = true, example = "一个标题") - @NotNull(message = "活动标题不能为空") - private String name; - - @Schema(description = "开始时间", required = true) - @NotNull(message = "开始时间不能为空") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime startTime; - - @Schema(description = "结束时间", required = true) - @NotNull(message = "结束时间不能为空") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime endTime; - - @Schema(description = "备注", example = "我是备注") - private String remark; - - @Schema(description = "商品") - @Data - public static class Product { - - @Schema(description = "商品 SPU 编号", required = true, example = "1") - @NotNull(message = "商品 SPU 编号不能为空") - private Long spuId; - - @Schema(description = "商品 SKU 编号", required = true, example = "1") - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - @Schema(description = "优惠类型,参见 PromotionDiscountTypeEnum 枚举", required = true, example = "1") - @NotNull(message = "优惠类型不能为空") - @InEnum(PromotionDiscountTypeEnum.class) - private Integer discountType; - - @Schema(description = "折扣百分比,例如说,80% 为 80", example = "80") - private Integer discountPercent; - - @Schema(description = "优惠金额,单位:分", example = "10") - @Min(value = 0, message = "优惠金额需要大于等于 0") - private Integer discountPrice; - - @AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99") - @JsonIgnore - public boolean isDiscountPercentValid() { - return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType()) - || (discountPercent != null && discountPercent >= 1 && discountPercent<= 99); - } - - @AssertTrue(message = "优惠金额不能为空") - @JsonIgnore - public boolean isDiscountPriceValid() { - return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType()) - || discountPrice != null; - } - - } -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java deleted file mode 100755 index 5b22cbd35..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; -import java.util.List; - -@Schema(description = "管理后台 - 限时折扣活动创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class DiscountActivityCreateReqVO extends DiscountActivityBaseVO { - - /** - * 商品列表 - */ - @NotEmpty(message = "商品列表不能为空") - @Valid - private List products; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java deleted file mode 100755 index caa0a648c..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.List; - -@Schema(description = "管理后台 - 限时折扣活动的详细 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class DiscountActivityDetailRespVO extends DiscountActivityRespVO { - - /** - * 商品列表 - */ - private List products; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java deleted file mode 100755 index 4463555ea..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - 限时折扣活动分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class DiscountActivityPageReqVO extends PageParam { - - @Schema(description = "活动标题", example = "一个标题") - private String name; - - @Schema(description = "活动状态", example = "1") - private Integer status; - - @Schema(description = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java deleted file mode 100755 index b552c56ed..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 限时折扣活动 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class DiscountActivityRespVO extends DiscountActivityBaseVO { - - @Schema(description = "活动编号", required = true, example = "1024") - private Long id; - - @Schema(description = "活动状态", required = true, example = "1") - @NotNull(message = "活动状态不能为空") - private Integer status; - - @Schema(description = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java deleted file mode 100755 index f9bf48c06..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.util.List; - -@Schema(description = "管理后台 - 限时折扣活动更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class DiscountActivityUpdateReqVO extends DiscountActivityBaseVO { - - @Schema(description = "活动编号", required = true, example = "1024") - @NotNull(message = "活动编号不能为空") - private Long id; - - /** - * 商品列表 - */ - @NotEmpty(message = "商品列表不能为空") - @Valid - private List products; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java deleted file mode 100755 index c8c13ccf0..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java +++ /dev/null @@ -1,83 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.reward; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; -import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - 满减送活动") -@RestController -@RequestMapping("/promotion/reward-activity") -@Validated -public class RewardActivityController { - - @Resource - private RewardActivityService rewardActivityService; - - @PostMapping("/create") - @Operation(summary = "创建满减送活动") - @PreAuthorize("@ss.hasPermission('promotion:reward-activity:create')") - public CommonResult createRewardActivity(@Valid @RequestBody RewardActivityCreateReqVO createReqVO) { - return success(rewardActivityService.createRewardActivity(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新满减送活动") - @PreAuthorize("@ss.hasPermission('promotion:reward-activity:update')") - public CommonResult updateRewardActivity(@Valid @RequestBody RewardActivityUpdateReqVO updateReqVO) { - rewardActivityService.updateRewardActivity(updateReqVO); - return success(true); - } - - @PutMapping("/close") - @Operation(summary = "关闭满减送活动") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('promotion:reward-activity:close')") - public CommonResult closeRewardActivity(@RequestParam("id") Long id) { - rewardActivityService.closeRewardActivity(id); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除满减送活动") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('promotion:reward-activity:delete')") - public CommonResult deleteRewardActivity(@RequestParam("id") Long id) { - rewardActivityService.deleteRewardActivity(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得满减送活动") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('promotion:reward-activity:query')") - public CommonResult getRewardActivity(@RequestParam("id") Long id) { - RewardActivityDO rewardActivity = rewardActivityService.getRewardActivity(id); - return success(RewardActivityConvert.INSTANCE.convert(rewardActivity)); - } - - @GetMapping("/page") - @Operation(summary = "获得满减送活动分页") - @PreAuthorize("@ss.hasPermission('promotion:reward-activity:query')") - public CommonResult> getRewardActivityPage(@Valid RewardActivityPageReqVO pageVO) { - PageResult pageResult = rewardActivityService.getRewardActivityPage(pageVO); - return success(RewardActivityConvert.INSTANCE.convertPage(pageResult)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java deleted file mode 100755 index 6896e93c9..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java +++ /dev/null @@ -1,98 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; -import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import javax.validation.Valid; -import javax.validation.constraints.AssertTrue; -import javax.validation.constraints.Future; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -/** -* 满减送活动 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class RewardActivityBaseVO { - - @Schema(description = "活动标题", required = true, example = "满啦满啦") - @NotNull(message = "活动标题不能为空") - private String name; - - @Schema(description = "开始时间", required = true) - @NotNull(message = "开始时间不能为空") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime startTime; - - @Schema(description = "结束时间", required = true) - @NotNull(message = "结束时间不能为空") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @Future(message = "结束时间必须大于当前时间") - private LocalDateTime endTime; - - @Schema(description = "备注", example = "biubiubiu") - private String remark; - - @Schema(description = "条件类型", required = true, example = "1") - @NotNull(message = "条件类型不能为空") - @InEnum(value = PromotionConditionTypeEnum.class, message = "条件类型必须是 {value}") - private Integer conditionType; - - @Schema(description = "商品范围", required = true, example = "1") - @NotNull(message = "商品范围不能为空") - @InEnum(value = PromotionConditionTypeEnum.class, message = "商品范围必须是 {value}") - private Integer productScope; - - @Schema(description = "商品 SPU 编号的数组", example = "1,2,3") - private List productSpuIds; - - /** - * 优惠规则的数组 - */ - @Valid // 校验下子对象 - private List rules; - - @Schema(description = "优惠规则") - @Data - public static class Rule { - - @Schema(description = "优惠门槛,1. 满 N 元,单位:分; 2. 满 N 件", required = true, example = "100") - @Min(value = 1L, message = "优惠门槛必须大于等于 1") - private Integer limit; - - @Schema(description = "优惠价格,单位:分", required = true, example = "100") - @Min(value = 1L, message = "优惠价格必须大于等于 1") - private Integer discountPrice; - - @Schema(description = "是否包邮", required = true, example = "true") - private Boolean freeDelivery; - - @Schema(description = "赠送的积分", required = true, example = "100") - @Min(value = 1L, message = "赠送的积分必须大于等于 1") - private Integer point; - - @Schema(description = "赠送的优惠劵编号的数组", example = "1,2,3") - private List couponIds; - - @Schema(description = "赠送的优惠卷数量的数组", example = "1,2,3") - private List couponCounts; - - @AssertTrue(message = "优惠劵和数量必须一一对应") - @JsonIgnore - public boolean isCouponCountsValid() { - return CollUtil.size(couponCounts) == CollUtil.size(couponCounts); - } - - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java deleted file mode 100755 index a5f35e030..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java +++ /dev/null @@ -1,11 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -@Schema(description = "管理后台 - 满减送活动创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class RewardActivityCreateReqVO extends RewardActivityBaseVO { - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java deleted file mode 100755 index dc99e79fa..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import cn.iocoder.yudao.framework.common.pojo.PageParam; - -@Schema(description = "管理后台 - 满减送活动分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class RewardActivityPageReqVO extends PageParam { - - @Schema(description = "活动标题", example = "满啦满啦") - private String name; - - @Schema(description = "活动状态", example = "1") - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java deleted file mode 100755 index 8ad93cb59..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; - -@Schema(description = "管理后台 - 满减送活动 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class RewardActivityRespVO extends RewardActivityBaseVO { - - @Schema(description = "活动编号", required = true, example = "1024") - private Integer id; - - @Schema(description = "活动状态", required = true, example = "1") - private Integer status; - - @Schema(description = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java deleted file mode 100755 index 5c1106d1e..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java +++ /dev/null @@ -1,16 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import javax.validation.constraints.*; - -@Schema(description = "管理后台 - 满减送活动更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class RewardActivityUpdateReqVO extends RewardActivityBaseVO { - - @Schema(description = "活动编号", required = true, example = "1024") - @NotNull(message = "活动编号不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java deleted file mode 100644 index 5acaf7cf0..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java +++ /dev/null @@ -1,96 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.*; -import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; -import cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity.SeckillActivityService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Api(tags = "管理后台 - 秒杀活动") -@RestController -@RequestMapping("/promotion/seckill-activity") -@Validated -public class SeckillActivityController { - - @Resource - private SeckillActivityService seckillActivityService; - - @PostMapping("/create") - @ApiOperation("创建秒杀活动") - @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:create')") - public CommonResult createSeckillActivity(@Valid @RequestBody SeckillActivityCreateReqVO createReqVO) { - return success(seckillActivityService.createSeckillActivity(createReqVO)); - } - - @PutMapping("/update") - @ApiOperation("更新秒杀活动") - @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:update')") - public CommonResult updateSeckillActivity(@Valid @RequestBody SeckillActivityUpdateReqVO updateReqVO) { - seckillActivityService.updateSeckillActivity(updateReqVO); - return success(true); - } - - @PutMapping("/close") - @ApiOperation("关闭秒杀活动") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:close')") - public CommonResult closeSeckillActivity(@RequestParam("id") Long id) { - seckillActivityService.closeSeckillActivity(id); - return success(true); - } - - @DeleteMapping("/delete") - @ApiOperation("删除秒杀活动") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:delete')") - public CommonResult deleteSeckillActivity(@RequestParam("id") Long id) { - seckillActivityService.deleteSeckillActivity(id); - return success(true); - } - - @GetMapping("/get") - @ApiOperation("获得秒杀活动") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')") - public CommonResult getSeckillActivity(@RequestParam("id") Long id) { - SeckillActivityDO seckillActivity = seckillActivityService.getSeckillActivity(id); - if (seckillActivity == null) { - return success(null); - } - List seckillProducts = seckillActivityService.getSeckillProductListByActivityId(id); - return success(SeckillActivityConvert.INSTANCE.convert(seckillActivity,seckillProducts)); - } - - @GetMapping("/list") - @ApiOperation("获得秒杀活动列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) - @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')") - public CommonResult> getSeckillActivityList(@RequestParam("ids") Collection ids) { - List list = seckillActivityService.getSeckillActivityList(ids); - return success(SeckillActivityConvert.INSTANCE.convertList(list)); - } - - @GetMapping("/page") - @ApiOperation("获得秒杀活动分页") - @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')") - public CommonResult> getSeckillActivityPage(@Valid SeckillActivityPageReqVO pageVO) { - PageResult pageResult = seckillActivityService.getSeckillActivityPage(pageVO); - return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java deleted file mode 100644 index 3cb6d4ca6..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java +++ /dev/null @@ -1,72 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime.SeckillTimeConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; -import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Api(tags = "管理后台 - 秒杀时段") -@RestController -@RequestMapping("/promotion/seckill-time") -@Validated -public class SeckillTimeController { - - @Resource - private SeckillTimeService seckillTimeService; - - @PostMapping("/create") - @ApiOperation("创建秒杀时段") - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:create')") - public CommonResult createSeckillTime(@Valid @RequestBody SeckillTimeCreateReqVO createReqVO) { - return success(seckillTimeService.createSeckillTime(createReqVO)); - } - - @PutMapping("/update") - @ApiOperation("更新秒杀时段") - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:update')") - public CommonResult updateSeckillTime(@Valid @RequestBody SeckillTimeUpdateReqVO updateReqVO) { - seckillTimeService.updateSeckillTime(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @ApiOperation("删除秒杀时段") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:delete')") - public CommonResult deleteSeckillTime(@RequestParam("id") Long id) { - seckillTimeService.deleteSeckillTime(id); - return success(true); - } - - @GetMapping("/get") - @ApiOperation("获得秒杀时段") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')") - public CommonResult getSeckillTime(@RequestParam("id") Long id) { - SeckillTimeDO seckillTime = seckillTimeService.getSeckillTime(id); - return success(SeckillTimeConvert.INSTANCE.convert(seckillTime)); - } - - @GetMapping("/list") - @ApiOperation("获得所有秒杀时段列表") - @PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')") - public CommonResult> getSeckillTimeList() { - List list = seckillTimeService.getSeckillTimeList(); - return success(SeckillTimeConvert.INSTANCE.convertList(list)); - } -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java deleted file mode 100644 index 877e7553a..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java +++ /dev/null @@ -1,66 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; - -import com.fasterxml.jackson.annotation.JsonFormat; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; - -/** - * 秒杀活动 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class SeckillActivityBaseVO { - - @ApiModelProperty(value = "秒杀活动名称", required = true, example = "晚九点限时秒杀") - @NotNull(message = "秒杀活动名称不能为空") - private String name; - - @ApiModelProperty(value = "活动开始时间", required = true) - @NotNull(message = "活动开始时间不能为空") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) - private LocalDateTime startTime; - - @ApiModelProperty(value = "活动结束时间", required = true) - @NotNull(message = "活动结束时间不能为空") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) - private LocalDateTime endTime; - - - @ApiModel("商品") - @Data - public static class Product { - - @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") - @NotNull(message = "商品 SPU 编号不能为空") - private Long spuId; - - @ApiModelProperty(value = "商品 SKU 编号", required = true, example = "1") - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - @ApiModelProperty(value = "秒杀金额", required = true, example = "12.00") - @NotNull(message = "秒杀金额不能为空") - private Integer seckillPrice; - - @ApiModelProperty(value = "秒杀库存", example = "80") - @Min(value = 0, message = "秒杀库存需要大于等于 0") - private Integer stock; - - @ApiModelProperty(value = "每人限购", example = "10", notes = "如果为0则不限购") - @Min(value = 0, message = "每人限购需要大于等于 0") - private Integer limitBuyCount; - - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java deleted file mode 100644 index 58dbd0dd9..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.util.List; - -@ApiModel("管理后台 - 秒杀活动创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillActivityCreateReqVO extends SeckillActivityBaseVO { - - @ApiModelProperty(value = "备注", example = "限时秒杀活动") - private String remark; - - @ApiModelProperty(value = "排序", required = true, example = "1") - @NotNull(message = "排序不能为空") - private Integer sort; - - @ApiModelProperty(value = "秒杀时段id", required = true, example = "1,3") - @NotEmpty(message = "参与场次不能为空") - private List timeIds; - - /** - * 商品列表 - */ - @NotEmpty(message = "商品列表不能为空") - @Valid - private List products; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityDetailRespVO.java deleted file mode 100644 index a8a079abf..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityDetailRespVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; - -import io.swagger.annotations.ApiModel; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.List; - -@ApiModel("管理后台 - 秒杀活动的详细 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillActivityDetailRespVO extends SeckillActivityRespVO { - - /** - * 商品列表 - */ - private List products; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityPageReqVO.java deleted file mode 100644 index 34808d523..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityPageReqVO.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import com.fasterxml.jackson.annotation.JsonFormat; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; - -@ApiModel("管理后台 - 秒杀活动分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillActivityPageReqVO extends PageParam { - - @ApiModelProperty(value = "秒杀活动名称", example = "晚九点限时秒杀") - private String name; - - @ApiModelProperty(value = "活动状态", example = "进行中") - private Integer status; - - @ApiModelProperty(value = "秒杀时段id", example = "1") - private Long timeId; - - @ApiModelProperty(value = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java deleted file mode 100644 index 50055f8b0..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; -import java.util.List; - -@ApiModel("管理后台 - 秒杀活动 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillActivityRespVO extends SeckillActivityBaseVO { - - @ApiModelProperty(value = "秒杀活动id", required = true, example = "1") - private Long id; - - @ApiModelProperty(value = "付款订单数", required = true, example = "1") - private Integer orderCount; - - @ApiModelProperty(value = "付款人数", required = true, example = "1") - private Integer userCount; - - @ApiModelProperty(value = "创建时间", required = true) - private LocalDateTime createTime; - - @ApiModelProperty(value = "秒杀时段id", required = true, example = "1,3") - private List timeIds; - - @ApiModelProperty(value = "排序", required = true, example = "1") - private Integer sort; - - @ApiModelProperty(value = "备注", example = "限时秒杀活动") - private String remark; - - @ApiModelProperty(value = "活动状态", example = "进行中") - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java deleted file mode 100644 index e55739a4b..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.util.List; - -@ApiModel("管理后台 - 秒杀活动更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillActivityUpdateReqVO extends SeckillActivityBaseVO { - - @ApiModelProperty(value = "秒杀活动编号", required = true, example = "224") - @NotNull(message = "秒杀活动编号不能为空") - private Long id; - - @ApiModelProperty(value = "备注", example = "限时秒杀活动") - private String remark; - - @ApiModelProperty(value = "排序", required = true, example = "1") - @NotNull(message = "排序不能为空") - private Integer sort; - - @ApiModelProperty(value = "秒杀时段id", required = true, example = "1,3") - @NotEmpty(message = "秒杀时段id不能为空") - private List timeIds; - - /** - * 商品列表 - */ - @NotEmpty(message = "商品列表不能为空") - @Valid - private List products; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java deleted file mode 100644 index 4fc8c8f3c..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotNull; -import java.time.LocalTime; - -/** - * 秒杀时段 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class SeckillTimeBaseVO { - - @ApiModelProperty(value = "秒杀时段名称", required = true, example = "上午场") - @NotNull(message = "秒杀时段名称不能为空") - private String name; - - @ApiModelProperty(value = "开始时间点", required = true, example = "16:30:40") - @NotNull(message = "开始时间点不能为空") - private LocalTime startTime; - - @ApiModelProperty(value = "结束时间点", required = true, example = "16:30:40") - @NotNull(message = "结束时间点不能为空") - private LocalTime endTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java deleted file mode 100644 index 197fb8a68..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java +++ /dev/null @@ -1,12 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; - -import lombok.*; -import io.swagger.annotations.*; - -@ApiModel("管理后台 - 秒杀时段创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillTimeCreateReqVO extends SeckillTimeBaseVO { - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java deleted file mode 100644 index b482ca34e..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalTime; - -@ApiModel("管理后台 - 秒杀时段分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillTimePageReqVO extends PageParam { - - @ApiModelProperty(value = "秒杀时段名称", example = "上午场") - private String name; - - @ApiModelProperty(value = "开始时间点", example = "16:30:40") - @DateTimeFormat(pattern = "HH:mm:ss") - private LocalTime startTime; - - @ApiModelProperty(value = "结束时间点", example = "16:30:40") - @DateTimeFormat(pattern = "HH:mm:ss") - private LocalTime endTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java deleted file mode 100644 index 632020191..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; - -@ApiModel("管理后台 - 秒杀时段 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillTimeRespVO extends SeckillTimeBaseVO { - - @ApiModelProperty(value = "编号", required = true, example = "1") - private Long id; - - @ApiModelProperty(value = "秒杀活动数量", required = true, example = "1") - private Integer seckillActivityCount; - - @ApiModelProperty(value = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java deleted file mode 100644 index 72931938d..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.constraints.NotNull; - -@ApiModel("管理后台 - 秒杀时段更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillTimeUpdateReqVO extends SeckillTimeBaseVO { - - @ApiModelProperty(value = "编号", required = true, example = "1") - @NotNull(message = "编号不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java deleted file mode 100644 index 510889f9c..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.app; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "用户 App - 营销") -@RestController -@RequestMapping("/market/test") -@Validated -public class AppMarketTestController { - - @GetMapping("/get") - @Operation(summary = "获取 market 信息") - public CommonResult get() { - return success("true"); - } -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java deleted file mode 100644 index 1a7f148ff..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.app.banner; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO; -import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; -import cn.iocoder.yudao.module.promotion.service.banner.BannerService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Operation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -/** - * @author: XIA - */ -@RestController -@RequestMapping("/market/banner") -@Tag(name = "用户APP- 首页Banner") -@Validated -public class AppBannerController { - - @Resource - private BannerService bannerService; - - // TODO @xia:新建一个 AppBannerRespVO,只返回必要的字段。status 要过滤下。然后 sort 下结果 - @GetMapping("/list") - @Operation(summary = "获得banner列表") - @PreAuthorize("@ss.hasPermission('market:banner:query')") - public CommonResult> getBannerList() { - List list = bannerService.getBannerList(); - return success(BannerConvert.INSTANCE.convertList(list)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java deleted file mode 100644 index 87d2da187..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.promotion.convert.banner; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -/** - * Banner Convert - * - * @author xia - */ -@Mapper -public interface BannerConvert { - - BannerConvert INSTANCE = Mappers.getMapper(BannerConvert.class); - - - List convertList(List list); - - PageResult convertPage(PageResult pageResult); - - BannerRespVO convert(BannerDO banner); - - BannerDO convert(BannerCreateReqVO createReqVO); - - BannerDO convert(BannerUpdateReqVO updateReqVO); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java deleted file mode 100755 index 281318f7d..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.promotion.convert.coupon; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -/** - * 优惠劵 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface CouponConvert { - - CouponConvert INSTANCE = Mappers.getMapper(CouponConvert.class); - - PageResult convertPage(PageResult page); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java deleted file mode 100755 index 22d78f46f..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.promotion.convert.coupon; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -/** - * 优惠劵模板 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface CouponTemplateConvert { - - CouponTemplateConvert INSTANCE = Mappers.getMapper(CouponTemplateConvert.class); - - CouponTemplateDO convert(CouponTemplateCreateReqVO bean); - - CouponTemplateDO convert(CouponTemplateUpdateReqVO bean); - - CouponTemplateRespVO convert(CouponTemplateDO bean); - - PageResult convertPage(PageResult page); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java deleted file mode 100755 index 07d2e03ab..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java +++ /dev/null @@ -1,102 +0,0 @@ -package cn.iocoder.yudao.module.promotion.convert.discount; - -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; -import java.util.Map; - -/** - * 限时折扣活动 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface DiscountActivityConvert { - - DiscountActivityConvert INSTANCE = Mappers.getMapper(DiscountActivityConvert.class); - - DiscountActivityDO convert(DiscountActivityCreateReqVO bean); - - DiscountActivityDO convert(DiscountActivityUpdateReqVO bean); - - DiscountActivityRespVO convert(DiscountActivityDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - DiscountProductDetailBO convert(DiscountProductDO product); - - default List convertList(List products, Map activityMap) { - return CollectionUtils.convertList(products, product -> { - DiscountProductDetailBO detail = convert(product); - MapUtils.findAndThen(activityMap, product.getActivityId(), activity -> { - detail.setActivityName(activity.getName()); - }); - return detail; - }); - } - - DiscountProductDO convert(DiscountActivityBaseVO.Product bean); - - DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List products); - - // =========== 比较是否相等 ========== - /** - * 比较两个限时折扣商品是否相等 - * - * @param productDO 数据库中的商品 - * @param productVO 前端传入的商品 - * @return 是否匹配 - */ - @SuppressWarnings("DuplicatedCode") - default boolean isEquals(DiscountProductDO productDO, DiscountActivityBaseVO.Product productVO) { - if (ObjectUtil.notEqual(productDO.getSpuId(), productVO.getSpuId()) - || ObjectUtil.notEqual(productDO.getSkuId(), productVO.getSkuId()) - || ObjectUtil.notEqual(productDO.getDiscountType(), productVO.getDiscountType())) { - return false; - } - if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PRICE.getType())) { - return ObjectUtil.equal(productDO.getDiscountPrice(), productVO.getDiscountPrice()); - } - if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PERCENT.getType())) { - return ObjectUtil.equal(productDO.getDiscountPercent(), productVO.getDiscountPercent()); - } - return true; - } - - /** - * 比较两个限时折扣商品是否相等 - * 注意,比较时忽略 id 编号 - * - * @param productDO 商品 1 - * @param productVO 商品 2 - * @return 是否匹配 - */ - @SuppressWarnings("DuplicatedCode") - default boolean isEquals(DiscountProductDO productDO, DiscountProductDO productVO) { - if (ObjectUtil.notEqual(productDO.getSpuId(), productVO.getSpuId()) - || ObjectUtil.notEqual(productDO.getSkuId(), productVO.getSkuId()) - || ObjectUtil.notEqual(productDO.getDiscountType(), productVO.getDiscountType())) { - return false; - } - if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PRICE.getType())) { - return ObjectUtil.equal(productDO.getDiscountPrice(), productVO.getDiscountPrice()); - } - if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PERCENT.getType())) { - return ObjectUtil.equal(productDO.getDiscountPercent(), productVO.getDiscountPercent()); - } - return true; - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java deleted file mode 100644 index 8e4b24666..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.yudao.module.promotion.convert.price; - -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Mapper -public interface PriceConvert { - - PriceConvert INSTANCE = Mappers.getMapper(PriceConvert.class); - - default PriceCalculateRespDTO convert(PriceCalculateReqDTO calculateReqDTO, List skuList) { - // 创建 PriceCalculateRespDTO 对象 - PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); - // 创建它的 Order 属性 - PriceCalculateRespDTO.Order order = new PriceCalculateRespDTO.Order().setOriginalPrice(0).setDiscountPrice(0) - .setCouponPrice(0).setPointPrice(0).setDeliveryPrice(0).setPayPrice(0) - .setItems(new ArrayList<>()).setCouponId(calculateReqDTO.getCouponId()); - priceCalculate.setOrder(order).setPromotions(new ArrayList<>()); - // 创建它的 OrderItem 属性 - Map skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), - PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); - skuList.forEach(sku -> { - Integer count = skuIdCountMap.get(sku.getId()); - PriceCalculateRespDTO.OrderItem orderItem = new PriceCalculateRespDTO.OrderItem() - .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setCount(count) - .setOriginalUnitPrice(sku.getPrice()).setOriginalPrice(sku.getPrice() * count) - .setDiscountPrice(0).setOrderPartPrice(0); - orderItem.setPayPrice(orderItem.getOriginalPrice()).setOrderDividePrice(orderItem.getOriginalPrice()); - priceCalculate.getOrder().getItems().add(orderItem); - // 补充价格信息到 Order 中 - order.setOriginalPrice(order.getOriginalPrice() + orderItem.getOriginalPrice()) - .setOrderPrice(order.getOriginalPrice()).setPayPrice(order.getOriginalPrice()); - }); - return priceCalculate; - } - - CouponMeetRespDTO convert(CouponDO coupon); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/reward/RewardActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/reward/RewardActivityConvert.java deleted file mode 100755 index 5343656ed..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/reward/RewardActivityConvert.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.promotion.convert.reward; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -/** - * 满减送活动 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface RewardActivityConvert { - - RewardActivityConvert INSTANCE = Mappers.getMapper(RewardActivityConvert.class); - - RewardActivityDO convert(RewardActivityCreateReqVO bean); - - RewardActivityDO convert(RewardActivityUpdateReqVO bean); - - RewardActivityRespVO convert(RewardActivityDO bean); - - PageResult convertPage(PageResult page); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java deleted file mode 100644 index 1a00fdeb6..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java +++ /dev/null @@ -1,83 +0,0 @@ -package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity; - -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.*; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -/** - * 秒杀活动 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface SeckillActivityConvert { - - SeckillActivityConvert INSTANCE = Mappers.getMapper(SeckillActivityConvert.class); - - SeckillProductDO convert(SeckillActivityBaseVO.Product product); - - - SeckillActivityDO convert(SeckillActivityCreateReqVO bean); - - default String map(Long[] value) { - return value.toString(); - } - - SeckillActivityDO convert(SeckillActivityUpdateReqVO bean); - - SeckillActivityRespVO convert(SeckillActivityDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - @Mappings({@Mapping(target = "products", source = "seckillProducts")}) - SeckillActivityDetailRespVO convert(SeckillActivityDO seckillActivity, List seckillProducts); - - - /** - * 比较两个秒杀商品对象是否相等 - * - * @param productDO 数据库中的商品 - * @param productVO 前端传入的商品 - * @return 是否匹配 - */ - default boolean isEquals(SeckillProductDO productDO, SeckillActivityBaseVO.Product productVO) { - return ObjectUtil.equals(productDO.getSpuId(), productVO.getSpuId()) - && ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId()) - && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice()) - && ObjectUtil.equals(productDO.getStock(), productVO.getStock()) - && ObjectUtil.equals(productDO.getLimitBuyCount(), productVO.getLimitBuyCount()); - } - - /** - * 比较两个秒杀商品对象是否相等 - * - * @param productDO 商品1 - * @param productVO 商品2 - * @return 是否匹配 - */ - default boolean isEquals(SeckillProductDO productDO, SeckillProductDO productVO) { - return ObjectUtil.equals(productDO.getSpuId(), productVO.getSpuId()) - && ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId()) - && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice()) - && ObjectUtil.equals(productDO.getStock(), productVO.getStock()) - && ObjectUtil.equals(productDO.getLimitBuyCount(), productVO.getLimitBuyCount()); - - } - - default List convertList(List products, SeckillActivityDO seckillActivity) { - return CollectionUtils.convertList(products, product -> convert(product) - .setActivityId(seckillActivity.getId()).setTimeIds(seckillActivity.getTimeIds())); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java deleted file mode 100644 index 4cea7a91c..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime; - -import java.util.*; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; - -/** - * 秒杀时段 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface SeckillTimeConvert { - - SeckillTimeConvert INSTANCE = Mappers.getMapper(SeckillTimeConvert.class); - - SeckillTimeDO convert(SeckillTimeCreateReqVO bean); - - SeckillTimeDO convert(SeckillTimeUpdateReqVO bean); - - SeckillTimeRespVO convert(SeckillTimeDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java deleted file mode 100644 index 585462b95..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java +++ /dev/null @@ -1,53 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.banner; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * banner DO - * - * @author xia - */ -@TableName("market_banner") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class BannerDO extends BaseDO { - - /** - * 编号 - */ - private Long id; - /** - * 标题 - */ - private String title; - /** - * 跳转链接 - */ - private String url; - /** - * 图片链接 - */ - private String picUrl; - /** - * 排序 - */ - private Integer sort; - - /** - * 状态 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum} - */ - private Integer status; - /** - * 备注 - */ - private String memo; - - // TODO 芋艿 点击次数。&& 其他数据相关 - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java deleted file mode 100644 index 7971392d4..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java +++ /dev/null @@ -1,139 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * 优惠劵 DO - * - * @author 芋道源码 - */ -@TableName(value = "promotion_coupon", autoResultMap = true) -@KeySequence("promotion_coupon_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -public class CouponDO extends BaseDO { - - // ========== 基本信息 BEGIN ========== - /** - * 优惠劵编号 - */ - private Long id; - /** - * 优惠劵模板编号 - * - * 关联 {@link CouponTemplateDO#getId()} - */ - private Integer templateId; - /** - * 优惠劵名 - * - * 冗余 {@link CouponTemplateDO#getName()} - */ - private String name; - /** - * 优惠码状态 - * - * 枚举 {@link CouponStatusEnum} - */ - private Integer status; - - // ========== 基本信息 END ========== - - // ========== 领取情况 BEGIN ========== - /** - * 用户编号 - * - * 关联 MemberUserDO 的 id 字段 - */ - private Long userId; - /** - * 领取类型 - * - * 枚举 {@link CouponTakeTypeEnum} - */ - private Integer takeType; - // ========== 领取情况 END ========== - - // ========== 使用规则 BEGIN ========== - /** - * 是否设置满多少金额可用,单位:分 - * - * 冗余 {@link CouponTemplateDO#getUsePrice()} - */ - private Integer usePrice; - /** - * 生效开始时间 - */ - private LocalDateTime validStartTime; - /** - * 生效结束时间 - */ - private LocalDateTime validEndTime; - /** - * 商品范围 - * - * 枚举 {@link PromotionProductScopeEnum} - */ - private Integer productScope; - /** - * 商品 SPU 编号的数组 - * - * 冗余 {@link CouponTemplateDO#getProductSpuIds()} - */ - @TableField(typeHandler = LongListTypeHandler.class) - private List productSpuIds; - // ========== 使用规则 END ========== - - // ========== 使用效果 BEGIN ========== - /** - * 折扣类型 - * - * 冗余 {@link CouponTemplateDO#getDiscountType()} - */ - private Integer discountType; - /** - * 折扣百分比 - * - * 冗余 {@link CouponTemplateDO#getDiscountPercent()} - */ - private Integer discountPercent; - /** - * 优惠金额,单位:分 - * - * 冗余 {@link CouponTemplateDO#getDiscountPrice()} - */ - private Integer discountPrice; - /** - * 折扣上限,仅在 {@link #discountType} 等于 {@link PromotionDiscountTypeEnum#PERCENT} 时生效 - * - * 冗余 {@link CouponTemplateDO#getDiscountLimitPrice()} - */ - private Integer discountLimitPrice; - // ========== 使用效果 END ========== - - // ========== 使用情况 BEGIN ========== - /** - * 使用订单号 - */ - private Long useOrderId; - /** - * 使用时间 - */ - private LocalDateTime useTime; - - // ========== 使用情况 END ========== - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java deleted file mode 100644 index 93f9ace35..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java +++ /dev/null @@ -1,162 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * 优惠劵模板 DO - * - * 当用户领取时,会生成 {@link CouponDO} 优惠劵 - * - * @author 芋道源码 - */ -@TableName(value = "promotion_coupon_template", autoResultMap = true) -@KeySequence("promotion_coupon_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -public class CouponTemplateDO extends BaseDO { - - // ========== 基本信息 BEGIN ========== - /** - * 模板编号,自增唯一 - */ - @TableId - private Long id; - /** - * 优惠劵名 - */ - private String name; - /** - * 状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - - // ========== 基本信息 END ========== - - // ========== 领取规则 BEGIN ========== - /** - * 发放数量 - * - * -1 - 则表示不限制发放数量 - */ - private Integer totalCount; - /** - * 每人限领个数 - * - * -1 - 则表示不限制 - */ - private Integer takeLimitCount; - /** - * 领取方式 - * - * 枚举 {@link CouponTakeTypeEnum} - */ - private Integer takeType; - // ========== 领取规则 END ========== - - // ========== 使用规则 BEGIN ========== - /** - * 是否设置满多少金额可用,单位:分 - * - * 0 - 不限制 - * 大于 0 - 多少金额可用 - */ - private Integer usePrice; - /** - * 商品范围 - * - * 枚举 {@link PromotionProductScopeEnum} - */ - private Integer productScope; - /** - * 商品 SPU 编号的数组 - */ - @TableField(typeHandler = LongListTypeHandler.class) - private List productSpuIds; - /** - * 生效日期类型 - * - * 枚举 {@link CouponTemplateValidityTypeEnum} - */ - private Integer validityType; - /** - * 固定日期 - 生效开始时间 - * - * 当 {@link #validityType} 为 {@link CouponTemplateValidityTypeEnum#DATE} - */ - private LocalDateTime validStartTime; - /** - * 固定日期 - 生效结束时间 - * - * 当 {@link #validityType} 为 {@link CouponTemplateValidityTypeEnum#DATE} - */ - private LocalDateTime validEndTime; - /** - * 领取日期 - 开始天数 - * - * 当 {@link #validityType} 为 {@link CouponTemplateValidityTypeEnum#TERM} - */ - private Integer fixedStartTerm; - /** - * 领取日期 - 结束天数 - * - * 当 {@link #validityType} 为 {@link CouponTemplateValidityTypeEnum#TERM} - */ - private Integer fixedEndTerm; - // ========== 使用规则 END ========== - - // ========== 使用效果 BEGIN ========== - /** - * 折扣类型 - * - * 枚举 {@link PromotionDiscountTypeEnum} - */ - private Integer discountType; - /** - * 折扣百分比 - * - * 例如,80% 为 80 - */ - private Integer discountPercent; - /** - * 优惠金额,单位:分 - * - * 当 {@link #discountType} 为 {@link PromotionDiscountTypeEnum#PRICE} 生效 - */ - private Integer discountPrice; - /** - * 折扣上限,仅在 {@link #discountType} 等于 {@link PromotionDiscountTypeEnum#PERCENT} 时生效 - * - * 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。 - */ - private Integer discountLimitPrice; - // ========== 使用效果 END ========== - - // ========== 统计信息 BEGIN ========== - /** - * 领取优惠券的数量 - */ - private Integer takeCount; - /** - * 使用优惠券的次数 - */ - private Integer useCount; - // ========== 统计信息 END ========== - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java deleted file mode 100644 index 91071f309..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java +++ /dev/null @@ -1,55 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.discount; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.time.LocalDateTime; - -/** - * 限时折扣活动 DO - * - * 一个活动下,可以有 {@link DiscountProductDO} 商品; - * 一个商品,在指定时间段内,只能属于一个活动; - * - * @author 芋道源码 - */ -@TableName(value = "promotion_discount_activity", autoResultMap = true) -@KeySequence("promotion_discount_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -public class DiscountActivityDO extends BaseDO { - - /** - * 活动编号,主键自增 - */ - @TableId - private Long id; - /** - * 活动标题 - */ - private String name; - /** - * 状态 - * - * 枚举 {@link PromotionActivityStatusEnum} - */ - private Integer status; - /** - * 开始时间 - */ - private LocalDateTime startTime; - /** - * 结束时间 - */ - private LocalDateTime endTime; - /** - * 备注 - */ - private String remark; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java deleted file mode 100644 index 55c924e4f..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java +++ /dev/null @@ -1,65 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.discount; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * 限时折扣商品 DO - * - * @author 芋道源码 - */ -@TableName(value = "promotion_discount_product", autoResultMap = true) -@KeySequence("promotion_discount_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -public class DiscountProductDO extends BaseDO { - - /** - * 编号,主键自增 - */ - @TableId - private Long id; - /** - * 限时折扣活动的编号 - * - * 关联 {@link DiscountActivityDO#getId()} - */ - private Long activityId; - /** - * 商品 SPU 编号 - * - * 关联 ProductSpuDO 的 id 编号 - */ - private Long spuId; - /** - * 商品 SKU 编号 - * - * 关联 ProductSkuDO 的 id 编号 - */ - private Long skuId; - - /** - * 折扣类型 - * - * 枚举 {@link PromotionDiscountTypeEnum} - */ - private Integer discountType; - /** - * 折扣百分比 - * - * 例如,80% 为 80 - */ - private Integer discountPercent; - /** - * 优惠金额,单位:分 - * - * 当 {@link #discountType} 为 {@link PromotionDiscountTypeEnum#PRICE} 生效 - */ - private Integer discountPrice; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java deleted file mode 100644 index e825881d1..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java +++ /dev/null @@ -1,133 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.reward; - -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.io.Serializable; -import java.time.LocalDateTime; -import java.util.List; - -/** - * 满减送活动 DO - * - * @author 芋道源码 - */ -@TableName(value = "promotion_reward_activity", autoResultMap = true) -@KeySequence("promotion_reward_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -public class RewardActivityDO extends BaseDO { - - /** - * 活动编号,主键自增 - */ - @TableId - private Long id; - /** - * 活动标题 - */ - private String name; - /** - * 状态 - * - * 枚举 {@link PromotionActivityStatusEnum} - */ - private Integer status; - /** - * 开始时间 - */ - private LocalDateTime startTime; - /** - * 结束时间 - */ - private LocalDateTime endTime; - /** - * 备注 - */ - private String remark; - /** - * 条件类型 - * - * 枚举 {@link PromotionConditionTypeEnum} - */ - private Integer conditionType; - /** - * 商品范围 - * - * 枚举 {@link PromotionProductScopeEnum} - */ - private Integer productScope; - /** - * 商品 SPU 编号的数组 - */ - @TableField(typeHandler = LongListTypeHandler.class) - private List productSpuIds; - /** - * 优惠规则的数组 - */ - @TableField(typeHandler = RuleTypeHandler.class) - private List rules; - - /** - * 优惠规则 - */ - @Data - public static class Rule implements Serializable { - - /** - * 优惠门槛 - * - * 1. 满 N 元,单位:分 - * 2. 满 N 件 - */ - private Integer limit; - /** - * 优惠价格,单位:分 - */ - private Integer discountPrice; - /** - * 是否包邮 - */ - private Boolean freeDelivery; - /** - * 赠送的积分 - */ - private Integer point; - /** - * 赠送的优惠劵编号的数组 - */ - private List couponIds; - /** - * 赠送的优惠卷数量的数组 - */ - private List couponCounts; - - } - - // TODO @芋艿:可以找一些新的思路 - public static class RuleTypeHandler extends AbstractJsonTypeHandler> { - - @Override - protected List parse(String json) { - return JsonUtils.parseArray(json, Rule.class); - } - - @Override - protected String toJson(List obj) { - return JsonUtils.toJsonString(obj); - } - - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java deleted file mode 100644 index 1d3b6da27..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java +++ /dev/null @@ -1,78 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * 秒杀活动 DO - * - * @author halfninety - */ -@TableName(value = "promotion_seckill_activity", autoResultMap = true) -@KeySequence("promotion_seckill_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillActivityDO extends BaseDO { - - /** - * 秒杀活动编号 - */ - @TableId - private Long id; - /** - * 秒杀活动名称 - */ - private String name; - /** - * 活动状态 - *

- * 枚举 {@link PromotionActivityStatusEnum 对应的类} - */ - private Integer status; - /** - * 备注 - */ - private String remark; - /** - * 活动开始时间 - */ - private LocalDateTime startTime; - /** - * 活动结束时间 - */ - private LocalDateTime endTime; - /** - * 排序 - */ - private Integer sort; - /** - * 秒杀时段 id - */ - @TableField(typeHandler = LongListTypeHandler.class) - private List timeIds; - /** - * 付款订单数 - */ - private Integer orderCount; - /** - * 付款人数 - */ - private Integer userCount; - /** - * 订单实付金额,单位:分 - */ - private Long totalPrice; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java deleted file mode 100644 index 3783d6dda..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java +++ /dev/null @@ -1,65 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; -import com.baomidou.mybatisplus.annotation.*; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.List; - -/** - * 秒杀参与商品 - * - * @author halfninety - * @TableName promotion_seckill_product - */ -@TableName(value = "promotion_seckill_product", autoResultMap = true) -@KeySequence("promotion_seckill_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillProductDO extends BaseDO { - /** - * 秒杀参与商品编号 - */ - @TableId(type = IdType.AUTO) - private Long id; - - /** - * 秒杀活动id - */ - private Long activityId; - - /** - * 秒杀时段id - */ - @TableField(typeHandler = LongListTypeHandler.class) - private List timeIds; - - /** - * 商品id - */ - private Long spuId; - - /** - * 商品sku_id - */ - private Long skuId; - - /** - * 秒杀金额 - */ - private Integer seckillPrice; - - /** - * 秒杀库存 - */ - private Integer stock; - - /** - * 每人限购 - */ - private Integer limitBuyCount; -} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java deleted file mode 100644 index df338c0e6..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalTime; - -/** - * 秒杀时段 DO - * - * @author 芋道源码 - */ -@TableName("promotion_seckill_time") -@KeySequence("promotion_seckill_time_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SeckillTimeDO extends BaseDO { - - /** - * 编号 - */ - @TableId - private Long id; - /** - * 秒杀时段名称 - */ - private String name; - /** - * 开始时间点 - */ - private LocalTime startTime; - /** - * 结束时间点 - */ - private LocalTime endTime; - /** - * 秒杀活动数量 - */ - private Integer seckillActivityCount; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java deleted file mode 100644 index d98375365..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.banner; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; -import org.apache.ibatis.annotations.Mapper; - -/** - * Banner Mapper - * - * @author xia - */ -@Mapper -public interface BannerMapper extends BaseMapperX { - - default PageResult selectPage(BannerPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(BannerDO::getTitle, reqVO.getTitle()) - .eqIfPresent(BannerDO::getStatus, reqVO.getStatus()) - .betweenIfPresent(BannerDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(BannerDO::getSort)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java deleted file mode 100755 index e5ae5f79d..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java +++ /dev/null @@ -1,52 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.coupon; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * 优惠劵 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface CouponMapper extends BaseMapperX { - - default PageResult selectPage(CouponPageReqVO reqVO, Collection userIds) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(CouponDO::getTemplateId, reqVO.getTemplateId()) - .eqIfPresent(CouponDO::getStatus, reqVO.getStatus()) - .inIfPresent(CouponDO::getUserId, userIds) - .betweenIfPresent(CouponDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(CouponDO::getId)); - } - - default List selectListByUserIdAndStatus(Long userId, Integer status) { - return selectList(new LambdaQueryWrapperX() - .eq(CouponDO::getUserId, userId).eq(CouponDO::getStatus, status)); - } - - default CouponDO selectByIdAndUserId(Long id, Long userId) { - return selectOne(new LambdaQueryWrapperX() - .eq(CouponDO::getId, id).eq(CouponDO::getUserId, userId)); - } - - default int delete(Long id, Collection whereStatuses) { - return update(null, new LambdaUpdateWrapper() - .eq(CouponDO::getId, id).in(CouponDO::getStatus, whereStatuses) - .set(CouponDO::getDeleted, 1)); - } - - default int updateByIdAndStatus(Long id, Integer status, CouponDO updateObj) { - return update(updateObj, new LambdaUpdateWrapper() - .eq(CouponDO::getId, id).eq(CouponDO::getStatus, status)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java deleted file mode 100755 index 7cea814af..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.coupon; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -/** - * 优惠劵模板 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface CouponTemplateMapper extends BaseMapperX { - - default PageResult selectPage(CouponTemplatePageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(CouponTemplateDO::getName, reqVO.getName()) - .eqIfPresent(CouponTemplateDO::getStatus, reqVO.getStatus()) - .eqIfPresent(CouponTemplateDO::getDiscountType, reqVO.getDiscountType()) - .betweenIfPresent(CouponTemplateDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(CouponTemplateDO::getId)); - } - - void updateTakeCount(@Param("id") Long id, @Param("incrCount") Integer incrCount); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountActivityMapper.java deleted file mode 100755 index 534ce627a..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountActivityMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.discount; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; -import java.util.Set; - -/** - * 限时折扣活动 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface DiscountActivityMapper extends BaseMapperX { - - default PageResult selectPage(DiscountActivityPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(DiscountActivityDO::getName, reqVO.getName()) - .eqIfPresent(DiscountActivityDO::getStatus, reqVO.getStatus()) - .betweenIfPresent(DiscountActivityDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(DiscountActivityDO::getId)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java deleted file mode 100755 index 646b60707..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.discount; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * 限时折扣商城 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface DiscountProductMapper extends BaseMapperX { - - default List selectListBySkuId(Collection skuIds) { - return selectList(DiscountProductDO::getSkuId, skuIds); - } - - default List selectListByActivityId(Long activityId) { - return selectList(DiscountProductDO::getActivityId, activityId); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java deleted file mode 100755 index 2ee879823..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.reward; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * 满减送活动 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface RewardActivityMapper extends BaseMapperX { - - default PageResult selectPage(RewardActivityPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(RewardActivityDO::getName, reqVO.getName()) - .eqIfPresent(RewardActivityDO::getStatus, reqVO.getStatus()) - .orderByDesc(RewardActivityDO::getId)); - } - - default List selectListByStatus(Collection statuses) { - return selectList(RewardActivityDO::getStatus, statuses); - } - - default List selectListByProductScopeAndStatus(Integer productScope, Integer status) { - return selectList(new LambdaQueryWrapperX() - .eq(RewardActivityDO::getProductScope, productScope) - .eq(RewardActivityDO::getStatus, status)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java deleted file mode 100644 index c01676c2a..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity; - -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; -import org.apache.ibatis.annotations.Mapper; - -/** - * 秒杀活动 Mapper - * - * @author halfninety - */ -@Mapper -public interface SeckillActivityMapper extends BaseMapperX { - default PageResult selectPage(SeckillActivityPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(SeckillActivityDO::getName, reqVO.getName()) - .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus()) - .betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime()) - .apply(ObjectUtil.isNotNull(reqVO.getTimeId()),"FIND_IN_SET(" + reqVO.getTimeId() + ",time_ids) > 0") - .orderByDesc(SeckillActivityDO::getId)); - } -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java deleted file mode 100644 index a590de1a5..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; -import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * 秒杀活动商品 Mapper - * - * @author halfninety - */ -@Mapper -public interface SeckillProductMapper extends BaseMapperX { - - default List selectListByActivityId(Long id) { - return selectList(SeckillProductDO::getActivityId, id); - } - - default List selectListBySkuIds(Collection skuIds) { - return selectList(SeckillProductDO::getSkuId, skuIds); - } - - default void updateTimeIdsByActivityId(Long id, List timeIds) { - new LambdaUpdateChainWrapper<>(this) - .set(SeckillProductDO::getTimeIds, CollUtil.join(timeIds, ",")) - .eq(SeckillProductDO::getActivityId, id) - .update(); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java deleted file mode 100644 index c34484e8c..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.time.LocalTime; -import java.util.Collection; -import java.util.List; - -/** - * 秒杀时段 Mapper - * - * @author halfninety - */ -@Mapper -public interface SeckillTimeMapper extends BaseMapperX { - - default List selectListByTime(LocalTime time) { - return selectList(SeckillTimeDO::getStartTime, SeckillTimeDO::getEndTime, time); - } - - default List selectListByTime(LocalTime startTime, LocalTime endTime) { - return selectList(new LambdaQueryWrapper() - .ge(SeckillTimeDO::getStartTime, startTime) - .le(SeckillTimeDO::getEndTime, endTime)); - } - - default void updateActivityCount(Collection ids, String type, Integer count) { - new LambdaUpdateChainWrapper<>(this) - .in(SeckillTimeDO::getId, ids) - .setSql("`seckill_activity_count` = `seckill_activity_count` " + type + count) - .update(); - } -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java deleted file mode 100644 index c022c6276..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * promotion 模块,我们放营销业务。 - * 例如说:营销活动、banner、优惠券等等 - * - * 1. Controller URL:以 /promotion/ 开头,避免和其它 Module 冲突 - * 2. DataObject 表名:以 promotion_ 开头,方便在数据库中区分 - */ -package cn.iocoder.yudao.module.promotion; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java deleted file mode 100644 index d541211be..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java +++ /dev/null @@ -1,63 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.banner; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; - -import javax.validation.Valid; -import java.util.List; - -/** - * 首页 Banner Service 接口 - * - * @author xia - */ -public interface BannerService { - - /** - * 创建 Banner - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createBanner(@Valid BannerCreateReqVO createReqVO); - - /** - * 更新 Banner - * - * @param updateReqVO 更新信息 - */ - void updateBanner(@Valid BannerUpdateReqVO updateReqVO); - - /** - * 删除 Banner - * - * @param id 编号 - */ - void deleteBanner(Long id); - - /** - * 获得 Banner - * - * @param id 编号 - * @return Banner - */ - BannerDO getBanner(Long id); - - /** - * 获得所有 Banner列表 - * @return Banner列表 - */ - List getBannerList(); - - /** - * 获得 Banner 分页 - * - * @param pageReqVO 分页查询 - * @return Banner分页 - */ - PageResult getBannerPage(BannerPageReqVO pageReqVO); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java deleted file mode 100644 index 013ae8992..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java +++ /dev/null @@ -1,78 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.banner; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.banner.BannerMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.BANNER_NOT_EXISTS; - -/** - * 首页 banner 实现类 - * - * @author xia - */ -@Service -@Validated -public class BannerServiceImpl implements BannerService { - - @Resource - private BannerMapper bannerMapper; - - @Override - public Long createBanner(BannerCreateReqVO createReqVO) { - // 插入 - BannerDO banner = BannerConvert.INSTANCE.convert(createReqVO); - bannerMapper.insert(banner); - // 返回 - return banner.getId(); - } - - @Override - public void updateBanner(BannerUpdateReqVO updateReqVO) { - // 校验存在 - this.validateBannerExists(updateReqVO.getId()); - // 更新 - BannerDO updateObj = BannerConvert.INSTANCE.convert(updateReqVO); - bannerMapper.updateById(updateObj); - } - - @Override - public void deleteBanner(Long id) { - // 校验存在 - this.validateBannerExists(id); - // 删除 - bannerMapper.deleteById(id); - } - - private void validateBannerExists(Long id) { - if (bannerMapper.selectById(id) == null) { - throw exception(BANNER_NOT_EXISTS); - } - } - - @Override - public BannerDO getBanner(Long id) { - return bannerMapper.selectById(id); - } - - @Override - public List getBannerList() { - return bannerMapper.selectList(); - } - - @Override - public PageResult getBannerPage(BannerPageReqVO pageReqVO) { - return bannerMapper.selectPage(pageReqVO); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java deleted file mode 100644 index 96b5b5d63..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java +++ /dev/null @@ -1,70 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.coupon; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; - -import java.util.List; - -/** - * 优惠劵 Service 接口 - * - * @author 芋道源码 - */ -public interface CouponService { - - /** - * 校验优惠劵,包括状态、有限期 - * - * 1. 如果校验通过,则返回优惠劵信息 - * 2. 如果校验不通过,则直接抛出业务异常 - * - * @param id 优惠劵编号 - * @param userId 用户编号 - * @return 优惠劵信息 - */ - CouponDO validCoupon(Long id, Long userId); - - /** - * 校验优惠劵,包括状态、有限期 - * - * @see #validCoupon(Long, Long) 逻辑相同,只是入参不同 - * - * @param coupon 优惠劵 - */ - void validCoupon(CouponDO coupon); - - /** - * 获得优惠劵分页 - * - * @param pageReqVO 分页查询 - * @return 优惠劵分页 - */ - PageResult getCouponPage(CouponPageReqVO pageReqVO); - - /** - * 使用优惠劵 - * - * @param id 优惠劵编号 - * @param userId 用户编号 - * @param orderId 订单编号 - */ - void useCoupon(Long id, Long userId, Long orderId); - - /** - * 回收优惠劵 - * - * @param id 优惠劵编号 - */ - void deleteCoupon(Long id); - - /** - * 获得用户的优惠劵列表 - * - * @param userId 用户编号 - * @param status 优惠劵状态 - * @return 优惠劵列表 - */ - List getCouponList(Long userId, Integer status); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java deleted file mode 100644 index a573e0d9c..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java +++ /dev/null @@ -1,123 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.coupon; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponMapper; -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Set; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static java.util.Arrays.asList; - -/** - * 优惠劵 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class CouponServiceImpl implements CouponService { - - @Resource - private CouponTemplateService couponTemplateService; - - @Resource - private CouponMapper couponMapper; - - @Resource - private MemberUserApi memberUserApi; - - @Override - public CouponDO validCoupon(Long id, Long userId) { - CouponDO coupon = couponMapper.selectByIdAndUserId(id, userId); - if (coupon == null) { - throw exception(COUPON_NOT_EXISTS); - } - validCoupon(coupon); - return coupon; - } - - @Override - public void validCoupon(CouponDO coupon) { - // 校验状态 - if (ObjectUtil.notEqual(coupon.getStatus(), CouponStatusEnum.UNUSED.getStatus())) { - throw exception(COUPON_STATUS_NOT_UNUSED); - } - // 校验有效期;为避免定时器没跑,实际优惠劵已经过期 - if (LocalDateTimeUtils.isBetween(coupon.getValidStartTime(), coupon.getValidEndTime())) { - throw exception(COUPON_VALID_TIME_NOT_NOW); - } - } - - @Override - public PageResult getCouponPage(CouponPageReqVO pageReqVO) { - // 获得用户编号 - Set userIds = null; - if (StrUtil.isNotEmpty(pageReqVO.getNickname())) { - userIds = CollectionUtils.convertSet(memberUserApi.getUserListByNickname(pageReqVO.getNickname()), - MemberUserRespDTO::getId); - if (CollUtil.isEmpty(userIds)) { - return PageResult.empty(); - } - } - // 分页查询 - return couponMapper.selectPage(pageReqVO, userIds); - } - - @Override - public void useCoupon(Long id, Long userId, Long orderId) { - // 校验优惠劵 - validCoupon(id, userId); - // 更新状态 - int updateCount = couponMapper.updateByIdAndStatus(id, CouponStatusEnum.UNUSED.getStatus(), - new CouponDO().setStatus(CouponStatusEnum.USED.getStatus()) - .setUseOrderId(orderId).setUseTime(LocalDateTime.now())); - if (updateCount == 0) { - throw exception(COUPON_STATUS_NOT_UNUSED); - } - } - - @Override - @Transactional - public void deleteCoupon(Long id) { - // 校验存在 - validateCouponExists(id); - - // 更新优惠劵 - int deleteCount = couponMapper.delete(id, - asList(CouponStatusEnum.UNUSED.getStatus(), CouponStatusEnum.EXPIRE.getStatus())); - if (deleteCount == 0) { - throw exception(COUPON_DELETE_FAIL_USED); - } - // 减少优惠劵模板的领取数量 -1 - couponTemplateService.updateCouponTemplateTakeCount(id, -1); - } - - @Override - public List getCouponList(Long userId, Integer status) { - return couponMapper.selectListByUserIdAndStatus(userId, status); - } - - private void validateCouponExists(Long id) { - if (couponMapper.selectById(id) == null) { - throw exception(COUPON_NOT_EXISTS); - } - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java deleted file mode 100755 index fdf018974..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java +++ /dev/null @@ -1,72 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.coupon; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; - -import javax.validation.Valid; - -/** - * 优惠劵模板 Service 接口 - * - * @author 芋道源码 - */ -public interface CouponTemplateService { - - /** - * 创建优惠劵模板 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createCouponTemplate(@Valid CouponTemplateCreateReqVO createReqVO); - - /** - * 更新优惠劵模板 - * - * @param updateReqVO 更新信息 - */ - void updateCouponTemplate(@Valid CouponTemplateUpdateReqVO updateReqVO); - - /** - * 更新优惠劵模板的状态 - * - * @param id 编号 - * @param status 状态 - */ - void updateCouponTemplateStatus(Long id, Integer status); - - /** - * 删除优惠劵模板 - * - * @param id 编号 - */ - void deleteCouponTemplate(Long id); - - /** - * 获得优惠劵模板 - * - * @param id 编号 - * @return 优惠劵模板 - */ - CouponTemplateDO getCouponTemplate(Long id); - - /** - * 获得优惠劵模板分页 - * - * @param pageReqVO 分页查询 - * @return 优惠劵模板分页 - */ - PageResult getCouponTemplatePage(CouponTemplatePageReqVO pageReqVO); - - /** - * 更新优惠劵模板的领取数量 - * - * @param id 优惠劵模板编号 - * @param incrCount 增加数量 - */ - void updateCouponTemplateTakeCount(Long id, int incrCount); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java deleted file mode 100755 index 1a9cc8bfb..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java +++ /dev/null @@ -1,94 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.coupon; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; - -/** - * 优惠劵模板 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class CouponTemplateServiceImpl implements CouponTemplateService { - - @Resource - private CouponTemplateMapper couponTemplateMapper; - - @Override - public Long createCouponTemplate(CouponTemplateCreateReqVO createReqVO) { - // 插入 - CouponTemplateDO couponTemplate = CouponTemplateConvert.INSTANCE.convert(createReqVO) - .setStatus(CommonStatusEnum.ENABLE.getStatus()); - couponTemplateMapper.insert(couponTemplate); - // 返回 - return couponTemplate.getId(); - } - - @Override - public void updateCouponTemplate(CouponTemplateUpdateReqVO updateReqVO) { - // 校验存在 - CouponTemplateDO couponTemplate = validateCouponTemplateExists(updateReqVO.getId()); - // 校验发放数量不能过小 - if (updateReqVO.getTotalCount() < couponTemplate.getTakeCount()) { - throw exception(COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL, couponTemplate.getTakeCount()); - } - - // 更新 - CouponTemplateDO updateObj = CouponTemplateConvert.INSTANCE.convert(updateReqVO); - couponTemplateMapper.updateById(updateObj); - } - - @Override - public void updateCouponTemplateStatus(Long id, Integer status) { - // 校验存在 - validateCouponTemplateExists(id); - // 更新 - couponTemplateMapper.updateById(new CouponTemplateDO().setId(id).setStatus(status)); - } - - @Override - public void deleteCouponTemplate(Long id) { - // 校验存在 - validateCouponTemplateExists(id); - // 删除 - couponTemplateMapper.deleteById(id); - } - - private CouponTemplateDO validateCouponTemplateExists(Long id) { - CouponTemplateDO couponTemplate = couponTemplateMapper.selectById(id); - if (couponTemplate == null) { - throw exception(COUPON_TEMPLATE_NOT_EXISTS); - } - return couponTemplate; - } - - @Override - public CouponTemplateDO getCouponTemplate(Long id) { - return couponTemplateMapper.selectById(id); - } - - @Override - public PageResult getCouponTemplatePage(CouponTemplatePageReqVO pageReqVO) { - return couponTemplateMapper.selectPage(pageReqVO); - } - - @Override - public void updateCouponTemplateTakeCount(Long id, int incrCount) { - couponTemplateMapper.updateTakeCount(id, incrCount); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java deleted file mode 100644 index 8b6e5895b..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java +++ /dev/null @@ -1,86 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.discount; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * 限时折扣 Service 接口 - * - * @author 芋道源码 - */ -public interface DiscountActivityService { - - /** - * 基于指定 SKU 编号数组,获得匹配的限时折扣商品 - * - * 注意,匹配的条件,仅仅是日期符合,并且处于开启状态 - * - * @param skuIds SKU 编号数组 - * @return 匹配的限时折扣商品 - */ - Map getMatchDiscountProducts(Collection skuIds); - - /** - * 创建限时折扣活动 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createDiscountActivity(@Valid DiscountActivityCreateReqVO createReqVO); - - /** - * 更新限时折扣活动 - * - * @param updateReqVO 更新信息 - */ - void updateDiscountActivity(@Valid DiscountActivityUpdateReqVO updateReqVO); - - /** - * 关闭限时折扣活动 - * - * @param id 编号 - */ - void closeRewardActivity(Long id); - - /** - * 删除限时折扣活动 - * - * @param id 编号 - */ - void deleteDiscountActivity(Long id); - - /** - * 获得限时折扣活动 - * - * @param id 编号 - * @return 限时折扣活动 - */ - DiscountActivityDO getDiscountActivity(Long id); - - /** - * 获得限时折扣活动分页 - * - * @param pageReqVO 分页查询 - * @return 限时折扣活动分页 - */ - PageResult getDiscountActivityPage(DiscountActivityPageReqVO pageReqVO); - - /** - * 获得活动编号,对应对应的商品列表 - * - * @param activityId 活动编号 - * @return 活动的商品列表 - */ - List getDiscountProductsByActivityId(Long activityId); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java deleted file mode 100644 index df54d44f2..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java +++ /dev/null @@ -1,196 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.discount; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.CollectionUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper; -import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; -import cn.iocoder.yudao.module.promotion.util.PromotionUtils; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.*; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static java.util.Arrays.asList; - -/** - * 限时折扣 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class DiscountActivityServiceImpl implements DiscountActivityService { - - @Resource - private DiscountActivityMapper discountActivityMapper; - @Resource - private DiscountProductMapper discountProductMapper; - - @Override - public Map getMatchDiscountProducts(Collection skuIds) { - List discountProducts = getRewardProductListBySkuIds(skuIds, singleton(PromotionActivityStatusEnum.RUN.getStatus())); - return convertMap(discountProducts, DiscountProductDetailBO::getSkuId); - } - - @Override - public Long createDiscountActivity(DiscountActivityCreateReqVO createReqVO) { - // 校验商品是否冲突 - validateDiscountActivityProductConflicts(null, createReqVO.getProducts()); - - // 插入活动 - DiscountActivityDO discountActivity = DiscountActivityConvert.INSTANCE.convert(createReqVO) - .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime())); - discountActivityMapper.insert(discountActivity); - // 插入商品 - List discountProducts = convertList(createReqVO.getProducts(), - product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(discountActivity.getId())); - discountProductMapper.insertBatch(discountProducts); - // 返回 - return discountActivity.getId(); - } - - @Override - public void updateDiscountActivity(DiscountActivityUpdateReqVO updateReqVO) { - // 校验存在 - DiscountActivityDO discountActivity = validateDiscountActivityExists(updateReqVO.getId()); - if (discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能修改噢 - throw exception(DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); - } - // 校验商品是否冲突 - validateDiscountActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts()); - - // 更新活动 - DiscountActivityDO updateObj = DiscountActivityConvert.INSTANCE.convert(updateReqVO) - .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); - discountActivityMapper.updateById(updateObj); - // 更新商品 - updateDiscountProduct(updateReqVO); - } - - private void updateDiscountProduct(DiscountActivityUpdateReqVO updateReqVO) { - List dbDiscountProducts = discountProductMapper.selectListByActivityId(updateReqVO.getId()); - // 计算要删除的记录 - List deleteIds = convertList(dbDiscountProducts, DiscountProductDO::getId, - discountProductDO -> updateReqVO.getProducts().stream() - .noneMatch(product -> DiscountActivityConvert.INSTANCE.isEquals(discountProductDO, product))); - if (CollUtil.isNotEmpty(deleteIds)) { - discountProductMapper.deleteBatchIds(deleteIds); - } - // 计算新增的记录 - List newDiscountProducts = convertList(updateReqVO.getProducts(), - product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(updateReqVO.getId())); - newDiscountProducts.removeIf(product -> dbDiscountProducts.stream().anyMatch( - dbProduct -> DiscountActivityConvert.INSTANCE.isEquals(dbProduct, product))); // 如果匹配到,说明是更新的 - if (CollectionUtil.isNotEmpty(newDiscountProducts)) { - discountProductMapper.insertBatch(newDiscountProducts); - } - } - - /** - * 校验商品是否冲突 - * - * @param id 编号 - * @param products 商品列表 - */ - private void validateDiscountActivityProductConflicts(Long id, List products) { - if (CollUtil.isEmpty(products)) { - return; - } - // 查询商品参加的活动 - List discountActivityProductList = getRewardProductListBySkuIds( - convertSet(products, DiscountActivityBaseVO.Product::getSkuId), - asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus())); - if (id != null) { // 排除自己这个活动 - discountActivityProductList.removeIf(product -> id.equals(product.getActivityId())); - } - // 如果非空,则说明冲突 - if (CollUtil.isNotEmpty(discountActivityProductList)) { - throw exception(DISCOUNT_ACTIVITY_SPU_CONFLICTS); - } - } - - private List getRewardProductListBySkuIds(Collection skuIds, - Collection statuses) { - // 查询商品 - List products = discountProductMapper.selectListBySkuId(skuIds); - if (CollUtil.isEmpty(products)) { - return new ArrayList<>(0); - } - - // 查询活动 - List activities = discountActivityMapper.selectBatchIds(skuIds); - activities.removeIf(activity -> !statuses.contains(activity.getStatus())); // 移除不满足 statuses 状态的 - Map activityMap = CollectionUtils.convertMap(activities, DiscountActivityDO::getId); - - // 移除不满足活动的商品 - products.removeIf(product -> !activityMap.containsKey(product.getActivityId())); - return DiscountActivityConvert.INSTANCE.convertList(products, activityMap); - } - - @Override - public void closeRewardActivity(Long id) { - // 校验存在 - DiscountActivityDO dbDiscountActivity = validateDiscountActivityExists(id); - if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能关闭噢 - throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED); - } - if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.END.getStatus())) { // 已关闭的活动,不能关闭噢 - throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END); - } - - // 更新 - DiscountActivityDO updateObj = new DiscountActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); - discountActivityMapper.updateById(updateObj); - } - - @Override - public void deleteDiscountActivity(Long id) { - // 校验存在 - DiscountActivityDO discountActivity = validateDiscountActivityExists(id); - if (!discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 未关闭的活动,不能删除噢 - throw exception(DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED); - } - - // 删除 - discountActivityMapper.deleteById(id); - } - - private DiscountActivityDO validateDiscountActivityExists(Long id) { - DiscountActivityDO discountActivity = discountActivityMapper.selectById(id); - if (discountActivity == null) { - throw exception(DISCOUNT_ACTIVITY_NOT_EXISTS); - } - return discountActivity; - } - - @Override - public DiscountActivityDO getDiscountActivity(Long id) { - return discountActivityMapper.selectById(id); - } - - @Override - public PageResult getDiscountActivityPage(DiscountActivityPageReqVO pageReqVO) { - return discountActivityMapper.selectPage(pageReqVO); - } - - @Override - public List getDiscountProductsByActivityId(Long activityId) { - return discountProductMapper.selectListByActivityId(activityId); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java deleted file mode 100644 index 7b8f4a20f..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.discount.bo; - -import lombok.Data; - -/** - * 限时折扣活动商品 BO - * - * @author 芋道源码 - */ -@Data -public class DiscountProductDetailBO { - - // ========== DiscountProductDO 字段 ========== - - /** - * 编号,主键自增 - */ - private Long id; - /** - * 限时折扣活动的编号 - */ - private Long activityId; - /** - * 商品 SPU 编号 - */ - private Long spuId; - /** - * 商品 SKU 编号 - */ - private Long skuId; - /** - * 折扣类型 - */ - private Integer discountType; - /** - * 折扣百分比 - */ - private Integer discountPercent; - /** - * 优惠金额,单位:分 - */ - private Integer discountPrice; - - // ========== DiscountActivityDO 字段 ========== - /** - * 活动标题 - */ - private String activityName; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java deleted file mode 100644 index a7420e119..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.price; - -import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; - -import java.util.List; - -/** - * 价格计算 Service 接口 - * - * @author 芋道源码 - */ -public interface PriceService { - - /** - * 计算商品的价格 - * - * @param calculateReqDTO 价格请求 - * @return 价格响应 - */ - PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); - - /** - * 获得优惠劵的匹配信息列表 - * - * @param calculateReqDTO 价格请求 - * @return 价格响应 - */ - List getMeetCouponList(PriceCalculateReqDTO calculateReqDTO); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java deleted file mode 100644 index 03abb061f..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java +++ /dev/null @@ -1,547 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.price; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.exception.ServiceException; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.promotion.convert.price.PriceConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; -import cn.iocoder.yudao.module.promotion.enums.common.*; -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; -import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; -import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; -import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; -import com.google.common.base.Suppliers; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.*; -import java.util.function.Supplier; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static java.util.Collections.singletonList; - -/** - * 价格计算 Service 实现类 - * - * 优惠计算顺序:min(限时折扣, 会员折扣) > 满减送 > 优惠券。 - * 参考文档: - * 1. 有赞文档:限时折扣、满减送、优惠券哪个优先计算? - * - * TODO 芋艿:进一步完善 - * 1. 限时折扣:指定金额、减免金额、折扣 - * 2. 满减送:循环、折扣 - * 3. 优惠劵:待定 - * - * @author 芋道源码 - */ -@Service -@Validated -@Slf4j -public class PriceServiceImpl implements PriceService { - - @Resource - private DiscountActivityService discountService; - @Resource - private RewardActivityService rewardActivityService; - @Resource - private CouponService couponService; - - @Resource - private ProductSkuApi productSkuApi; - - @Override - public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { - // 获得商品 SKU 数组 - List skuList = checkSkus(calculateReqDTO); - // 初始化 PriceCalculateRespDTO 对象 - PriceCalculateRespDTO priceCalculate = PriceConvert.INSTANCE.convert(calculateReqDTO, skuList); - - // 计算商品级别的价格 - calculatePriceForSkuLevel(calculateReqDTO.getUserId(), priceCalculate); - // 计算订单级别的价格 - calculatePriceForOrderLevel(calculateReqDTO.getUserId(), priceCalculate); - // 计算优惠劵级别的价格 - calculatePriceForCouponLevel(calculateReqDTO.getUserId(), calculateReqDTO.getCouponId(), priceCalculate); - - // 如果最终支付金额小于等于 0,则抛出业务异常 - if (priceCalculate.getOrder().getPayPrice() <= 0) { - log.error("[calculatePrice][价格计算不正确,请求 calculateReqDTO({}),结果 priceCalculate({})]", - calculateReqDTO, priceCalculate); - throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL); - } - return priceCalculate; - } - - @Override - public List getMeetCouponList(PriceCalculateReqDTO calculateReqDTO) { - // 先计算一轮价格 - PriceCalculateRespDTO priceCalculate = calculatePrice(calculateReqDTO); - - // 获得用户的待使用优惠劵 - List couponList = couponService.getCouponList(calculateReqDTO.getUserId(), CouponStatusEnum.UNUSED.getStatus()); - if (CollUtil.isEmpty(couponList)) { - return Collections.emptyList(); - } - - // 获得优惠劵的匹配信息 - return CollectionUtils.convertList(couponList, coupon -> { - CouponMeetRespDTO couponMeetRespDTO = PriceConvert.INSTANCE.convert(coupon); - try { - // 校验优惠劵 - couponService.validCoupon(coupon); - - // 获得匹配的商品 SKU 数组 - List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); - if (CollUtil.isEmpty(orderItems)) { - return couponMeetRespDTO.setMeet(false).setMeetTip("所结算商品没有符合条件的商品"); - } - - // 计算是否满足优惠劵的使用金额 - Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert originPrice != null; - if (originPrice < coupon.getUsePrice()) { - return couponMeetRespDTO.setMeet(false) -// .setMeetTip(String.format("差 %s 元可用优惠劵", formatPrice(coupon.getUsePrice() - originPrice))); - .setMeetTip("所结算的商品中未满足使用的金额"); - } - } catch (ServiceException serviceException) { - couponMeetRespDTO.setMeet(false); - if (serviceException.getCode().equals(COUPON_VALID_TIME_NOT_NOW.getCode())) { - couponMeetRespDTO.setMeetTip("优惠劵未到使用时间"); - } else { - log.error("[getMeetCouponList][calculateReqDTO({}) 获得优惠劵匹配信息异常]", calculateReqDTO, serviceException); - couponMeetRespDTO.setMeetTip("优惠劵不满足使用条件"); - } - return couponMeetRespDTO; - } - // 满足 - return couponMeetRespDTO.setMeet(true); - }); - } - - private List checkSkus(PriceCalculateReqDTO calculateReqDTO) { - // 获得商品 SKU 数组 - Map skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), - PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); - List skus = productSkuApi.getSkuList(skuIdCountMap.keySet()); - - // 校验商品 SKU - skus.forEach(sku -> { - Integer count = skuIdCountMap.get(sku.getId()); - if (count == null) { - throw exception(SKU_NOT_EXISTS); - } - // 不校验库存不足,避免购物车场景,商品无货的情况 - }); - return skus; - } - - // ========== 计算商品级别的价格 ========== - - /** - * 计算商品级别的价格,例如说: - * 1. 会员折扣 - * 2. 限时折扣 {@link cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO} - * - * 其中,会员折扣、限时折扣取最低价 - * - * @param userId 用户编号 - * @param priceCalculate 价格计算的结果 - */ - private void calculatePriceForSkuLevel(Long userId, PriceCalculateRespDTO priceCalculate) { - // 获取 SKU 级别的所有优惠信息 - Supplier memberDiscountPercentSupplier = getMemberDiscountPercentSupplier(userId); - Map discountProducts = discountService.getMatchDiscountProducts( - convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSkuId)); - - // 处理每个 SKU 的优惠 - priceCalculate.getOrder().getItems().forEach(orderItem -> { - // 获取该 SKU 的优惠信息 - Double memberDiscountPercent = memberDiscountPercentSupplier.get(); - DiscountProductDetailBO discountProduct = discountProducts.get(orderItem.getSkuId()); - if (memberDiscountPercent == null && discountProduct == null) { - return; - } - // 计算价格,判断选择哪个折扣 - Integer memberPrice = memberDiscountPercent != null ? (int) (orderItem.getPayPrice() * memberDiscountPercent / 100) : null; - Integer promotionPrice = discountProduct != null ? getDiscountProductPrice(discountProduct, orderItem) : null; - if (memberPrice == null) { - calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); - } else if (promotionPrice == null) { - calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); - } else if (memberPrice < promotionPrice) { - calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); - } else { - calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); - } - }); - } - - private Integer getDiscountProductPrice(DiscountProductDetailBO discountProduct, - PriceCalculateRespDTO.OrderItem orderItem) { - Integer price = orderItem.getPayPrice(); - if (PromotionDiscountTypeEnum.PRICE.getType().equals(discountProduct.getDiscountType())) { // 减价 - price -= discountProduct.getDiscountPrice() * orderItem.getCount(); - } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discountProduct.getDiscountType())) { // 打折 - price = price * discountProduct.getDiscountPercent() / 100; - } else { - throw new IllegalArgumentException(String.format("优惠活动的商品(%s) 的优惠类型不正确", discountProduct)); - } - return price; - } - - private void calculatePriceByMemberDiscount(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - Integer memberPrice) { - // 记录优惠明细 - addPromotion(priceCalculate, orderItem, null, PromotionTypeEnum.MEMBER.getName(), - PromotionTypeEnum.MEMBER.getType(), PromotionLevelEnum.SKU.getLevel(), memberPrice, - true, StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice))); - // 修改 SKU 的优惠 - modifyOrderItemPayPrice(orderItem, memberPrice, priceCalculate); - } - - private void calculatePriceByDiscountActivity(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - DiscountProductDetailBO discountProduct, Integer promotionPrice) { - // 记录优惠明细 - addPromotion(priceCalculate, orderItem, discountProduct.getActivityId(), discountProduct.getActivityName(), - PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), PromotionLevelEnum.SKU.getLevel(), promotionPrice, - true, StrUtil.format("限时折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - promotionPrice))); - // 修改 SKU 的优惠 - modifyOrderItemPayPrice(orderItem, promotionPrice, priceCalculate); - } - - // TODO 芋艿:提前实现 - private Supplier getMemberDiscountPercentSupplier(Long userId) { - return Suppliers.memoize(() -> { - if (userId == 1) { - return 90d; - } - if (userId == 2) { - return 80d; - } - return null; // 无优惠 - }); - } - - // ========== 计算商品级别的价格 ========== - - /** - * 计算订单级别的价格,例如说: - * 1. 满减送 {@link cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO} - * - * @param userId 用户编号 - * @param priceCalculate 价格计算的结果 - */ - @SuppressWarnings("unused") - private void calculatePriceForOrderLevel(Long userId, PriceCalculateRespDTO priceCalculate) { - // 获取 SKU 级别的所有优惠信息 - Set spuIds = convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSpuId); - Map> rewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); - - // 处理满减送活动 - if (CollUtil.isNotEmpty(rewardActivities)) { - rewardActivities.forEach((rewardActivity, activitySpuIds) -> { - List orderItems = CollectionUtils.filterList(priceCalculate.getOrder().getItems(), - orderItem -> CollUtil.contains(activitySpuIds, orderItem.getSpuId())); - calculatePriceByRewardActivity(priceCalculate, orderItems, rewardActivity); - }); - } - } - - private void calculatePriceByRewardActivity(PriceCalculateRespDTO priceCalculate, List orderItems, - RewardActivityDO rewardActivity) { - // 获得最大匹配的满减送活动的规则 - RewardActivityDO.Rule rule = getLastMatchRewardActivityRule(rewardActivity, orderItems); - if (rule == null) { - // 获取不到的情况下,记录不满足的优惠明细 - addNotMeetPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), - PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), - getRewardActivityNotMeetTip(rewardActivity)); - return; - } - - // 分摊金额 - List discountPartPrices = dividePrice(orderItems, rule.getDiscountPrice()); - // 记录优惠明细 - addPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), - PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), discountPartPrices, - true, StrUtil.format("满减送:省 {} 元", formatPrice(rule.getDiscountPrice()))); - // 修改 SKU 的分摊 - for (int i = 0; i < orderItems.size(); i++) { - modifyOrderItemOrderPartPriceFromDiscountPrice(orderItems.get(i), discountPartPrices.get(i), priceCalculate); - } - } - - /** - * 获得最大匹配的满减送活动的规则 - * - * @param rewardActivity 满减送活动 - * @param orderItems 商品项 - * @return 匹配的活动规则 - */ - private RewardActivityDO.Rule getLastMatchRewardActivityRule(RewardActivityDO rewardActivity, - List orderItems) { - Integer count = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getCount, Integer::sum); - // price 的计算逻辑,使用 orderDividePrice 的原因,主要考虑分摊后,这个才是该 SKU 当前真实的支付总价 - Integer price = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert count != null && price != null; - for (int i = rewardActivity.getRules().size() - 1; i >= 0; i--) { - RewardActivityDO.Rule rule = rewardActivity.getRules().get(i); - if (PromotionConditionTypeEnum.PRICE.getType().equals(rewardActivity.getConditionType()) - && price >= rule.getLimit()) { - return rule; - } - if (PromotionConditionTypeEnum.COUNT.getType().equals(rewardActivity.getConditionType()) - && count >= rule.getLimit()) { - return rule; - } - } - return null; - } - - /** - * 获得满减送活动部匹配时的提示 - * - * @param rewardActivity 满减送活动 - * @return 提示 - */ - private String getRewardActivityNotMeetTip(RewardActivityDO rewardActivity) { - return "TODO"; // TODO 芋艿:后面再想想 - } - - // ========== 计算优惠劵级别的价格 ========== - - private void calculatePriceForCouponLevel(Long userId, Long couponId, PriceCalculateRespDTO priceCalculate) { - // 校验优惠劵 - if (couponId == null) { - return; - } - CouponDO coupon = couponService.validCoupon(couponId, userId); - - // 获得匹配的商品 SKU 数组 - List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); - if (CollUtil.isEmpty(orderItems)) { - throw exception(COUPON_NO_MATCH_SPU); - } - - // 计算是否满足优惠劵的使用金额 - Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert originPrice != null; - if (originPrice < coupon.getUsePrice()) { - throw exception(COUPON_NO_MATCH_MIN_PRICE); - } - - // 计算可以优惠的金额 - priceCalculate.getOrder().setCouponId(couponId); - Integer couponPrice = getCouponPrice(coupon, originPrice); - // 分摊金额 - List couponPartPrices = dividePrice(orderItems, couponPrice); - // 记录优惠明细 - addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getName(), - PromotionTypeEnum.COUPON.getType(), PromotionLevelEnum.COUPON.getLevel(), couponPartPrices, - true, StrUtil.format("优惠劵:省 {} 元", formatPrice(couponPrice))); - // 修改 SKU 的分摊 - for (int i = 0; i < orderItems.size(); i++) { - modifyOrderItemOrderPartPriceFromCouponPrice(orderItems.get(i), couponPartPrices.get(i), priceCalculate); - } - } - - private List getMatchCouponOrderItems(PriceCalculateRespDTO priceCalculate, - CouponDO coupon) { - if (PromotionProductScopeEnum.ALL.getScope().equals(coupon.getProductScope())) { - return priceCalculate.getOrder().getItems(); - } - return CollectionUtils.filterList(priceCalculate.getOrder().getItems(), - orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId())); - } - - private Integer getCouponPrice(CouponDO coupon, Integer originPrice) { - if (PromotionDiscountTypeEnum.PRICE.getType().equals(coupon.getDiscountType())) { // 减价 - return coupon.getDiscountPrice(); - } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(coupon.getDiscountType())) { // 打折 - int couponPrice = originPrice * coupon.getDiscountPercent() / 100; - return coupon.getDiscountLimitPrice() == null ? couponPrice - : Math.min(couponPrice, coupon.getDiscountLimitPrice()); // 优惠上限 - } - throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon)); - } - - // ========== 其它相对通用的方法 ========== - - /** - * 添加单个 OrderItem 的营销明细 - * - * @param priceCalculate 价格计算结果 - * @param orderItem 单个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param type 营销类型 - * @param level 营销级别 - * @param newPayPrice 新的单实付金额(总) - * @param meet 是否满足优惠条件 - * @param meetTip 满足条件的提示 - */ - private void addPromotion(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - Long id, String name, Integer type, Integer level, - Integer newPayPrice, Boolean meet, String meetTip) { - // 创建营销明细 Item - // TODO 芋艿:orderItem.getPayPrice() 要不要改成 orderDividePrice;同时,newPayPrice 要不要改成直接传递 discountPrice - PriceCalculateRespDTO.PromotionItem promotionItem = new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(orderItem.getPayPrice() - newPayPrice); - // 创建营销明细 - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setOriginalPrice(promotionItem.getOriginalPrice()).setDiscountPrice(promotionItem.getDiscountPrice()) - .setItems(singletonList(promotionItem)).setMeet(meet).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - /** - * 添加多个 OrderItem 的营销明细 - * - * @param priceCalculate 价格计算结果 - * @param orderItems 多个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param type 营销类型 - * @param level 营销级别 - * @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应 - * @param meet 是否满足优惠条件 - * @param meetTip 满足条件的提示 - */ - private void addPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, - Long id, String name, Integer type, Integer level, - List discountPrices, Boolean meet, String meetTip) { - // 创建营销明细 Item - List promotionItems = new ArrayList<>(discountPrices.size()); - for (int i = 0; i < orderItems.size(); i++) { - PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); - promotionItems.add(new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(discountPrices.get(i))); - } - // 创建营销明细 - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setOriginalPrice(getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum)) - .setDiscountPrice(getSumValue(discountPrices, value -> value, Integer::sum)) - .setItems(promotionItems).setMeet(meet).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - private void addNotMeetPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, - Long id, String name, Integer type, Integer level, String meetTip) { - // 创建营销明细 Item - List promotionItems = CollectionUtils.convertList(orderItems, - orderItem -> new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getOrderDividePrice()).setDiscountPrice(0)); - // 创建营销明细 - Integer originalPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setOriginalPrice(originalPrice).setDiscountPrice(0) - .setItems(promotionItems).setMeet(false).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - /** - * 修改 OrderItem 的 payPrice 价格,同时会修改 Order 的 payPrice 价格 - * - * @param orderItem 订单商品 SKU - * @param newPayPrice 新的 payPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemPayPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer newPayPrice, - PriceCalculateRespDTO priceCalculate) { - // diffPayPrice 等于额外增加的商品级的优惠 - int diffPayPrice = orderItem.getPayPrice() - newPayPrice; - // 设置 OrderItem 价格相关字段 - orderItem.setDiscountPrice(orderItem.getDiscountPrice() + diffPayPrice); - orderItem.setPayPrice(newPayPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setPayPrice(order.getPayPrice() - diffPayPrice); - order.setOrderPrice(order.getOrderPrice() - diffPayPrice); - } - - /** - * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 discountPrice 价格 - * - * 本质:分摊 Order 的 discountPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 - * - * @param orderItem 订单商品 SKU - * @param addOrderPartPrice 新增的 discountPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemOrderPartPriceFromDiscountPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, - PriceCalculateRespDTO priceCalculate) { - // 设置 OrderItem 价格相关字段 - orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setDiscountPrice(order.getDiscountPrice() + addOrderPartPrice); - order.setPayPrice(order.getPayPrice() - addOrderPartPrice); - } - - /** - * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 couponPrice 价格 - * - * 本质:分摊 Order 的 couponPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 - * - * @param orderItem 订单商品 SKU - * @param addOrderPartPrice 新增的 couponPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemOrderPartPriceFromCouponPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, - PriceCalculateRespDTO priceCalculate) { - // 设置 OrderItem 价格相关字段 - orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setCouponPrice(order.getCouponPrice() + addOrderPartPrice); - order.setPayPrice(order.getPayPrice() - addOrderPartPrice); - } - - private List dividePrice(List orderItems, Integer price) { - List prices = new ArrayList<>(orderItems.size()); - Integer total = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert total != null; - int remainPrice = price; - // 遍历每一个,进行分摊 - for (int i = 0; i < orderItems.size(); i++) { - PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); - int partPrice; - if (i < orderItems.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 - partPrice = (int) (price * (1.0D * orderItem.getOrderDividePrice() / total)); - remainPrice -= partPrice; - } else { - partPrice = remainPrice; - } - Assert.isTrue(partPrice > 0, "分摊金额必须大于 0"); - prices.add(partPrice); - } - return prices; - } - - private String formatPrice(Integer price) { - return String.format("%.2f", price / 100d); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java deleted file mode 100755 index 40bcc2836..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java +++ /dev/null @@ -1,73 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.reward; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; - -import javax.validation.Valid; -import java.util.Map; -import java.util.Set; - -/** - * 满减送活动 Service 接口 - * - * @author 芋道源码 - */ -public interface RewardActivityService { - - /** - * 创建满减送活动 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createRewardActivity(@Valid RewardActivityCreateReqVO createReqVO); - - /** - * 更新满减送活动 - * - * @param updateReqVO 更新信息 - */ - void updateRewardActivity(@Valid RewardActivityUpdateReqVO updateReqVO); - - /** - * 关闭满减送活动 - * - * @param id 活动编号 - */ - void closeRewardActivity(Long id); - - /** - * 删除满减送活动 - * - * @param id 编号 - */ - void deleteRewardActivity(Long id); - - /** - * 获得满减送活动 - * - * @param id 编号 - * @return 满减送活动 - */ - RewardActivityDO getRewardActivity(Long id); - - /** - * 获得满减送活动分页 - * - * @param pageReqVO 分页查询 - * @return 满减送活动分页 - */ - PageResult getRewardActivityPage(RewardActivityPageReqVO pageReqVO); - - /** - * 基于指定的 SPU 编号数组,获得它们匹配的满减送活动 - * - * @param spuIds SPU 编号数组 - * @return 满减送活动,与对应的 SPU 编号的映射。即,value 就是 SPU 编号的集合 - */ - Map> getMatchRewardActivities(Set spuIds); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java deleted file mode 100755 index 51d0ce626..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java +++ /dev/null @@ -1,169 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.reward; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.reward.RewardActivityMapper; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; -import cn.iocoder.yudao.module.promotion.util.PromotionUtils; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static cn.hutool.core.collection.CollUtil.intersectionDistinct; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static java.util.Arrays.asList; -import static java.util.Collections.singleton; - -/** - * 满减送活动 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class RewardActivityServiceImpl implements RewardActivityService { - - @Resource - private RewardActivityMapper rewardActivityMapper; - - @Override - public Long createRewardActivity(RewardActivityCreateReqVO createReqVO) { - // 校验商品是否冲突 - validateRewardActivitySpuConflicts(null, createReqVO.getProductSpuIds()); - - // 插入 - RewardActivityDO rewardActivity = RewardActivityConvert.INSTANCE.convert(createReqVO) - .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime())); - rewardActivityMapper.insert(rewardActivity); - // 返回 - return rewardActivity.getId(); - } - - @Override - public void updateRewardActivity(RewardActivityUpdateReqVO updateReqVO) { - // 校验存在 - RewardActivityDO dbRewardActivity = validateRewardActivityExists(updateReqVO.getId()); - if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能修改噢 - throw exception(REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); - } - // 校验商品是否冲突 - validateRewardActivitySpuConflicts(updateReqVO.getId(), updateReqVO.getProductSpuIds()); - - // 更新 - RewardActivityDO updateObj = RewardActivityConvert.INSTANCE.convert(updateReqVO) - .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); - rewardActivityMapper.updateById(updateObj); - } - - @Override - public void closeRewardActivity(Long id) { - // 校验存在 - RewardActivityDO dbRewardActivity = validateRewardActivityExists(id); - if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能关闭噢 - throw exception(REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED); - } - if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.END.getStatus())) { // 已关闭的活动,不能关闭噢 - throw exception(REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END); - } - - // 更新 - RewardActivityDO updateObj = new RewardActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); - rewardActivityMapper.updateById(updateObj); - } - - @Override - public void deleteRewardActivity(Long id) { - // 校验存在 - RewardActivityDO dbRewardActivity = validateRewardActivityExists(id); - if (!dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 未关闭的活动,不能删除噢 - throw exception(REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED); - } - - // 删除 - rewardActivityMapper.deleteById(id); - } - - private RewardActivityDO validateRewardActivityExists(Long id) { - RewardActivityDO activity = rewardActivityMapper.selectById(id); - if (activity == null) { - throw exception(REWARD_ACTIVITY_NOT_EXISTS); - } - return activity; - } - - /** - * 校验商品参加的活动是否冲突 - * - * @param id 活动编号 - * @param spuIds 商品 SPU 编号数组 - */ - private void validateRewardActivitySpuConflicts(Long id, Collection spuIds) { - if (CollUtil.isEmpty(spuIds)) { - return; - } - // 查询商品参加的活动 - List rewardActivityList = getRewardActivityListBySpuIds(spuIds, - asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus())); - if (id != null) { // 排除自己这个活动 - rewardActivityList.removeIf(activity -> id.equals(activity.getId())); - } - // 如果非空,则说明冲突 - if (CollUtil.isNotEmpty(rewardActivityList)) { - throw exception(REWARD_ACTIVITY_SPU_CONFLICTS); - } - } - - /** - * 获得商品参加的满减送活动的数组 - * - * @param spuIds 商品 SPU 编号数组 - * @param statuses 活动状态数组 - * @return 商品参加的满减送活动的数组 - */ - private List getRewardActivityListBySpuIds(Collection spuIds, - Collection statuses) { - List list = rewardActivityMapper.selectListByStatus(statuses); - return CollUtil.filter(list, activity -> CollUtil.containsAny(activity.getProductSpuIds(), spuIds)); - } - - @Override - public RewardActivityDO getRewardActivity(Long id) { - return rewardActivityMapper.selectById(id); - } - - @Override - public PageResult getRewardActivityPage(RewardActivityPageReqVO pageReqVO) { - return rewardActivityMapper.selectPage(pageReqVO); - } - - @Override - public Map> getMatchRewardActivities(Set spuIds) { - // 如果有全局活动,则直接选择它 - List allActivities = rewardActivityMapper.selectListByProductScopeAndStatus( - PromotionProductScopeEnum.ALL.getScope(), PromotionActivityStatusEnum.RUN.getStatus()); - if (CollUtil.isNotEmpty(allActivities)) { - return MapUtil.builder(allActivities.get(0), spuIds).build(); - } - - // 查询某个活动参加的活动 - List productActivityList = getRewardActivityListBySpuIds(spuIds, - singleton(PromotionActivityStatusEnum.RUN.getStatus())); - return convertMap(productActivityList, activity -> activity, - rewardActivityDO -> intersectionDistinct(rewardActivityDO.getProductSpuIds(), spuIds)); // 求交集返回 - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java deleted file mode 100644 index a0ff74dc8..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java +++ /dev/null @@ -1,80 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity; - -import java.util.*; -import javax.validation.*; - -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; - -/** - * 秒杀活动 Service 接口 - * - * @author halfninety - */ -public interface SeckillActivityService { - - /** - * 创建秒杀活动 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createSeckillActivity(@Valid SeckillActivityCreateReqVO createReqVO); - - /** - * 更新秒杀活动 - * - * @param updateReqVO 更新信息 - */ - void updateSeckillActivity(@Valid SeckillActivityUpdateReqVO updateReqVO); - - /** - * 关闭秒杀活动 - * - * @param id 编号 - */ - void closeSeckillActivity(Long id); - - /** - * 删除秒杀活动 - * - * @param id 编号 - */ - void deleteSeckillActivity(Long id); - - /** - * 获得秒杀活动 - * - * @param id 编号 - * @return 秒杀活动 - */ - SeckillActivityDO getSeckillActivity(Long id); - - /** - * 获得秒杀活动列表 - * - * @param ids 编号 - * @return 秒杀活动列表 - */ - List getSeckillActivityList(Collection ids); - - /** - * 获得秒杀活动分页 - * - * @param pageReqVO 分页查询 - * @return 秒杀活动分页 - */ - PageResult getSeckillActivityPage(SeckillActivityPageReqVO pageReqVO); - - /** - * 通过活动编号获取活动商品 - * - * @param id 活动编号 - * @return 活动商品列表 - */ - List getSeckillProductListByActivityId(Long id); -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java deleted file mode 100644 index 45581d825..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java +++ /dev/null @@ -1,226 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityBaseVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper; -import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillProductMapper; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeService; -import cn.iocoder.yudao.module.promotion.util.PromotionUtils; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static java.util.Arrays.asList; - -/** - * 秒杀活动 Service 实现类 - * - * @author halfninety - */ -@Service -@Validated -public class SeckillActivityServiceImpl implements SeckillActivityService { - @Resource - private SeckillActivityMapper seckillActivityMapper; - @Resource - private SeckillProductMapper seckillProductMapper; - @Resource - private SeckillTimeService seckillTimeService; - - @Override - public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) { - // 校验商品是否冲突 - validateSeckillActivityProductConflicts(null, createReqVO.getProducts()); - // 校验秒杀时段是否存在 - seckillTimeService.validateSeckillTimeExists(createReqVO.getTimeIds()); - - // 插入秒杀活动 - SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO) - .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime())); - seckillActivityMapper.insert(seckillActivity); - // 插入商品 - List productDOS = SeckillActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), seckillActivity); - seckillProductMapper.insertBatch(productDOS); - // 更新秒杀时段的秒杀活动数量 - seckillTimeService.sekillActivityCountIncr(createReqVO.getTimeIds()); - return seckillActivity.getId(); - } - - @Override - public void updateSeckillActivity(SeckillActivityUpdateReqVO updateReqVO) { - // 校验存在 - SeckillActivityDO seckillActivity = validateSeckillActivityExists(updateReqVO.getId()); - if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) { - throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); - } - // 校验商品是否冲突 - validateSeckillActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts()); - - // 更新活动 - SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO) - .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); - seckillActivityMapper.updateById(updateObj); - // 更新商品 - updateSeckillProduct(updateReqVO); - // 更新秒杀时段的秒杀活动数量 - updateSeckillTimeActivityCount(seckillActivity, updateReqVO.getTimeIds()); - } - - - /** - * 更新秒杀时段的秒杀活动数量 - * - * @param seckillActivity 查询出的秒杀活动 - * @param updateTimeIds 更新后的秒杀时段id列表 - */ - private void updateSeckillTimeActivityCount(SeckillActivityDO seckillActivity, List updateTimeIds) { - // 查询出 timeIds - List existsTimeIds = seckillActivity.getTimeIds(); - // 需要减少的时间段 - Collection reduceIds = CollUtil.filterNew(existsTimeIds, existsTimeId -> !updateTimeIds.contains(existsTimeId)); - // 需要添加的时间段 - updateTimeIds.removeIf(existsTimeIds::contains); - // 更新减少时间段和增加时间段 - if (CollUtil.isNotEmpty(updateTimeIds)) { - seckillTimeService.sekillActivityCountIncr(updateTimeIds); - } - if (CollUtil.isNotEmpty(reduceIds)) { - seckillTimeService.sekillActivityCountDecr(reduceIds); - } - } - - /** - * 更新秒杀商品 - * 后台查出的数据和前台查出的数据进行遍历, - * 1. 对前台数据进行遍历:如果不存在于后台的 sku 中需要新增 - * 2. 对后台数据进行遍历:如果不存在于前台的 sku 中需要删除 - * 3. 最后对当前活动商品全部更新,更新秒杀时段id列表 - * - * @param updateReqVO 更新的请求VO - */ - private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) { - List seckillProductDOS = seckillProductMapper.selectListByActivityId(updateReqVO.getId()); - List products = updateReqVO.getProducts(); - - // 计算需要删除的数据 - List deleteIds = CollectionUtils.convertList(seckillProductDOS, SeckillProductDO::getId, - seckillProductDO -> products.stream() - .noneMatch(product -> SeckillActivityConvert.INSTANCE.isEquals(seckillProductDO, product))); - if (CollUtil.isNotEmpty(deleteIds)) { - seckillProductMapper.deleteBatchIds(deleteIds); - } - - // 计算需要新增的数据 - List newSeckillProductDOs = CollectionUtils.convertList(products, - product -> SeckillActivityConvert.INSTANCE.convert(product).setActivityId(updateReqVO.getId())); - newSeckillProductDOs.removeIf(product -> seckillProductDOS.stream() - .anyMatch(seckillProduct -> SeckillActivityConvert.INSTANCE.isEquals(seckillProduct, product))); - if (CollUtil.isNotEmpty(newSeckillProductDOs)) { - seckillProductMapper.insertBatch(newSeckillProductDOs); - } - - //全量更新当前活动商品的秒杀时段id列表(timeIds) - seckillProductMapper.updateTimeIdsByActivityId(updateReqVO.getId(), updateReqVO.getTimeIds()); - } - - /** - * 校验商品是否冲突 - * - * @param id 秒杀活动编号 - * @param products 商品列表 - */ - private void validateSeckillActivityProductConflicts(Long id, List products) { - if (CollUtil.isEmpty(products)) { - return; - } - List seckillProductDOS = seckillProductMapper - .selectListBySkuIds(CollectionUtils.convertSet(products, SeckillActivityBaseVO.Product::getSkuId)); - if (CollUtil.isEmpty(seckillProductDOS)) { - return; - } - List seckillActivityDOS = seckillActivityMapper - .selectBatchIds(CollectionUtils.convertSet(seckillProductDOS, SeckillProductDO::getActivityId)); - if (id != null) { // 排除自己这个活动 - seckillActivityDOS.removeIf(item -> id.equals(item.getId())); - } - // 排除不满足 status 的活动 - List statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()); - seckillActivityDOS.removeIf(item -> !statuses.contains(item.getStatus())); - // 如果非空,则说明冲突 - if (CollUtil.isNotEmpty(seckillActivityDOS)) { - throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS); - } - } - - @Override - public void closeSeckillActivity(Long id) { - // 校验存在 - SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id); - if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) { - throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED); - } - if (PromotionActivityStatusEnum.END.getStatus().equals(seckillActivity.getStatus())) { - throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END); - } - // 更新 - SeckillActivityDO updateObj = new SeckillActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); - seckillActivityMapper.updateById(updateObj); - } - - @Override - public void deleteSeckillActivity(Long id) { - // 校验存在 - SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id); - List statuses = asList(PromotionActivityStatusEnum.CLOSE.getStatus(), PromotionActivityStatusEnum.END.getStatus()); - if (!statuses.contains(seckillActivity.getStatus())) { - throw exception(SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END); - } - // 更新秒杀时段的秒杀活动数量 - seckillTimeService.sekillActivityCountDecr(seckillActivity.getTimeIds()); - // 删除 - seckillActivityMapper.deleteById(id); - } - - private SeckillActivityDO validateSeckillActivityExists(Long id) { - SeckillActivityDO seckillActivity = seckillActivityMapper.selectById(id); - if (seckillActivity == null) { - throw exception(SECKILL_ACTIVITY_NOT_EXISTS); - } - return seckillActivity; - } - - @Override - public SeckillActivityDO getSeckillActivity(Long id) { - return seckillActivityMapper.selectById(id); - } - - @Override - public List getSeckillActivityList(Collection ids) { - return seckillActivityMapper.selectBatchIds(ids); - } - - @Override - public PageResult getSeckillActivityPage(SeckillActivityPageReqVO pageReqVO) { - return seckillActivityMapper.selectPage(pageReqVO); - } - - @Override - public List getSeckillProductListByActivityId(Long id) { - return seckillProductMapper.selectListByActivityId(id); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java deleted file mode 100644 index 2e9c21249..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java +++ /dev/null @@ -1,76 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.seckill.seckilltime; - -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; - -/** - * 秒杀时段 Service 接口 - * - * @author halfninety - */ -public interface SeckillTimeService { - - /** - * 创建秒杀时段 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createSeckillTime(@Valid SeckillTimeCreateReqVO createReqVO); - - /** - * 更新秒杀时段 - * - * @param updateReqVO 更新信息 - */ - void updateSeckillTime(@Valid SeckillTimeUpdateReqVO updateReqVO); - - /** - * 删除秒杀时段 - * - * @param id 编号 - */ - void deleteSeckillTime(Long id); - - /** - * 获得秒杀时段 - * - * @param id 编号 - * @return 秒杀时段 - */ - SeckillTimeDO getSeckillTime(Long id); - - /** - * 获得所有秒杀时段列表 - * - * @return 所有秒杀时段列表 - */ - List getSeckillTimeList(); - - /** - * 校验秒杀时段是否存在 - * - * @param timeIds 秒杀时段id集合 - */ - void validateSeckillTimeExists(Collection timeIds); - - /** - * 秒杀时段列表的秒杀活动数量加 1 - * - * @param ids 秒杀时段id列表 - */ - void sekillActivityCountIncr(Collection ids); - - - /** - * 秒杀时段列表的秒杀活动数量减 1 - * - * @param ids 秒杀时段id列表 - */ - void sekillActivityCountDecr(Collection ids); -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java deleted file mode 100644 index d38183860..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java +++ /dev/null @@ -1,124 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.seckill.seckilltime; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; -import cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime.SeckillTimeConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime.SeckillTimeMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.time.LocalTime; -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_CONFLICTS; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_NOT_EXISTS; - -/** - * 秒杀时段 Service 实现类 - * - * @author halfninety - */ -@Service -@Validated -public class SeckillTimeServiceImpl implements SeckillTimeService { - - @Resource - private SeckillTimeMapper seckillTimeMapper; - - @Override - public Long createSeckillTime(SeckillTimeCreateReqVO createReqVO) { - // 校验时间段是否冲突 - validateSeckillTimeConflict(null, createReqVO.getStartTime(), createReqVO.getEndTime()); - // 插入 - SeckillTimeDO seckillTime = SeckillTimeConvert.INSTANCE.convert(createReqVO); - seckillTimeMapper.insert(seckillTime); - // 返回 - return seckillTime.getId(); - } - - @Override - public void updateSeckillTime(SeckillTimeUpdateReqVO updateReqVO) { - // 校验存在 - this.validateSeckillTimeExists(updateReqVO.getId()); - // 校验时间段是否冲突 - validateSeckillTimeConflict(updateReqVO.getId(), updateReqVO.getStartTime(), updateReqVO.getEndTime()); - // 更新 - SeckillTimeDO updateObj = SeckillTimeConvert.INSTANCE.convert(updateReqVO); - seckillTimeMapper.updateById(updateObj); - } - - @Override - public void deleteSeckillTime(Long id) { - // 校验存在 - this.validateSeckillTimeExists(id); - // 删除 - seckillTimeMapper.deleteById(id); - } - - private void validateSeckillTimeExists(Long id) { - if (seckillTimeMapper.selectById(id) == null) { - throw exception(SECKILL_TIME_NOT_EXISTS); - } - } - - /** - * 校验时间是否存在冲突 - * - * @param startTime 开始时间 - * @param endTime 结束时间 - */ - private void validateSeckillTimeConflict(Long id, LocalTime startTime, LocalTime endTime) { - //查询开始时间,结束时间,是否在别人的时间段内 - List startTimeList = seckillTimeMapper.selectListByTime(startTime); - List endTimeList = seckillTimeMapper.selectListByTime(endTime); - //查询自己时间段内是否有时间段 - List startEndTimeList = seckillTimeMapper.selectListByTime(startTime, endTime); - if (id != null) { - //移除自己 - startTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id)); - endTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id)); - startEndTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id)); - } - if (CollUtil.isNotEmpty(startTimeList) || CollUtil.isNotEmpty(endTimeList) - || CollUtil.isNotEmpty(startEndTimeList)) { - throw exception(SECKILL_TIME_CONFLICTS); - } - } - - @Override - public SeckillTimeDO getSeckillTime(Long id) { - return seckillTimeMapper.selectById(id); - } - - @Override - public List getSeckillTimeList() { - return seckillTimeMapper.selectList(); - } - - @Override - public void validateSeckillTimeExists(Collection timeIds) { - if (CollUtil.isEmpty(timeIds)) { - throw exception(SECKILL_TIME_NOT_EXISTS); - } - if (seckillTimeMapper.selectBatchIds(timeIds).size() != timeIds.size()) { - throw exception(SECKILL_TIME_NOT_EXISTS); - } - } - - @Override - public void sekillActivityCountIncr(Collection ids) { - seckillTimeMapper.updateActivityCount(ids, "+", 1); - } - - @Override - public void sekillActivityCountDecr(Collection ids) { - seckillTimeMapper.updateActivityCount(ids, "-", 1); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java deleted file mode 100644 index fc8ca16cf..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.promotion.util; - -import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; - -import java.time.LocalDateTime; - -/** - * 活动工具类 - * - * @author 芋道源码 - */ -public class PromotionUtils { - - /** - * 根据时间,计算活动状态 - * - * @param startTime 开始时间 - * @param endTime 结束时间 - * @return 活动状态 - */ - public static Integer calculateActivityStatus(LocalDateTime startTime, LocalDateTime endTime) { - if (LocalDateTimeUtils.beforeNow(endTime)) { - return PromotionActivityStatusEnum.END.getStatus(); - } - if (LocalDateTimeUtils.afterNow(startTime)) { - return PromotionActivityStatusEnum.WAIT.getStatus(); - } - return PromotionActivityStatusEnum.RUN.getStatus(); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml b/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml deleted file mode 100644 index 987143534..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - UPDATE promotion_coupon_template - SET take_count = take_count + #{incrCount} - WHERE id = #{id} - - - diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImplTest.java deleted file mode 100755 index 5a41563e7..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImplTest.java +++ /dev/null @@ -1,147 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.coupon; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.time.LocalDateTime; - -import static cn.hutool.core.util.RandomUtil.randomEle; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS; -import static org.junit.jupiter.api.Assertions.*; - -/** -* {@link CouponTemplateServiceImpl} 的单元测试类 -* -* @author 芋道源码 -*/ -@Import(CouponTemplateServiceImpl.class) -public class CouponTemplateServiceImplTest extends BaseDbUnitTest { - - @Resource - private CouponTemplateServiceImpl couponTemplateService; - - @Resource - private CouponTemplateMapper couponTemplateMapper; - - @Test - public void testCreateCouponTemplate_success() { - // 准备参数 - CouponTemplateCreateReqVO reqVO = randomPojo(CouponTemplateCreateReqVO.class, - o -> o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()) - .setValidityType(randomEle(CouponTemplateValidityTypeEnum.values()).getType()) - .setDiscountType(randomEle(PromotionDiscountTypeEnum.values()).getType())); - - // 调用 - Long couponTemplateId = couponTemplateService.createCouponTemplate(reqVO); - // 断言 - assertNotNull(couponTemplateId); - // 校验记录的属性是否正确 - CouponTemplateDO couponTemplate = couponTemplateMapper.selectById(couponTemplateId); - assertPojoEquals(reqVO, couponTemplate); - } - - @Test - public void testUpdateCouponTemplate_success() { - // mock 数据 - CouponTemplateDO dbCouponTemplate = randomPojo(CouponTemplateDO.class); - couponTemplateMapper.insert(dbCouponTemplate);// @Sql: 先插入出一条存在的数据 - // 准备参数 - CouponTemplateUpdateReqVO reqVO = randomPojo(CouponTemplateUpdateReqVO.class, o -> { - o.setId(dbCouponTemplate.getId()); // 设置更新的 ID - // 其它通用字段 - o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()) - .setValidityType(randomEle(CouponTemplateValidityTypeEnum.values()).getType()) - .setDiscountType(randomEle(PromotionDiscountTypeEnum.values()).getType()); - }); - - // 调用 - couponTemplateService.updateCouponTemplate(reqVO); - // 校验是否更新正确 - CouponTemplateDO couponTemplate = couponTemplateMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, couponTemplate); - } - - @Test - public void testUpdateCouponTemplate_notExists() { - // 准备参数 - CouponTemplateUpdateReqVO reqVO = randomPojo(CouponTemplateUpdateReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> couponTemplateService.updateCouponTemplate(reqVO), COUPON_TEMPLATE_NOT_EXISTS); - } - - @Test - public void testDeleteCouponTemplate_success() { - // mock 数据 - CouponTemplateDO dbCouponTemplate = randomPojo(CouponTemplateDO.class); - couponTemplateMapper.insert(dbCouponTemplate);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbCouponTemplate.getId(); - - // 调用 - couponTemplateService.deleteCouponTemplate(id); - // 校验数据不存在了 - assertNull(couponTemplateMapper.selectById(id)); - } - - @Test - public void testDeleteCouponTemplate_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> couponTemplateService.deleteCouponTemplate(id), COUPON_TEMPLATE_NOT_EXISTS); - } - - @Test - public void testGetCouponTemplatePage() { - // mock 数据 - CouponTemplateDO dbCouponTemplate = randomPojo(CouponTemplateDO.class, o -> { // 等会查询到 - o.setName("芋艿"); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()); - o.setCreateTime(buildTime(2022, 2, 2)); - }); - couponTemplateMapper.insert(dbCouponTemplate); - // 测试 name 不匹配 - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setName("土豆"))); - // 测试 status 不匹配 - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); - // 测试 type 不匹配 - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()))); - // 测试 createTime 不匹配 - couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setCreateTime(buildTime(2022, 1, 1)))); - // 准备参数 - CouponTemplatePageReqVO reqVO = new CouponTemplatePageReqVO(); - reqVO.setName("芋艿"); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2022, 2, 1), buildTime(2022, 2, 3)})); - - // 调用 - PageResult pageResult = couponTemplateService.getCouponTemplatePage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbCouponTemplate, pageResult.getList().get(0)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java deleted file mode 100755 index 5ad517463..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java +++ /dev/null @@ -1,210 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.discount; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper; -import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.time.Duration; -import java.time.LocalDateTime; -import java.util.Date; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.DISCOUNT_ACTIVITY_NOT_EXISTS; -import static java.util.Arrays.asList; -import static org.junit.jupiter.api.Assertions.*; - -/** -* {@link DiscountActivityServiceImpl} 的单元测试类 -* -* @author 芋道源码 -*/ -@Import(DiscountActivityServiceImpl.class) -public class DiscountActivityServiceImplTest extends BaseDbUnitTest { - - @Resource - private DiscountActivityServiceImpl discountActivityService; - - @Resource - private DiscountActivityMapper discountActivityMapper; - @Resource - private DiscountProductMapper discountProductMapper; - - @Test - public void testCreateDiscountActivity_success() { - // 准备参数 - DiscountActivityCreateReqVO reqVO = randomPojo(DiscountActivityCreateReqVO.class, o -> { - // 用于触发进行中的状态 - o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); - // 设置商品 - o.setProducts(asList(new DiscountActivityBaseVO.Product().setSpuId(1L).setSkuId(2L) - .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3), - new DiscountActivityBaseVO.Product().setSpuId(10L).setSkuId(20L) - .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30))); - }); - - // 调用 - Long discountActivityId = discountActivityService.createDiscountActivity(reqVO); - // 断言 - assertNotNull(discountActivityId); - // 校验活动 - DiscountActivityDO discountActivity = discountActivityMapper.selectById(discountActivityId); - assertPojoEquals(reqVO, discountActivity); - assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); - // 校验商品 - List discountProducts = discountProductMapper.selectList(DiscountProductDO::getActivityId, discountActivity.getId()); - assertEquals(discountProducts.size(), reqVO.getProducts().size()); - for (int i = 0; i < reqVO.getProducts().size(); i++) { - DiscountActivityBaseVO.Product product = reqVO.getProducts().get(i); - DiscountProductDO discountProduct = discountProducts.get(i); - assertEquals(discountProduct.getActivityId(), discountActivity.getId()); - assertEquals(discountProduct.getSpuId(), product.getSpuId()); - assertEquals(discountProduct.getSkuId(), product.getSkuId()); - assertEquals(discountProduct.getDiscountType(), product.getDiscountType()); - assertEquals(discountProduct.getDiscountPrice(), product.getDiscountPrice()); - assertEquals(discountProduct.getDiscountPercent(), product.getDiscountPercent()); - } - } - - @Test - public void testUpdateDiscountActivity_success() { - // mock 数据(商品) - DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class); - discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 - // mock 数据(活动) - DiscountProductDO dbDiscountProduct01 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(dbDiscountActivity.getId()) - .setSpuId(1L).setSkuId(2L).setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3).setDiscountPercent(null)); - DiscountProductDO dbDiscountProduct02 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(dbDiscountActivity.getId()) - .setSpuId(10L).setSkuId(20L).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30).setDiscountPrice(null)); - discountProductMapper.insert(dbDiscountProduct01); - discountProductMapper.insert(dbDiscountProduct02); - // 准备参数 - DiscountActivityUpdateReqVO reqVO = randomPojo(DiscountActivityUpdateReqVO.class, o -> { - o.setId(dbDiscountActivity.getId()); // 设置更新的 ID - // 用于触发进行中的状态 - o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); - // 设置商品 - o.setProducts(asList(new DiscountActivityBaseVO.Product().setSpuId(1L).setSkuId(2L) - .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3).setDiscountPercent(null), - new DiscountActivityBaseVO.Product().setSpuId(100L).setSkuId(200L) - .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30).setDiscountPrice(null))); - }); - - // 调用 - discountActivityService.updateDiscountActivity(reqVO); - // 校验活动 - DiscountActivityDO discountActivity = discountActivityMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, discountActivity); - assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); - // 校验商品 - List discountProducts = discountProductMapper.selectList(DiscountProductDO::getActivityId, discountActivity.getId()); - assertEquals(discountProducts.size(), reqVO.getProducts().size()); - for (int i = 0; i < reqVO.getProducts().size(); i++) { - DiscountActivityBaseVO.Product product = reqVO.getProducts().get(i); - DiscountProductDO discountProduct = discountProducts.get(i); - assertEquals(discountProduct.getActivityId(), discountActivity.getId()); - assertEquals(discountProduct.getSpuId(), product.getSpuId()); - assertEquals(discountProduct.getSkuId(), product.getSkuId()); - assertEquals(discountProduct.getDiscountType(), product.getDiscountType()); - assertEquals(discountProduct.getDiscountPrice(), product.getDiscountPrice()); - assertEquals(discountProduct.getDiscountPercent(), product.getDiscountPercent()); - } - } - - @Test - public void testCloseDiscountActivity() { - // mock 数据 - DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, - o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus())); - discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbDiscountActivity.getId(); - - // 调用 - discountActivityService.closeRewardActivity(id); - // 校验状态 - DiscountActivityDO discountActivity = discountActivityMapper.selectById(id); - assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus()); - } - - @Test - public void testUpdateDiscountActivity_notExists() { - // 准备参数 - DiscountActivityUpdateReqVO reqVO = randomPojo(DiscountActivityUpdateReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> discountActivityService.updateDiscountActivity(reqVO), DISCOUNT_ACTIVITY_NOT_EXISTS); - } - - @Test - public void testDeleteDiscountActivity_success() { - // mock 数据 - DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, - o -> o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus())); - discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbDiscountActivity.getId(); - - // 调用 - discountActivityService.deleteDiscountActivity(id); - // 校验数据不存在了 - assertNull(discountActivityMapper.selectById(id)); - } - - @Test - public void testDeleteDiscountActivity_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> discountActivityService.deleteDiscountActivity(id), DISCOUNT_ACTIVITY_NOT_EXISTS); - } - - @Test - public void testGetDiscountActivityPage() { - // mock 数据 - DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, o -> { // 等会查询到 - o.setName("芋艿"); - o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus()); - o.setCreateTime(buildTime(2021, 1, 15)); - }); - discountActivityMapper.insert(dbDiscountActivity); - // 测试 name 不匹配 - discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setName("土豆"))); - // 测试 status 不匹配 - discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setStatus(PromotionActivityStatusEnum.END.getStatus()))); - // 测试 createTime 不匹配 - discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setCreateTime(buildTime(2021, 2, 10)))); - // 准备参数 - DiscountActivityPageReqVO reqVO = new DiscountActivityPageReqVO(); - reqVO.setName("芋艿"); - reqVO.setStatus(PromotionActivityStatusEnum.WAIT.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 1, 1), buildTime(2021, 1, 31)})); - - // 调用 - PageResult pageResult = discountActivityService.getDiscountActivityPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbDiscountActivity, pageResult.getList().get(0)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java deleted file mode 100644 index 0c7b2d6ec..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java +++ /dev/null @@ -1,506 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.price; - -import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.framework.common.exception.ServiceException; -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; -import cn.iocoder.yudao.module.promotion.enums.common.*; -import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; -import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; -import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; -import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; -import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_VALID_TIME_NOT_NOW; -import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.when; - -/** - * {@link PriceServiceImpl} 的单元测试 - * - * @author 芋道源码 - */ -public class PriceServiceTest extends BaseMockitoUnitTest { - - @InjectMocks - private PriceServiceImpl priceService; - - @Mock - private DiscountActivityService discountService; - @Mock - private RewardActivityService rewardActivityService; - @Mock - private CouponService couponService; - @Mock - private ProductSkuApi productSkuApi; - - @Test - public void testCalculatePrice_memberDiscount() { - // 准备参数 - // TODO 芋艿:userId = 1,实现 9 折;后续改成 mock - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1L) - .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); - when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 200); - assertEquals(order.getOrderPrice(), 180); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 180); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 1); - PriceCalculateRespDTO.OrderItem orderItem = order.getItems().get(0); - assertEquals(orderItem.getSkuId(), 10L); - assertEquals(orderItem.getCount(), 2); - assertEquals(orderItem.getOriginalPrice(), 200); - assertEquals(orderItem.getOriginalUnitPrice(), 100); - assertEquals(orderItem.getDiscountPrice(), 20); - assertEquals(orderItem.getPayPrice(), 180); - assertEquals(orderItem.getOrderPartPrice(), 0); - assertEquals(orderItem.getOrderDividePrice(), 180); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 1); - PriceCalculateRespDTO.Promotion promotion = priceCalculate.getPromotions().get(0); - assertNull(promotion.getId()); - assertEquals(promotion.getName(), "会员折扣"); - assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); - assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion.getOriginalPrice(), 200); - assertEquals(promotion.getDiscountPrice(), 20); - assertTrue(promotion.getMeet()); - assertEquals(promotion.getMeetTip(), "会员折扣:省 0.20 元"); - PriceCalculateRespDTO.PromotionItem promotionItem = promotion.getItems().get(0); - assertEquals(promotion.getItems().size(), 1); - assertEquals(promotionItem.getSkuId(), 10L); - assertEquals(promotionItem.getOriginalPrice(), 200); - assertEquals(promotionItem.getDiscountPrice(), 20); - } - - @Test - public void testCalculatePrice_discountActivity() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); - // mock 方法(限时折扣 DiscountActivity 信息) - DiscountProductDetailBO discountProduct01 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(1000L) - .setActivityName("活动 1000 号").setSkuId(10L) - .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(40)); - DiscountProductDetailBO discountProduct02 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(2000L) - .setActivityName("活动 2000 号").setSkuId(20L) - .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(60)); - when(discountService.getMatchDiscountProducts(eq(asSet(10L, 20L)))).thenReturn( - MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map()); - - // 10L: 100 * 2 - 40 * 2 = 120 - // 20L:50 * 3 - 50 * 3 * 0.4 = 90 - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 350); - assertEquals(order.getOrderPrice(), 210); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 210); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 2); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 80); - assertEquals(orderItem01.getPayPrice(), 120); - assertEquals(orderItem01.getOrderPartPrice(), 0); - assertEquals(orderItem01.getOrderDividePrice(), 120); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 60); - assertEquals(orderItem02.getPayPrice(), 90); - assertEquals(orderItem02.getOrderPartPrice(), 0); - assertEquals(orderItem02.getOrderDividePrice(), 90); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 2); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1000L); - assertEquals(promotion01.getName(), "活动 1000 号"); - assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 200); - assertEquals(promotion01.getDiscountPrice(), 80); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.80 元"); - PriceCalculateRespDTO.PromotionItem promotionItem01 = promotion01.getItems().get(0); - assertEquals(promotion01.getItems().size(), 1); - assertEquals(promotionItem01.getSkuId(), 10L); - assertEquals(promotionItem01.getOriginalPrice(), 200); - assertEquals(promotionItem01.getDiscountPrice(), 80); - PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); - assertEquals(promotion02.getId(), 2000L); - assertEquals(promotion02.getName(), "活动 2000 号"); - assertEquals(promotion02.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); - assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion02.getOriginalPrice(), 150); - assertEquals(promotion02.getDiscountPrice(), 60); - assertTrue(promotion02.getMeet()); - assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.60 元"); - PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); - assertEquals(promotion02.getItems().size(), 1); - assertEquals(promotionItem02.getSkuId(), 20L); - assertEquals(promotionItem02.getOriginalPrice(), 150); - assertEquals(promotionItem02.getDiscountPrice(), 60); - } - - /** - * 测试满减送活动,匹配的情况 - */ - @Test - public void testCalculatePrice_rewardActivity() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), - new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); - ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); - // mock 方法(限时折扣 DiscountActivity 信息) - RewardActivityDO rewardActivity01 = randomPojo(RewardActivityDO.class, o -> o.setId(1000L).setName("活动 1000 号") - .setProductSpuIds(asList(10L, 20L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) - .setRules(singletonList(new RewardActivityDO.Rule().setLimit(200).setDiscountPrice(70)))); - RewardActivityDO rewardActivity02 = randomPojo(RewardActivityDO.class, o -> o.setId(2000L).setName("活动 2000 号") - .setProductSpuIds(singletonList(30L)).setConditionType(PromotionConditionTypeEnum.COUNT.getType()) - .setRules(asList(new RewardActivityDO.Rule().setLimit(1).setDiscountPrice(10), - new RewardActivityDO.Rule().setLimit(2).setDiscountPrice(60), // 最大可满足,因为是 4 个 - new RewardActivityDO.Rule().setLimit(10).setDiscountPrice(100)))); - Map> matchRewardActivities = new LinkedHashMap<>(); - matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); - matchRewardActivities.put(rewardActivity02, asSet(3L)); - when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 470); - assertEquals(order.getOrderPrice(), 470); - assertEquals(order.getDiscountPrice(), 130); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 340); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 3); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 0); - assertEquals(orderItem01.getPayPrice(), 200); - assertEquals(orderItem01.getOrderPartPrice(), 40); - assertEquals(orderItem01.getOrderDividePrice(), 160); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 0); - assertEquals(orderItem02.getPayPrice(), 150); - assertEquals(orderItem02.getOrderPartPrice(), 30); - assertEquals(orderItem02.getOrderDividePrice(), 120); - PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); - assertEquals(orderItem03.getSkuId(), 30L); - assertEquals(orderItem03.getCount(), 4); - assertEquals(orderItem03.getOriginalPrice(), 120); - assertEquals(orderItem03.getOriginalUnitPrice(), 30); - assertEquals(orderItem03.getDiscountPrice(), 0); - assertEquals(orderItem03.getPayPrice(), 120); - assertEquals(orderItem03.getOrderPartPrice(), 60); - assertEquals(orderItem03.getOrderDividePrice(), 60); - // 断言 Promotion 部分(第一个) - assertEquals(priceCalculate.getPromotions().size(), 2); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1000L); - assertEquals(promotion01.getName(), "活动 1000 号"); - assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 350); - assertEquals(promotion01.getDiscountPrice(), 70); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "满减送:省 0.70 元"); - assertEquals(promotion01.getItems().size(), 2); - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); - assertEquals(promotionItem011.getSkuId(), 10L); - assertEquals(promotionItem011.getOriginalPrice(), 200); - assertEquals(promotionItem011.getDiscountPrice(), 40); - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); - assertEquals(promotionItem012.getSkuId(), 20L); - assertEquals(promotionItem012.getOriginalPrice(), 150); - assertEquals(promotionItem012.getDiscountPrice(), 30); - // 断言 Promotion 部分(第二个) - PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); - assertEquals(promotion02.getId(), 2000L); - assertEquals(promotion02.getName(), "活动 2000 号"); - assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); - assertEquals(promotion02.getOriginalPrice(), 120); - assertEquals(promotion02.getDiscountPrice(), 60); - assertTrue(promotion02.getMeet()); - assertEquals(promotion02.getMeetTip(), "满减送:省 0.60 元"); - PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); - assertEquals(promotion02.getItems().size(), 1); - assertEquals(promotionItem02.getSkuId(), 30L); - assertEquals(promotionItem02.getOriginalPrice(), 120); - assertEquals(promotionItem02.getDiscountPrice(), 60); - } - - /** - * 测试满减送活动,不匹配的情况 - */ - @Test - public void testCalculatePrice_rewardActivityNotMeet() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); - // mock 方法(限时折扣 DiscountActivity 信息) - RewardActivityDO rewardActivity01 = randomPojo(RewardActivityDO.class, o -> o.setId(1000L).setName("活动 1000 号") - .setProductSpuIds(asList(10L, 20L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) - .setRules(singletonList(new RewardActivityDO.Rule().setLimit(351).setDiscountPrice(70)))); - Map> matchRewardActivities = new LinkedHashMap<>(); - matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); - when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 350); - assertEquals(order.getOrderPrice(), 350); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 350); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 2); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 0); - assertEquals(orderItem01.getPayPrice(), 200); - assertEquals(orderItem01.getOrderPartPrice(), 0); - assertEquals(orderItem01.getOrderDividePrice(), 200); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 0); - assertEquals(orderItem02.getPayPrice(), 150); - assertEquals(orderItem02.getOrderPartPrice(), 0); - assertEquals(orderItem02.getOrderDividePrice(), 150); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 1); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1000L); - assertEquals(promotion01.getName(), "活动 1000 号"); - assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 350); - assertEquals(promotion01.getDiscountPrice(), 0); - assertFalse(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "TODO"); // TODO 芋艿:后面再想想 - assertEquals(promotion01.getItems().size(), 2); - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); - assertEquals(promotionItem011.getSkuId(), 10L); - assertEquals(promotionItem011.getOriginalPrice(), 200); - assertEquals(promotionItem011.getDiscountPrice(), 0); - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); - assertEquals(promotionItem012.getSkuId(), 20L); - assertEquals(promotionItem012.getOriginalPrice(), 150); - assertEquals(promotionItem012.getDiscountPrice(), 0); - } - - @Test - public void testCalculatePrice_coupon() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), - new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))) - .setCouponId(1024L); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); - ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); - // mock 方法(优惠劵 Coupon 信息) - CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setName("程序员节") - .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)) - .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()) - .setDiscountPercent(50).setDiscountLimitPrice(70)); - when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 470); - assertEquals(order.getOrderPrice(), 470); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 400); - assertEquals(order.getCouponId(), 1024L); - assertEquals(order.getCouponPrice(), 70); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 3); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 0); - assertEquals(orderItem01.getPayPrice(), 200); - assertEquals(orderItem01.getOrderPartPrice(), 40); - assertEquals(orderItem01.getOrderDividePrice(), 160); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 0); - assertEquals(orderItem02.getPayPrice(), 150); - assertEquals(orderItem02.getOrderPartPrice(), 30); - assertEquals(orderItem02.getOrderDividePrice(), 120); - PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); - assertEquals(orderItem03.getSkuId(), 30L); - assertEquals(orderItem03.getCount(), 4); - assertEquals(orderItem03.getOriginalPrice(), 120); - assertEquals(orderItem03.getOriginalUnitPrice(), 30); - assertEquals(orderItem03.getDiscountPrice(), 0); - assertEquals(orderItem03.getPayPrice(), 120); - assertEquals(orderItem03.getOrderPartPrice(), 0); - assertEquals(orderItem03.getOrderDividePrice(), 120); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 1); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1024L); - assertEquals(promotion01.getName(), "程序员节"); - assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 350); - assertEquals(promotion01.getDiscountPrice(), 70); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "优惠劵:省 0.70 元"); - assertEquals(promotion01.getItems().size(), 2); - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); - assertEquals(promotionItem011.getSkuId(), 10L); - assertEquals(promotionItem011.getOriginalPrice(), 200); - assertEquals(promotionItem011.getDiscountPrice(), 40); - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); - assertEquals(promotionItem012.getSkuId(), 20L); - assertEquals(promotionItem012.getOriginalPrice(), 150); - assertEquals(promotionItem012.getDiscountPrice(), 30); - } - - @Test - public void testGetMeetCouponList() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1024L) - .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); - when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); - // mock 方法(情况一:优惠劵未到使用时间) - CouponDO coupon01 = randomPojo(CouponDO.class); - doThrow(new ServiceException(COUPON_VALID_TIME_NOT_NOW)).when(couponService).validCoupon(coupon01); - // mock 方法(情况二:所结算商品没有符合条件的商品) - CouponDO coupon02 = randomPojo(CouponDO.class); - // mock 方法(情况三:使用金额不足) - CouponDO coupon03 = randomPojo(CouponDO.class, o -> o.setProductScope(PromotionProductScopeEnum.ALL.getScope()) - .setUsePrice(300)); - // mock 方法(情况五:满足条件) - CouponDO coupon04 = randomPojo(CouponDO.class, o -> o.setProductScope(PromotionProductScopeEnum.ALL.getScope()) - .setUsePrice(190)); - // mock 方法(获得用户的待使用优惠劵) - when(couponService.getCouponList(eq(1024L), eq(CouponStatusEnum.UNUSED.getStatus()))) - .thenReturn(asList(coupon01, coupon02, coupon03, coupon04)); - // 调用 - List list = priceService.getMeetCouponList(calculateReqDTO); - // 断言 - assertEquals(list.size(), 4); - // 断言情况一:优惠劵未到使用时间 - CouponMeetRespDTO couponMeetRespDTO01 = list.get(0); - assertPojoEquals(couponMeetRespDTO01, coupon01); - assertFalse(couponMeetRespDTO01.getMeet()); - assertEquals(couponMeetRespDTO01.getMeetTip(), "优惠劵未到使用时间"); - // 断言情况二:所结算商品没有符合条件的商品 - CouponMeetRespDTO couponMeetRespDTO02 = list.get(1); - assertPojoEquals(couponMeetRespDTO02, coupon02); - assertFalse(couponMeetRespDTO02.getMeet()); - assertEquals(couponMeetRespDTO02.getMeetTip(), "所结算商品没有符合条件的商品"); - // 断言情况三:差 %s 元可用优惠劵 - CouponMeetRespDTO couponMeetRespDTO03 = list.get(2); - assertPojoEquals(couponMeetRespDTO03, coupon03); - assertFalse(couponMeetRespDTO03.getMeet()); - assertEquals(couponMeetRespDTO03.getMeetTip(), "所结算的商品中未满足使用的金额"); - // 断言情况四:满足条件 - CouponMeetRespDTO couponMeetRespDTO04 = list.get(3); - assertPojoEquals(couponMeetRespDTO04, coupon04); - assertTrue(couponMeetRespDTO04.getMeet()); - assertNull(couponMeetRespDTO04.getMeetTip()); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java deleted file mode 100755 index 9f9e28c07..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java +++ /dev/null @@ -1,218 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.reward; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.reward.RewardActivityMapper; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.time.Duration; -import java.util.Map; -import java.util.Set; - -import static cn.hutool.core.util.RandomUtil.randomEle; -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.REWARD_ACTIVITY_NOT_EXISTS; -import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; -import static org.junit.jupiter.api.Assertions.*; - -/** -* {@link RewardActivityServiceImpl} 的单元测试类 -* -* @author 芋道源码 -*/ -@Import(RewardActivityServiceImpl.class) -public class RewardActivityServiceImplTest extends BaseDbUnitTest { - - @Resource - private RewardActivityServiceImpl rewardActivityService; - - @Resource - private RewardActivityMapper rewardActivityMapper; - - @Test - public void testCreateRewardActivity_success() { - // 准备参数 - RewardActivityCreateReqVO reqVO = randomPojo(RewardActivityCreateReqVO.class, o -> { - o.setConditionType(randomEle(PromotionConditionTypeEnum.values()).getType()); - o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()); - // 用于触发进行中的状态 - o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); - }); - - // 调用 - Long rewardActivityId = rewardActivityService.createRewardActivity(reqVO); - // 断言 - assertNotNull(rewardActivityId); - // 校验记录的属性是否正确 - RewardActivityDO rewardActivity = rewardActivityMapper.selectById(rewardActivityId); - assertPojoEquals(reqVO, rewardActivity, "rules"); - assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); - for (int i = 0; i < reqVO.getRules().size(); i++) { - assertPojoEquals(reqVO.getRules().get(i), rewardActivity.getRules().get(i)); - } - } - - @Test - public void testUpdateRewardActivity_success() { - // mock 数据 - RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus())); - rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据 - // 准备参数 - RewardActivityUpdateReqVO reqVO = randomPojo(RewardActivityUpdateReqVO.class, o -> { - o.setId(dbRewardActivity.getId()); // 设置更新的 ID - o.setConditionType(randomEle(PromotionConditionTypeEnum.values()).getType()); - o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()); - // 用于触发进行中的状态 - o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); - }); - - // 调用 - rewardActivityService.updateRewardActivity(reqVO); - // 校验是否更新正确 - RewardActivityDO rewardActivity = rewardActivityMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, rewardActivity, "rules"); - assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); - for (int i = 0; i < reqVO.getRules().size(); i++) { - assertPojoEquals(reqVO.getRules().get(i), rewardActivity.getRules().get(i)); - } - } - - @Test - public void testCloseRewardActivity() { - // mock 数据 - RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus())); - rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbRewardActivity.getId(); - - // 调用 - rewardActivityService.closeRewardActivity(id); - // 校验状态 - RewardActivityDO rewardActivity = rewardActivityMapper.selectById(id); - assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus()); - } - - @Test - public void testUpdateRewardActivity_notExists() { - // 准备参数 - RewardActivityUpdateReqVO reqVO = randomPojo(RewardActivityUpdateReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> rewardActivityService.updateRewardActivity(reqVO), REWARD_ACTIVITY_NOT_EXISTS); - } - - @Test - public void testDeleteRewardActivity_success() { - // mock 数据 - RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus())); - rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbRewardActivity.getId(); - - // 调用 - rewardActivityService.deleteRewardActivity(id); - // 校验数据不存在了 - assertNull(rewardActivityMapper.selectById(id)); - } - - @Test - public void testDeleteRewardActivity_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> rewardActivityService.deleteRewardActivity(id), REWARD_ACTIVITY_NOT_EXISTS); - } - - @Test - public void testGetRewardActivityPage() { - // mock 数据 - RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> { // 等会查询到 - o.setName("芋艿"); - o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); - }); - rewardActivityMapper.insert(dbRewardActivity); - // 测试 name 不匹配 - rewardActivityMapper.insert(cloneIgnoreId(dbRewardActivity, o -> o.setName("土豆"))); - // 测试 status 不匹配 - rewardActivityMapper.insert(cloneIgnoreId(dbRewardActivity, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()))); - // 准备参数 - RewardActivityPageReqVO reqVO = new RewardActivityPageReqVO(); - reqVO.setName("芋艿"); - reqVO.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); - - // 调用 - PageResult pageResult = rewardActivityService.getRewardActivityPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbRewardActivity, pageResult.getList().get(0), "rules"); - } - - @Test - public void testGetRewardActivities_all() { - // mock 数据 - RewardActivityDO allActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) - .setProductScope(PromotionProductScopeEnum.ALL.getScope())); - rewardActivityMapper.insert(allActivity); - RewardActivityDO productActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) - .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L))); - rewardActivityMapper.insert(productActivity); - // 准备参数 - Set spuIds = asSet(1L, 2L); - - // 调用 - Map> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); - // 断言 - assertEquals(matchRewardActivities.size(), 1); - Map.Entry> next = matchRewardActivities.entrySet().iterator().next(); - assertPojoEquals(next.getKey(), allActivity); - assertEquals(next.getValue(), spuIds); - } - - @Test - public void testGetRewardActivities_product() { - // mock 数据 - RewardActivityDO productActivity01 = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) - .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L))); - rewardActivityMapper.insert(productActivity01); - RewardActivityDO productActivity02 = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) - .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(singletonList(3L))); - rewardActivityMapper.insert(productActivity02); - // 准备参数 - Set spuIds = asSet(1L, 2L, 3L); - - // 调用 - Map> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); - // 断言 - assertEquals(matchRewardActivities.size(), 2); - matchRewardActivities.forEach((activity, activitySpuIds) -> { - if (activity.getId().equals(productActivity01.getId())) { - assertPojoEquals(activity, productActivity01); - assertEquals(activitySpuIds, asSet(1L, 2L)); - } else if (activity.getId().equals(productActivity02.getId())) { - assertPojoEquals(activity, productActivity02); - assertEquals(activitySpuIds, asSet(3L)); - } else { - fail(); - } - }); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java deleted file mode 100644 index 853568077..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java +++ /dev/null @@ -1,170 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.seckillactivity; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper; -import cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity.SeckillActivityServiceImpl; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_NOT_EXISTS; -import static org.junit.jupiter.api.Assertions.*; - -/** -* {@link SeckillActivityServiceImpl} 的单元测试类 -* -* @author 芋道源码 -*/ -@Import(SeckillActivityServiceImpl.class) -public class SeckillActivityServiceImplTest extends BaseDbUnitTest { - - @Resource - private SeckillActivityServiceImpl seckillActivityService; - - @Resource - private SeckillActivityMapper seckillActivityMapper; - - @Test - public void testCreateSeckillActivity_success() { - // 准备参数 - SeckillActivityCreateReqVO reqVO = randomPojo(SeckillActivityCreateReqVO.class); - - // 调用 - Long seckillActivityId = seckillActivityService.createSeckillActivity(reqVO); - // 断言 - assertNotNull(seckillActivityId); - // 校验记录的属性是否正确 - SeckillActivityDO seckillActivity = seckillActivityMapper.selectById(seckillActivityId); - assertPojoEquals(reqVO, seckillActivity); - } - - @Test - public void testUpdateSeckillActivity_success() { - // mock 数据 - SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class); - seckillActivityMapper.insert(dbSeckillActivity);// @Sql: 先插入出一条存在的数据 - // 准备参数 - SeckillActivityUpdateReqVO reqVO = randomPojo(SeckillActivityUpdateReqVO.class, o -> { - o.setId(dbSeckillActivity.getId()); // 设置更新的 ID - }); - - // 调用 - seckillActivityService.updateSeckillActivity(reqVO); - // 校验是否更新正确 - SeckillActivityDO seckillActivity = seckillActivityMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, seckillActivity); - } - - @Test - public void testUpdateSeckillActivity_notExists() { - // 准备参数 - SeckillActivityUpdateReqVO reqVO = randomPojo(SeckillActivityUpdateReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> seckillActivityService.updateSeckillActivity(reqVO), SECKILL_ACTIVITY_NOT_EXISTS); - } - - @Test - public void testDeleteSeckillActivity_success() { - // mock 数据 - SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class); - seckillActivityMapper.insert(dbSeckillActivity);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbSeckillActivity.getId(); - - // 调用 - seckillActivityService.deleteSeckillActivity(id); - // 校验数据不存在了 - assertNull(seckillActivityMapper.selectById(id)); - } - - @Test - public void testDeleteSeckillActivity_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> seckillActivityService.deleteSeckillActivity(id), SECKILL_ACTIVITY_NOT_EXISTS); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetSeckillActivityPage() { - // mock 数据 - SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class, o -> { // 等会查询到 - o.setName(null); - o.setStatus(null); - o.setTimeIds(null); - o.setCreateTime(null); - }); - seckillActivityMapper.insert(dbSeckillActivity); - // 测试 name 不匹配 - seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setName(null))); - // 测试 status 不匹配 - seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setStatus(null))); - // 测试 timeId 不匹配 - seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setTimeIds(null))); - // 测试 createTime 不匹配 - seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setCreateTime(null))); - // 准备参数 - SeckillActivityPageReqVO reqVO = new SeckillActivityPageReqVO(); - reqVO.setName(null); - reqVO.setStatus(null); - reqVO.setTimeId(null); - reqVO.setCreateTime((new LocalDateTime[]{})); - - // 调用 - PageResult pageResult = seckillActivityService.getSeckillActivityPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbSeckillActivity, pageResult.getList().get(0)); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetSeckillActivityList() { - // mock 数据 - SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class, o -> { // 等会查询到 - o.setName(null); - o.setStatus(null); - o.setTimeIds(null); - o.setCreateTime(null); - }); - seckillActivityMapper.insert(dbSeckillActivity); - // 测试 name 不匹配 - seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setName(null))); - // 测试 status 不匹配 - seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setStatus(null))); - // 测试 timeId 不匹配 - seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setTimeIds(null))); - // 测试 createTime 不匹配 - seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setCreateTime(null))); - // 准备参数 -// SeckillActivityExportReqVO reqVO = new SeckillActivityExportReqVO(); -// reqVO.setName(null); -// reqVO.setStatus(null); -// reqVO.setTimeId(null); -// reqVO.setCreateTime((new Date[]{})); -// -// // 调用 -// List list = seckillActivityService.getSeckillActivityList(reqVO); -// // 断言 -// assertEquals(1, list.size()); -// assertPojoEquals(dbSeckillActivity, list.get(0)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java deleted file mode 100644 index e61023c66..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java +++ /dev/null @@ -1,189 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.seckilltime; - -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; -import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeServiceImpl; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import javax.annotation.Resource; - -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; - -import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime.SeckillTimeMapper; - -import org.springframework.context.annotation.Import; - -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; -import static org.junit.jupiter.api.Assertions.*; - -/** -* {@link SeckillTimeServiceImpl} 的单元测试类 -* -* @author 芋道源码 -*/ -@Import(SeckillTimeServiceImpl.class) -public class SeckillTimeServiceImplTest extends BaseDbUnitTest { - - @Resource - private SeckillTimeServiceImpl seckillTimeService; - - @Resource - private SeckillTimeMapper seckillTimeMapper; - - @Resource - private ObjectMapper objectMapper; - - @Test - public void testJacksonSerializ(){ - - // 准备参数 - SeckillTimeCreateReqVO reqVO = randomPojo(SeckillTimeCreateReqVO.class); -// ObjectMapper objectMapper = new ObjectMapper(); - try { - String string = objectMapper.writeValueAsString(reqVO); - System.out.println(string); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - - - } - - @Test - public void testCreateSeckillTime_success() { - // 准备参数 - SeckillTimeCreateReqVO reqVO = randomPojo(SeckillTimeCreateReqVO.class); - - // 调用 - Long seckillTimeId = seckillTimeService.createSeckillTime(reqVO); - // 断言 - assertNotNull(seckillTimeId); - // 校验记录的属性是否正确 - SeckillTimeDO seckillTime = seckillTimeMapper.selectById(seckillTimeId); - assertPojoEquals(reqVO, seckillTime); - } - - @Test - public void testUpdateSeckillTime_success() { - // mock 数据 - SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class); - seckillTimeMapper.insert(dbSeckillTime);// @Sql: 先插入出一条存在的数据 - // 准备参数 - SeckillTimeUpdateReqVO reqVO = randomPojo(SeckillTimeUpdateReqVO.class, o -> { - o.setId(dbSeckillTime.getId()); // 设置更新的 ID - }); - - // 调用 - seckillTimeService.updateSeckillTime(reqVO); - // 校验是否更新正确 - SeckillTimeDO seckillTime = seckillTimeMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, seckillTime); - } - - @Test - public void testUpdateSeckillTime_notExists() { - // 准备参数 - SeckillTimeUpdateReqVO reqVO = randomPojo(SeckillTimeUpdateReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> seckillTimeService.updateSeckillTime(reqVO), SECKILL_TIME_NOT_EXISTS); - } - - @Test - public void testDeleteSeckillTime_success() { - // mock 数据 - SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class); - seckillTimeMapper.insert(dbSeckillTime);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbSeckillTime.getId(); - - // 调用 - seckillTimeService.deleteSeckillTime(id); - // 校验数据不存在了 - assertNull(seckillTimeMapper.selectById(id)); - } - - @Test - public void testDeleteSeckillTime_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> seckillTimeService.deleteSeckillTime(id), SECKILL_TIME_NOT_EXISTS); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetSeckillTimePage() { - // mock 数据 -// SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class, o -> { // 等会查询到 -// o.setName(null); -// o.setStartTime(null); -// o.setEndTime(null); -// o.setCreateTime(null); -// }); -// seckillTimeMapper.insert(dbSeckillTime); -// // 测试 name 不匹配 -// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setName(null))); -// // 测试 startTime 不匹配 -// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setStartTime(null))); -// // 测试 endTime 不匹配 -// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setEndTime(null))); -// // 测试 createTime 不匹配 -// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setCreateTime(null))); -// // 准备参数 -// SeckillTimePageReqVO reqVO = new SeckillTimePageReqVO(); -// reqVO.setName(null); -//// reqVO.setStartTime((new LocalTime())); -//// reqVO.setEndTime((new LocalTime[]{})); -//// reqVO.setCreateTime((new Date[]{})); -// -// // 调用 -// PageResult pageResult = seckillTimeService.getSeckillTimePage(reqVO); -// // 断言 -// assertEquals(1, pageResult.getTotal()); -// assertEquals(1, pageResult.getList().size()); -// assertPojoEquals(dbSeckillTime, pageResult.getList().get(0)); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetSeckillTimeList() { - // mock 数据 - SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class, o -> { // 等会查询到 - o.setName(null); - o.setStartTime(null); - o.setEndTime(null); - o.setCreateTime(null); - }); - seckillTimeMapper.insert(dbSeckillTime); - // 测试 name 不匹配 - seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setName(null))); - // 测试 startTime 不匹配 - seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setStartTime(null))); - // 测试 endTime 不匹配 - seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setEndTime(null))); - // 测试 createTime 不匹配 - seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setCreateTime(null))); - // 准备参数 -// SeckillTimeExportReqVO reqVO = new SeckillTimeExportReqVO(); -// reqVO.setName(null); -// reqVO.setStartTime((new LocalTime[]{})); -// reqVO.setEndTime((new LocalTime[]{})); -// reqVO.setCreateTime((new Date[]{})); -// -// // 调用 -// List list = seckillTimeService.getSeckillTimeList(reqVO); -// // 断言 -// assertEquals(1, list.size()); -// assertPojoEquals(dbSeckillTime, list.get(0)); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index a384353aa..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,49 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - -# Resilience4j 配置项 - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao.module diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml deleted file mode 100644 index daf756bff..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql deleted file mode 100644 index d3f8e3718..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql +++ /dev/null @@ -1,6 +0,0 @@ -DELETE FROM "market_activity"; -DELETE FROM "promotion_coupon_template"; -DELETE FROM "promotion_coupon"; -DELETE FROM "promotion_reward_activity"; -DELETE FROM "promotion_discount_activity"; -DELETE FROM "promotion_discount_product"; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql deleted file mode 100644 index 7ff1a7239..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql +++ /dev/null @@ -1,124 +0,0 @@ -CREATE TABLE IF NOT EXISTS "market_activity" ( - "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "title" varchar(50) NOT NULL, - "activity_type" tinyint(4) NOT NULL, - "status" tinyint(4) NOT NULL, - "start_time" datetime NOT NULL, - "end_time" datetime NOT NULL, - "invalid_time" datetime, - "delete_time" datetime, - "time_limited_discount" varchar(2000), - "full_privilege" varchar(2000), - "creator" varchar(64) DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint(20) NOT NULL, - PRIMARY KEY ("id") - ) COMMENT '促销活动'; - -CREATE TABLE IF NOT EXISTS "promotion_coupon_template" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar NOT NULL, - "status" int NOT NULL, - "total_count" int NOT NULL, - "take_limit_count" int NOT NULL, - "take_type" int NOT NULL, - "use_price" int NOT NULL, - "product_scope" int NOT NULL, - "product_spu_ids" varchar, - "validity_type" int NOT NULL, - "valid_start_time" datetime, - "valid_end_time" datetime, - "fixed_start_term" int, - "fixed_end_term" int, - "discount_type" int NOT NULL, - "discount_percent" int, - "discount_price" int, - "discount_limit_price" int, - "take_count" int NOT NULL DEFAULT 0, - "use_count" int NOT NULL DEFAULT 0, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '优惠劵模板'; - -CREATE TABLE IF NOT EXISTS "promotion_coupon" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "template_id" bigint NOT NULL, - "name" varchar NOT NULL, - "status" int NOT NULL, - "user_id" bigint NOT NULL, - "take_type" int NOT NULL, - "useprice" int NOT NULL, - "valid_start_time" datetime NOT NULL, - "valid_end_time" datetime NOT NULL, - "product_scope" int NOT NULL, - "product_spu_ids" varchar, - "discount_type" int NOT NULL, - "discount_percent" int, - "discount_price" int, - "discount_limit_price" int, - "use_order_id" bigint, - "use_time" datetime, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '优惠劵'; - -CREATE TABLE IF NOT EXISTS "promotion_reward_activity" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar NOT NULL, - "status" int NOT NULL, - "start_time" datetime NOT NULL, - "end_time" datetime NOT NULL, - "remark" varchar, - "condition_type" int NOT NULL, - "product_scope" int NOT NULL, - "product_spu_ids" varchar, - "rules" varchar, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '满减送活动'; - -CREATE TABLE IF NOT EXISTS "promotion_discount_activity" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "name" varchar NOT NULL, - "status" int NOT NULL, - "start_time" datetime NOT NULL, - "end_time" datetime NOT NULL, - "remark" varchar, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '限时折扣活动'; - -CREATE TABLE IF NOT EXISTS "promotion_discount_product" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "activity_id" bigint NOT NULL, - "spu_id" bigint NOT NULL, - "sku_id" bigint NOT NULL, - "discount_type" int NOT NULL, - "discount_percent" int, - "discount_price" int, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '限时折扣活动'; diff --git a/yudao-module-mall/yudao-module-trade-api/pom.xml b/yudao-module-mall/yudao-module-trade-api/pom.xml deleted file mode 100644 index 1299ad11d..000000000 --- a/yudao-module-mall/yudao-module-trade-api/pom.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - cn.iocoder.boot - yudao-module-mall - ${revision} - - 4.0.0 - yudao-module-trade-api - jar - - ${project.artifactId} - - trade 模块 API,暴露给其它模块调用 - - - - - cn.iocoder.boot - yudao-common - - - - diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java deleted file mode 100644 index af387ab85..000000000 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.yudao.module.trade.enums; - -import cn.iocoder.yudao.framework.common.exception.ErrorCode; - -/** - * 交易 错误码枚举类 - * 交易系统,使用 1-011-000-000 段 - * - * @author LeeYan9 - * @since 2022-08-26 - */ -public interface ErrorCodeConstants { - - // ========== Order 模块 1-011-000-000 ========== - ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1011000001, "商品 SKU 不存在"); - ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1011000002, "商品 SPU 不可售卖"); - ErrorCode ORDER_CREATE_SKU_NOT_SALE = new ErrorCode(1011000003, "商品 SKU 不可售卖"); - ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1011000004, "商品 SKU 库存不足"); - ErrorCode ORDER_CREATE_SPU_NOT_FOUND = new ErrorCode(1011000005, "商品 SPU 不可售卖"); - ErrorCode ORDER_CREATE_ADDRESS_NOT_FOUND = new ErrorCode(1011000006, "收货地址不存在"); - - ErrorCode ORDER_ITEM_NOT_FOUND = new ErrorCode(1011000010, "交易订单项不存在"); - ErrorCode ORDER_NOT_FOUND = new ErrorCode(1011000011, "交易订单不存在"); - ErrorCode ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL = new ErrorCode(1011000012, "交易订单项更新售后状态失败,请重试"); - ErrorCode ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1011000013, "交易订单更新支付状态失败,订单不是【未支付】状态"); - ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(1011000014, "交易订单更新支付状态失败,支付单编号不匹配"); - ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1011000015, "交易订单更新支付状态失败,支付单状态不是【支付成功】状态"); - ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1011000016, "交易订单更新支付状态失败,支付单金额不匹配"); - ErrorCode ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED = new ErrorCode(1011000017, "交易订单发货失败,订单不是【待发货】状态"); - ErrorCode ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1011000018, "交易订单收货失败,订单不是【待收货】状态"); - - // ========== After Sale 模块 1-011-000-000 ========== - ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在"); - ErrorCode AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR = new ErrorCode(1011000101, "申请退款金额错误"); - ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_CANCELED = new ErrorCode(1011000102, "订单已关闭,无法申请售后"); - ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_PAID = new ErrorCode(1011000103, "订单未支付,无法申请售后"); - ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED = new ErrorCode(1011000104, "订单未发货,无法申请【退货退款】售后"); - ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_ITEM_APPLIED = new ErrorCode(1011000105, "订单项已申请售后,无法重复申请"); - ErrorCode AFTER_SALE_AUDIT_FAIL_STATUS_NOT_APPLY = new ErrorCode(1011000106, "审批失败,售后状态不处于审批中"); - ErrorCode AFTER_SALE_UPDATE_STATUS_FAIL = new ErrorCode(1011000107, "操作售后单失败,请刷新后重试"); - ErrorCode AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE = new ErrorCode(1011000108, "退货失败,售后单状态不处于【待买家退货】"); - ErrorCode AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY = new ErrorCode(1011000109, "确认收货失败,售后单状态不处于【待确认收货】"); - ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1011000110, "退款失败,售后单状态不是【待退款】"); - ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE = new ErrorCode(1011000111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】"); - - // ========== Cart 模块 1-011-001-000 ========== - ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在"); - -} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java deleted file mode 100644 index 88ea5230c..000000000 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java +++ /dev/null @@ -1,67 +0,0 @@ -package cn.iocoder.yudao.module.trade.enums.aftersale; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -import static cn.hutool.core.util.ArrayUtil.firstMatch; - -/** - * 售后状态的枚举 - * - * 状态流转 - * - * @author 芋道源码 - */ -@AllArgsConstructor -@Getter -public enum TradeAfterSaleStatusEnum implements IntArrayValuable { - - APPLY(10,"申请中", // 【申请售后】 - "会员申请退款"), - SELLER_AGREE(20, "卖家通过", // 卖家通过售后;【商品待退货】 - "商家同意退款"), - BUYER_DELIVERY(30,"待卖家收货", // 买家已退货,等待卖家收货;【商家待收货】 - "会员填写退货物流信息"), - WAIT_REFUND(40, "等待平台退款", // 卖家已收货,等待平台退款;等待退款【等待退款】 - "商家收货"), - COMPLETE(50, "完成", // 完成退款【退款成功】 - "商家确认退款"), - - BUYER_CANCEL(61, "买家取消售后", // 【买家取消】 - "会员取消退款"), - SELLER_DISAGREE(62,"卖家拒绝", // 卖家拒绝售后;商家拒绝【商家拒绝】 - "商家拒绝退款"), - SELLER_REFUSE(63,"卖家拒绝收货", // 卖家拒绝收货,终止售后;【商家拒收货】 - "商家拒绝收货"), - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray(); - - /** - * 状态 - */ - private final Integer status; - /** - * 状态名 - */ - private final String name; - /** - * 操作内容 - * - * 目的:记录售后日志的内容 - */ - private final String content; - - @Override - public int[] array() { - return ARRAYS; - } - - public static TradeAfterSaleStatusEnum valueOf(Integer status) { - return firstMatch(value -> value.getStatus().equals(status), values()); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleTypeEnum.java deleted file mode 100644 index d5323aac8..000000000 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleTypeEnum.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.trade.enums.aftersale; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.util.Arrays; - -/** - * 交易售后 - 类型 - * - * @author 芋道源码 - */ -@RequiredArgsConstructor -@Getter -public enum TradeAfterSaleTypeEnum implements IntArrayValuable { - - IN_SALE(10, "售中退款"), // 交易完成前买家申请退款 - AFTER_SALE(20, "售后退款"); // 交易完成后买家申请退款 - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleTypeEnum::getType).toArray(); - - /** - * 类型 - */ - private final Integer type; - /** - * 类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleWayEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleWayEnum.java deleted file mode 100644 index 1bbb35327..000000000 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleWayEnum.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.trade.enums.aftersale; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.util.Arrays; - -/** - * 交易售后 - 方式 - * - * @author Sin - */ -@RequiredArgsConstructor -@Getter -public enum TradeAfterSaleWayEnum implements IntArrayValuable { - - REFUND(10, "仅退款"), - RETURN_AND_REFUND(20, "退货退款"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleWayEnum::getWay).toArray(); - - /** - * 方式 - */ - private final Integer way; - /** - * 方式名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java deleted file mode 100644 index 40402b6f8..000000000 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.trade.enums.order; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.util.Arrays; - -/** - * 交易订单 - 售后状态 - * - * @author Sin - */ -@RequiredArgsConstructor -@Getter -public enum TradeOrderAfterSaleStatusEnum implements IntArrayValuable { - - NONE(0, "未退款"), - PART(1, "部分退款"), - ALL(2, "全部退款"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderAfterSaleStatusEnum::getStatus).toArray(); - - /** - * 状态值 - */ - private final Integer status; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java deleted file mode 100644 index 1dabec194..000000000 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.trade.enums.order; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.util.Arrays; - -/** - * 交易订单 - 关闭类型 - * - * @author Sin - */ -@RequiredArgsConstructor -@Getter -public enum TradeOrderCancelTypeEnum implements IntArrayValuable { - - PAY_TIMEOUT(10, "超时未支付"), - AFTER_SALE_CLOSE(20, "退款关闭"), - MEMBER_CANCEL(30, "买家取消"), - PAY_ON_DELIVERY(40, "已通过货到付款交易"),; // TODO 芋艿:这个类型,是不是可以去掉 - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderCancelTypeEnum::getType).toArray(); - - /** - * 关闭类型 - */ - private final Integer type; - /** - * 关闭类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java deleted file mode 100644 index 27b061e37..000000000 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.module.trade.enums.order; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -/** - * 交易订单 - 发货状态 - * - * @author 芋道源码 - */ -@RequiredArgsConstructor -@Getter -public enum TradeOrderDeliveryStatusEnum { - - UNDELIVERED(0, "未发货"), - DELIVERED(1, "已发货"), - RECEIVED(2, "已收货"); - - /** - * 状态值 - */ - private final Integer status; - /** - * 状态名 - */ - private final String name; - -} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java deleted file mode 100644 index c4fc8a373..000000000 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java +++ /dev/null @@ -1,52 +0,0 @@ -package cn.iocoder.yudao.module.trade.enums.order; - -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.util.Arrays; - -/** - * 交易订单项 - 售后状态 - * - * @author 芋道源码 - */ -@RequiredArgsConstructor -@Getter -public enum TradeOrderItemAfterSaleStatusEnum implements IntArrayValuable { - - NONE(0, "未售后"), - APPLY(1, "售后中"), - SUCCESS(2, "已退款"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderItemAfterSaleStatusEnum::getStatus).toArray(); - - /** - * 状态值 - */ - private final Integer status; - /** - * 状态名 - */ - private final String name; - - // TODO 芋艿:EXPIRED 已失效不允许申请售后 - // TODO 芋艿:PART_AFTER_SALE 部分售后 - - @Override - public int[] array() { - return ARRAYS; - } - - /** - * 判断指定状态,是否正处于【未申请】状态 - * - * @param status 指定状态 - * @return 是否 - */ - public static boolean isNone(Integer status) { - return ObjectUtil.equals(status, NONE.getStatus()); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java deleted file mode 100644 index 06fc3821e..000000000 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java +++ /dev/null @@ -1,118 +0,0 @@ -package cn.iocoder.yudao.module.trade.enums.order; - -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.util.Arrays; - -/** - * 交易订单 - 状态 - * - * @author Sin - */ -@RequiredArgsConstructor -@Getter -public enum TradeOrderStatusEnum implements IntArrayValuable { - - UNPAID(0, "待支付"), - UNDELIVERED(10, "待发货"), - DELIVERED(20, "已发货"), - COMPLETED(30, "已完成"), - CANCELED(40, "已取消"); - - // TODO 芋艿: TAKE("待核验"):虚拟订单需要核验商品 - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderStatusEnum::getStatus).toArray(); - - /** - * 状态值 - */ - private final Integer status; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - - // ========== 问:为什么写了很多 isXXX 和 haveXXX 的判断逻辑呢? ========== - // ========== 答:方便找到某一类判断,哪些业务正在使用 ========== - - /** - * 判断指定状态,是否正处于【未付款】状态 - * - * @param status 指定状态 - * @return 是否 - */ - public static boolean isUnpaid(Integer status) { - return ObjectUtil.equal(UNPAID.getStatus(), status); - } - - /** - * 判断指定状态,是否正处于【待发货】状态 - * - * @param status 指定状态 - * @return 是否 - */ - public static boolean isUndelivered(Integer status) { - return ObjectUtil.equal(UNDELIVERED.getStatus(), status); - } - - /** - * 判断指定状态,是否正处于【已发货】状态 - * - * @param status 指定状态 - * @return 是否 - */ - public static boolean isDelivered(Integer status) { - return ObjectUtil.equals(status, DELIVERED.getStatus()); - } - - /** - * 判断指定状态,是否正处于【已取消】状态 - * - * @param status 指定状态 - * @return 是否 - */ - public static boolean isCanceled(Integer status) { - return ObjectUtil.equals(status, CANCELED.getStatus()); - } - - /** - * 判断指定状态,是否正处于【已完成】状态 - * - * @param status 指定状态 - * @return 是否 - */ - public static boolean isCompleted(Integer status) { - return ObjectUtil.equals(status, COMPLETED.getStatus()); - } - - /** - * 判断指定状态,是否有过【已付款】状态 - * - * @param status 指定状态 - * @return 是否 - */ - public static boolean havePaid(Integer status) { - return ObjectUtils.equalsAny(status, UNDELIVERED.getStatus(), - DELIVERED.getStatus(), COMPLETED.getStatus()); - } - - /** - * 判断指定状态,是否有过【已发货】状态 - * - * @param status 指定状态 - * @return 是否 - */ - public static boolean haveDelivered(Integer status) { - return ObjectUtils.equalsAny(status, DELIVERED.getStatus(), COMPLETED.getStatus()); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java deleted file mode 100644 index c8001b490..000000000 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.trade.enums.order; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.util.Arrays; - -/** - * 交易订单 - 类型 - * - * @author Sin - */ -@RequiredArgsConstructor -@Getter -public enum TradeOrderTypeEnum implements IntArrayValuable { - - NORMAL(0, "普通订单"), - SECKILL(1, "秒杀订单"), - TEAM(2, "拼团订单"), - BARGAIN(3, "砍价订单"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderTypeEnum::getType).toArray(); - - /** - * 类型 - */ - private final Integer type; - /** - * 类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/pom.xml b/yudao-module-mall/yudao-module-trade-biz/pom.xml deleted file mode 100644 index 4eb0164d4..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/pom.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - cn.iocoder.boot - yudao-module-mall - ${revision} - - 4.0.0 - yudao-module-trade-biz - jar - - ${project.artifactId} - - trade 模块,主要实现交易相关功能 - 例如:订单、退款、购物车等功能。 - - - - - cn.iocoder.boot - yudao-module-trade-api - ${revision} - - - - cn.iocoder.boot - yudao-module-product-api - ${revision} - - - cn.iocoder.boot - yudao-module-pay-api - ${revision} - - - cn.iocoder.boot - yudao-module-promotion-api - ${revision} - - - cn.iocoder.boot - yudao-module-member-api - ${revision} - - - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-operatelog - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-ip - - - - - cn.iocoder.boot - yudao-spring-boot-starter-web - - - - cn.iocoder.boot - yudao-spring-boot-starter-security - - - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-pay - - - - - cn.iocoder.boot - yudao-spring-boot-starter-mybatis - - - - - cn.iocoder.boot - yudao-spring-boot-starter-test - - - - - cn.iocoder.boot - yudao-spring-boot-starter-excel - - - - diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http deleted file mode 100644 index d1a2acaf7..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http +++ /dev/null @@ -1,4 +0,0 @@ -### 获得交易售后分页 => 成功 -GET {{baseUrl}}/trade/after-sale/page?pageNo=1&pageSize=10 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java deleted file mode 100644 index f2c7b1cc1..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java +++ /dev/null @@ -1,113 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.aftersale; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO; -import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; -import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; -import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; - -@Api(tags = "管理后台 - 交易售后") -@RestController -@RequestMapping("/trade/after-sale") -@Validated -@Slf4j -public class TradeAfterSaleController { - - @Resource - private TradeAfterSaleService afterSaleService; - - @Resource - private MemberUserApi memberUserApi; - @Resource - private ProductPropertyValueApi productPropertyValueApi; - - @GetMapping("/page") - @ApiOperation("获得交易售后分页") - @PreAuthorize("@ss.hasPermission('trade:after-sale:query')") - public CommonResult> getAfterSalePage(@Valid TradeAfterSalePageReqVO pageVO) { - // 查询售后 - PageResult pageResult = afterSaleService.getAfterSalePage(pageVO); - if (CollUtil.isEmpty(pageResult.getList())) { - return success(PageResult.empty()); - } - - // 查询商品属性 - List propertyValueDetails = productPropertyValueApi - .getPropertyValueDetailList(TradeAfterSaleConvert.INSTANCE.convertPropertyValueIds(pageResult.getList())); - // 查询会员 - Map memberUsers = memberUserApi.getUserMap( - convertSet(pageResult.getList(), TradeAfterSaleDO::getUserId)); - return success(TradeAfterSaleConvert.INSTANCE.convertPage(pageResult, memberUsers, propertyValueDetails)); - } - - @PutMapping("/agree") - @ApiOperation("同意售后") - @ApiImplicitParam(name = "id", value = "售后编号", required = true, example = "1") - @PreAuthorize("@ss.hasPermission('trade:after-sale:agree')") - public CommonResult agreeAfterSale(@RequestParam("id") Long id) { - afterSaleService.agreeAfterSale(getLoginUserId(), id); - return success(true); - } - - @PutMapping("/disagree") - @ApiOperation("拒绝售后") - @PreAuthorize("@ss.hasPermission('trade:after-sale:disagree')") - public CommonResult disagreeAfterSale(@RequestBody TradeAfterSaleDisagreeReqVO confirmReqVO) { - afterSaleService.disagreeAfterSale(getLoginUserId(), confirmReqVO); - return success(true); - } - - @PutMapping("/receive") - @ApiOperation("确认收货") - @ApiImplicitParam(name = "id", value = "售后编号", required = true, example = "1") - @PreAuthorize("@ss.hasPermission('trade:after-sale:receive')") - public CommonResult receiveAfterSale(@RequestParam("id") Long id) { - afterSaleService.receiveAfterSale(getLoginUserId(), id); - return success(true); - } - - @PutMapping("/refuse") - @ApiOperation("确认收货") - @ApiImplicitParam(name = "id", value = "售后编号", required = true, example = "1") - @PreAuthorize("@ss.hasPermission('trade:after-sale:receive')") - public CommonResult refuseAfterSale(TradeAfterSaleRefuseReqVO refuseReqVO) { - afterSaleService.refuseAfterSale(getLoginUserId(), refuseReqVO); - return success(true); - } - - @PostMapping("/refund") - @ApiOperation(value = "确认退款") - @ApiImplicitParam(name = "id", value = "售后编号", required = true, example = "1") - @PreAuthorize("@ss.hasPermission('trade:after-sale:refund')") - public CommonResult refundAfterSale(@RequestParam("id") Long id) { - afterSaleService.refundAfterSale(getLoginUserId(), getClientIP(), id); - return success(true); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java deleted file mode 100644 index 4277fadd3..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java +++ /dev/null @@ -1,119 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -/** -* 交易售后 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class TradeAfterSaleBaseVO { - - @ApiModelProperty(value = "售后流水号", required = true, example = "202211190847450020500077") - @NotNull(message = "售后流水号不能为空") - private String no; - - @ApiModelProperty(value = "售后状态", required = true, example = "10", notes = "参见 TradeAfterSaleStatusEnum 枚举") - @NotNull(message = "售后状态不能为空") - private Integer status; - - @ApiModelProperty(value = "售后类型", required = true, example = "20", notes = "参见 TradeAfterSaleTypeEnum 枚举") - @NotNull(message = "售后类型不能为空") - private Integer type; - - @ApiModelProperty(value = "售后方式", required = true, example = "10", notes = "参见 TradeAfterSaleWayEnum 枚举") - @NotNull(message = "售后方式不能为空") - private Integer way; - - @ApiModelProperty(value = "用户编号", required = true, example = "30337") - @NotNull(message = "用户编号不能为空") - private Long userId; - - @ApiModelProperty(value = "申请原因", required = true, example = "不喜欢") - @NotNull(message = "申请原因不能为空") - private String applyReason; - - @ApiModelProperty(value = "补充描述", example = "你说的对") - private String applyDescription; - - @ApiModelProperty(value = "补充凭证图片", example = "https://www.iocoder.cn/1.png") - private List applyPicUrls; - - @ApiModelProperty(value = "订单编号", required = true, example = "18078") - @NotNull(message = "订单编号不能为空") - private Long orderId; - - @ApiModelProperty(value = "订单流水号", required = true, example = "2022111917190001") - @NotNull(message = "订单流水号不能为空") - private Long orderNo; - - @ApiModelProperty(value = "订单项编号", required = true, example = "572") - @NotNull(message = "订单项编号不能为空") - private Long orderItemId; - - @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "2888") - @NotNull(message = "商品 SPU 编号不能为空") - private Long spuId; - - @ApiModelProperty(value = "商品 SPU 名称", required = true, example = "李四") - @NotNull(message = "商品 SPU 名称不能为空") - private String spuName; - - @ApiModelProperty(value = "商品 SKU 编号", required = true, example = "15657") - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - @ApiModelProperty(value = "商品图片", example = "https://www.iocoder.cn/2.png") - private String picUrl; - - @ApiModelProperty(value = "购买数量", required = true, example = "20012") - @NotNull(message = "购买数量不能为空") - private Integer count; - - @ApiModelProperty(value = "审批时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime auditTime; - - @ApiModelProperty(value = "审批人", example = "30835") - private Long auditUserId; - - @ApiModelProperty(value = "审批备注", example = "不香") - private String auditReason; - - @ApiModelProperty(value = "退款金额,单位:分", required = true, example = "18077") - @NotNull(message = "退款金额,单位:分不能为空") - private Integer refundPrice; - - @ApiModelProperty(value = "支付退款编号", example = "10271") - private Long payRefundId; - - @ApiModelProperty(value = "退款时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime refundTime; - - @ApiModelProperty(value = "退货物流公司编号", example = "10") - private Long logisticsId; - - @ApiModelProperty(value = "退货物流单号", example = "610003952009") - private String logisticsNo; - - @ApiModelProperty(value = "退货时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime deliveryTime; - - @ApiModelProperty(value = "收货时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime receiveTime; - - @ApiModelProperty(value = "收货备注", example = "不喜欢") - private String receiveReason; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDisagreeReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDisagreeReqVO.java deleted file mode 100644 index 67baca3b7..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDisagreeReqVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -@ApiModel("管理后台 - 交易售后拒绝 Request VO") -@Data -public class TradeAfterSaleDisagreeReqVO { - - @ApiModelProperty(value = "售后编号", required = true, example = "1024") - @NotNull(message = "售后编号不能为空") - private Long id; - - @ApiModelProperty(value = "审批备注", required = true, example = "你猜") - @NotEmpty(message = "审批备注不能为空") - private String auditReason; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java deleted file mode 100644 index 628b8bc56..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel("管理后台 - 交易售后分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class TradeAfterSalePageReqVO extends PageParam { - - @ApiModelProperty(value = "售后流水号", example = "202211190847450020500077", notes = "模糊匹配") - private String no; - - @ApiModelProperty(value = "售后状态", example = "10", notes = "参见 TradeAfterSaleStatusEnum 枚举") - @InEnum(value = TradeAfterSaleStatusEnum.class, message = "售后状态必须是 {value}") - private Integer status; - - @ApiModelProperty(value = "售后类型", example = "20", notes = "参见 TradeAfterSaleTypeEnum 枚举") - @InEnum(value = TradeAfterSaleTypeEnum.class, message = "售后类型必须是 {value}") - private Integer type; - - @ApiModelProperty(value = "售后方式", example = "10", notes = "参见 TradeAfterSaleWayEnum 枚举") - @InEnum(value = TradeAfterSaleWayEnum.class, message = "售后方式必须是 {value}") - private Integer way; - - @ApiModelProperty(value = "订单编号", example = "18078", notes = "模糊匹配") - private String orderNo; - - @ApiModelProperty(value = "商品 SPU 名称", example = "李四", notes = "模糊匹配") - private String spuName; - - @ApiModelProperty(value = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRefuseReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRefuseReqVO.java deleted file mode 100644 index b74d73c7c..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRefuseReqVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotNull; - -@ApiModel("管理后台 - 交易售后拒绝收货 Request VO") -@Data -public class TradeAfterSaleRefuseReqVO { - - @ApiModelProperty(value = "售后编号", required = true, example = "1024") - @NotNull(message = "售后编号不能为空") - private Long id; - - @ApiModelProperty(value = "收货备注", required = true, example = "你猜") - @NotNull(message = "收货备注不能为空") - private String refuseMemo; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespPageItemVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespPageItemVO.java deleted file mode 100644 index f57676bdc..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespPageItemVO.java +++ /dev/null @@ -1,36 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; - -import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; -import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.time.LocalDateTime; -import java.util.List; - -@ApiModel("管理后台 - 交易售后分页的每一条记录 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class TradeAfterSaleRespPageItemVO extends TradeAfterSaleBaseVO { - - @ApiModelProperty(value = "售后编号", required = true, example = "27630") - private Long id; - - @ApiModelProperty(value = "创建时间", required = true) - private LocalDateTime createTime; - - /** - * 商品属性数组 - */ - private List properties; - - /** - * 用户信息 - */ - private MemberUserRespVO user; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/TradeAfterSaleLogRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/TradeAfterSaleLogRespVO.java deleted file mode 100644 index 990182499..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/TradeAfterSaleLogRespVO.java +++ /dev/null @@ -1,51 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; - -@ApiModel("管理后台 - 交易售后日志 Response VO") -@Data -public class TradeAfterSaleLogRespVO { - - @ApiModelProperty(value = "编号", required = true, example = "20669") - private Long id; - - @ApiModelProperty(value = "用户编号", required = true, example = "22634") - @NotNull(message = "用户编号不能为空") - private Long userId; - - @ApiModelProperty(value = "用户类型", required = true, example = "2") - @NotNull(message = "用户类型不能为空") - private Integer userType; - - @ApiModelProperty(value = "售后编号", required = true, example = "3023") - @NotNull(message = "售后编号不能为空") - private Long afterSaleId; - - @ApiModelProperty(value = "订单编号", required = true, example = "25870") - @NotNull(message = "订单编号不能为空") - private Long orderId; - - @ApiModelProperty(value = "订单项编号", required = true, example = "23154") - @NotNull(message = "订单项编号不能为空") - private Long orderItemId; - - @ApiModelProperty(value = "售后状态(之前)", example = "2", notes = "参见 TradeAfterSaleStatusEnum 枚举") - private Integer beforeStatus; - - @ApiModelProperty(value = "售后状态(之后)", required = true, example = "1", notes = "参见 TradeAfterSaleStatusEnum 枚举") - @NotNull(message = "售后状态(之后)不能为空") - private Integer afterStatus; - - @ApiModelProperty(value = "操作明细", required = true, example = "维权完成,退款金额:¥37776.00") - @NotNull(message = "操作明细不能为空") - private String content; - - @ApiModelProperty(value = "创建时间", required = true) - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/package-info.java deleted file mode 100644 index f874e482d..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 占位符,可忽略 - */ -package cn.iocoder.yudao.module.trade.controller.admin.base.member; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/user/MemberUserRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/user/MemberUserRespVO.java deleted file mode 100644 index 4f3545a91..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/user/MemberUserRespVO.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.base.member.user; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -@ApiModel("管理后台 - 会员用户 Response VO") -@Data -public class MemberUserRespVO { - - @ApiModelProperty(value = "用户 ID", required = true, example = "1") - private Long id; - - @ApiModelProperty(value = "用户昵称", required = true, example = "芋道源码") - private String nickname; - - @ApiModelProperty(value = "用户头像", example = "https://www.iocoder.cn/xxx.png") - private String avatar; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java deleted file mode 100644 index 0baa83e49..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 放置该模块通用的 VO 类 - */ -package cn.iocoder.yudao.module.trade.controller.admin.base; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/product/property/ProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/product/property/ProductPropertyValueDetailRespVO.java deleted file mode 100644 index b9978770c..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/product/property/ProductPropertyValueDetailRespVO.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.base.product.property; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -@ApiModel("管理后台 - 商品属性值的明细 Response VO") -@Data -public class ProductPropertyValueDetailRespVO { - - @ApiModelProperty(value = "属性的编号", required = true, example = "1") - private Long propertyId; - - @ApiModelProperty(value = "属性的名称", required = true, example = "颜色") - private String propertyName; - - @ApiModelProperty(value = "属性值的编号", required = true, example = "1024") - private Long valueId; - - @ApiModelProperty(value = "属性值的名称", required = true, example = "红色") - private String valueName; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.http deleted file mode 100644 index 0bf8812b2..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.http +++ /dev/null @@ -1,9 +0,0 @@ -### 获得交易订单分页 => 成功 -GET {{baseUrl}}/trade/order/page?pageNo=1&pageSize=10 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -### 获得交易订单分页 => 成功 -GET {{baseUrl}}/trade/order/get-detail?id=21 -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java deleted file mode 100644 index 58f3bf318..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java +++ /dev/null @@ -1,93 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.order; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; - -@Api(tags = "管理后台 - 交易订单") -@RestController -@RequestMapping("/trade/order") -@Validated -@Slf4j -public class TradeOrderController { - - @Resource - private TradeOrderService tradeOrderService; - - @Resource - private ProductPropertyValueApi productPropertyValueApi; - @Resource - private MemberUserApi memberUserApi; - - @GetMapping("/page") - @ApiOperation("获得交易订单分页") - @PreAuthorize("@ss.hasPermission('trade:order:query')") - public CommonResult> getOrderPage(TradeOrderPageReqVO reqVO) { - // 查询订单 - PageResult pageResult = tradeOrderService.getOrderPage(reqVO); - if (CollUtil.isEmpty(pageResult.getList())) { - return success(PageResult.empty()); - } - // 查询订单项 - List orderItems = tradeOrderService.getOrderItemListByOrderId( - convertSet(pageResult.getList(), TradeOrderDO::getId)); - // 查询商品属性 - List propertyValueDetails = productPropertyValueApi - .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); - // 最终组合 - return success(TradeOrderConvert.INSTANCE.convertPage(pageResult, orderItems, propertyValueDetails)); - } - - @GetMapping("/get-detail") - @ApiOperation("获得交易订单详情") - @ApiImplicitParam(name = "id", value = "订单编号", required = true, example = "1") - @PreAuthorize("@ss.hasPermission('trade:order:query')") - public CommonResult getOrderDetail(@RequestParam("id") Long id) { - // 查询订单 - TradeOrderDO order = tradeOrderService.getOrder(id); - // 查询订单项 - List orderItems = tradeOrderService.getOrderItemListByOrderId(id); - // 查询商品属性 - List propertyValueDetails = productPropertyValueApi - .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); - // 查询会员 - MemberUserRespDTO user = memberUserApi.getUser(order.getUserId()); - // 最终组合 - return success(TradeOrderConvert.INSTANCE.convert(order, orderItems, propertyValueDetails, user)); - } - - @PostMapping("/delivery") - @ApiOperation("发货订单") - @PreAuthorize("@ss.hasPermission('trade:order:delivery')") - public CommonResult deliveryOrder(@RequestBody TradeOrderDeliveryReqVO deliveryReqVO) { - tradeOrderService.deliveryOrder(getLoginUserId(), deliveryReqVO); - return success(true); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java deleted file mode 100755 index 1669bc1ff..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java +++ /dev/null @@ -1,145 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.order.vo; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.Date; - -/** -* 交易订单 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class TradeOrderBaseVO { - - // ========== 订单基本信息 ========== - - @ApiModelProperty(value = "订单编号", required = true, example = "1024") - private Long id; - - @ApiModelProperty(value = "订单流水号", required = true, example = "1146347329394184195") - private String no; - - @ApiModelProperty(value = "创建时间", required = true, notes = "下单时间") - private Date createTime; - - @ApiModelProperty(value = "订单类型", required = true, example = "1", notes = "参见 TradeOrderTypeEnum 枚举") - private Integer type; - - @ApiModelProperty(value = "订单来源", required = true, example = "1", notes = "参见 TerminalEnum 枚举") - private Integer terminal; - - @ApiModelProperty(value = "用户编号", required = true, example = "2048") - private Long userId; - - @ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1") - private String userIp; - - @ApiModelProperty(value = "用户备注", required = true, example = "你猜") - private String userRemark; - - @ApiModelProperty(value = "订单状态", required = true, example = "1", notes = "参见 TradeOrderStatusEnum 枚举") - private Integer status; - - @ApiModelProperty(value = "购买的商品数量", required = true, example = "10") - private Integer productCount; - - @ApiModelProperty(value = "订单完成时间") - private LocalDateTime finishTime; - - @ApiModelProperty(value = "订单取消时间") - private LocalDateTime cancelTime; - - @ApiModelProperty(value = "取消类型", example = "10", notes = "参见 TradeOrderCancelTypeEnum 枚举") - private Integer cancelType; - - @ApiModelProperty(value = "商家备注", example = "你猜一下") - private String remark; - - // ========== 价格 + 支付基本信息 ========== - - @ApiModelProperty(value = "支付订单编号", required = true, example = "1024") - private Long payOrderId; - - @ApiModelProperty(value = "是否已支付", required = true, example = "true") - private Boolean payed; - - @ApiModelProperty(value = "付款时间") - private LocalDateTime payTime; - - @ApiModelProperty(value = "支付渠道", required = true, example = "wx_lite", notes = "参见 PayChannelEnum 枚举") - private String payChannelCode; - - @ApiModelProperty(value = "商品原价(总)", required = true, example = "1000", notes = "单位:分") - private Integer originalPrice; - - @ApiModelProperty(value = "订单原价(总)", required = true, example = "1000", notes = "单位:分") - private Integer orderPrice; - - @ApiModelProperty(value = "订单优惠(总)", required = true, example = "100", notes = "单位:分") - private Integer discountPrice; - - @ApiModelProperty(value = "运费金额", required = true, example = "100", notes = "单位:分") - private Integer deliveryPrice; - - @ApiModelProperty(value = "订单调价(总)", required = true, example = "100", notes = "单位:分") - private Integer adjustPrice; - - @ApiModelProperty(value = "应付金额(总)", required = true, example = "1000", notes = "单位:分") - private Integer payPrice; - - // ========== 收件 + 物流基本信息 ========== - - @ApiModelProperty(value = "配送模板编号", example = "1024") - private Long deliveryTemplateId; - - @ApiModelProperty(value = "发货物流公司编号", example = "1024") - private Long logisticsId; - - @ApiModelProperty(value = "发货物流单号", example = "1024") - private String logisticsNo; - - @ApiModelProperty(value = "发货状态", required = true, example = "1", notes = "参见 TradeOrderDeliveryStatusEnum 枚举") - private Integer deliveryStatus; - - @ApiModelProperty(value = "发货时间") - private LocalDateTime deliveryTime; - - @ApiModelProperty(value = "收货时间") - private LocalDateTime receiveTime; - - @ApiModelProperty(value = "收件人名称", required = true, example = "张三") - private String receiverName; - - @ApiModelProperty(value = "收件人手机", required = true, example = "13800138000") - private String receiverMobile; - - @ApiModelProperty(value = "收件人地区编号", required = true, example = "110000") - private Integer receiverAreaId; - - @ApiModelProperty(value = "收件人邮编", required = true, example = "100000") - private Integer receiverPostCode; - - @ApiModelProperty(value = "收件人详细地址", required = true, example = "中关村大街 1 号") - private String receiverDetailAddress; - - // ========== 售后基本信息 ========== - - @ApiModelProperty(value = "售后状态", example = "1", notes = "参见 TradeOrderAfterSaleStatusEnum 枚举") - private Integer afterSaleStatus; - - @ApiModelProperty(value = "退款金额", required = true, example = "100", notes = "单位:分") - private Integer refundPrice; - - // ========== 营销基本信息 ========== - - @ApiModelProperty(value = "优惠劵编号", example = "1024") - private Long couponId; - - @ApiModelProperty(value = "优惠劵减免金额", required = true, example = "100", notes = "单位:分") - private Integer couponPrice; - - @ApiModelProperty(value = "积分抵扣的金额", required = true, example = "100", notes = "单位:分") - private Integer pointPrice; -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java deleted file mode 100644 index e75fcacf2..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.order.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -@ApiModel("管理后台 - 订单发货 Request VO") -@Data -public class TradeOrderDeliveryReqVO { - - @ApiModelProperty(name = "订单编号", required = true, example = "1024") - @NotNull(message = "订单编号不能为空") - private Long id; - - @ApiModelProperty(name = "发货物流公司编号", required = true, example = "1") - @NotNull(message = "发货物流公司编号不能为空") - private Long logisticsId; - - @ApiModelProperty(name = "发货物流单号", required = true, example = "SF123456789") - @NotEmpty(message = "发货物流单号不能为空") - private String logisticsNo; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java deleted file mode 100644 index a5fe26fda..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.order.vo; - -import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; -import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; - -@ApiModel("管理后台 - 交易订单的详情 Response VO") -@Data -public class TradeOrderDetailRespVO extends TradeOrderBaseVO { - - @ApiModelProperty(value = "收件人地区名字", required = true, example = "上海 上海市 普陀区") - private String receiverAreaName; - - /** - * 订单项列表 - */ - private List items; - - /** - * 用户信息 - */ - private MemberUserRespVO user; - - @ApiModel("管理后台 - 交易订单的详情的订单项目") - @Data - public static class Item extends TradeOrderItemBaseVO { - - /** - * 属性数组 - */ - private List properties; - - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java deleted file mode 100644 index 8e55b8ea7..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java +++ /dev/null @@ -1,70 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.order.vo; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -/** - * 交易订单项 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ -@Data -public class TradeOrderItemBaseVO { - - // ========== 订单项基本信息 ========== - - @ApiModelProperty(value = "编号", required = true, example = "1") - private Long id; - - @ApiModelProperty(value = "用户编号", required = true, example = "1") - private Long userId; - - @ApiModelProperty(value = "订单编号", required = true, example = "1") - private Long orderId; - - // ========== 商品基本信息 ========== - - @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") - private Long spuId; - - @ApiModelProperty(value = "商品 SPU 名称", required = true, example = "芋道源码") - private String spuName; - - @ApiModelProperty(value = "商品 SKU 编号", required = true, example = "1") - private Long skuId; - - @ApiModelProperty(value = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") - private String picUrl; - - @ApiModelProperty(value = "购买数量", required = true, example = "1") - private Integer count; - - // ========== 价格 + 支付基本信息 ========== - - @ApiModelProperty(value = "商品原价(总)", required = true, example = "100", notes = "单位:分") - private Integer originalPrice; - - @ApiModelProperty(value = "商品原价(单)", required = true, example = "100", notes = "单位:分") - private Integer originalUnitPrice; - - @ApiModelProperty(value = "商品优惠(总)", required = true, example = "100", notes = "单位:分") - private Integer discountPrice; - - @ApiModelProperty(value = "商品实付金额(总)", required = true, example = "100", notes = "单位:分") - private Integer payPrice; - - @ApiModelProperty(value = "子订单分摊金额(总)", required = true, example = "100", notes = "单位:分") - private Integer orderPartPrice; - - @ApiModelProperty(value = "分摊后子订单实付金额(总)", required = true, example = "100", notes = "单位:分") - private Integer orderDividePrice; - - // ========== 营销基本信息 ========== - - // TODO 芋艿:在捉摸一下 - - // ========== 售后基本信息 ========== - - @ApiModelProperty(value = "售后状态", required = true, example = "1", notes = "参见 TradeOrderItemAfterSaleStatusEnum 枚举类") - private Integer afterSaleStatus; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java deleted file mode 100644 index deb71d819..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.order.vo; - -import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; - -@ApiModel("管理后台 - 交易订单的分页项 Response VO") -@Data -public class TradeOrderPageItemRespVO extends TradeOrderBaseVO { - - @ApiModelProperty(value = "收件人地区名字", required = true, example = "上海 上海市 普陀区") - private String receiverAreaName; - - /** - * 订单项列表 - */ - private List items; - - @ApiModel("管理后台 - 交易订单的分页项的订单项目") - @Data - public static class Item extends TradeOrderItemBaseVO { - - /** - * 属性数组 - */ - private List properties; - - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageReqVO.java deleted file mode 100644 index 4295d8c3d..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageReqVO.java +++ /dev/null @@ -1,54 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.admin.order.vo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.framework.common.validation.Mobile; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel("管理后台 - 交易订单的分页 Request VO") -@Data -public class TradeOrderPageReqVO extends PageParam { - - @ApiModelProperty(value = "订单号", example = "88888888", notes = "模糊匹配") - private String no; - - @ApiModelProperty(value = "用户编号", example = "1024") - private Long userId; - - @ApiModelProperty(value = "用户昵称", example = "小王", notes = "模糊匹配") - private String userNickname; - - @ApiModelProperty(value = "用户手机号", example = "小王", notes = "精准匹配") - @Mobile - private String userMobile; - - @ApiModelProperty(value = "收件人名称", example = "小红", notes = "模糊匹配") - private String receiverName; - - @ApiModelProperty(value = "收件人手机", example = "1560", notes = "模糊匹配") - @Mobile - private String receiverMobile; - - @ApiModelProperty(value = "订单类型", example = "1", notes = "参见 TradeOrderTypeEnum 枚举") - private Integer type; - - @ApiModelProperty(value = "订单状态", example = "1", notes = "参见 TradeOrderStatusEnum 枚举") - @InEnum(value = TradeOrderStatusEnum.class, message = "订单状态必须是 {value}") - private Integer status; - - @ApiModelProperty(value = "支付渠道", example = "wx_lite") - private String payChannelCode; - - @ApiModelProperty(value = "创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java deleted file mode 100644 index 5c1758f3b..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.aftersale; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; -import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; - -@Api(tags = "用户 App - 交易售后") -@RestController -@RequestMapping("/trade/after-sale") -@Validated -@Slf4j -public class AppTradeAfterSaleController { - - @Resource - private TradeAfterSaleService afterSaleService; - - @PostMapping(value = "/create") - @ApiOperation(value = "申请售后") - public CommonResult createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) { - return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO)); - } - - @PostMapping(value = "/delivery") - @ApiOperation(value = "退回货物") - public CommonResult deliveryAfterSale(@RequestBody AppTradeAfterSaleDeliveryReqVO deliveryReqVO) { - afterSaleService.deliveryAfterSale(getLoginUserId(), deliveryReqVO); - return success(true); - } - - @DeleteMapping(value = "/cancel") - @ApiOperation(value = "取消售后") - @ApiImplicitParam(name = "id", value = "售后编号", required = true, example = "1") - public CommonResult cancelAfterSale(@RequestParam("id") Long id) { - afterSaleService.cancelAfterSale(getLoginUserId(), id); - return success(true); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java deleted file mode 100644 index b5ea83904..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java +++ /dev/null @@ -1,41 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import java.util.List; - -@ApiModel("用户 App - 交易售后创建 Request VO") -@Data -public class AppTradeAfterSaleCreateReqVO { - - @ApiModelProperty(name = "订单项编号", required = true, example = "1024") - @NotNull(message = "订单项编号不能为空") - private Long orderItemId; - - @ApiModelProperty(name = "售后方式", required = true, example = "1", notes = "对应 TradeAfterSaleWayEnum 枚举") - @NotNull(message = "售后方式不能为空") - @InEnum(value = TradeAfterSaleWayEnum.class, message = "售后方式必须是 {value}") - private Integer way; - - @ApiModelProperty(name = "退款金额", required = true, example = "100", notes = "单位:分") - @NotNull(message = "退款金额不能为空") - @Min(value = 1, message = "退款金额必须大于 0") - private Integer refundPrice; - - @ApiModelProperty(name = "申请原因", required = true, example = "1", notes = "使用数据字典枚举,对应 trade_refund_apply_reason 类型") - @NotNull(message = "申请原因不能为空") - private String applyReason; - - @ApiModelProperty(name = "补充描述", example = "商品质量不好") - private String applyDescription; - - @ApiModelProperty(name = "补充凭证图片", example = "https://www.iocoder.cn/1.png, https://www.iocoder.cn/2.png") - private List applyPicUrls; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java deleted file mode 100644 index c59d00034..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.time.LocalDateTime; - -@ApiModel("用户 App - 交易售后退回货物 Request VO") -@Data -public class AppTradeAfterSaleDeliveryReqVO { - - @ApiModelProperty(name = "售后编号", required = true, example = "1024") - @NotNull(message = "售后编号不能为空") - private Long id; - - @ApiModelProperty(name = "退货物流公司编号", required = true, example = "1") - @NotNull(message = "退货物流公司编号不能为空") - private Long logisticsId; - - @ApiModelProperty(name = "退货物流单号", required = true, example = "SF123456789") - @NotNull(message = "退货物流单号不能为空") - private String logisticsNo; - - @ApiModelProperty(name = "退货时间", required = true) - @NotEmpty(message = "退货时间不能为空") - private LocalDateTime deliveryTime; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/package-info.java deleted file mode 100644 index 08acfdbca..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 基础包,放一些通用的 VO 类 - */ -package cn.iocoder.yudao.module.trade.controller.app.base; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java deleted file mode 100644 index adcb978ec..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.base.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description ="用户 App - 商品属性值的明细 Response VO") -@Data -public class AppProductPropertyValueDetailRespVO { - - @Schema(description = "属性的编号", required = true, example = "1") - private Long propertyId; - - @Schema(description = "属性的名称", required = true, example = "颜色") - private String propertyName; - - @Schema(description = "属性值的编号", required = true, example = "1024") - private Long valueId; - - @Schema(description = "属性值的名称", required = true, example = "红色") - private String valueName; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java deleted file mode 100644 index 053e329b4..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.base.sku; - -import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.util.List; - -/** - * 商品 SKU 基础 Response VO - * - * @author 芋道源码 - */ -@Data -public class AppProductSkuBaseRespVO { - - @Schema(description = "主键", required = true, example = "1024") - private Long id; - - @Schema(description = "商品 SKU 名字", required = true, example = "芋道") - private String name; - - @Schema(description = "图片地址", example = "https://www.iocoder.cn/xx.png") - private String picUrl; - - @Schema(description = "库存", required = true, example = "1") - private Integer stock; - - /** - * 属性数组 - */ - private List properties; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java deleted file mode 100644 index 61ecf59d2..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.base.spu; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.util.List; - -/** - * 商品 SPU 基础 Response VO - * - * @author 芋道源码 - */ -@Data -public class AppProductSpuBaseRespVO { - - @Schema(description = "主键", required = true, example = "1024") - private Long id; - - @Schema(description = "商品 SPU 名字", required = true, example = "芋道") - private String name; - - @Schema(description = "商品主图地址", example = "https://www.iocoder.cn/xx.png") - private List picUrls; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http deleted file mode 100644 index 3ce8797fc..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http +++ /dev/null @@ -1,47 +0,0 @@ -### 请求 /trade/cart/add-count 接口 => 成功 -POST {{appApi}}/trade/cart/add-count -tenant-id: {{appTenentId}} -Authorization: Bearer {{appToken}} -Content-Type: application/json - -{ - "skuId": 1, - "count": 1 -} - -### 请求 /trade/cart/update-count 接口 => 成功 -PUT {{appApi}}/trade/cart/update-count -tenant-id: {{appTenentId}} -Authorization: Bearer {{appToken}} -Content-Type: application/json - -{ - "skuId": 1, - "count": 5 -} - -### 请求 /trade/cart/update-selected 接口 => 成功 -PUT {{appApi}}/trade/cart/update-selected -tenant-id: {{appTenentId}} -Authorization: Bearer {{appToken}} -Content-Type: application/json - -{ - "skuIds": [1], - "selected": false -} - -### 请求 /trade/cart/delete 接口 => 成功 -DELETE {{appApi}}/trade/cart/delete?skuIds=1 -tenant-id: {{appTenentId}} -Authorization: Bearer {{appToken}} - -### 请求 /trade/cart/get-count 接口 => 成功 -GET {{appApi}}/trade/cart/get-count -tenant-id: {{appTenentId}} -Authorization: Bearer {{appToken}} - -### 请求 /trade/cart/get-detail 接口 => 成功 -GET {{appApi}}/trade/cart/get-detail -tenant-id: {{appTenentId}} -Authorization: Bearer {{appToken}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java deleted file mode 100644 index 96f55d9a3..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java +++ /dev/null @@ -1,84 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.cart; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO; -import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; - -@Tag(name = "用户 App - 购物车") -@RestController -@RequestMapping("/trade/cart") -@RequiredArgsConstructor -@Validated -@Slf4j -public class TradeCartController { - - @Resource - private TradeCartService cartService; - - @PostMapping("/add-count") - @Operation(summary = "添加商品到购物车") - @PreAuthenticated - public CommonResult addCartItemCount(@Valid @RequestBody AppTradeCartItemAddCountReqVO addCountReqVO) { - cartService.addCartItemCount(getLoginUserId(), addCountReqVO); - return success(true); - } - - @PutMapping("update-count") - @Operation(summary = "更新购物车商品数量") - @PreAuthenticated - public CommonResult updateCartItemQuantity(@Valid @RequestBody AppTradeCartItemUpdateCountReqVO updateCountReqVO) { - cartService.updateCartItemCount(getLoginUserId(), updateCountReqVO); - return success(true); - } - - @PutMapping("update-selected") - @Operation(summary = "更新购物车商品是否选中") - @PreAuthenticated - public CommonResult updateCartItemSelected(@Valid @RequestBody AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO) { - cartService.updateCartItemSelected(getLoginUserId(), updateSelectedReqVO); - // 获得目前购物车明细 - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除购物车商品") - @Parameter(name = "skuIds", description = "商品 SKU 编号的数组", required = true, example = "1024,2048") - @PreAuthenticated - public CommonResult deleteCartItem(@RequestParam("skuIds") List skuIds) { - cartService.deleteCartItems(getLoginUserId(), skuIds); - return success(true); - } - - @GetMapping("get-count") - @Operation(summary = "查询用户在购物车中的商品数量") - @PreAuthenticated - public CommonResult getCartCount() { - return success(cartService.getCartCount(getLoginUserId())); - } - - @GetMapping("/get-detail") - @Operation(summary = "查询用户的购物车的详情") - @PreAuthenticated - public CommonResult getCartDetail() { - return success(cartService.getCartDetail(getLoginUserId())); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java deleted file mode 100644 index f58421b68..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java +++ /dev/null @@ -1,117 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.cart.vo; - -import cn.iocoder.yudao.module.trade.controller.app.base.sku.AppProductSkuBaseRespVO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.util.List; - -@Schema(description = "用户 App - 用户的购物车明细 Response VO") -@Data -public class AppTradeCartDetailRespVO { - - /** - * 商品分组数组 - */ - private List itemGroups; - - /** - * 费用 - */ - private Order order; - - @Schema(description = "商品分组,多个商品,参加同一个活动,从而形成分组") - @Data - public static class ItemGroup { - - /** - * 商品数组 - */ - private List items; - /** - * 营销活动,订单级别 - */ - private Promotion promotion; - - } - - @Schema(description = "商品 SKU") - @Data - public static class Sku extends AppProductSkuBaseRespVO { - - /** - * SPU 信息 - */ - private AppProductSkuBaseRespVO spu; - - // ========== 购物车相关的字段 ========== - - @Schema(description = "商品数量", required = true, example = "1") - private Integer count; - @Schema(description = "是否选中", required = true, example = "true") - private Boolean selected; - - // ========== 价格相关的字段,对应 PriceCalculateRespDTO.OrderItem 的属性 ========== - - // TODO 芋艿:后续可以去除一些无用的字段 - - @Schema(description = "商品原价(单)", required = true, example = "100") - private Integer originalPrice; - @Schema(description = "商品原价(总)", required = true, example = "200") - private Integer totalOriginalPrice; - @Schema(description = "商品级优惠(总)", required = true, example = "300") - private Integer totalPromotionPrice; - @Schema(description = "最终购买金额(总)", required = true, example = "400") - private Integer totalPresentPrice; - @Schema(description = "最终购买金额(单)", required = true, example = "500") - private Integer presentPrice; - @Schema(description = "应付金额(总)", required = true, example = "600") - private Integer totalPayPrice; - - // ========== 营销相关的字段 ========== - /** - * 营销活动,商品级别 - */ - private Promotion promotion; - - } - - @Schema(description = "订单,对应 PriceCalculateRespDTO.Order 类,用于费用(合计)") - @Data - public static class Order { - - // TODO 芋艿:后续可以去除一些无用的字段 - - @Schema(description = "商品原价(总)", required = true, example = "100") - private Integer skuOriginalPrice; - @Schema(description = "商品优惠(总)", required = true, example = "200") - private Integer skuPromotionPrice; - @Schema(description = "订单优惠(总)", required = true, example = "300") - private Integer orderPromotionPrice; - @Schema(description = "运费金额", required = true, example = "400") - private Integer deliveryPrice; - @Schema(description = "应付金额(总)", required = true, example = "500") - private Integer payPrice; - - } - - @Schema(description = "营销活动,对应 PriceCalculateRespDTO.Promotion 类的属性") - @Data - public static class Promotion { - - @Schema(description = "营销编号,营销活动的编号、优惠劵的编号", required = true, example = "1024") - private Long id; - @Schema(description = "营销名字", required = true, example = "xx 活动") - private String name; - @Schema(description = "营销类型,参见 PromotionTypeEnum 枚举类", required = true, example = "1") - private Integer type; - - // ========== 匹配情况 ========== - @Schema(description = "是否满足优惠条件", required = true, example = "true") - private Boolean meet; - @Schema(description = "满足条件的提示", required = true, example = "圣诞价:省 150.00 元") - private String meetTip; - - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java deleted file mode 100644 index 280150537..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.cart.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; - -@Schema(description = "用户 App - 购物车添加购物项 Request VO") -@Data -public class AppTradeCartItemAddCountReqVO { - - @Schema(description = "商品 SKU 编号", required = true,example = "1024") - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - @Schema(description = "商品数量,注意,这是新增数量", required = true, example = "1") - @NotNull(message = "数量不能为空") - @Min(message = "数量必须大于 0", value = 1L) - private Integer count; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java deleted file mode 100644 index d3d12487e..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.cart.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; - -@Schema(description = "用户 App - 购物车更新数量 Request VO") -@Data -public class AppTradeCartItemUpdateCountReqVO { - - @Schema(description = "商品 SKU 编号", required = true, example = "1024") - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - @Schema(description = "商品数量", required = true, example = "1") - @NotNull(message = "数量不能为空") - @Min(message = "数量必须大于 0", value = 1L) - private Integer count; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java deleted file mode 100644 index 62327f320..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.cart.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.constraints.NotNull; -import java.util.Collection; - -@Schema(description = "用户 App - 购物车更新是否选中 Request VO") -@Data -public class AppTradeCartItemUpdateSelectedReqVO { - - @Schema(description = "商品 SKU 编号列表", required = true, example = "1024,2048") - @NotNull(message = "商品 SKU 编号列表不能为空") - private Collection skuIds; - - @Schema(description = "是否选中", required = true, example = "true") - @NotNull(message = "是否选中不能为空") - private Boolean selected; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http deleted file mode 100644 index 8e7746359..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http +++ /dev/null @@ -1,37 +0,0 @@ -### /trade-order/confirm-create-order-info 基于商品,确认创建订单 -GET {{appApi}}/trade/order/get-create-info?items[0].skuId=1&items[0].count=1 -Authorization: Bearer {{user-access-token}} -tenant-id: {{appTenentId}} - -### /trade-order/confirm-create-order-info-from-cart 基于购物车,确认创建订单 -GET {{shop-api-base-url}}/trade-order/confirm-create-order-info-from-cart -Content-Type: application/x-www-form-urlencoded -Authorization: Bearer {{user-access-token}} - -### /trade-order/create 基于商品,创建订单 -POST {{appApi}}/trade/order/create -Content-Type: application/json -Authorization: Bearer {{appToken}} -tenant-id: {{appTenentId}} - -{ - "addressId": 21, - "remark": "我是备注", - "fromCart": false, - "items": [ - { - "skuId": 29, - "count": 1 - } - ] -} - -### 获得订单交易的分页 -GET {{appApi}}/trade/order/page?pageNo=1&pageSize=10 -Authorization: Bearer {{appToken}} -tenant-id: {{appTenentId}} - -### 获得订单交易的详细 -GET {{appApi}}/trade/order/get-detail?id=21 -Authorization: Bearer {{appToken}} -tenant-id: {{appTenentId}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java deleted file mode 100644 index 876da3621..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ /dev/null @@ -1,102 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.order; - -import cn.hutool.extra.servlet.ServletUtil; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; -import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; -import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Operation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; - -@Tag(name = "用户 App - 交易订单") -@RestController -@RequestMapping("/trade/order") -@Validated -@Slf4j -public class AppTradeOrderController { - - @Resource - private TradeOrderService tradeOrderService; - - @Resource - private ProductPropertyValueApi productPropertyValueApi; - - @GetMapping("/get-create-info") - @Operation(summary = "基于商品,确认创建订单") - @PreAuthenticated - public CommonResult getOrderCreateInfo(AppTradeOrderCreateReqVO createReqVO) { -// return success(tradeOrderService.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId)); - return null; - } - - @PostMapping("/create") - @Operation(summary = "创建订单") - @PreAuthenticated - public CommonResult createOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO, - HttpServletRequest servletRequest) { - // 获取登录用户、用户 IP 地址 - Long loginUserId = getLoginUserId(); - String clientIp = ServletUtil.getClientIP(servletRequest); - // 创建交易订单,预支付记录 - Long orderId = tradeOrderService.createOrder(loginUserId, clientIp, createReqVO); - return success(orderId); - } - - @PostMapping("/update-paid") - @Operation(summary = "更新订单为已支付", notes = "由 pay-module 支付服务,进行回调,可见 PayNotifyJob") - public CommonResult updateOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { - tradeOrderService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), - notifyReqDTO.getPayOrderId()); - return success(true); - } - - @GetMapping("/get-detail") - @Operation(summary = "获得交易订单") - @Parameter(name = "id", description = "交易订单编号", required = true) - public CommonResult getOrder(@RequestParam("id") Long id) { - // 查询订单 - TradeOrderDO order = tradeOrderService.getOrder(getLoginUserId(), id); - // 查询订单项 - List orderItems = tradeOrderService.getOrderItemListByOrderId(order.getId()); - // 查询商品属性 - List propertyValueDetails = productPropertyValueApi - .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); - // 最终组合 - return success(TradeOrderConvert.INSTANCE.convert02(order, orderItems, propertyValueDetails)); - } - - @GetMapping("/page") - @Operation(summary = "获得订单交易分页") - public CommonResult> getOrderPage(AppTradeOrderPageReqVO reqVO) { - // 查询订单 - PageResult pageResult = tradeOrderService.getOrderPage(getLoginUserId(), reqVO); - // 查询订单项 - List orderItems = tradeOrderService.getOrderItemListByOrderId( - convertSet(pageResult.getList(), TradeOrderDO::getId)); - // 查询商品属性 - List propertyValueDetails = productPropertyValueApi - .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); - // 最终组合 - return success(TradeOrderConvert.INSTANCE.convertPage02(pageResult, orderItems, propertyValueDetails)); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java deleted file mode 100644 index 4d6c19c34..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java +++ /dev/null @@ -1,52 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.order.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import javax.validation.Valid; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.util.List; - -@Schema(description = "用户 App - 交易订单创建 Request VO") -@Data -public class AppTradeOrderCreateReqVO { - - @Schema(description = "收件地址编号", required = true, example = "1") - @NotNull(message = "收件地址不能为空") - private Long addressId; - - @Schema(description = "优惠劵编号", example = "1024") - private Long couponId; - - @Schema(description = "备注", example = "这个是我的订单哟") - private String remark; - - @Schema(description = "是否来自购物车,true - 来自购物车;false - 立即购买", required = true, example = "true") - @NotNull(message = "是否来自购物车不能为空") - private Boolean fromCart; - - /** - * 订单商品项列表 - */ - @NotEmpty(message = "必须选择购买的商品") - @Valid - private List items; - - @Schema(description = "订单商品项") - @Data - public static class Item { - - @Schema(description = "商品 SKU 编号", required = true, example = "111") - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - @Schema(description = "商品 SKU 购买数量", required = true, example = "1024") - @NotNull(message = "商品 SKU 购买数量不能为空") - @Min(value = 1, message = "商品 SKU 购买数量必须大于 0") - private Integer count; - - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java deleted file mode 100644 index 14614a57e..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java +++ /dev/null @@ -1,150 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.order.vo; - -import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.Date; -import java.util.List; - -@ApiModel("用户 App - 订单交易的明细 Response VO") -@Data -public class AppTradeOrderDetailRespVO { - - // ========== 订单基本信息 ========== - - @ApiModelProperty(value = "订单编号", required = true, example = "1024") - private Long id; - - @ApiModelProperty(value = "订单流水号", required = true, example = "1146347329394184195") - private String no; - - @ApiModelProperty(value = "创建时间", required = true, notes = "下单时间") - private Date createTime; - - @ApiModelProperty(value = "用户备注", required = true, example = "你猜") - private String userRemark; - - @ApiModelProperty(value = "订单状态", required = true, example = "1", notes = "参见 TradeOrderStatusEnum 枚举") - private Integer status; - - @ApiModelProperty(value = "购买的商品数量", required = true, example = "10") - private Integer productCount; - - @ApiModelProperty(value = "订单完成时间") - private LocalDateTime finishTime; - - @ApiModelProperty(value = "订单取消时间") - private LocalDateTime cancelTime; - - // ========== 价格 + 支付基本信息 ========== - - @ApiModelProperty(value = "支付订单编号", required = true, example = "1024") - private Long payOrderId; - - @ApiModelProperty(value = "付款时间") - private LocalDateTime payTime; - - @ApiModelProperty(value = "商品原价(总)", required = true, example = "1000", notes = "单位:分") - private Integer originalPrice; - - @ApiModelProperty(value = "订单原价(总)", required = true, example = "1000", notes = "单位:分") - private Integer orderPrice; - - @ApiModelProperty(value = "订单优惠(总)", required = true, example = "100", notes = "单位:分") - private Integer discountPrice; - - @ApiModelProperty(value = "运费金额", required = true, example = "100", notes = "单位:分") - private Integer deliveryPrice; - - @ApiModelProperty(value = "订单调价(总)", required = true, example = "100", notes = "单位:分") - private Integer adjustPrice; - - @ApiModelProperty(value = "应付金额(总)", required = true, example = "1000", notes = "单位:分") - private Integer payPrice; - - // ========== 收件 + 物流基本信息 ========== - - @ApiModelProperty(value = "发货物流单号", example = "1024") - private String logisticsNo; - - @ApiModelProperty(value = "发货时间") - private LocalDateTime deliveryTime; - - @ApiModelProperty(value = "收货时间") - private LocalDateTime receiveTime; - - @ApiModelProperty(value = "收件人名称", required = true, example = "张三") - private String receiverName; - - @ApiModelProperty(value = "收件人手机", required = true, example = "13800138000") - private String receiverMobile; - - @ApiModelProperty(value = "收件人地区编号", required = true, example = "110000") - private Integer receiverAreaId; - - @ApiModelProperty(value = "收件人地区名字", required = true, example = "上海 上海市 普陀区") - private String receiverAreaName; - - @ApiModelProperty(value = "收件人邮编", required = true, example = "100000") - private Integer receiverPostCode; - - @ApiModelProperty(value = "收件人详细地址", required = true, example = "中关村大街 1 号") - private String receiverDetailAddress; - - // ========== 售后基本信息 ========== - - // ========== 营销基本信息 ========== - - @ApiModelProperty(value = "优惠劵编号", example = "1024") - private Long couponId; - - @ApiModelProperty(value = "优惠劵减免金额", required = true, example = "100", notes = "单位:分") - private Integer couponPrice; - - @ApiModelProperty(value = "积分抵扣的金额", required = true, example = "100", notes = "单位:分") - private Integer pointPrice; - - /** - * 订单项数组 - */ - private List items; - - @ApiModel("用户 App - 交易订单的分页项的订单项目") - @Data - public static class Item { - - @ApiModelProperty(value = "编号", required = true, example = "1") - private Long id; - - @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") - private Long spuId; - - @ApiModelProperty(value = "商品 SPU 名称", required = true, example = "芋道源码") - private String spuName; - - @ApiModelProperty(value = "商品 SKU 编号", required = true, example = "1") - private Long skuId; - - @ApiModelProperty(value = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") - private String picUrl; - - @ApiModelProperty(value = "购买数量", required = true, example = "1") - private Integer count; - - @ApiModelProperty(value = "商品原价(总)", required = true, example = "100", notes = "单位:分") - private Integer originalPrice; - - @ApiModelProperty(value = "商品原价(单)", required = true, example = "100", notes = "单位:分") - private Integer originalUnitPrice; - - /** - * 属性数组 - */ - private List properties; - - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java deleted file mode 100644 index 2f73a5c8e..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java +++ /dev/null @@ -1,168 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.order.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; - -import java.util.List; - -@Schema(description = "用户 App - 订单获得创建信息 Response VO") -@Data -public class AppTradeOrderGetCreateInfoRespVO { - - /** - * 商品分组数组 - */ - private List itemGroups; - /** - * 费用 - */ - private Fee fee; - -// /** -// * 优惠劵列表 TODO 芋艿,后续改改 -// */ -// private List coupons; - - @Schema(description = "商品分组,多个商品,参加同一个活动,从而形成分组") - @Data - public static class ItemGroup { - -// /** -// * 优惠活动 -// */ -// private PromotionActivityRespDTO activity; // TODO 芋艿,偷懒 - /** - * 商品 SKU 数组 - */ - private List items; - - } - - @Schema(description = "商品 SKU") - @Data - public static class Sku { - - // SKU 自带信息 - @Schema(description = "SKU 编号", required = true, example = "1024") - private Integer id; - /** - * SPU 信息 - */ - private Spu spu; - /** - * 图片地址 - */ - private String picURL; -// /** -// * 属性数组 -// */ -// private List attrs; // TODO 后面改下 - /** - * 价格,单位:分 - */ - private Integer price; - /** - * 库存数量 - */ - private Integer stock; - - // 非 SKU 自带信息 - - /** - * 购买数量 - */ - private Integer buyQuantity; -// /** -// * 优惠活动 -// */ -// private PromotionActivityRespDTO activity; // TODO 芋艿,偷懒 - /** - * 原始单价,单位:分。 - */ - private Integer originPrice; - /** - * 购买单价,单位:分 - */ - private Integer buyPrice; - /** - * 最终价格,单位:分。 - */ - private Integer presentPrice; - /** - * 购买总金额,单位:分 - * - * 用途类似 {@link #presentTotal} - */ - private Integer buyTotal; - /** - * 优惠总金额,单位:分。 - */ - private Integer discountTotal; - /** - * 最终总金额,单位:分。 - * - * 注意,presentPrice * quantity 不一定等于 presentTotal 。 - * 因为,存在无法整除的情况。 - * 举个例子,presentPrice = 8.33 ,quantity = 3 的情况,presentTotal 有可能是 24.99 ,也可能是 25 。 - * 所以,需要存储一个该字段。 - */ - private Integer presentTotal; - - } - - @Data - public static class Spu { - - /** - * SPU 编号 - */ - private Integer id; - - // ========== 基本信息 ========= - /** - * SPU 名字 - */ - private String name; - /** - * 分类编号 - */ - private Integer cid; - /** - * 商品主图地址 - * - * 数组,以逗号分隔 - * - * 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张 - */ - private List picUrls; - - } - - @Schema(description = "费用(合计)") - @Data - @AllArgsConstructor - public static class Fee { - - @Schema(description = "购买总价", required = true, example = "1024") - private Integer buyPrice; - /** - * 优惠总价 - * - * 注意,满多少元包邮,不算在优惠中。 - */ - private Integer discountTotal; - /** - * 邮费 - */ - private Integer postageTotal; - /** - * 最终价格 - * - * 计算公式 = 总价 - 优惠总价 + 邮费 - */ - private Integer presentTotal; - - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java deleted file mode 100644 index 8815c0c39..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java +++ /dev/null @@ -1,66 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.order.vo; - -import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import java.util.List; - -@ApiModel("用户 App - 订单交易的分页项 Response VO") -@Data -public class AppTradeOrderPageItemRespVO { - - @ApiModelProperty(value = "订单编号", required = true, example = "1024") - private Long id; - - @ApiModelProperty(value = "订单流水号", required = true, example = "1146347329394184195") - private String no; - - @ApiModelProperty(value = "订单状态", required = true, example = "1", notes = "参见 TradeOrderStatusEnum 枚举") - private Integer status; - - @ApiModelProperty(value = "购买的商品数量", required = true, example = "10") - private Integer productCount; - - /** - * 订单项数组 - */ - private List items; - - @ApiModel("用户 App - 交易订单的明细的订单项目") - @Data - public static class Item { - - @ApiModelProperty(value = "编号", required = true, example = "1") - private Long id; - - @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1") - private Long spuId; - - @ApiModelProperty(value = "商品 SPU 名称", required = true, example = "芋道源码") - private String spuName; - - @ApiModelProperty(value = "商品 SKU 编号", required = true, example = "1") - private Long skuId; - - @ApiModelProperty(value = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") - private String picUrl; - - @ApiModelProperty(value = "购买数量", required = true, example = "1") - private Integer count; - - @ApiModelProperty(value = "商品原价(总)", required = true, example = "100", notes = "单位:分") - private Integer originalPrice; - - @ApiModelProperty(value = "商品原价(单)", required = true, example = "100", notes = "单位:分") - private Integer originalUnitPrice; - - /** - * 属性数组 - */ - private List properties; - - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java deleted file mode 100644 index 00bd2a571..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.yudao.module.trade.controller.app.order.vo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -// TODO 芋艿:字段优化 -@Schema(description = "交易订单分页 Request VO") -@Data -public class AppTradeOrderPageReqVO extends PageParam { - - @Schema(description = "订单状态-参见 TradeOrderStatusEnum 枚举", example = "1") - @InEnum(value = TradeOrderStatusEnum.class, message = "订单状态必须是 {value}") - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderItemRespVO.java deleted file mode 100644 index e69de29bb..000000000 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/TradeOrderRespVO.java deleted file mode 100644 index e69de29bb..000000000 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java deleted file mode 100644 index aa2f99f35..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 提供 RESTful API 给前端: - * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目 - * 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分 - */ -package cn.iocoder.yudao.module.trade.controller; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java deleted file mode 100644 index fe1e3bd01..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java +++ /dev/null @@ -1,89 +0,0 @@ -package cn.iocoder.yudao.module.trade.convert.aftersale; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO; -import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; -import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; -import org.mapstruct.factory.Mappers; - -import java.util.*; -import java.util.stream.Collectors; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -@Mapper -public interface TradeAfterSaleConvert { - - TradeAfterSaleConvert INSTANCE = Mappers.getMapper(TradeAfterSaleConvert.class); - - @Mappings({ - @Mapping(target = "id", ignore = true), - @Mapping(target = "createTime", ignore = true), - @Mapping(target = "updateTime", ignore = true), - @Mapping(target = "creator", ignore = true), - @Mapping(target = "updater", ignore = true), - }) - TradeAfterSaleDO convert(AppTradeAfterSaleCreateReqVO createReqVO, TradeOrderItemDO tradeOrderItem); - - @Mappings({ - @Mapping(source = "afterSale.orderId", target = "merchantOrderId"), - @Mapping(source = "afterSale.applyReason", target = "reason"), - @Mapping(source = "afterSale.refundPrice", target = "amount") - }) - PayRefundCreateReqDTO convert(String userIp, TradeAfterSaleDO afterSale, - TradeOrderProperties orderProperties); - - MemberUserRespVO convert(MemberUserRespDTO bean); - - PageResult convertPage(PageResult page); - - default PageResult convertPage(PageResult pageResult, - Map memberUsers, List propertyValueDetails) { - PageResult pageVOResult = convertPage(pageResult); - // 处理会员 + 商品属性等关联信息 - Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); - for (int i = 0; i < pageResult.getList().size(); i++) { - TradeAfterSaleRespPageItemVO afterSaleVO = pageVOResult.getList().get(i); - TradeAfterSaleDO afterSaleDO = pageResult.getList().get(i); - // 会员 - afterSaleVO.setUser(convert(memberUsers.get(afterSaleDO.getUserId()))); - // 商品属性 - if (CollUtil.isNotEmpty(afterSaleDO.getProperties())) { - afterSaleVO.setProperties(new ArrayList<>(afterSaleDO.getProperties().size())); - // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 - afterSaleDO.getProperties().forEach(property -> { - ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); - if (propertyValueDetail == null) { - return; - } - afterSaleVO.getProperties().add(convert(propertyValueDetail)); - }); - } - } - return pageVOResult; - } - - ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean); - - default Set convertPropertyValueIds(List list) { - if (CollUtil.isEmpty(list)) { - return new HashSet<>(); - } - return list.stream().filter(item -> item.getProperties() != null) - .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 - .map(TradeOrderItemDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 - .collect(Collectors.toSet()); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java deleted file mode 100644 index eb696ae30..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java +++ /dev/null @@ -1,45 +0,0 @@ -package cn.iocoder.yudao.module.trade.convert.cart; - -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; -import org.mapstruct.factory.Mappers; - -import java.util.Collections; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; - -@Mapper -public interface TradeCartConvert { - - TradeCartConvert INSTANCE = Mappers.getMapper(TradeCartConvert.class); - - default AppTradeCartDetailRespVO buildEmptyAppTradeCartDetailRespVO() { - return new AppTradeCartDetailRespVO().setItemGroups(Collections.emptyList()) - .setOrder(new AppTradeCartDetailRespVO.Order().setSkuOriginalPrice(0).setSkuPromotionPrice(0) - .setOrderPromotionPrice(0).setDeliveryPrice(0).setPayPrice(0)); - } - - default PriceCalculateReqDTO convert(Long userId, List cartItems) { - return new PriceCalculateReqDTO().setUserId(userId) - .setItems(convertList(cartItems, cartItem -> new PriceCalculateReqDTO.Item().setSkuId(cartItem.getSkuId()) - .setCount(cartItem.getSelected() ? cartItem.getCount() : 0))); - } - - // ========== AppTradeCartDetailRespVO 相关 ========== - - AppTradeCartDetailRespVO.Promotion convert(PriceCalculateRespDTO.Promotion bean); - - @Mappings({ - @Mapping(source = "cartItem.count", target = "count") - }) - AppTradeCartDetailRespVO.Sku convert(PriceCalculateRespDTO.OrderItem orderItem, TradeCartItemDO cartItem); - - AppTradeCartDetailRespVO.Order convert(PriceCalculateRespDTO.Order bean); - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java deleted file mode 100644 index b1f0b4b2a..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ /dev/null @@ -1,241 +0,0 @@ -package cn.iocoder.yudao.module.trade.convert.order; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; -import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO; -import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageItemRespVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; -import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; -import org.mapstruct.factory.Mappers; - -import java.util.*; -import java.util.stream.Collectors; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; - -@Mapper -public interface TradeOrderConvert { - - TradeOrderConvert INSTANCE = Mappers.getMapper(TradeOrderConvert.class); - - @Mappings({ - @Mapping(target = "id", ignore = true), - @Mapping(source = "createReqVO.couponId", target = "couponId"), - @Mapping(target = "remark", ignore = true), - @Mapping(source = "createReqVO.remark", target = "userRemark"), - @Mapping(source = "address.name", target = "receiverName"), - @Mapping(source = "address.mobile", target = "receiverMobile"), - @Mapping(source = "address.areaId", target = "receiverAreaId"), - @Mapping(source = "address.postCode", target = "receiverPostCode"), - @Mapping(source = "address.detailAddress", target = "receiverDetailAddress"), - }) - TradeOrderDO convert(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO, - PriceCalculateRespDTO.Order order, AddressRespDTO address); - - @Mappings({ - @Mapping(target = "id", ignore = true), - @Mapping(source = "sku.spuId", target = "spuId"), - }) - TradeOrderItemDO convert(PriceCalculateRespDTO.OrderItem orderItem, ProductSkuRespDTO sku); - - default List convertList(TradeOrderDO tradeOrderDO, - List orderItems, List skus) { - Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); - return CollectionUtils.convertList(orderItems, orderItem -> { - TradeOrderItemDO tradeOrderItemDO = convert(orderItem, skuMap.get(orderItem.getSkuId())); - tradeOrderItemDO.setOrderId(tradeOrderDO.getId()); - tradeOrderItemDO.setUserId(tradeOrderDO.getUserId()); - tradeOrderItemDO.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); // 退款信息 -// tradeOrderItemDO.setCommented(false); - return tradeOrderItemDO; - }); - } - - @Mapping(source = "userId" , target = "userId") - PriceCalculateReqDTO convert(AppTradeOrderCreateReqVO createReqVO, Long userId); - - @Mappings({ - @Mapping(source = "skuId", target = "id"), - @Mapping(source = "count", target = "incrCount"), - }) - ProductSkuUpdateStockReqDTO.Item convert(TradeOrderItemDO bean); - List convertList(List list); - - default PayOrderCreateReqDTO convert(TradeOrderDO tradeOrderDO, List tradeOrderItemDOs, - List spus, TradeOrderProperties tradeOrderProperties) { - PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO() - .setAppId(tradeOrderProperties.getAppId()).setUserIp(tradeOrderDO.getUserIp()); - // 商户相关字段 - createReqDTO.setMerchantOrderId(String.valueOf(tradeOrderDO.getId())); - String subject = spus.get(0).getName(); - if (spus.size() > 1) { - subject += " 等多件"; - } - createReqDTO.setSubject(subject); - // 订单相关字段 - createReqDTO.setAmount(tradeOrderDO.getPayPrice()).setExpireTime(addTime(tradeOrderProperties.getExpireTime())); - return createReqDTO; - } - - default Set convertPropertyValueIds(List list) { - if (CollUtil.isEmpty(list)) { - return new HashSet<>(); - } - return list.stream().filter(item -> item.getProperties() != null) - .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 - .map(TradeOrderItemDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 - .collect(Collectors.toSet()); - } - - default PageResult convertPage(PageResult pageResult, List orderItems, - List propertyValueDetails) { - Map> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId); - Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); - // 转化 List - List orderVOs = CollectionUtils.convertList(pageResult.getList(), order -> { - List xOrderItems = orderItemMap.get(order.getId()); - TradeOrderPageItemRespVO orderVO = convert(order, xOrderItems); - if (CollUtil.isNotEmpty(xOrderItems)) { - // 处理商品属性 - for (int i = 0; i < xOrderItems.size(); i++) { - List properties = xOrderItems.get(i).getProperties(); - if (CollUtil.isEmpty(properties)) { - continue; - } - TradeOrderPageItemRespVO.Item item = orderVO.getItems().get(i); - item.setProperties(new ArrayList<>(properties.size())); - // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 - properties.forEach(property -> { - ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); - if (propertyValueDetail == null) { - return; - } - item.getProperties().add(convert(propertyValueDetail)); - }); - } - } - // 处理收货地址 - orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); - return orderVO; - }); - return new PageResult<>(orderVOs, pageResult.getTotal()); - } - TradeOrderPageItemRespVO convert(TradeOrderDO order, List items); - ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean); - - default TradeOrderDetailRespVO convert(TradeOrderDO order, List orderItems, - List propertyValueDetails, MemberUserRespDTO user) { - TradeOrderDetailRespVO orderVO = convert2(order, orderItems); - // 处理商品属性 - Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); - for (int i = 0; i < orderItems.size(); i++) { - List properties = orderItems.get(i).getProperties(); - if (CollUtil.isEmpty(properties)) { - continue; - } - TradeOrderDetailRespVO.Item item = orderVO.getItems().get(i); - item.setProperties(new ArrayList<>(properties.size())); - // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 - properties.forEach(property -> { - ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); - if (propertyValueDetail == null) { - return; - } - item.getProperties().add(convert(propertyValueDetail)); - }); - } - // 处理收货地址 - orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); - // 处理用户信息 - orderVO.setUser(convert(user)); - return orderVO; - } - TradeOrderDetailRespVO convert2(TradeOrderDO order, List items); - MemberUserRespVO convert(MemberUserRespDTO bean); - - default PageResult convertPage02(PageResult pageResult, List orderItems, - List propertyValueDetails) { - Map> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId); - Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); - // 转化 List - List orderVOs = CollectionUtils.convertList(pageResult.getList(), order -> { - List xOrderItems = orderItemMap.get(order.getId()); - AppTradeOrderPageItemRespVO orderVO = convert02(order, xOrderItems); - if (CollUtil.isNotEmpty(xOrderItems)) { - // 处理商品属性 - for (int i = 0; i < xOrderItems.size(); i++) { - List properties = xOrderItems.get(i).getProperties(); - if (CollUtil.isEmpty(properties)) { - continue; - } - AppTradeOrderPageItemRespVO.Item item = orderVO.getItems().get(i); - item.setProperties(new ArrayList<>(properties.size())); - // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 - properties.forEach(property -> { - ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); - if (propertyValueDetail == null) { - return; - } - item.getProperties().add(convert02(propertyValueDetail)); - }); - } - } - return orderVO; - }); - return new PageResult<>(orderVOs, pageResult.getTotal()); - } - AppTradeOrderPageItemRespVO convert02(TradeOrderDO order, List items); - AppProductPropertyValueDetailRespVO convert02(ProductPropertyValueDetailRespDTO bean); - - default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List orderItems, - List propertyValueDetails) { - AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems); - // 处理商品属性 - Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); - for (int i = 0; i < orderItems.size(); i++) { - List properties = orderItems.get(i).getProperties(); - if (CollUtil.isEmpty(properties)) { - continue; - } - AppTradeOrderDetailRespVO.Item item = orderVO.getItems().get(i); - item.setProperties(new ArrayList<>(properties.size())); - // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 - properties.forEach(property -> { - ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); - if (propertyValueDetail == null) { - return; - } - item.getProperties().add(convert02(propertyValueDetail)); - }); - } - // 处理收货地址 - orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); - return orderVO; - } - AppTradeOrderDetailRespVO convert3(TradeOrderDO order, List items); - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java deleted file mode 100644 index 1b703d9e7..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java +++ /dev/null @@ -1,201 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.dataobject.aftersale; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.experimental.Accessors; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * 交易售后,用于处理 {@link TradeOrderDO} 交易订单的退款退货流程 - * - * @author 芋道源码 - */ -@TableName(value = "trade_after_sale", autoResultMap = true) -@Data -@EqualsAndHashCode(callSuper = true) -@Accessors(chain = true) -public class TradeAfterSaleDO extends BaseDO { - - /** - * 售后编号,主键自增 - */ - private Long id; - /** - * 售后流水号 - * - * 例如说,1146347329394184195 - */ - private String no; - /** - * 退款状态 - * - * 枚举 {@link TradeAfterSaleStatusEnum} - */ - private Integer status; - /** - * 售后方式 - * - * 枚举 {@link TradeAfterSaleWayEnum} - */ - private Integer way; - /** - * 售后类型 - * - * 枚举 {@link TradeAfterSaleTypeEnum} - */ - private Integer type; - /** - * 用户编号 - * - * 关联 MemberUserDO 的 id 编号 - */ - private Long userId; - /** - * 申请原因 - * - * type = 退款,对应 trade_after_sale_refund_reason 类型 - * type = 退货退款,对应 trade_after_sale_refund_and_return_reason 类型 - */ - private String applyReason; - /** - * 补充描述 - */ - private String applyDescription; - /** - * 补充凭证图片 - * - * 数组,以逗号分隔 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private List applyPicUrls; - - // ========== 交易订单相关 ========== - /** - * 交易订单编号 - * - * 关联 {@link TradeOrderDO#getId()} - */ - private Long orderId; - /** - * 订单流水号 - * - * 冗余 {@link TradeOrderDO#getNo()} - */ - private String orderNo; - /** - * 交易订单项编号 - * - * 关联 {@link TradeOrderItemDO#getId()} - */ - private Long orderItemId; - /** - * 商品 SPU 编号 - * - * 关联 ProductSpuDO 的 id 字段 - * 冗余 {@link TradeOrderItemDO#getSpuId()} - */ - private Long spuId; - /** - * 商品 SPU 名称 - * - * 关联 ProductSkuDO 的 name 字段 - * 冗余 {@link TradeOrderItemDO#getSpuName()} - */ - private String spuName; - /** - * 商品 SKU 编号 - * - * 关联 ProductSkuDO 的编号 - */ - private Long skuId; - /** - * 属性数组,JSON 格式 - * - * 冗余 {@link TradeOrderItemDO#getProperties()} - */ - @TableField(typeHandler = TradeOrderItemDO.PropertyTypeHandler.class) - private List properties; - /** - * 商品图片 - * - * 冗余 {@link TradeOrderItemDO#getPicUrl()} - */ - private String picUrl; - /** - * 退货商品数量 - */ - private Integer count; - - // ========== 审批相关 ========== - - /** - * 审批时间 - */ - private LocalDateTime auditTime; - /** - * 审批人 - * - * 关联 AdminUserDO 的 id 编号 - */ - private Long auditUserId; - /** - * 审批备注 - * - * 注意,只有审批不通过才会填写 - */ - private String auditReason; - - // ========== 退款相关 ========== - /** - * 退款金额,单位:分。 - */ - private Integer refundPrice; - /** - * 支付退款编号 - * - * 对接 pay-module-biz 支付服务的退款订单编号,即 PayRefundDO 的 id 编号 - */ - private Long payRefundId; - /** - * 退款时间 - */ - private LocalDateTime refundTime; - - // ========== 退货相关 ========== - /** - * 退货物流公司编号 - * - * 关联 LogisticsDO 的 id 编号 - */ - private Long logisticsId; - /** - * 退货物流单号 - */ - private String logisticsNo; - /** - * 退货时间 - */ - private LocalDateTime deliveryTime; - /** - * 收货时间 - */ - private LocalDateTime receiveTime; - /** - * 收货备注 - * - * 注意,只有拒绝收货才会填写 - */ - private String receiveReason; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java deleted file mode 100644 index 5aa627403..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java +++ /dev/null @@ -1,83 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.dataobject.aftersale; - -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 交易售后日志 DO - * - * // TODO 可优化:参考淘宝或者有赞:1)增加 action 表示什么操作;2)content 记录每个操作的明细 - * - * @author 芋道源码 - */ -@TableName("trade_after_sale_log") -@KeySequence("trade_after_sale_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class TradeAfterSaleLogDO extends BaseDO { - - /** - * 编号 - */ - @TableId - private Long id; - /** - * 用户编号 - * - * 关联 1:AdminUserDO 的 id 字段 - * 关联 2:MemberUserDO 的 id 字段 - */ - private Long userId; - /** - * 用户类型 - * - * 枚举 {@link UserTypeEnum} - */ - private Integer userType; - /** - * 售后编号 - * - * 关联 {@link TradeAfterSaleDO#getId()} - */ - private Long afterSaleId; - /** - * 订单编号 - * - * 关联 {@link TradeOrderDO#getId()} - */ - private Long orderId; - /** - * 订单项编号 - * - * 关联 {@link TradeOrderItemDO#getId()} - */ - private Long orderItemId; - /** - * 售后状态(之前) - * - * 枚举 {@link TradeAfterSaleStatusEnum} - */ - private Integer beforeStatus; - /** - * 售后状态(之后) - * - * 枚举 {@link TradeAfterSaleStatusEnum} - */ - private Integer afterStatus; - /** - * 操作明细 - */ - private String content; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java deleted file mode 100644 index 05fbb801d..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java +++ /dev/null @@ -1,90 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.dataobject.cart; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.experimental.Accessors; - -/** - * 购物车的商品信息 DO - * - * @author 芋道源码 - */ -@TableName("trade_cart_item") -@Data -@EqualsAndHashCode(callSuper = true) -@Accessors(chain = true) -public class TradeCartItemDO extends BaseDO { - - // ========= 基础字段 BEGIN ========= - - /** - * 编号,唯一自增 - */ - private Long id; - /** - * 是否选中 - */ - private Boolean selected; - - // ========= 基础字段 END ========= - - // ========= 买家信息 BEGIN ========= - - /** - * 用户编号 - * - * 关联 MemberUserDO 的 id 编号 - */ - private Long userId; - - // ========= 买家信息 END ========= - - // ========= 商品信息 BEGIN ========= - - /** - * 商品 SPU 编号 - * - * 关联 ProductSpuDO 的 id 编号 - */ - private Long spuId; - /** - * 商品 SKU 编号 - * - * 关联 ProductSkuDO 的 id 编号 - */ - private Long skuId; - /** - * 商品购买数量 - */ - private Integer count; - - // ========= 商品信息 END ========= - - // ========= 优惠信息 BEGIN ========= - -// /** -// * 商品营销活动编号 -// */ -// private Long activityId; // discount_id -// /** -// * 商品营销活动类型 -// */ -// private Integer activityType; - // TODO 芋艿:combination_id 拼团 ID - // TODO 芋艿:seckill_id 秒杀产品 ID - // TODO 芋艿:bargain_id 砍价 ID - - // ========= 优惠信息 END ========= - - // TODO 待确定字段:mf - // TODO 芋艿:distribution_card_no 推广员 - // TODO 芋艿:is_pay 未购买、已购买 - // TODO 芋艿:is_new 是否立即购买 - - // TODO 待确定字段: yv - // TODO isPay: 是否购买 - // TODO isNew:是否立即购买 - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java deleted file mode 100644 index 49d60ee37..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ /dev/null @@ -1,257 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.dataobject.order; - -import cn.iocoder.yudao.framework.common.enums.TerminalEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO.OrderItem; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderAfterSaleStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderDeliveryStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -import java.time.LocalDateTime; - -/** - * 交易订单 DO - * - * @author 芋道源码 - */ -@TableName("trade_order") -@KeySequence("trade_order_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class TradeOrderDO extends BaseDO { - - // ========== 订单基本信息 ========== - /** - * 订单编号,主键自增 - */ - private Long id; - /** - * 订单流水号 - * - * 例如说,1146347329394184195 - */ - private String no; - /** - * 订单类型 - * - * 枚举 {@link TradeOrderTypeEnum} - */ - private Integer type; - /** - * 订单来源 - * - * 枚举 {@link TerminalEnum} - */ - private Integer terminal; - /** - * 用户编号 - * - * 关联 MemberUserDO 的 id 编号 - */ - private Long userId; - /** - * 用户 IP - */ - private String userIp; - /** - * 用户备注 - */ - private String userRemark; - /** - * 订单状态 - * - * 枚举 {@link TradeOrderStatusEnum} - */ - private Integer status; - /** - * 购买的商品数量 - */ - private Integer productCount; - /** - * 订单完成时间 - */ - private LocalDateTime finishTime; - /** - * 订单取消时间 - */ - private LocalDateTime cancelTime; - /** - * 取消类型 - * - * 枚举 {@link TradeOrderCancelTypeEnum} - */ - private Integer cancelType; - /** - * 商家备注 - */ - private String remark; - - // ========== 价格 + 支付基本信息 ========== - - // 价格文档 - 淘宝:https://open.taobao.com/docV3.htm?docId=108471&docType=1 - // 价格文档 - 京东到家:https://openo2o.jddj.com/api/getApiDetail/182/4d1494c5e7ac4679bfdaaed950c5bc7f.htm - // 价格文档 - 有赞:https://doc.youzanyun.com/detail/API/0/906 - - /** - * 支付订单编号 - * - * 对接 pay-module-biz 支付服务的支付订单编号,即 PayOrderDO 的 id 编号 - */ - private Long payOrderId; - /** - * 是否已支付 - * - * true - 已经支付过 - * false - 没有支付过 - */ - private Boolean payed; - /** - * 付款时间 - */ - private LocalDateTime payTime; - /** - * 支付渠道 - * - * 对应 PayChannelEnum 枚举 - */ - private String payChannelCode; - - /** - * 商品原价(总),单位:分 - * - * 基于 {@link TradeOrderItemDO#getOriginalPrice()} 求和 - * - * 对应 taobao 的 trade.total_fee 字段 - */ - private Integer originalPrice; - /** - * 订单原价(总),单位:分 - * - * 基于 {@link OrderItem#getPayPrice()} 求和 - * 和 {@link #originalPrice} 的差异:去除商品级优惠 - */ - private Integer orderPrice; - /** - * 订单优惠(总),单位:分 - * - * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。 - * - * 对应 taobao 的 order.discount_fee 字段 - */ - private Integer discountPrice; - /** - * 运费金额,单位:分 - */ - private Integer deliveryPrice; - /** - * 订单调价(总),单位:分 - * - * 正数,加价;负数,减价 - */ - private Integer adjustPrice; - /** - * 应付金额(总),单位:分 - * - * = {@link OrderItem#getPayPrice()} 求和 - * - {@link #couponPrice} - * - {@link #pointPrice} - * + {@link #deliveryPrice} - * - {@link #discountPrice} - * + {@link #adjustPrice} - */ - private Integer payPrice; - - // ========== 收件 + 物流基本信息 ========== - /** - * 配置模板的编号 - * - * 关联 DeliveryTemplateDO 的 id 编号 - */ - private Long deliveryTemplateId; - /** - * 发货物流公司编号 - */ - private Long logisticsId; - /** - * 发货物流单号 - */ - private String logisticsNo; - /** - * 发货状态 - * - * 枚举 {@link TradeOrderDeliveryStatusEnum} - */ - private Integer deliveryStatus; - /** - * 发货时间 - */ - private LocalDateTime deliveryTime; - - /** - * 收货时间 - */ - private LocalDateTime receiveTime; - /** - * 收件人名称 - */ - private String receiverName; - /** - * 收件人手机 - */ - private String receiverMobile; - /** - * 收件人地区编号 - */ - private Integer receiverAreaId; - /** - * 收件人邮编 - */ - private Integer receiverPostCode; - /** - * 收件人详细地址 - */ - private String receiverDetailAddress; - - // ========== 售后基本信息 ========== - /** - * 收货状态 - * - * 枚举 {@link TradeOrderAfterSaleStatusEnum} - */ - private Integer afterSaleStatus; - /** - * 退款金额,单位:分 - * - * 注意,退款并不会影响 {@link #payPrice} 实际支付金额 - * 也就说,一个订单最终产生多少金额的收入 = payPrice - refundPrice - */ - private Integer refundPrice; - - // ========== 营销基本信息 ========== - /** - * 优惠劵编号 - */ - private Long couponId; - /** - * 优惠劵减免金额,单位:分 - * - * 对应 taobao 的 trade.coupon_fee 字段 - */ - private Integer couponPrice; - /** - * 积分抵扣的金额,单位:分 - * - * 对应 taobao 的 trade.point_fee 字段 - */ - private Integer pointPrice; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java deleted file mode 100644 index f8438030b..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java +++ /dev/null @@ -1,190 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.dataobject.order; - -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.experimental.Accessors; - -import java.io.Serializable; -import java.util.List; - -/** - * 交易订单项 DO - * - * @author 芋道源码 - */ -@TableName(value = "trade_order_item", autoResultMap = true) -@Data -@Accessors(chain = true) -@EqualsAndHashCode(callSuper = true) -public class TradeOrderItemDO extends BaseDO { - - // ========== 订单项基本信息 ========== - /** - * 编号 - */ - private Long id; - /** - * 用户编号 - * - * 关联 MemberUserDO 的 id 编号 - */ - private Long userId; - /** - * 订单编号 - * - * 关联 {@link TradeOrderDO#getId()} - */ - private Long orderId; - - // ========== 商品基本信息; 冗余较多字段,减少关联查询 ========== - /** - * 商品 SPU 编号 - * - * 关联 ProductSkuDO 的 spuId 编号 - */ - private Long spuId; - /** - * 商品 SPU 名称 - * - * 冗余 ProductSkuDO 的 spuName 编号 - */ - private String spuName; - /** - * 商品 SKU 编号 - * - * 关联 ProductSkuDO 的 id 编号 - */ - private Long skuId; - /** - * 属性数组,JSON 格式 - * - * 冗余 ProductSkuDO 的 properties 字段 - */ - @TableField(typeHandler = PropertyTypeHandler.class) - private List properties; - /** - * 商品图片 - */ - private String picUrl; - /** - * 购买数量 - */ - private Integer count; -// /** -// * 是否评论 TODO -// * -// * false - 未评论 -// * true - 已评论 -// */ -// private Boolean commented; - - // ========== 价格 + 支付基本信息 ========== - - /** - * 商品原价(总),单位:分 - * - * = {@link #originalUnitPrice} * {@link #getCount()} - */ - private Integer originalPrice; - /** - * 商品原价(单),单位:分 - * - * 对应 ProductSkuDO 的 price 字段 - * 对应 taobao 的 order.price 字段 - */ - private Integer originalUnitPrice; - /** - * 商品优惠(总),单位:分 - * - * 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元 - * - * 对应 taobao 的 order.discount_fee 字段 - */ - private Integer discountPrice; - /** - * 子订单实付金额,不算主订单分摊金额,单位:分 - * - * = {@link #originalPrice} - * - {@link #discountPrice} - * - * 对应 taobao 的 order.payment 字段 - */ - private Integer payPrice; - - /** - * 子订单分摊金额(总),单位:分 - * 需要分摊 {@link TradeOrderDO#getDiscountPrice()}、{@link TradeOrderDO#getCouponPrice()}、{@link TradeOrderDO#getPointPrice()} - * - * 对应 taobao 的 order.part_mjz_discount 字段 - * 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。 - */ - private Integer orderPartPrice; - /** - * 分摊后子订单实付金额(总),单位:分 - * - * = {@link #payPrice} - * - {@link #orderPartPrice} - * - * 对应 taobao 的 divide_order_fee 字段 - */ - private Integer orderDividePrice; - - // ========== 营销基本信息 ========== - - // TODO 芋艿:在捉摸一下 - - // ========== 售后基本信息 ========== - /** - * 售后状态 - * - * 枚举 {@link TradeOrderItemAfterSaleStatusEnum} - * - * @see TradeAfterSaleDO - */ - private Integer afterSaleStatus; - - /** - * 商品属性 - */ - @Data - public static class Property implements Serializable { - - /** - * 属性编号 - * - * 关联 ProductPropertyDO 的 id 编号 - */ - private Long propertyId; - /** - * 属性值编号 - * - * 关联 ProductPropertyValueDO 的 id 编号 - */ - private Long valueId; - - } - - // TODO @芋艿:可以找一些新的思路 - public static class PropertyTypeHandler extends AbstractJsonTypeHandler> { - - @Override - protected List parse(String json) { - return JsonUtils.parseArray(json, Property.class); - } - - @Override - protected String toJson(List obj) { - return JsonUtils.toJsonString(obj); - } - - } - -} - diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleLogMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleLogMapper.java deleted file mode 100644 index b92ce075f..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleLogMapper.java +++ /dev/null @@ -1,9 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.mysql.aftersale; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface TradeAfterSaleLogMapper extends BaseMapperX { -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java deleted file mode 100644 index 175d7d2b0..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.mysql.aftersale; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface TradeAfterSaleMapper extends BaseMapperX { - - default PageResult selectPage(TradeAfterSalePageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(TradeAfterSaleDO::getNo, reqVO.getNo()) - .eqIfPresent(TradeAfterSaleDO::getStatus, reqVO.getStatus()) - .eqIfPresent(TradeAfterSaleDO::getType, reqVO.getType()) - .eqIfPresent(TradeAfterSaleDO::getWay, reqVO.getWay()) - .likeIfPresent(TradeAfterSaleDO::getOrderNo, reqVO.getOrderNo()) - .likeIfPresent(TradeAfterSaleDO::getSpuName, reqVO.getSpuName()) - .betweenIfPresent(TradeAfterSaleDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(TradeAfterSaleDO::getId)); - } - - default int updateByIdAndStatus(Long id, Integer status, TradeAfterSaleDO update) { - return update(update, new LambdaUpdateWrapper() - .eq(TradeAfterSaleDO::getId, id).eq(TradeAfterSaleDO::getStatus, status)); - } - - default TradeAfterSaleDO selectByPayRefundId(Long payRefundId) { - return selectOne(TradeAfterSaleDO::getPayRefundId, payRefundId); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java deleted file mode 100644 index fa6adbf41..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.mysql.cart; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -@Mapper -public interface TradeCartItemMapper extends BaseMapperX { - - default TradeCartItemDO selectByUserIdAndSkuId(Long userId, Long skuId) { - return selectOne(TradeCartItemDO::getUserId, userId, - TradeCartItemDO::getSkuId, skuId); - } - - default List selectListByUserIdAndSkuIds(Long userId, Collection skuIds) { - return selectList(new LambdaQueryWrapper().eq(TradeCartItemDO::getUserId, userId) - .in(TradeCartItemDO::getSkuId, skuIds)); - } - - default void updateByIds(Collection ids, TradeCartItemDO updateObject) { - update(updateObject, new LambdaQueryWrapper().in(TradeCartItemDO::getId, ids)); - } - - default Integer selectSumByUserId(Long userId) { - // SQL sum 查询 - List> result = selectMaps(new QueryWrapper() - .select("SUM(count) AS sumCount") - .eq("user_id", userId)); - // 获得数量 - return CollUtil.isNotEmpty(result) ? MapUtil.getInt(result.get(0), "sumCount") : 0; - } - - default List selectListByUserId(Long userId, Boolean selected) { - return selectList(new LambdaQueryWrapperX().eq(TradeCartItemDO::getUserId, userId) - .eqIfPresent(TradeCartItemDO::getSelected, selected)); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java deleted file mode 100644 index edb45fb62..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.mysql.order; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -@Mapper -public interface TradeOrderItemMapper extends BaseMapperX { - - default int updateAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus) { - return update(new TradeOrderItemDO().setAfterSaleStatus(newAfterSaleStatus), - new LambdaUpdateWrapper<>(new TradeOrderItemDO().setId(id).setAfterSaleStatus(oldAfterSaleStatus))); - } - - default List selectListByOrderId(Long orderId) { - return selectList(TradeOrderItemDO::getOrderId, orderId); - } - - default List selectListByOrderId(Collection orderIds) { - return selectList(TradeOrderItemDO::getOrderId, orderIds); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java deleted file mode 100644 index 7be224744..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.iocoder.yudao.module.trade.dal.mysql.order; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Set; - -@Mapper -public interface TradeOrderMapper extends BaseMapperX { - - default int updateByIdAndStatus(Long id, Integer status, TradeOrderDO update) { - return update(update, new LambdaUpdateWrapper() - .eq(TradeOrderDO::getId, id).eq(TradeOrderDO::getStatus, status)); - } - - default TradeOrderDO selectByIdAndUserId(Long id, Long userId) { - return selectOne(TradeOrderDO::getId, id, TradeOrderDO::getUserId, userId); - } - - default PageResult selectPage(TradeOrderPageReqVO reqVO, Set userIds) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(TradeOrderDO::getNo, reqVO.getNo()) - .eqIfPresent(TradeOrderDO::getUserId, reqVO.getUserId()) - .inIfPresent(TradeOrderDO::getUserId, userIds) - .likeIfPresent(TradeOrderDO::getReceiverName, reqVO.getReceiverName()) - .likeIfPresent(TradeOrderDO::getReceiverMobile, reqVO.getReceiverMobile()) - .eqIfPresent(TradeOrderDO::getType, reqVO.getType()) - .eqIfPresent(TradeOrderDO::getStatus, reqVO.getStatus()) - .eqIfPresent(TradeOrderDO::getPayChannelCode, reqVO.getPayChannelCode()) - .betweenIfPresent(TradeOrderDO::getCreateTime, reqVO.getCreateTime())); - } - - default PageResult selectPage(AppTradeOrderPageReqVO reqVO, Long userId) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eq(TradeOrderDO::getUserId, userId) - .eqIfPresent(TradeOrderDO::getStatus, reqVO.getStatus()) - .orderByDesc(TradeOrderDO::getId)); // TODO 芋艿:未来不同的 status,不同的排序 - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/package-info.java deleted file mode 100644 index 37e0ba7d6..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * TODO 占位 - */ -package cn.iocoder.yudao.module.trade.dal.mysql; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java deleted file mode 100644 index 715169275..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.module.trade.framework.order.config; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -// TODO @LeeYan9: 可以直接给 TradeOrderProperties 一个 @Component生效哈 -/** - * @author LeeYan9 - * @since 2022-09-15 - */ -@Configuration -@EnableConfigurationProperties(TradeOrderProperties.class) -public class TradeOrderConfig { -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java deleted file mode 100644 index 4d584f4c9..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.trade.framework.order.config; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -import javax.validation.constraints.NotNull; -import java.time.Duration; - -/** - * 交易订单的配置项 - * - * @author LeeYan9 - * @since 2022-09-15 - */ -@ConfigurationProperties(prefix = "yudao.trade.order") -@Data -@Validated -public class TradeOrderProperties { - - /** - * 应用编号 - */ - @NotNull(message = "应用编号不能为空") - private Long appId; - - /** - * 支付超时时间 - */ - @NotNull(message = "支付超时时间不能为空") - private Duration expireTime; - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/package-info.java deleted file mode 100644 index 393abea6a..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * product 模块,product 模块,主要实现商品相关功能 - * 例如:品牌、商品分类、spu、sku等功能。 - * - * 1. Controller URL:以 /product/ 开头,避免和其它 Module 冲突 - * 2. DataObject 表名:以 product_ 开头,方便在数据库中区分 - */ -package cn.iocoder.yudao.module.trade; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java deleted file mode 100644 index d0d86c033..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java +++ /dev/null @@ -1,94 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.aftersale; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO; -import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; - -/** - * 交易售后 Service 接口 - * - * @author 芋道源码 - */ -public interface TradeAfterSaleService { - - /** - * 获得交易售后分页 - * - * @param pageReqVO 分页查询 - * @return 交易售后分页 - */ - PageResult getAfterSalePage(TradeAfterSalePageReqVO pageReqVO); - - /** - * 【会员】创建交易售后 - *

- * 一般是用户发起售后请求 - * - * @param userId 会员用户编号 - * @param createReqVO 创建 Request 信息 - * @return 交易售后编号 - */ - Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO); - - /** - * 【管理员】同意交易售后 - * - * @param userId 管理员用户编号 - * @param id 交易售后编号 - */ - void agreeAfterSale(Long userId, Long id); - - /** - * 【管理员】拒绝交易售后 - * - * @param userId 管理员用户编号 - * @param auditReqVO 审批 Request 信息 - */ - void disagreeAfterSale(Long userId, TradeAfterSaleDisagreeReqVO auditReqVO); - - /** - * 【会员】退回货物 - * - * @param userId 会员用户编号 - * @param deliveryReqVO 退货 Request 信息 - */ - void deliveryAfterSale(Long userId, AppTradeAfterSaleDeliveryReqVO deliveryReqVO); - - /** - * 【管理员】确认收货 - * - * @param userId 管理员编号 - * @param id 交易售后编号 - */ - void receiveAfterSale(Long userId, Long id); - - /** - * 【管理员】拒绝收货 - * - * @param userId 管理员用户编号 - * @param refuseReqVO 拒绝收货 Request 信息 - */ - void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO refuseReqVO); - - /** - * 【管理员】确认退款 - * - * @param userId 管理员用户编号 - * @param userIp 管理员用户 IP - * @param id 售后编号 - */ - void refundAfterSale(Long userId, String userIp, Long id); - - /** - * 【会员】取消售后 - * - * @param userId 会员用户编号 - * @param id 交易售后编号 - */ - void cancelAfterSale(Long userId, Long id); - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java deleted file mode 100644 index 2da892d61..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java +++ /dev/null @@ -1,392 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.aftersale; - -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; -import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; -import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO; -import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; -import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; -import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleLogMapper; -import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleMapper; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; -import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; -import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.transaction.support.TransactionSynchronization; -import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; - -/** - * 交易售后 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { - - @Resource - private TradeOrderService tradeOrderService; - - @Resource - private TradeAfterSaleMapper tradeAfterSaleMapper; - @Resource - private TradeAfterSaleLogMapper tradeAfterSaleLogMapper; - - @Resource - private PayRefundApi payRefundApi; - - @Resource - private TradeOrderProperties tradeOrderProperties; - - @Override - public PageResult getAfterSalePage(TradeAfterSalePageReqVO pageReqVO) { - return tradeAfterSaleMapper.selectPage(pageReqVO); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO) { - // 第一步,前置校验 - TradeOrderItemDO tradeOrderItem = validateOrderItemApplicable(userId, createReqVO); - - // 第二步,存储交易售后 - TradeAfterSaleDO afterSale = createAfterSale(createReqVO, tradeOrderItem); - return afterSale.getId(); - } - - /** - * 校验交易订单项是否可以申请售后 - * - * @param userId 用户编号 - * @param createReqVO 售后创建信息 - * @return 交易订单项 - */ - private TradeOrderItemDO validateOrderItemApplicable(Long userId, AppTradeAfterSaleCreateReqVO createReqVO) { - // 校验订单项存在 - TradeOrderItemDO orderItem = tradeOrderService.getOrderItem(userId, createReqVO.getOrderItemId()); - if (orderItem == null) { - throw exception(ORDER_ITEM_NOT_FOUND); - } - - // 已申请售后,不允许再发起售后申请 - if (!TradeOrderItemAfterSaleStatusEnum.isNone(orderItem.getAfterSaleStatus())) { - throw exception(AFTER_SALE_CREATE_FAIL_ORDER_ITEM_APPLIED); - } - - // 申请的退款金额,不能超过商品的价格 - if (createReqVO.getRefundPrice() > orderItem.getOrderDividePrice()) { - throw exception(AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR); - } - - // 校验订单存在 - TradeOrderDO order = tradeOrderService.getOrder(userId, orderItem.getOrderId()); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - // TODO 芋艿:超过一定时间,不允许售后 - // 已取消,无法发起售后 - if (TradeOrderStatusEnum.isCanceled(order.getStatus())) { - throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_CANCELED); - } - // 未支付,无法发起售后 - if (!TradeOrderStatusEnum.havePaid(order.getStatus())) { - throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_PAID); - } - // 如果是【退货退款】的情况,需要额外校验是否发货 - if (createReqVO.getWay().equals(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay()) - && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) { - throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED); - } - return orderItem; - } - - private TradeAfterSaleDO createAfterSale(AppTradeAfterSaleCreateReqVO createReqVO, - TradeOrderItemDO orderItem) { - // 创建售后单 - TradeAfterSaleDO afterSale = TradeAfterSaleConvert.INSTANCE.convert(createReqVO, orderItem); - afterSale.setNo(RandomUtil.randomString(10)); // TODO 芋艿:优化 no 生成逻辑 - afterSale.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus()); - // 标记是售中还是售后 - TradeOrderDO order = tradeOrderService.getOrder(orderItem.getUserId(), orderItem.getOrderId()); - afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索 - afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus()) - ? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType()); - // TODO 退还积分 - tradeAfterSaleMapper.insert(afterSale); - - // 更新交易订单项的售后状态 - tradeOrderService.updateOrderItemAfterSaleStatus(orderItem.getId(), - TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), - TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), null); - - // 记录售后日志 - createAfterSaleLog(orderItem.getUserId(), UserTypeEnum.MEMBER.getValue(), - afterSale, null, afterSale.getStatus()); - - // TODO 发送售后消息 - return afterSale; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void agreeAfterSale(Long userId, Long id) { - // 校验售后单存在,并状态未审批 - TradeAfterSaleDO afterSale = validateAfterSaleAuditable(id); - - // 更新售后单的状态 - // 情况一:退款:标记为 WAIT_REFUND 状态。后续等退款发起成功后,在标记为 COMPLETE 状态 - // 情况二:退货退款:需要等用户退货后,才能发起退款 - Integer newStatus = afterSale.getType().equals(TradeAfterSaleWayEnum.REFUND.getWay()) ? - TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus() : TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus(); - updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO() - .setStatus(newStatus).setAuditUserId(userId).setAuditTime(LocalDateTime.now())); - - // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), - afterSale, afterSale.getStatus(), newStatus); - - // TODO 发送售后消息 - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void disagreeAfterSale(Long userId, TradeAfterSaleDisagreeReqVO auditReqVO) { - // 校验售后单存在,并状态未审批 - TradeAfterSaleDO afterSale = validateAfterSaleAuditable(auditReqVO.getId()); - - // 更新售后单的状态 - Integer newStatus = TradeAfterSaleStatusEnum.SELLER_DISAGREE.getStatus(); - updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO() - .setStatus(newStatus).setAuditUserId(userId).setAuditTime(LocalDateTime.now()) - .setAuditReason(auditReqVO.getAuditReason())); - - // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), - afterSale, afterSale.getStatus(), newStatus); - - // TODO 发送售后消息 - - // 更新交易订单项的售后状态为【未申请】 - tradeOrderService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(), - TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), - TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null); - } - - /** - * 校验售后单是否可审批(同意售后、拒绝售后) - * - * @param id 售后编号 - * @return 售后单 - */ - private TradeAfterSaleDO validateAfterSaleAuditable(Long id) { - TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); - if (afterSale == null) { - throw exception(AFTER_SALE_NOT_FOUND); - } - if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus())) { - throw exception(AFTER_SALE_AUDIT_FAIL_STATUS_NOT_APPLY); - } - return afterSale; - } - - private void updateAfterSaleStatus(Long id, Integer status, TradeAfterSaleDO updateObj) { - int updateCount = tradeAfterSaleMapper.updateByIdAndStatus(id, status, updateObj); - if (updateCount == 0) { - throw exception(AFTER_SALE_UPDATE_STATUS_FAIL); - } - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void deliveryAfterSale(Long userId, AppTradeAfterSaleDeliveryReqVO deliveryReqVO) { - // 校验售后单存在,并状态未退货 - TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(deliveryReqVO.getId()); - if (afterSale == null) { - throw exception(AFTER_SALE_NOT_FOUND); - } - if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus())) { - throw exception(AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE); - } - - // 更新售后单的物流信息 - updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus(), new TradeAfterSaleDO() - .setStatus(TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus()) - .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()) - .setDeliveryTime(deliveryReqVO.getDeliveryTime())); - - // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.MEMBER.getValue(), - afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus()); - - // TODO 发送售后消息 - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void receiveAfterSale(Long userId, Long id) { - // 校验售后单存在,并状态为已退货 - TradeAfterSaleDO afterSale = validateAfterSaleReceivable(id); - - // 更新售后单的状态 - updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new TradeAfterSaleDO() - .setStatus(TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus()).setReceiveTime(LocalDateTime.now())); - - // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), - afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus()); - - // TODO 发送售后消息 - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO refuseReqVO) { - // 校验售后单存在,并状态为已退货 - TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(refuseReqVO.getId()); - if (afterSale == null) { - throw exception(AFTER_SALE_NOT_FOUND); - } - if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) { - throw exception(AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY); - } - - // 更新售后单的状态 - updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new TradeAfterSaleDO() - .setStatus(TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()).setReceiveTime(LocalDateTime.now()) - .setReceiveReason(refuseReqVO.getRefuseMemo())); - - // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), - afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()); - - // TODO 发送售后消息 - - // 更新交易订单项的售后状态为【未申请】 - tradeOrderService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(), - TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), - TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null); - } - - /** - * 校验售后单是否可收货,即处于买家已发货 - * - * @param id 售后编号 - * @return 售后单 - */ - private TradeAfterSaleDO validateAfterSaleReceivable(Long id) { - TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); - if (afterSale == null) { - throw exception(AFTER_SALE_NOT_FOUND); - } - if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) { - throw exception(AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY); - } - return afterSale; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void refundAfterSale(Long userId, String userIp, Long id) { - // 校验售后单的状态,并状态待退款 - TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectByPayRefundId(id); - if (afterSale == null) { - throw exception(AFTER_SALE_NOT_FOUND); - } - if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus())) { - throw exception(AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND); - } - - // 发起退款单。注意,需要在事务提交后,再进行发起,避免重复发起 - createPayRefund(userIp, afterSale); - - // 更新售后单的状态为【已完成】 - updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus(), new TradeAfterSaleDO() - .setStatus(TradeAfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now())); - - // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), - afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.COMPLETE.getStatus()); - - // TODO 发送售后消息 - - // 更新交易订单项的售后状态为【已完成】 - tradeOrderService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(), - TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), - TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus(), afterSale.getRefundPrice()); - } - - private void createPayRefund(String userIp, TradeAfterSaleDO afterSale) { - TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { - - @Override - public void afterCommit() { - // 创建退款单 - PayRefundCreateReqDTO createReqDTO = TradeAfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties); - Long payRefundId = payRefundApi.createPayRefund(createReqDTO); - // 更新售后单的退款单号 - tradeAfterSaleMapper.updateById(new TradeAfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId)); - } - }); - } - - @Override - public void cancelAfterSale(Long userId, Long id) { - // 校验售后单的状态,并状态待退款 - TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectByPayRefundId(id); - if (afterSale == null) { - throw exception(AFTER_SALE_NOT_FOUND); - } - if (ObjectUtils.equalsAny(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus(), - TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus())) { - throw exception(AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE); - } - - // 更新售后单的状态为【已取消】 - updateAfterSaleStatus(afterSale.getId(), afterSale.getStatus(), new TradeAfterSaleDO() - .setStatus(TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus())); - - // 记录售后日志 - createAfterSaleLog(userId, UserTypeEnum.MEMBER.getValue(), - afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus()); - - // TODO 发送售后消息 - - // 更新交易订单项的售后状态为【未申请】 - tradeOrderService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(), - TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), - TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null); - } - - private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale, - Integer beforeStatus, Integer afterStatus) { - TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO().setUserId(userId).setUserType(userType) - .setAfterSaleId(afterSale.getId()).setOrderId(afterSale.getOrderId()) - .setOrderItemId(afterSale.getOrderItemId()).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus) - .setContent(TradeAfterSaleStatusEnum.valueOf(afterStatus).getContent()); - tradeAfterSaleLogMapper.insert(afterSaleLog); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java deleted file mode 100644 index 3f46f5102..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java +++ /dev/null @@ -1,66 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.cart; - -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO; - -import javax.validation.Valid; -import java.util.Collection; - -/** - * 购物车 Service 接口 - * - * @author 芋道源码 - */ -public interface TradeCartService { - - /** - * 添加商品到购物车 - * - * @param userId 用户编号 - * @param addCountReqVO 添加信息 - */ - void addCartItemCount(Long userId, @Valid AppTradeCartItemAddCountReqVO addCountReqVO); - - /** - * 更新购物车商品数量 - * - * @param userId 用户编号 - * @param updateCountReqVO 更新信息 - */ - void updateCartItemCount(Long userId, AppTradeCartItemUpdateCountReqVO updateCountReqVO); - - /** - * 更新购物车商品是否选中 - * - * @param userId 用户编号 - * @param updateSelectedReqVO 更新信息 - */ - void updateCartItemSelected(Long userId, AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO); - - /** - * 删除购物车商品 - * - * @param userId 用户编号 - * @param skuIds SKU 编号的数组 - */ - void deleteCartItems(Long userId, Collection skuIds); - - /** - * 查询用户在购物车中的商品数量 - * - * @param userId 用户编号 - * @return 商品数量 - */ - Integer getCartCount(Long userId); - - /** - * 查询用户的购物车详情 - * - * @param userId 用户编号 - * @return 购物车详情 - */ - AppTradeCartDetailRespVO getCartDetail(Long userId); - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java deleted file mode 100644 index ae0301e83..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java +++ /dev/null @@ -1,184 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.cart; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.promotion.api.price.PriceApi; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO; -import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO; -import cn.iocoder.yudao.module.trade.convert.cart.TradeCartConvert; -import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO; -import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartItemMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.CARD_ITEM_NOT_FOUND; - -/** - * 购物车 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class TradeCartServiceImpl implements TradeCartService { - - @Resource - private TradeCartItemMapper cartItemMapper; - - @Resource - private ProductSkuApi productSkuApi; - @Resource - private PriceApi priceApi; - - @Override - public void addCartItemCount(Long userId, AppTradeCartItemAddCountReqVO addCountReqVO) { - Long skuId = addCountReqVO.getSkuId(); - Integer count = addCountReqVO.getCount(); - // 查询 CartItemDO - TradeCartItemDO tradeItem = cartItemMapper.selectByUserIdAndSkuId(userId, addCountReqVO.getSkuId()); - - // 存在,则进行数量更新 - if (tradeItem != null) { - checkProductSku(skuId, tradeItem.getCount() + count); - cartItemMapper.updateById(new TradeCartItemDO().setId(tradeItem.getId()) - .setSelected(true).setCount(tradeItem.getCount() + count)); - return; - } - - // 不存在,则进行插入 - ProductSkuRespDTO sku = checkProductSku(skuId, count); - cartItemMapper.insert(new TradeCartItemDO().setUserId(userId).setSpuId(sku.getSpuId()).setSkuId(sku.getId()) - .setSelected(true).setCount(count)); - } - - @Override - public void updateCartItemCount(Long userId, AppTradeCartItemUpdateCountReqVO updateCountReqVO) { - // 校验 TradeCartItemDO 存在 - TradeCartItemDO tradeItem = cartItemMapper.selectByUserIdAndSkuId(userId, updateCountReqVO.getSkuId()); - if (tradeItem == null) { - throw exception(CARD_ITEM_NOT_FOUND); - } - // 校验商品 SKU - checkProductSku(updateCountReqVO.getSkuId(), updateCountReqVO.getCount()); - - // 更新数量 - cartItemMapper.updateById(new TradeCartItemDO().setId(tradeItem.getId()).setCount(updateCountReqVO.getCount())); - } - - @Override - public void updateCartItemSelected(Long userId, AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO) { - // 查询 CartItemDO 列表 - List cartItems = cartItemMapper.selectListByUserIdAndSkuIds(userId, updateSelectedReqVO.getSkuIds()); - if (CollUtil.isEmpty(cartItems)) { - return; - } - - // 更新选中 - cartItemMapper.updateByIds(CollectionUtils.convertList(cartItems, TradeCartItemDO::getId), - new TradeCartItemDO().setSelected(updateSelectedReqVO.getSelected())); - } - - /** - * 购物车删除商品 - * - * @param userId 用户编号 - * @param skuIds 商品 SKU 编号的数组 - */ - @Override - public void deleteCartItems(Long userId, Collection skuIds) { - // 查询 CartItemDO 列表 - List cartItems = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds); - if (CollUtil.isEmpty(cartItems)) { - return; - } - - // 批量标记删除 - cartItemMapper.deleteBatchIds(CollectionUtils.convertSet(cartItems, TradeCartItemDO::getId)); - } - - @Override - public Integer getCartCount(Long userId) { - return cartItemMapper.selectSumByUserId(userId); - } - - @Override - public AppTradeCartDetailRespVO getCartDetail(Long userId) { - // 获得购物车的商品 - List cartItems = cartItemMapper.selectListByUserId(userId, null); - // 如果未空,则返回空结果 - if (CollUtil.isEmpty(cartItems)) { - return TradeCartConvert.INSTANCE.buildEmptyAppTradeCartDetailRespVO(); - } - - // 调用价格服务,计算价格 - PriceCalculateRespDTO priceCalculate = priceApi.calculatePrice(TradeCartConvert.INSTANCE.convert(userId, cartItems)); - - // 转换返回 - Map cartItemMap = convertMap(cartItems, TradeCartItemDO::getSkuId); - Map orderItemMap = convertMap(priceCalculate.getOrder().getItems(), - PriceCalculateRespDTO.OrderItem::getSkuId); - List itemGroups = new ArrayList<>(cartItems.size()); - // ① 场景一,营销活动,订单级别 TODO 芋艿:待测试 - priceCalculate.getPromotions().stream().filter(promotion -> PromotionLevelEnum.ORDER.getLevel().equals(promotion.getLevel())) - .forEach(promotion -> { - AppTradeCartDetailRespVO.ItemGroup itemGroup = new AppTradeCartDetailRespVO.ItemGroup().setItems(new ArrayList<>()) - .setPromotion(TradeCartConvert.INSTANCE.convert(promotion)); - itemGroups.add(itemGroup); - promotion.getItems().forEach(promotionItem -> { - PriceCalculateRespDTO.OrderItem orderItem = orderItemMap.remove(promotionItem.getSkuId()); - Assert.notNull(orderItem, "商品 SKU({}) 对应的订单项不能为空", promotionItem.getSkuId()); - TradeCartItemDO cartItem = cartItemMap.get(orderItem.getSkuId()); - itemGroup.getItems().add(TradeCartConvert.INSTANCE.convert(orderItem, cartItem)); // TODO spu - }); - }); - // ② 场景二,营销活动,商品级别 - orderItemMap.values().forEach(orderItem -> { - AppTradeCartDetailRespVO.ItemGroup itemGroup = new AppTradeCartDetailRespVO.ItemGroup().setItems(new ArrayList<>(1)).setPromotion(null); - itemGroups.add(itemGroup); - TradeCartItemDO cartItem = cartItemMap.get(orderItem.getSkuId()); - itemGroup.getItems().add(TradeCartConvert.INSTANCE.convert(orderItem, cartItem)); // TODO spu - }); - return new AppTradeCartDetailRespVO().setItemGroups(itemGroups) - .setOrder(TradeCartConvert.INSTANCE.convert(priceCalculate.getOrder())); - } - - /** - * 校验商品 SKU 是否合法 - * 1. 是否存在 - * 2. 是否下架 - * 3. 库存不足 - * - * @param skuId 商品 SKU 编号 - * @param count 商品数量 - * @return 商品 SKU - */ - private ProductSkuRespDTO checkProductSku(Long skuId, Integer count) { - ProductSkuRespDTO sku = productSkuApi.getSku(skuId); - if (sku == null || CommonStatusEnum.DISABLE.getStatus().equals(sku.getStatus())) { - throw exception(SKU_NOT_EXISTS); - } - if (count > sku.getStock()) { - throw exception(SKU_STOCK_NOT_ENOUGH); - } - return sku; - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java deleted file mode 100644 index 086f65edd..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java +++ /dev/null @@ -1,142 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.order; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; - -import java.util.Collection; -import java.util.List; - -import static java.util.Collections.singleton; - -/** - * 交易订单 Service 接口 - * - * @author LeeYan9 - * @since 2022-08-26 - */ -public interface TradeOrderService { - - // =================== Order =================== - - /** - * 【会员】创建交易订单 - * - * @param userId 登录用户 - * @param userIp 用户 IP 地址 - * @param createReqVO 创建交易订单请求模型 - * @return 交易订单的编号 - */ - Long createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO); - - /** - * 更新交易订单已支付 - * - * @param id 交易订单编号 - * @param payOrderId 支付订单编号 - */ - void updateOrderPaid(Long id, Long payOrderId); - - /** - * 【管理员】发货交易订单 - * - * @param userId 管理员编号 - * @param deliveryReqVO 发货请求 - */ - void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO); - - /** - * 【会员】收货交易订单 - * - * @param userId 用户编号 - * @param id 订单编号 - */ - void receiveOrder(Long userId, Long id); - - /** - * 获得指定编号的交易订单 - * - * @param id 交易订单编号 - * @return 交易订单 - */ - TradeOrderDO getOrder(Long id); - - /** - * 获得指定用户,指定的交易订单 - * - * @param userId 用户编号 - * @param id 交易订单编号 - * @return 交易订单 - */ - TradeOrderDO getOrder(Long userId, Long id); - - /** - * 【管理员】获得交易订单分页 - * - * @param reqVO 分页请求 - * @return 交易订单 - */ - PageResult getOrderPage(TradeOrderPageReqVO reqVO); - - /** - * 【会员】获得交易订单分页 - * - * @param userId 用户编号 - * @param reqVO 分页请求 - * @return 交易订单 - */ - PageResult getOrderPage(Long userId, AppTradeOrderPageReqVO reqVO); - - // =================== Order Item =================== - - /** - * 获得指定用户,指定的交易订单项 - * - * @param userId 用户编号 - * @param itemId 交易订单项编号 - * @return 交易订单项 - */ - TradeOrderItemDO getOrderItem(Long userId, Long itemId); - - /** - * 更新交易订单项的售后状态 - * - * @param id 交易订单项编号 - * @param oldAfterSaleStatus 当前售后状态;如果不符,更新后会抛出异常 - * @param newAfterSaleStatus 目标售后状态 - * @param refundPrice 退款金额;当订单项退款成功时,必须传递该值 - */ - void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, - Integer newAfterSaleStatus, Integer refundPrice); - - /** - * 根据交易订单项编号数组,查询交易订单项 - * - * @param ids 交易订单项编号数组 - * @return 交易订单项数组 - */ - List getOrderItemList(Collection ids); - - /** - * 根据交易订单编号,查询交易订单项 - * - * @param orderId 交易订单编号 - * @return 交易订单项数组 - */ - default List getOrderItemListByOrderId(Long orderId) { - return getOrderItemListByOrderId(singleton(orderId)); - } - - /** - * 根据交易订单编号数组,查询交易订单项 - * - * @param orderIds 交易订单编号数组 - * @return 交易订单项数组 - */ - List getOrderItemListByOrderId(Collection orderIds); - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java deleted file mode 100644 index 86d84c415..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ /dev/null @@ -1,530 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.order; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.core.KeyValue; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.enums.TerminalEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.module.member.api.address.AddressApi; -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; -import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; -import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; -import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; -import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; -import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; -import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; -import cn.iocoder.yudao.module.promotion.api.price.PriceApi; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO.Item; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; -import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; -import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants; -import cn.iocoder.yudao.module.trade.enums.order.*; -import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Resource; -import java.time.LocalDateTime; -import java.util.*; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND; -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; - -/** - * 交易订单 Service 实现类 - * - * @author LeeYan9 - * @since 2022-08-26 - */ -@Service -@Slf4j -public class TradeOrderServiceImpl implements TradeOrderService { - - @Resource - private TradeOrderMapper tradeOrderMapper; - @Resource - private TradeOrderItemMapper tradeOrderItemMapper; - - @Resource - private PriceApi priceApi; - @Resource - private ProductSkuApi productSkuApi; - @Resource - private ProductSpuApi productSpuApi; - @Resource - private PayOrderApi payOrderApi; - @Resource - private AddressApi addressApi; - @Resource - private CouponApi couponApi; - @Resource - private MemberUserApi memberUserApi; - - @Resource - private TradeOrderProperties tradeOrderProperties; - - // =================== Order =================== - - @Override - @Transactional(rollbackFor = Exception.class) - public Long createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) { - // 商品 SKU 检查:可售状态、库存 - List skus = validateSkuSaleable(createReqVO.getItems()); - // 商品 SPU 检查:可售状态 - List spus = validateSpuSaleable(convertSet(skus, ProductSkuRespDTO::getSpuId)); - // 用户收件地址的校验 - AddressRespDTO address = validateAddress(userId, createReqVO.getAddressId()); - - // 价格计算 - PriceCalculateRespDTO priceResp = priceApi.calculatePrice(TradeOrderConvert.INSTANCE.convert(createReqVO, userId)); - - // 插入 TradeOrderDO 订单 - TradeOrderDO tradeOrderDO = createTradeOrder(userId, userIp, createReqVO, priceResp.getOrder(), address); - // 插入 TradeOrderItemDO 订单项 - List tradeOrderItems = createTradeOrderItems(tradeOrderDO, priceResp.getOrder().getItems(), skus); - - // 订单创建完后的逻辑 - afterCreateTradeOrder(userId, createReqVO, tradeOrderDO, tradeOrderItems, spus); - // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! - return tradeOrderDO.getId(); - } - - /** - * 校验商品 SKU 是否可出售 - * - * @param items 商品 SKU - * @return 商品 SKU 数组 - */ - private List validateSkuSaleable(List items) { - List skus = productSkuApi.getSkuList(convertSet(items, Item::getSkuId)); - // SKU 不存在 - if (items.size() != skus.size()) { - throw exception(ORDER_CREATE_SKU_NOT_FOUND); - } - // 校验是否禁用 or 库存不足 - Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); - items.forEach(item -> { - ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); - // SKU 禁用 - if (ObjectUtil.notEqual(CommonStatusEnum.ENABLE.getStatus(), sku.getStatus())) { - throw exception(ORDER_CREATE_SKU_NOT_SALE); - } - // SKU 库存不足 - if (item.getCount() > sku.getStock()) { - throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH); - } - }); - return skus; - } - - /** - * 校验商品 SPU 是否可出售 - * - * @param spuIds 商品 SPU 编号数组 - * @return 商品 SPU 数组 - */ - private List validateSpuSaleable(Set spuIds) { - List spus = productSpuApi.getSpuList(spuIds); - // SPU 不存在 - if (spus.size() != spuIds.size()) { - throw exception(ORDER_CREATE_SPU_NOT_FOUND); - } - // 校验是否存在禁用的 SPU - ProductSpuRespDTO spu = CollectionUtils.findFirst(spus, - spuDTO -> ObjectUtil.notEqual(ProductSpuStatusEnum.ENABLE.getStatus(), spuDTO.getStatus())); - if (spu != null) { - throw exception(ErrorCodeConstants.ORDER_CREATE_SPU_NOT_SALE); - } - return spus; - } - - /** - * 校验收件地址是否存在 - * - * @param userId 用户编号 - * @param addressId 收件地址编号 - * @return 收件地址 - */ - private AddressRespDTO validateAddress(Long userId, Long addressId) { - AddressRespDTO address = addressApi.getAddress(addressId, userId); - if (Objects.isNull(address)) { - throw exception(ErrorCodeConstants.ORDER_CREATE_ADDRESS_NOT_FOUND); - } - return address; - } - - private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO, - PriceCalculateRespDTO.Order order, AddressRespDTO address) { - TradeOrderDO tradeOrderDO = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, order, address); - tradeOrderDO.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的; - tradeOrderDO.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); - tradeOrderDO.setType(TradeOrderTypeEnum.NORMAL.getType()); - tradeOrderDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NONE.getStatus()); - tradeOrderDO.setProductCount(getSumValue(order.getItems(), PriceCalculateRespDTO.OrderItem::getCount, Integer::sum)); - tradeOrderDO.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源? - tradeOrderDO.setAdjustPrice(0).setPayed(false); // 支付信息 - tradeOrderDO.setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); // 物流信息 - tradeOrderDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NONE.getStatus()).setRefundPrice(0); // 退款信息 - tradeOrderMapper.insert(tradeOrderDO); - return tradeOrderDO; - } - - private List createTradeOrderItems(TradeOrderDO tradeOrderDO, - List orderItems, List skus) { - List tradeOrderItemDOs = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, orderItems, skus); - tradeOrderItemMapper.insertBatch(tradeOrderItemDOs); - return tradeOrderItemDOs; - } - - /** - * 执行创建完创建完订单后的逻辑 - * - * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等 - * - * @param userId 用户编号 - * @param createReqVO 创建订单请求 - * @param tradeOrderDO 交易订单 - */ - private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, - TradeOrderDO tradeOrderDO, List tradeOrderItemDOs, - List spus) { - // 下单时扣减商品库存 - productSkuApi.updateSkuStock(new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(tradeOrderItemDOs))); - - // 删除购物车商品 TODO 芋艿:待实现 - - // 扣减积分,抵扣金额 TODO 芋艿:待实现 - - // 有使用优惠券时更新 - if (createReqVO.getCouponId() != null) { - couponApi.useCoupon(new CouponUseReqDTO().setId(createReqVO.getCouponId()).setUserId(userId) - .setOrderId(tradeOrderDO.getId())); - } - - // 生成预支付 - createPayOrder(tradeOrderDO, tradeOrderItemDOs, spus); - - // 增加订单日志 TODO 芋艿:待实现 - } - - private void createPayOrder(TradeOrderDO tradeOrderDO, List tradeOrderItemDOs, - List spus) { - // 创建支付单,用于后续的支付 - PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert( - tradeOrderDO, tradeOrderItemDOs, spus, tradeOrderProperties); - Long payOrderId = payOrderApi.createOrder(payOrderCreateReqDTO); - - // 更新到交易单上 - tradeOrderMapper.updateById(new TradeOrderDO().setId(tradeOrderDO.getId()).setPayOrderId(payOrderId)); - } - - @Override - public void updateOrderPaid(Long id, Long payOrderId) { - // 校验并获得交易订单(可支付) - KeyValue orderResult = validateOrderPayable(id, payOrderId); - TradeOrderDO order = orderResult.getKey(); - PayOrderRespDTO payOrder = orderResult.getValue(); - - // 更新 TradeOrderDO 状态为已支付,等待发货 - int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(), - new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayed(true) - .setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode())); - if (updateCount == 0) { - throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); - } - - // TODO 芋艿:发送订单变化的消息 - - // TODO 芋艿:发送站内信 - - // TODO 芋艿:OrderLog - } - - /** - * 校验交易订单满足被支付的条件 - * - * 1. 交易订单未支付 - * 2. 支付单已支付 - * - * @param id 交易订单编号 - * @param payOrderId 支付订单编号 - * @return 交易订单 - */ - private KeyValue validateOrderPayable(Long id, Long payOrderId) { - // 校验订单是否存在 - TradeOrderDO order = tradeOrderMapper.selectById(id); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - // 校验订单未支付 - if (!TradeOrderStatusEnum.isUnpaid(order.getStatus()) || order.getPayed()) { - log.error("[validateOrderPaid][order({}) 不处于待支付状态,请进行处理!order 数据是:{}]", - id, JsonUtils.toJsonString(order)); - throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); - } - // 校验支付订单匹配 - if (ObjectUtil.notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号 - log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(order)); - throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); - } - - // 校验支付单是否存在 - PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); - if (payOrder == null) { - log.error("[validateOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId); - throw exception(PAY_ORDER_NOT_FOUND); - } - // 校验支付单已支付 - if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { - log.error("[validateOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(payOrder)); - throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); - } - // 校验支付金额一致 - if (ObjectUtil.notEqual(payOrder.getAmount(), order.getPayPrice())) { - log.error("[validateOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder)); - throw exception(ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH); - } - // 校验支付订单匹配(二次) - if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), id.toString())) { - log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(payOrder)); - throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); - } - return new KeyValue<>(order, payOrder); - } - - // TODO 芋艿:如果无需发货,需要怎么存储? - @Override - public void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO) { - // 校验并获得交易订单(可发货) - TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId()); - - // TODO 芋艿:logisticsId 校验存在 - - // 更新 TradeOrderDO 状态为已发货,等待收货 - int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), - new TradeOrderDO().setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()) - .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()) - .setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now())); - if (updateCount == 0) { - throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); - } - - // TODO 芋艿:发送订单变化的消息 - - // TODO 芋艿:发送站内信 - - // TODO 芋艿:OrderLog - - // TODO 设计:like:是否要单独一个 delivery 发货单表??? - // TODO 设计:niu:要不要支持一个订单下,多个 order item 单独发货,类似有赞 - // TODO 设计:lili:是不是发货后,才支持售后? - } - - /** - * 校验交易订单满足被发货的条件 - * - * 1. 交易订单未发货 - * - * @param id 交易订单编号 - * @return 交易订单 - */ - private TradeOrderDO validateOrderDeliverable(Long id) { - // 校验订单是否存在 - TradeOrderDO order = tradeOrderMapper.selectById(id); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - // 校验订单是否是待发货状态 - if (!TradeOrderStatusEnum.isUndelivered(order.getStatus()) - || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) { - throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); - } - return order; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void receiveOrder(Long userId, Long id) { - // 校验并获得交易订单(可收货) - TradeOrderDO order = validateOrderReceivable(userId, id); - - // 更新 TradeOrderDO 状态为已完成 - int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), - new TradeOrderDO().setStatus(TradeOrderStatusEnum.COMPLETED.getStatus()) - .setDeliveryStatus(TradeOrderDeliveryStatusEnum.RECEIVED.getStatus()).setReceiveTime(LocalDateTime.now())); - if (updateCount == 0) { - throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED); - } - - // TODO 芋艿:OrderLog - - // TODO 芋艿:lili 发送订单变化的消息 - - // TODO 芋艿:lili 发送商品被购买完成的数据 - } - - @Override - public TradeOrderDO getOrder(Long id) { - return tradeOrderMapper.selectById(id); - } - - /** - * 校验交易订单满足可售货的条件 - * - * 1. 交易订单待收货 - * - * @param userId 用户编号 - * @param id 交易订单编号 - * @return 交易订单 - */ - private TradeOrderDO validateOrderReceivable(Long userId, Long id) { - // 校验订单是否存在 - TradeOrderDO order = tradeOrderMapper.selectByIdAndUserId(id, userId); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - // 校验订单是否是待收货状态 - if (!TradeOrderStatusEnum.isDelivered(order.getStatus()) - || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus())) { - throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED); - } - return order; - } - - @Override - public TradeOrderDO getOrder(Long userId, Long id) { - TradeOrderDO order = tradeOrderMapper.selectById(id); - if (order != null - && ObjectUtil.notEqual(order.getUserId(), userId)) { - return null; - } - return order; - } - - @Override - public PageResult getOrderPage(TradeOrderPageReqVO reqVO) { - // 获得 userId 相关的查询 - Set userIds = new HashSet<>(); - if (StrUtil.isNotEmpty(reqVO.getUserMobile())) { - MemberUserRespDTO user = memberUserApi.getUserByMobile(reqVO.getUserMobile()); - if (user == null) { // 没查询到用户,说明肯定也没他的订单 - return new PageResult<>(); - } - userIds.add(user.getId()); - } - if (StrUtil.isNotEmpty(reqVO.getUserNickname())) { - List users = memberUserApi.getUserListByNickname(reqVO.getUserNickname()); - if (CollUtil.isEmpty(users)) { // 没查询到用户,说明肯定也没他的订单 - return new PageResult<>(); - } - userIds.addAll(convertSet(users, MemberUserRespDTO::getId)); - } - // 分页查询 - return tradeOrderMapper.selectPage(reqVO, userIds); - } - - @Override - public PageResult getOrderPage(Long userId, AppTradeOrderPageReqVO reqVO) { - return tradeOrderMapper.selectPage(reqVO, userId); - } - - // =================== Order Item =================== - - @Override - public TradeOrderItemDO getOrderItem(Long userId, Long itemId) { - TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(itemId); - if (orderItem != null - && ObjectUtil.notEqual(orderItem.getUserId(), userId)) { - return null; - } - return orderItem; - } - - @Override - public void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus, Integer refundPrice) { - // 如果退款成功,则 refundPrice 非空 - if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus()) - && refundPrice == null) { - throw new IllegalArgumentException(StrUtil.format("id({}) 退款成功,退款金额不能为空", id)); - } - - // 更新订单项 - int updateCount = tradeOrderItemMapper.updateAfterSaleStatus(id, oldAfterSaleStatus, newAfterSaleStatus); - if (updateCount <= 0) { - throw exception(ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL); - } - - // 如果有退款金额,则需要更新订单 - if (refundPrice == null) { - return; - } - // 计算总的退款金额 - TradeOrderDO order = tradeOrderMapper.selectById(tradeOrderItemMapper.selectById(id).getOrderId()); - Integer orderRefundPrice = order.getRefundPrice() + refundPrice; - if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单 - tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) - .setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.ALL.getStatus()).setRefundPrice(orderRefundPrice) - .setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now())); - - // TODO 芋艿:记录订单日志 - - // TODO 芋艿:站内信? - } else { // 如果部分售后,则更新退款金额 - tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) - .setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice)); - } - - // TODO 芋艿:未来如果有分佣,需要更新相关分佣订单为已失效 - } - - @Override - public List getOrderItemList(Collection ids) { - return tradeOrderItemMapper.selectBatchIds(ids); - } - - @Override - public List getOrderItemListByOrderId(Collection orderIds) { - return tradeOrderItemMapper.selectListByOrderId(orderIds); - } - - /** - * 判断指定订单的所有订单项,是不是都售后成功 - * - * @param id 订单编号 - * @return 是否都售后成功 - */ - private boolean isAllOrderItemAfterSaleSuccess(Long id) { - List orderItems = tradeOrderItemMapper.selectListByOrderId(id); - return orderItems.stream().allMatch(orderItem -> Objects.equals(orderItem.getAfterSaleStatus(), - TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java deleted file mode 100644 index f628cef4a..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java +++ /dev/null @@ -1,154 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.aftersale; - -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; -import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; -import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleLogMapper; -import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleMapper; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum; -import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; -import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; -import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static java.util.Arrays.asList; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; - -/** - * {@link TradeAfterSaleService} 的单元测试 - * - * @author 芋道源码 - */ -@Import(TradeAfterSaleServiceImpl.class) -public class TradeAfterSaleServiceTest extends BaseDbUnitTest { - - @Resource - private TradeAfterSaleServiceImpl tradeAfterSaleService; - - @Resource - private TradeAfterSaleMapper tradeAfterSaleMapper; - @Resource - private TradeAfterSaleLogMapper tradeAfterSaleLogMapper; - - @MockBean - private TradeOrderService tradeOrderService; - @MockBean - private PayRefundApi payRefundApi; - - @MockBean - private TradeOrderProperties tradeOrderProperties; - - @Test - public void testCreateAfterSale() { - // 准备参数 - Long userId = 1024L; - AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO() - .setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay()) - .setApplyReason("退钱").setApplyDescription("快退") - .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png")); - // mock 方法(交易订单项) - TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> { - o.setOrderId(111L).setUserId(userId).setOrderDividePrice(200); - o.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); - }); - when(tradeOrderService.getOrderItem(eq(1024L), eq(1L))) - .thenReturn(orderItem); - // mock 方法(交易订单) - TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> o.setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()) - .setNo("202211301234")); - when(tradeOrderService.getOrder(eq(1024L), eq(111L))).thenReturn(order); - - // 调用 - Long afterSaleId = tradeAfterSaleService.createAfterSale(userId, createReqVO); - // 断言(TradeAfterSaleDO) - TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(afterSaleId); - assertNotNull(afterSale.getNo()); - assertEquals(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus()); - assertEquals(afterSale.getType(), TradeAfterSaleTypeEnum.IN_SALE.getType()); - assertPojoEquals(afterSale, createReqVO); - assertEquals(afterSale.getUserId(), 1024L); - assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime"); - assertEquals(afterSale.getOrderNo(), "202211301234"); - assertNull(afterSale.getPayRefundId()); - assertNull(afterSale.getRefundTime()); - assertNull(afterSale.getLogisticsId()); - assertNull(afterSale.getLogisticsNo()); - assertNull(afterSale.getDeliveryTime()); - assertNull(afterSale.getReceiveReason()); - // 断言(TradeAfterSaleLogDO) - TradeAfterSaleLogDO afterSaleLog = tradeAfterSaleLogMapper.selectList().get(0); - assertEquals(afterSaleLog.getUserId(), userId); - assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue()); - assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId); - assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime"); - assertNull(afterSaleLog.getBeforeStatus()); - assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus()); - assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent()); - } - - @Test - public void testGetAfterSalePage() { - // mock 数据 - TradeAfterSaleDO dbAfterSale = randomPojo(TradeAfterSaleDO.class, o -> { // 等会查询到 - o.setNo("202211190847450020500077"); - o.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus()); - o.setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay()); - o.setType(TradeAfterSaleTypeEnum.IN_SALE.getType()); - o.setOrderNo("202211190847450020500011"); - o.setSpuName("芋艿"); - o.setCreateTime(buildTime(2022, 1, 15)); - }); - tradeAfterSaleMapper.insert(dbAfterSale); - // 测试 no 不匹配 - tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setNo("202211190847450020500066"))); - // 测试 status 不匹配 - tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setStatus(TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()))); - // 测试 way 不匹配 - tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setWay(TradeAfterSaleWayEnum.REFUND.getWay()))); - // 测试 type 不匹配 - tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setType(TradeAfterSaleTypeEnum.AFTER_SALE.getType()))); - // 测试 orderNo 不匹配 - tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setOrderNo("202211190847450020500022"))); - // 测试 spuName 不匹配 - tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setSpuName("土豆"))); - // 测试 createTime 不匹配 - tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setCreateTime(buildTime(2022, 1, 20)))); - // 准备参数 - TradeAfterSalePageReqVO reqVO = new TradeAfterSalePageReqVO(); - reqVO.setNo("20221119084745002050007"); - reqVO.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus()); - reqVO.setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay()); - reqVO.setType(TradeAfterSaleTypeEnum.IN_SALE.getType()); - reqVO.setOrderNo("20221119084745002050001"); - reqVO.setSpuName("芋"); - reqVO.setCreateTime(new LocalDateTime[]{buildTime(2022, 1, 1), buildTime(2022, 1, 16)}); - - // 调用 - PageResult pageResult = tradeAfterSaleService.getAfterSalePage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbAfterSale, pageResult.getList().get(0)); - } -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java deleted file mode 100644 index 55bff8de6..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java +++ /dev/null @@ -1,320 +0,0 @@ -package cn.iocoder.yudao.module.trade.service.order; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.enums.TerminalEnum; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.member.api.address.AddressApi; -import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; -import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; -import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; -import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; -import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; -import cn.iocoder.yudao.module.promotion.api.price.PriceApi; -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; -import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; -import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; -import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; -import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; -import cn.iocoder.yudao.module.trade.enums.order.*; -import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderConfig; -import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.time.Duration; -import java.util.Arrays; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static java.util.Collections.singletonList; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * {@link TradeOrderServiceImpl} 的单元测试类 - * - * @author LeeYan9 - * @since 2022-09-07 - */ -@Import({TradeOrderServiceImpl.class, TradeOrderConfig.class}) -public class TradeOrderServiceTest extends BaseDbUnitTest { - - @Resource - private TradeOrderServiceImpl tradeOrderService; - - @Resource - private TradeOrderMapper tradeOrderMapper; - @Resource - private TradeOrderItemMapper tradeOrderItemMapper; - - @MockBean - private ProductSpuApi productSpuApi; - @MockBean - private ProductSkuApi productSkuApi; - @MockBean - private PriceApi priceApi; - @MockBean - private PayOrderApi payOrderApi; - @MockBean - private AddressApi addressApi; - @MockBean - private CouponApi couponApi; - - @MockBean - private TradeOrderProperties tradeOrderProperties; - - @BeforeEach - public void setUp() { - when(tradeOrderProperties.getAppId()).thenReturn(888L); - when(tradeOrderProperties.getExpireTime()).thenReturn(Duration.ofDays(1)); - } - - @Test - public void testCreateTradeOrder_success() { - // 准备参数 - Long userId = 100L; - String userIp = "127.0.0.1"; - AppTradeOrderCreateReqVO reqVO = new AppTradeOrderCreateReqVO() - .setAddressId(10L).setCouponId(101L).setRemark("我是备注").setFromCart(true) - .setItems(Arrays.asList(new AppTradeOrderCreateReqVO.Item().setSkuId(1L).setCount(3), - new AppTradeOrderCreateReqVO.Item().setSkuId(2L).setCount(4))); - // mock 方法(商品 SKU 检查) - ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L) - .setPrice(50).setStock(100).setStatus(CommonStatusEnum.ENABLE.getStatus()) - .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(111L).setValueId(222L)))); - ProductSkuRespDTO sku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(2L).setSpuId(21L) - .setPrice(20).setStock(50).setStatus(CommonStatusEnum.ENABLE.getStatus())) - .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(333L).setValueId(444L))); - when(productSkuApi.getSkuList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(sku01, sku02)); - // mock 方法(商品 SPU 检查) - ProductSpuRespDTO spu01 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(11L) - .setStatus(ProductSpuStatusEnum.ENABLE.getStatus()).setName("商品 1")); - ProductSpuRespDTO spu02 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(21L) - .setStatus(ProductSpuStatusEnum.ENABLE.getStatus())); - when(productSpuApi.getSpuList(eq(asSet(11L, 21L)))).thenReturn(Arrays.asList(spu01, spu02)); - // mock 方法(用户收件地址的校验) - AddressRespDTO addressRespDTO = new AddressRespDTO().setId(10L).setUserId(userId).setName("芋艿") - .setMobile("15601691300").setAreaId(3306L).setPostCode("85757").setDetailAddress("土豆村"); - when(addressApi.getAddress(eq(10L), eq(userId))).thenReturn(addressRespDTO); - // mock 方法(价格计算) - PriceCalculateRespDTO.OrderItem priceOrderItem01 = new PriceCalculateRespDTO.OrderItem() - .setSpuId(11L).setSkuId(1L).setCount(3).setOriginalPrice(150).setOriginalUnitPrice(50) - .setDiscountPrice(20).setPayPrice(130).setOrderPartPrice(7).setOrderDividePrice(35); - PriceCalculateRespDTO.OrderItem priceOrderItem02 = new PriceCalculateRespDTO.OrderItem() - .setSpuId(21L).setSkuId(2L).setCount(4).setOriginalPrice(80).setOriginalUnitPrice(20) - .setDiscountPrice(40).setPayPrice(40).setOrderPartPrice(15).setOrderDividePrice(25); - PriceCalculateRespDTO.Order priceOrder = new PriceCalculateRespDTO.Order() - .setOriginalPrice(230).setOrderPrice(100).setDiscountPrice(0).setCouponPrice(30) - .setPointPrice(10).setDeliveryPrice(20).setPayPrice(80).setCouponId(101L).setCouponPrice(30) - .setItems(Arrays.asList(priceOrderItem01, priceOrderItem02)); - when(priceApi.calculatePrice(argThat(priceCalculateReqDTO -> { - assertEquals(priceCalculateReqDTO.getUserId(), 100L); - assertEquals(priceCalculateReqDTO.getCouponId(), 101L); - assertEquals(priceCalculateReqDTO.getItems().get(0).getSkuId(), 1L); - assertEquals(priceCalculateReqDTO.getItems().get(0).getCount(), 3); - assertEquals(priceCalculateReqDTO.getItems().get(1).getSkuId(), 2L); - assertEquals(priceCalculateReqDTO.getItems().get(1).getCount(), 4); - return true; - }))).thenReturn(new PriceCalculateRespDTO().setOrder(priceOrder)); - // mock 方法(创建支付单) - when(payOrderApi.createOrder(argThat(createReqDTO -> { - assertEquals(createReqDTO.getAppId(), 888L); - assertEquals(createReqDTO.getUserIp(), userIp); - assertNotNull(createReqDTO.getMerchantOrderId()); // 由于 tradeOrderId 后生成,只能校验非空 - assertEquals(createReqDTO.getSubject(), "商品 1 等多件"); - assertNull(createReqDTO.getBody()); - assertEquals(createReqDTO.getAmount(), 80); - assertNotNull(createReqDTO.getExpireTime()); - return true; - }))).thenReturn(1000L); - - // 调用方法 - Long tradeOrderId = tradeOrderService.createOrder(userId, userIp, reqVO); - // 断言 TradeOrderDO 订单 - List tradeOrderDOs = tradeOrderMapper.selectList(); - assertEquals(tradeOrderDOs.size(), 1); - TradeOrderDO tradeOrderDO = tradeOrderDOs.get(0); - assertEquals(tradeOrderDO.getId(), tradeOrderId); - assertNotNull(tradeOrderDO.getNo()); - assertEquals(tradeOrderDO.getType(), TradeOrderTypeEnum.NORMAL.getType()); - assertEquals(tradeOrderDO.getTerminal(), TerminalEnum.H5.getTerminal()); - assertEquals(tradeOrderDO.getUserId(), userId); - assertEquals(tradeOrderDO.getUserIp(), userIp); - assertEquals(tradeOrderDO.getStatus(), TradeOrderStatusEnum.UNPAID.getStatus()); - assertEquals(tradeOrderDO.getProductCount(), 7); - assertNull(tradeOrderDO.getFinishTime()); - assertNull(tradeOrderDO.getCancelTime()); - assertNull(tradeOrderDO.getCancelType()); - assertEquals(tradeOrderDO.getUserRemark(), "我是备注"); - assertNull(tradeOrderDO.getRemark()); - assertFalse(tradeOrderDO.getPayed()); - assertNull(tradeOrderDO.getPayTime()); - assertEquals(tradeOrderDO.getOriginalPrice(), 230); - assertEquals(tradeOrderDO.getOrderPrice(), 100); - assertEquals(tradeOrderDO.getDiscountPrice(), 0); - assertEquals(tradeOrderDO.getAdjustPrice(), 0); - assertEquals(tradeOrderDO.getPayPrice(), 80); - assertEquals(tradeOrderDO.getPayOrderId(), 1000L); - assertNull(tradeOrderDO.getPayChannelCode()); - assertNull(tradeOrderDO.getDeliveryTemplateId()); - assertNull(tradeOrderDO.getLogisticsId()); - assertEquals(tradeOrderDO.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); - assertNull(tradeOrderDO.getDeliveryTime()); - assertNull(tradeOrderDO.getReceiveTime()); - assertEquals(tradeOrderDO.getReceiverName(), "芋艿"); - assertEquals(tradeOrderDO.getReceiverMobile(), "15601691300"); - assertEquals(tradeOrderDO.getReceiverAreaId(), 3306); - assertEquals(tradeOrderDO.getReceiverPostCode(), 85757); - assertEquals(tradeOrderDO.getReceiverDetailAddress(), "土豆村"); - assertEquals(tradeOrderDO.getAfterSaleStatus(), TradeOrderAfterSaleStatusEnum.NONE.getStatus()); - assertEquals(tradeOrderDO.getRefundPrice(), 0); - assertEquals(tradeOrderDO.getCouponPrice(), 30); - assertEquals(tradeOrderDO.getPointPrice(), 10); - // 断言 TradeOrderItemDO 订单(第 1 个) - List tradeOrderItemDOs = tradeOrderItemMapper.selectList(); - assertEquals(tradeOrderItemDOs.size(), 2); - TradeOrderItemDO tradeOrderItemDO01 = tradeOrderItemDOs.get(0); - assertNotNull(tradeOrderItemDO01.getId()); - assertEquals(tradeOrderItemDO01.getUserId(), userId); - assertEquals(tradeOrderItemDO01.getOrderId(), tradeOrderId); - assertEquals(tradeOrderItemDO01.getSpuId(), 11L); - assertEquals(tradeOrderItemDO01.getSkuId(), 1L); - assertEquals(tradeOrderItemDO01.getProperties().size(), 1); - assertEquals(tradeOrderItemDO01.getProperties().get(0).getPropertyId(), 111L); - assertEquals(tradeOrderItemDO01.getProperties().get(0).getValueId(), 222L); - assertEquals(tradeOrderItemDO01.getSpuName(), sku01.getSpuName()); - assertEquals(tradeOrderItemDO01.getPicUrl(), sku01.getPicUrl()); - assertEquals(tradeOrderItemDO01.getCount(), 3); - assertEquals(tradeOrderItemDO01.getOriginalPrice(), 150); - assertEquals(tradeOrderItemDO01.getOriginalUnitPrice(), 50); - assertEquals(tradeOrderItemDO01.getDiscountPrice(), 20); - assertEquals(tradeOrderItemDO01.getPayPrice(), 130); - assertEquals(tradeOrderItemDO01.getOrderPartPrice(), 7); - assertEquals(tradeOrderItemDO01.getOrderDividePrice(), 35); - assertEquals(tradeOrderItemDO01.getAfterSaleStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); - // 断言 TradeOrderItemDO 订单(第 2 个) - TradeOrderItemDO tradeOrderItemDO02 = tradeOrderItemDOs.get(1); - assertNotNull(tradeOrderItemDO02.getId()); - assertEquals(tradeOrderItemDO02.getUserId(), userId); - assertEquals(tradeOrderItemDO02.getOrderId(), tradeOrderId); - assertEquals(tradeOrderItemDO02.getSpuId(), 21L); - assertEquals(tradeOrderItemDO02.getSkuId(), 2L); - assertEquals(tradeOrderItemDO02.getProperties().size(), 1); - assertEquals(tradeOrderItemDO02.getProperties().get(0).getPropertyId(), 333L); - assertEquals(tradeOrderItemDO02.getProperties().get(0).getValueId(), 444L); - assertEquals(tradeOrderItemDO02.getSpuName(), sku02.getSpuName()); - assertEquals(tradeOrderItemDO02.getPicUrl(), sku02.getPicUrl()); - assertEquals(tradeOrderItemDO02.getCount(), 4); - assertEquals(tradeOrderItemDO02.getOriginalPrice(), 80); - assertEquals(tradeOrderItemDO02.getOriginalUnitPrice(), 20); - assertEquals(tradeOrderItemDO02.getDiscountPrice(), 40); - assertEquals(tradeOrderItemDO02.getPayPrice(), 40); - assertEquals(tradeOrderItemDO02.getOrderPartPrice(), 15); - assertEquals(tradeOrderItemDO02.getOrderDividePrice(), 25); - assertEquals(tradeOrderItemDO02.getAfterSaleStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); - // 校验调用 - verify(productSkuApi).updateSkuStock(argThat(updateStockReqDTO -> { - assertEquals(updateStockReqDTO.getItems().size(), 2); - assertEquals(updateStockReqDTO.getItems().get(0).getId(), 1L); - assertEquals(updateStockReqDTO.getItems().get(0).getIncrCount(), 3); - assertEquals(updateStockReqDTO.getItems().get(1).getId(), 2L); - assertEquals(updateStockReqDTO.getItems().get(1).getIncrCount(), 4); - return true; - })); - verify(couponApi).useCoupon(argThat(reqDTO -> { - assertEquals(reqDTO.getId(), reqVO.getCouponId()); - assertEquals(reqDTO.getUserId(), userId); - assertEquals(reqDTO.getOrderId(), tradeOrderId); - return true; - })); - } - - @Test - public void testUpdateOrderPaid() { - // mock 数据(TradeOrder) - TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { - o.setId(1L).setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); - o.setPayOrderId(10L).setPayed(false).setPayPrice(100).setPayTime(null); - }); - tradeOrderMapper.insert(order); - // 准备参数 - Long id = 1L; - Long payOrderId = 10L; - // mock 方法(支付单) - when(payOrderApi.getOrder(eq(10L))).thenReturn(randomPojo(PayOrderRespDTO.class, - o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()).setChannelCode("wx_pub") - .setMerchantOrderId("1")).setAmount(100)); - - // 调用 - tradeOrderService.updateOrderPaid(id, payOrderId); - // 断言 - TradeOrderDO dbOrder = tradeOrderMapper.selectById(id); - assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus()); - assertTrue(dbOrder.getPayed()); - assertNotNull(dbOrder.getPayTime()); - assertEquals(dbOrder.getPayChannelCode(), "wx_pub"); - } - - @Test - public void testDeliveryOrder() { - // mock 数据(TradeOrder) - TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { - o.setId(1L).setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()); - o.setLogisticsId(null).setLogisticsNo(null).setDeliveryTime(null) - .setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); - }); - tradeOrderMapper.insert(order); - // 准备参数 - TradeOrderDeliveryReqVO deliveryReqVO = new TradeOrderDeliveryReqVO().setId(1L) - .setLogisticsId(10L).setLogisticsNo("100"); - // mock 方法(支付单) - - // 调用 - tradeOrderService.deliveryOrder(randomLongId(), deliveryReqVO); - // 断言 - TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L); - assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.DELIVERED.getStatus()); - assertEquals(dbOrder.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()); - assertPojoEquals(dbOrder, deliveryReqVO); - assertNotNull(dbOrder.getDeliveryTime()); - } - - @Test - public void testReceiveOrder() { - // mock 数据(TradeOrder) - TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { - o.setId(1L).setUserId(10L).setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()); - o.setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setReceiveTime(null); - }); - tradeOrderMapper.insert(order); - // 准备参数 - Long id = 1L; - Long userId = 10L; - // mock 方法(支付单) - - // 调用 - tradeOrderService.receiveOrder(userId, id); - // 断言 - TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L); - assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus()); - assertEquals(dbOrder.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.RECEIVED.getStatus()); - assertNotNull(dbOrder.getReceiveTime()); - } - -} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index 19dd0e97b..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,53 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - -# Resilience4j 配置项 - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao.module - trade: - order: - app-id: 1 - merchant-order-id: 1 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/logback.xml b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/logback.xml deleted file mode 100644 index daf756bff..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/logback.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/clean.sql deleted file mode 100644 index dfa4a5b42..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/clean.sql +++ /dev/null @@ -1,4 +0,0 @@ -DELETE FROM trade_order; -DELETE FROM trade_order_item; -DELETE FROM trade_after_sale; -DELETE FROM trade_after_sale_log; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql deleted file mode 100644 index 452362eb5..000000000 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql +++ /dev/null @@ -1,128 +0,0 @@ -CREATE TABLE IF NOT EXISTS "trade_order" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "no" varchar NOT NULL, - "type" int NOT NULL, - "terminal" int NOT NULL, - "user_id" bigint NOT NULL, - "user_ip" varchar NOT NULL, - "user_remark" varchar, - "status" int NOT NULL, - "product_count" int NOT NULL, - "cancel_type" int, - "remark" varchar, - "payed" bit NOT NULL, - "pay_time" datetime, - "finish_time" datetime, - "cancel_time" datetime, - "original_price" int NOT NULL, - "order_price" int NOT NULL, - "discount_price" int NOT NULL, - "delivery_price" int NOT NULL, - "adjust_price" int NOT NULL, - "pay_price" int NOT NULL, - "pay_order_id" bigint, - "pay_channel_code" varchar, - "delivery_template_id" bigint, - "logistics_id" bigint, - "logistics_no" varchar, - "delivery_status" smallint NOT NULL, - "delivery_time" datetime, - "receive_time" datetime, - "receiver_name" varchar NOT NULL, - "receiver_mobile" varchar NOT NULL, - "receiver_area_id" int NOT NULL, - "receiver_post_code" int, - "receiver_detail_address" varchar NOT NULL, - "after_sale_status" int NOT NULL, - "refund_price" int NOT NULL, - "coupon_id" bigint NOT NULL, - "coupon_price" int NOT NULL, - "point_price" int NOT NULL, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '交易订单表'; - -CREATE TABLE IF NOT EXISTS "trade_order_item" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint NOT NULL, - "order_id" bigint NOT NULL, - "spu_id" bigint NOT NULL, - "spu_name" varchar NOT NULL, - "sku_id" bigint NOT NULL, - "properties" varchar, - "pic_url" varchar, - "count" int NOT NULL, - "original_price" int NOT NULL, - "original_unit_price" int NOT NULL, - "discount_price" int NOT NULL, - "pay_price" int NOT NULL, - "order_part_price" int NOT NULL, - "order_divide_price" int NOT NULL, - "after_sale_status" int NOT NULL, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '交易订单明细表'; - -CREATE TABLE IF NOT EXISTS "trade_after_sale" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "no" varchar NOT NULL, - "status" int NOT NULL, - "type" int NOT NULL, - "way" int NOT NULL, - "user_id" bigint NOT NULL, - "apply_reason" varchar NOT NULL, - "apply_description" varchar, - "apply_pic_urls" varchar, - "order_id" bigint NOT NULL, - "order_no" varchar NOT NULL, - "order_item_id" bigint NOT NULL, - "spu_id" bigint NOT NULL, - "spu_name" varchar NOT NULL, - "sku_id" bigint NOT NULL, - "properties" varchar, - "pic_url" varchar, - "count" int NOT NULL, - "audit_time" varchar, - "audit_user_id" bigint, - "audit_reason" varchar, - "refund_price" int NOT NULL, - "pay_refund_id" bigint, - "refund_time" varchar, - "logistics_id" bigint, - "logistics_no" varchar, - "delivery_time" varchar, - "receive_time" varchar, - "receive_reason" varchar, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '交易售后表'; - -CREATE TABLE IF NOT EXISTS "trade_after_sale_log" ( - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "user_id" bigint NOT NULL, - "user_type" int NOT NULL, - "after_sale_id" bigint NOT NULL, - "order_id" bigint NOT NULL, - "order_item_id" bigint NOT NULL, - "before_status" int, - "after_status" int NOT NULL, - "content" varchar NOT NULL, - "creator" varchar DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - PRIMARY KEY ("id") -) COMMENT '交易售后日志'; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java index fa9177538..62b753730 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java @@ -6,8 +6,8 @@ import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; import cn.iocoder.yudao.module.pay.service.order.PayOrderService; import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND; -@Api(tags = "管理后台 - 支付通知") +@Tag(name = "管理后台 - 支付通知") @RestController @RequestMapping("/pay/notify") @Validated @@ -43,7 +43,7 @@ public class PayNotifyController { * @return 返回跳转页面 */ @GetMapping(value = "/return/{channelId}") - @ApiOperation("渠道统一的支付成功返回地址") + @Operation(summary = "渠道统一的支付成功返回地址") @Deprecated // TODO yunai:如果是 way 的情况,应该是跳转回前端地址 public String returnCallback(@PathVariable("channelId") Long channelId, @RequestParam Map params) { @@ -60,7 +60,7 @@ public class PayNotifyController { * @return 成功返回 "success" */ @PostMapping(value = "/callback/{channelId}") - @ApiOperation(value = "支付渠道的统一回调接口", notes = "包括支付回调,退款回调") + @Operation(summary = "支付渠道的统一回调接口 - 包括支付回调,退款回调") @PermitAll @OperateLog(enable = false) // 回调地址,无需记录操作日志 public String notifyCallback(@PathVariable("channelId") Long channelId, diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java index a7e4d3e03..2d5c766fd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java @@ -7,9 +7,9 @@ import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.framework.ip.core.utils.IPUtils; import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO; import cn.iocoder.yudao.module.system.convert.ip.AreaConvert; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -20,14 +20,14 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 地区") +@Tag(name = "管理后台 - 地区") @RestController @RequestMapping("/system/area") @Validated public class AreaController { @GetMapping("/tree") - @ApiOperation("获得地区树") + @Operation(summary = "获得地区树") public CommonResult> getAreaTree() { Area area = AreaUtils.getArea(Area.ID_CHINA); Assert.notNull(area, "获取不到中国"); @@ -35,8 +35,8 @@ public class AreaController { } @GetMapping("/get-by-ip") - @ApiOperation("获得 IP 对应的地区名") - @ApiImplicitParam(name = "ip", value = "IP", required = true, dataTypeClass = String.class) + @Operation(summary = "获得 IP 对应的地区名") + @Parameter(name = "ip", description = "IP", required = true) public CommonResult getAreaByIp(@RequestParam("ip") String ip) { // 获得城市 Area area = IPUtils.getArea(ip); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeRespVO.java index a2416832d..614b84fe0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/vo/AreaNodeRespVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.system.controller.admin.ip.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; -@ApiModel("管理后台 - 地区节点 Response VO") +@Schema(description = "管理后台 - 地区节点 Response VO") @Data public class AreaNodeRespVO { - @ApiModelProperty(value = "编号", required = true, example = "110000") + @Schema(description = "编号", required = true, example = "110000") private Integer id; - @ApiModelProperty(value = "名字", required = true, example = "北京") + @Schema(description = "名字", required = true, example = "北京") private String name; /** From c9d242c7e1c26b02b71aa8ebfead14ecb7211ad8 Mon Sep 17 00:00:00 2001 From: "zhang.xionghui" <13834222683@163.com> Date: Wed, 11 Jan 2023 02:35:38 +0000 Subject: [PATCH 08/59] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E5=8F=AA?= =?UTF-8?q?=E6=9C=89=E4=B8=80=E4=B8=AA=E8=8F=9C=E5=8D=95=E6=97=B6=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E6=98=BE=E7=A4=BA=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhang.xionghui <13834222683@163.com> --- yudao-ui-admin/src/store/modules/permission.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yudao-ui-admin/src/store/modules/permission.js b/yudao-ui-admin/src/store/modules/permission.js index a9dbd2b41..4b6212367 100644 --- a/yudao-ui-admin/src/store/modules/permission.js +++ b/yudao-ui-admin/src/store/modules/permission.js @@ -73,6 +73,8 @@ function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) { } else { route.component = ParentView } + // 解决只有一个菜单时无法显示目录 + route.alwaysShow = true } else { // 根节点 route.component = loadView(route.component) } From cba69e94df970ed5e6290a9d0578603ec5fd049b Mon Sep 17 00:00:00 2001 From: xingyu Date: Mon, 16 Jan 2023 15:15:31 +0800 Subject: [PATCH 09/59] revert: file --- yudao-dependencies/pom.xml | 13 ------------- .../yudao-spring-boot-starter-web/pom.xml | 10 ---------- .../config/YudaoSwaggerAutoConfiguration.java | 14 +++++--------- .../admin/captcha/CaptchaController.java | 10 +++++----- yudao-server/src/main/resources/application.yaml | 7 +++++++ yudao-ui-admin-vue3/.env.dev | 4 ++-- yudao-ui-admin-vue3/.env.pro | 4 ++-- yudao-ui-admin-vue3/.env.test | 4 ++-- 8 files changed, 23 insertions(+), 43 deletions(-) diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index d1038eb5b..af759726f 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -18,7 +18,6 @@ 2.7.7 - 1.6.14 4.0.0 2.5 @@ -170,18 +169,6 @@ ${knife4j.version} - - org.springdoc - springdoc-openapi-ui - ${springdoc.version} - - - - org.springdoc - springdoc-openapi-security - ${springdoc.version} - - cn.iocoder.boot diff --git a/yudao-framework/yudao-spring-boot-starter-web/pom.xml b/yudao-framework/yudao-spring-boot-starter-web/pom.xml index 5a4951ae9..89d35f44f 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-web/pom.xml @@ -38,16 +38,6 @@ knife4j-openapi3-spring-boot-starter - - org.springdoc - springdoc-openapi-ui - - - - org.springdoc - springdoc-openapi-security - - org.springframework.security spring-security-core diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index 9e05fe3a0..a064ee46d 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -4,8 +4,8 @@ import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; -import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springdoc.core.GroupedOpenApi; import org.springdoc.core.*; import org.springdoc.core.customizers.OpenApiBuilderCustomizer; import org.springdoc.core.customizers.ServerBaseUrlCustomizer; @@ -44,21 +44,16 @@ public class YudaoSwaggerAutoConfiguration { //鉴权组件(随便起名的) SecurityScheme securityScheme = new SecurityScheme() .type(SecurityScheme.Type.APIKEY) - .scheme("bearer")//固定写法 + .scheme("Bearer")//固定写法 .bearerFormat("JWT") .in(SecurityScheme.In.HEADER) .name(HttpHeaders.AUTHORIZATION); Components components = new Components() - .addSecuritySchemes("Bearer", securityScheme); - - //鉴权限制要求(随便起名的) - SecurityRequirement securityRequirement = new SecurityRequirement() - .addList(HttpHeaders.AUTHORIZATION, Arrays.asList("read", "write")); + .addSecuritySchemes("bearer", securityScheme); return new OpenAPI() .info(info) - .components(components) - .addSecurityItem(securityRequirement); + .components(components); } /** @@ -92,3 +87,4 @@ public class YudaoSwaggerAutoConfiguration { } } + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java index 71a02efd4..92359fda9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java @@ -6,8 +6,8 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import com.anji.captcha.model.common.ResponseModel; import com.anji.captcha.model.vo.CaptchaVO; import com.anji.captcha.service.CaptchaService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -22,7 +22,7 @@ import javax.servlet.http.HttpServletRequest; * * @author 芋道源码 */ -@Api(tags = "管理后台 - 验证码") +@Tag(name = "管理后台 - 验证码") @RestController("adminCaptchaController") @RequestMapping("/system/captcha") public class CaptchaController { @@ -31,7 +31,7 @@ public class CaptchaController { private CaptchaService captchaService; @PostMapping({"/get"}) - @ApiOperation("获得验证码") + @Operation(summary = "获得验证码") @PermitAll @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) { @@ -41,7 +41,7 @@ public class CaptchaController { } @PostMapping("/check") - @ApiOperation("校验验证码") + @Operation(summary = "校验验证码") @PermitAll @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) { diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 3ba88daa1..0cc0d271e 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -38,6 +38,13 @@ springdoc: show-actuator: true swagger-ui: path: /swagger-ui + api-docs: + path: /v3/api-docs + +knife4j: + enable: true + setting: + language: zh_cn # 工作流 Flowable 配置 flowable: diff --git a/yudao-ui-admin-vue3/.env.dev b/yudao-ui-admin-vue3/.env.dev index a67cdc686..bece32fd3 100644 --- a/yudao-ui-admin-vue3/.env.dev +++ b/yudao-ui-admin-vue3/.env.dev @@ -2,10 +2,10 @@ NODE_ENV=production # 请求路径 -VITE_BASE_URL='http://localhost:48080' +VITE_BASE_URL='http://localhost:58080' # 上传路径 -VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload' +VITE_UPLOAD_URL='http://localhost:58080/admin-api/infra/file/upload' # 接口前缀 VITE_API_BASEPATH=/dev-api diff --git a/yudao-ui-admin-vue3/.env.pro b/yudao-ui-admin-vue3/.env.pro index 4b47737e1..36168fe0e 100644 --- a/yudao-ui-admin-vue3/.env.pro +++ b/yudao-ui-admin-vue3/.env.pro @@ -2,10 +2,10 @@ NODE_ENV=production # 请求路径 -VITE_BASE_URL='http://localhost:48080' +VITE_BASE_URL='http://localhost:58080' # 上传路径 -VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload' +VITE_UPLOAD_URL='http://localhost:58080/admin-api/infra/file/upload' # 接口前缀 VITE_API_BASEPATH= diff --git a/yudao-ui-admin-vue3/.env.test b/yudao-ui-admin-vue3/.env.test index 6166840fa..e1a0c33b9 100644 --- a/yudao-ui-admin-vue3/.env.test +++ b/yudao-ui-admin-vue3/.env.test @@ -2,10 +2,10 @@ NODE_ENV=production # 请求路径 -VITE_BASE_URL='http://localhost:48080' +VITE_BASE_URL='http://localhost:58080' # 上传路径 -VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload' +VITE_UPLOAD_URL='http://localhost:58080/admin-api/infra/file/upload' # 接口前缀 VITE_API_BASEPATH= From 4d35bcef65162f28904b219f1640987c0b91fe4a Mon Sep 17 00:00:00 2001 From: xingyu Date: Mon, 16 Jan 2023 22:58:56 +0800 Subject: [PATCH 10/59] feat: springdoc success --- yudao-dependencies/pom.xml | 36 +++++++------ yudao-framework/yudao-common/pom.xml | 10 +++- .../yudao-spring-boot-starter-web/pom.xml | 8 ++- .../config/YudaoSwaggerAutoConfiguration.java | 51 ++++++++++++++----- .../src/main/resources/application.yaml | 11 ++-- .../src/views/infra/swagger/index.vue | 2 +- 6 files changed, 81 insertions(+), 37 deletions(-) diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index af759726f..a29a0052f 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -18,7 +18,8 @@ 2.7.7 - 4.0.0 + 1.6.14 + 2.5 1.2.15 @@ -163,10 +164,15 @@ ${revision} + + + + + - com.github.xiaoymin - knife4j-openapi3-spring-boot-starter - ${knife4j.version} + org.springdoc + springdoc-openapi-ui + ${springdoc.version} @@ -276,16 +282,16 @@ org.apache.skywalking apm-toolkit-opentracing ${skywalking.version} - - - - - - - - - - + + + + + + + + + + io.opentracing @@ -448,7 +454,7 @@ org.freemarker freemarker - + com.alibaba fastjson diff --git a/yudao-framework/yudao-common/pom.xml b/yudao-framework/yudao-common/pom.xml index 24fc39dec..0bf582993 100644 --- a/yudao-framework/yudao-common/pom.xml +++ b/yudao-framework/yudao-common/pom.xml @@ -58,10 +58,16 @@ provided + + + + - com.github.xiaoymin - knife4j-openapi3-spring-boot-starter + org.springdoc + springdoc-openapi-ui + provided + org.apache.skywalking diff --git a/yudao-framework/yudao-spring-boot-starter-web/pom.xml b/yudao-framework/yudao-spring-boot-starter-web/pom.xml index 89d35f44f..31bf43e12 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-web/pom.xml @@ -33,9 +33,13 @@ true + + + + - com.github.xiaoymin - knife4j-openapi3-spring-boot-starter + org.springdoc + springdoc-openapi-ui diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index a064ee46d..313b60010 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -1,9 +1,12 @@ package cn.iocoder.yudao.framework.swagger.config; -import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.media.IntegerSchema; +import io.swagger.v3.oas.models.parameters.Parameter; +import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import org.springdoc.core.GroupedOpenApi; import org.springdoc.core.*; @@ -17,10 +20,11 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.http.HttpHeaders; -import java.util.Arrays; import java.util.List; import java.util.Optional; +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; + /** * Swagger3 自动配置类 * @@ -40,20 +44,23 @@ public class YudaoSwaggerAutoConfiguration { .title(properties.getTitle()) .description(properties.getDescription()) .version(properties.getVersion()) + .contact(new Contact().name("xingyuv").url("xingyuv.com").email("xingyu4j@vip.qq.com")) .license(new License().name("MIT").url("https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE")); - //鉴权组件(随便起名的) - SecurityScheme securityScheme = new SecurityScheme() - .type(SecurityScheme.Type.APIKEY) - .scheme("Bearer")//固定写法 - .bearerFormat("JWT") - .in(SecurityScheme.In.HEADER) - .name(HttpHeaders.AUTHORIZATION); - Components components = new Components() - .addSecuritySchemes("bearer", securityScheme); - return new OpenAPI() .info(info) - .components(components); + .schemaRequirement(HttpHeaders.AUTHORIZATION, securityScheme()) + .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION)); + } + + private SecurityScheme securityScheme() { + SecurityScheme securityScheme = new SecurityScheme(); + //类型 + securityScheme.setType(SecurityScheme.Type.APIKEY); + //请求头的name + securityScheme.setName(HttpHeaders.AUTHORIZATION); + //token所在未知 + securityScheme.setIn(SecurityScheme.In.HEADER); + return securityScheme; } /** @@ -74,6 +81,9 @@ public class YudaoSwaggerAutoConfiguration { public GroupedOpenApi appApi() { return GroupedOpenApi.builder() .group("app") + .addOperationCustomizer((operation, handlerMethod) -> + operation.addParametersItem(globalHeaderParameter()) + ) .pathsToMatch("/app-api/**") .build(); } @@ -82,9 +92,24 @@ public class YudaoSwaggerAutoConfiguration { public GroupedOpenApi adminApi() { return GroupedOpenApi.builder() .group("admin") + .addOperationCustomizer((operation, handlerMethod) -> + operation.addParametersItem(globalHeaderParameter()) + ) .pathsToMatch("/admin-api/**") .build(); } + private static Parameter globalHeaderParameter() { + return new Parameter() + .name(HEADER_TENANT_ID) + .description("租户编号") + .in(String.valueOf(SecurityScheme.In.HEADER)) + .schema(new IntegerSchema() + ._default(1L) + .name(HEADER_TENANT_ID) + .description("租户编号") + ); + } + } diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 0cc0d271e..a14208ea0 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -37,14 +37,17 @@ spring: springdoc: show-actuator: true swagger-ui: + enabled: true path: /swagger-ui api-docs: + enabled: true path: /v3/api-docs -knife4j: - enable: true - setting: - language: zh_cn + +#knife4j: +# enable: true +# setting: +# language: zh_cn # 工作流 Flowable 配置 flowable: diff --git a/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue b/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue index 5d4697c1a..574e9ddd2 100644 --- a/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue +++ b/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue @@ -8,5 +8,5 @@ import { ref } from 'vue' import { IFrame } from '@/components/IFrame' const BASE_URL = import.meta.env.VITE_BASE_URL -const src = ref(BASE_URL + '/doc.html') +const src = ref(BASE_URL + '/swagger-ui') From 3d390d0d8f39affa3403a5d3edf533ce67365c38 Mon Sep 17 00:00:00 2001 From: xingyu Date: Tue, 17 Jan 2023 20:42:18 +0800 Subject: [PATCH 11/59] feat: knife4j --- yudao-dependencies/pom.xml | 12 +++++----- yudao-framework/yudao-common/pom.xml | 4 ---- .../yudao-spring-boot-starter-web/pom.xml | 8 +++---- .../swagger/config/SwaggerProperties.java | 22 +++++++++++++++++++ .../config/YudaoSwaggerAutoConfiguration.java | 4 ++-- ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../src/main/resources/application.yaml | 13 ++++++----- .../src/views/infra/swagger/index.vue | 2 +- 8 files changed, 44 insertions(+), 22 deletions(-) diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index a29a0052f..e42ef66ab 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -19,7 +19,7 @@ 2.7.7 1.6.14 - + 4.0.0 2.5 1.2.15 @@ -164,11 +164,11 @@ ${revision} - - - - - + + com.github.xiaoymin + knife4j-openapi3-spring-boot-starter + ${knife4j.version} + org.springdoc springdoc-openapi-ui diff --git a/yudao-framework/yudao-common/pom.xml b/yudao-framework/yudao-common/pom.xml index 0bf582993..760160330 100644 --- a/yudao-framework/yudao-common/pom.xml +++ b/yudao-framework/yudao-common/pom.xml @@ -58,10 +58,6 @@ provided - - - - org.springdoc springdoc-openapi-ui diff --git a/yudao-framework/yudao-spring-boot-starter-web/pom.xml b/yudao-framework/yudao-spring-boot-starter-web/pom.xml index 31bf43e12..e591cc329 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/pom.xml +++ b/yudao-framework/yudao-spring-boot-starter-web/pom.xml @@ -33,10 +33,10 @@ true - - - - + + com.github.xiaoymin + knife4j-openapi3-spring-boot-starter + org.springdoc springdoc-openapi-ui diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/SwaggerProperties.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/SwaggerProperties.java index d1008eddc..21680cd00 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/SwaggerProperties.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/SwaggerProperties.java @@ -39,5 +39,27 @@ public class SwaggerProperties { */ @NotEmpty(message = "扫描的 package 不能为空") private String basePackage; + /** + * url + */ + @NotEmpty(message = "扫描的 package 不能为空") + private String url; + /** + * email + */ + @NotEmpty(message = "扫描的 email 不能为空") + private String email; + + /** + * license + */ + @NotEmpty(message = "扫描的 license 不能为空") + private String license; + + /** + * license-url + */ + @NotEmpty(message = "扫描的 license-url 不能为空") + private String licenseUrl; } diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index 313b60010..0eb39b7ce 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -44,8 +44,8 @@ public class YudaoSwaggerAutoConfiguration { .title(properties.getTitle()) .description(properties.getDescription()) .version(properties.getVersion()) - .contact(new Contact().name("xingyuv").url("xingyuv.com").email("xingyu4j@vip.qq.com")) - .license(new License().name("MIT").url("https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE")); + .contact(new Contact().name(properties.getAuthor()).url(properties.getUrl()).email(properties.getEmail())) + .license(new License().name(properties.getLicense()).url(properties.getLicenseUrl())); return new OpenAPI() .info(info) .schemaRequirement(HttpHeaders.AUTHORIZATION, securityScheme()) diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/yudao-framework/yudao-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 2a422bfa2..44678daef 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,4 +1,5 @@ cn.iocoder.yudao.framework.apilog.config.YudaoApiLogAutoConfiguration cn.iocoder.yudao.framework.jackson.config.YudaoJacksonAutoConfiguration +com.github.xiaoymin.knife4j.spring.configuration.Knife4jAutoConfiguration cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration \ No newline at end of file diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index a14208ea0..f9cbf7759 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -43,11 +43,10 @@ springdoc: enabled: true path: /v3/api-docs - -#knife4j: -# enable: true -# setting: -# language: zh_cn +knife4j: + enable: true + setting: + language: zh_cn # 工作流 Flowable 配置 flowable: @@ -117,6 +116,10 @@ yudao: description: 提供管理员管理的所有功能 version: ${yudao.info.version} base-package: ${yudao.info.base-package} + url: ${yudao.web.admin-ui.url} + email: xingyu4j@vip.qq.com + license: MIT + license-url: https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE captcha: enable: true # 验证码的开关,默认为 true codegen: diff --git a/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue b/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue index 574e9ddd2..5d4697c1a 100644 --- a/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue +++ b/yudao-ui-admin-vue3/src/views/infra/swagger/index.vue @@ -8,5 +8,5 @@ import { ref } from 'vue' import { IFrame } from '@/components/IFrame' const BASE_URL = import.meta.env.VITE_BASE_URL -const src = ref(BASE_URL + '/swagger-ui') +const src = ref(BASE_URL + '/doc.html') From 0ebba2eb8116e4da42753f0e2c732e137baade9a Mon Sep 17 00:00:00 2001 From: xingyu Date: Tue, 17 Jan 2023 20:47:07 +0800 Subject: [PATCH 12/59] =?UTF-8?q?=E7=A7=BB=E9=99=A4springfox=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/YudaoSwaggerAutoConfiguration.java | 6 +-- ...ngFoxHandlerProviderBeanPostProcessor.java | 43 ------------------- 2 files changed, 2 insertions(+), 47 deletions(-) delete mode 100644 yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index 0eb39b7ce..fec3e21e6 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -15,7 +15,6 @@ import org.springdoc.core.customizers.ServerBaseUrlCustomizer; import org.springdoc.core.providers.JavadocProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpHeaders; @@ -26,14 +25,13 @@ import java.util.Optional; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; /** - * Swagger3 自动配置类 + * springdoc 自动配置类 + * 使用 knife4j.enable=false 禁用 Swagger * * @author 芋道源码 */ @AutoConfiguration @ConditionalOnClass({OpenAPI.class}) -// 允许使用 swagger.enable=false 禁用 Swagger -@ConditionalOnProperty(prefix = "yudao.swagger", value = "enable", matchIfMissing = true) @EnableConfigurationProperties(SwaggerProperties.class) public class YudaoSwaggerAutoConfiguration { diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java deleted file mode 100644 index 4eea3cc36..000000000 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/core/SpringFoxHandlerProviderBeanPostProcessor.java +++ /dev/null @@ -1,43 +0,0 @@ -//package cn.iocoder.yudao.framework.swagger.core; -// -//import cn.hutool.core.util.ReflectUtil; -//import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -//import org.springframework.beans.BeansException; -//import org.springframework.beans.factory.config.BeanPostProcessor; -//import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; -//import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider; -//import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; -// -//import java.util.List; -// -///** -// * 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题 -// * 该问题对应的 issue 为 https://github.com/springfox/springfox/issues/3462 -// * -// * @author 芋道源码 -// */ -//public class SpringFoxHandlerProviderBeanPostProcessor implements BeanPostProcessor { -// -// @Override -// public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { -// if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { -// customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); -// } -// return bean; -// } -// -// private void customizeSpringfoxHandlerMappings(List mappings) { -// // 移除,只保留 patternParser -// List copy = CollectionUtils.filterList(mappings, mapping -> mapping.getPatternParser() == null); -// // 添加到 mappings 中 -// mappings.clear(); -// mappings.addAll(copy); -// } -// -// @SuppressWarnings("unchecked") -// private List getHandlerMappings(Object bean) { -// return (List) -// ReflectUtil.getFieldValue(bean, "handlerMappings"); -// } -// -//} From e314a63ee90f4caa5731578c9695630554dda15a Mon Sep 17 00:00:00 2001 From: xingyu Date: Tue, 17 Jan 2023 21:18:10 +0800 Subject: [PATCH 13/59] =?UTF-8?q?feat:=20springdoc=20=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/codegen/java/controller/controller.vm | 4 +++- .../src/main/resources/codegen/java/controller/vo/baseVO.vm | 2 +- .../main/resources/codegen/java/controller/vo/createReqVO.vm | 2 +- .../src/main/resources/codegen/java/controller/vo/excelVO.vm | 2 +- .../main/resources/codegen/java/controller/vo/exportReqVO.vm | 2 +- .../main/resources/codegen/java/controller/vo/pageReqVO.vm | 2 +- .../src/main/resources/codegen/java/controller/vo/respVO.vm | 2 +- .../main/resources/codegen/java/controller/vo/updateReqVO.vm | 2 +- .../system/controller/admin/notice/NoticeController.java | 1 - 9 files changed, 10 insertions(+), 9 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm index 0296df771..a8c1f62c5 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/controller.vm @@ -5,7 +5,9 @@ import javax.annotation.Resource; import org.springframework.validation.annotation.Validated; #if ($sceneEnum.scene == 1)import org.springframework.security.access.prepost.PreAuthorize;#end -import io.swagger.annotations.*; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; import javax.validation.constraints.*; import javax.validation.*; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/baseVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/baseVO.vm index a0ad48d60..e2c1f0b39 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/baseVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/baseVO.vm @@ -1,5 +1,6 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; #foreach ($column in $columns) @@ -10,7 +11,6 @@ import java.math.BigDecimal; import java.time.LocalDateTime; #end #end -import io.swagger.annotations.*; import javax.validation.constraints.*; ## 处理 Date 字段的引入 #foreach ($column in $columns) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm index 32ab0f2ba..d4f6f8ea9 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/createReqVO.vm @@ -2,7 +2,7 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePac import lombok.*; import java.util.*; -import io.swagger.annotations.*; +import io.swagger.v3.oas.annotations.media.Schema; import javax.validation.constraints.*; ## 处理 Date 字段的引入 #foreach ($column in $columns) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/excelVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/excelVO.vm index 8bfd92b69..15c6660c8 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/excelVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/excelVO.vm @@ -1,5 +1,6 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; #foreach ($column in $columns) @@ -10,7 +11,6 @@ import java.math.BigDecimal; import java.time.LocalDateTime; #end #end -import io.swagger.annotations.*; import com.alibaba.excel.annotation.ExcelProperty; #foreach ($column in $columns) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm index 9d3be20cd..d3ef4aacd 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/exportReqVO.vm @@ -2,7 +2,7 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePac import lombok.*; import java.util.*; -import io.swagger.annotations.*; +import io.swagger.v3.oas.annotations.media.Schema; import ${PageParamClassName}; ## 处理 Date 字段的引入 #foreach ($column in $columns) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm index 3105132b9..6f9868da3 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/pageReqVO.vm @@ -2,7 +2,7 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePac import lombok.*; import java.util.*; -import io.swagger.annotations.*; +import io.swagger.v3.oas.annotations.media.Schema; import ${PageParamClassName}; ## 处理 Date 字段的引入 #foreach ($column in $columns) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm index ba49133af..2288ceee8 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/respVO.vm @@ -1,5 +1,6 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; #foreach ($column in $columns) #if (${column.javaType} == "LocalDateTime") @@ -7,7 +8,6 @@ import java.time.LocalDateTime; #break #end #end -import io.swagger.annotations.*; @Schema(description = "${sceneEnum.name} - ${table.classComment} Response VO") @Data diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm index 1bdadf2ed..48d74321d 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/controller/vo/updateReqVO.vm @@ -1,8 +1,8 @@ package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; ## 处理 Date 字段的引入 #foreach ($column in $columns) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java index 7143b934e..39d24bf3e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java @@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.system.service.notice.NoticeService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; From 13afc3d57af8c3008759500cdcac5a5cfb3a9454 Mon Sep 17 00:00:00 2001 From: xingyu Date: Tue, 17 Jan 2023 21:25:06 +0800 Subject: [PATCH 14/59] feat: springdoc --- .../cn/iocoder/yudao/framework/common/pojo/PageResult.java | 1 + .../system/controller/admin/captcha/CaptchaController.java | 6 +++--- .../system/service/auth/AdminAuthServiceImplTest.java | 5 +---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java index f0048517d..ff167d149 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/PageResult.java @@ -1,4 +1,5 @@ package cn.iocoder.yudao.framework.common.pojo; + import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java index 92359fda9..9f163a62f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/captcha/CaptchaController.java @@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.system.controller.admin.captcha; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.servlet.ServletUtil; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import com.anji.captcha.model.common.ResponseModel; -import com.anji.captcha.model.vo.CaptchaVO; -import com.anji.captcha.service.CaptchaService; +import com.xingyuv.captcha.model.common.ResponseModel; +import com.xingyuv.captcha.model.vo.CaptchaVO; +import com.xingyuv.captcha.service.CaptchaService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.PostMapping; diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java index 218778ac9..dc607b7ce 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java @@ -5,8 +5,6 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.framework.test.core.util.AssertUtils; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; -import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginReqVO; -import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthLoginRespVO; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; @@ -16,7 +14,7 @@ import cn.iocoder.yudao.module.system.service.member.MemberService; import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService; import cn.iocoder.yudao.module.system.service.social.SocialUserService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; -import com.anji.captcha.service.CaptchaService; +import com.xingyuv.captcha.service.CaptchaService; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; @@ -25,7 +23,6 @@ import javax.annotation.Resource; import javax.validation.Validator; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; From be9d670beed60fe4f50e3760c7e2298621b8a0dc Mon Sep 17 00:00:00 2001 From: xingyu Date: Wed, 18 Jan 2023 16:15:08 +0800 Subject: [PATCH 15/59] feat: mp springdoc --- yudao-module-mp/yudao-module-mp-biz/pom.xml | 5 ++ .../admin/account/MpAccountController.java | 32 +++++----- .../admin/account/vo/MpAccountBaseVO.java | 16 ++--- .../account/vo/MpAccountCreateReqVO.java | 4 +- .../admin/account/vo/MpAccountPageReqVO.java | 14 +++-- .../admin/account/vo/MpAccountRespVO.java | 11 ++-- .../account/vo/MpAccountSimpleRespVO.java | 9 ++- .../account/vo/MpAccountUpdateReqVO.java | 13 ++-- .../admin/material/MpMaterialController.java | 20 +++--- .../material/vo/MpMaterialPageReqVO.java | 11 ++-- .../admin/material/vo/MpMaterialRespVO.java | 29 +++++---- .../vo/MpMaterialUploadNewsImageReqVO.java | 9 ++- .../vo/MpMaterialUploadPermanentReqVO.java | 17 +++--- .../material/vo/MpMaterialUploadRespVO.java | 9 ++- .../vo/MpMaterialUploadTemporaryReqVO.java | 11 ++-- .../admin/menu/MpMenuController.java | 18 +++--- .../admin/menu/vo/MpMenuBaseVO.java | 31 +++++----- .../admin/menu/vo/MpMenuRespVO.java | 13 ++-- .../admin/menu/vo/MpMenuSaveReqVO.java | 9 ++- .../admin/message/MpAutoReplyController.java | 22 +++---- .../admin/message/MpMessageController.java | 10 +-- .../vo/autoreply/MpAutoReplyBaseVO.java | 31 +++++----- .../vo/autoreply/MpAutoReplyCreateReqVO.java | 7 +-- .../vo/autoreply/MpAutoReplyPageReqVO.java | 7 +-- .../vo/autoreply/MpAutoReplyRespVO.java | 13 ++-- .../vo/autoreply/MpAutoReplyUpdateReqVO.java | 7 +-- .../vo/message/MpMessagePageReqVO.java | 17 +++--- .../message/vo/message/MpMessageRespVO.java | 61 +++++++++---------- .../vo/message/MpMessageSendReqVO.java | 25 ++++---- .../admin/news/MpDraftController.java | 37 +++++------ .../admin/news/MpFreePublishController.java | 32 +++++----- .../admin/news/vo/MpDraftPageReqVO.java | 7 +-- .../admin/news/vo/MpFreePublishPageReqVO.java | 7 +-- .../admin/open/MpOpenController.java | 10 +-- .../open/vo/MpOpenCheckSignatureReqVO.java | 17 ++---- .../open/vo/MpOpenHandleMessageReqVO.java | 17 +++--- .../statistics/MpStatisticsController.java | 14 ++--- .../statistics/vo/MpStatisticsGetReqVO.java | 9 ++- .../MpStatisticsInterfaceSummaryRespVO.java | 15 +++-- .../vo/MpStatisticsUpstreamMessageRespVO.java | 11 ++-- .../vo/MpStatisticsUserCumulateRespVO.java | 9 ++- .../vo/MpStatisticsUserSummaryRespVO.java | 13 ++-- .../controller/admin/tag/MpTagController.java | 24 ++++---- .../controller/admin/tag/vo/MpTagBaseVO.java | 4 +- .../admin/tag/vo/MpTagCreateReqVO.java | 7 +-- .../admin/tag/vo/MpTagPageReqVO.java | 9 ++- .../controller/admin/tag/vo/MpTagRespVO.java | 11 ++-- .../admin/tag/vo/MpTagSimpleRespVO.java | 11 ++-- .../admin/tag/vo/MpTagUpdateReqVO.java | 12 ++-- .../admin/user/MpUserController.java | 20 +++--- .../admin/user/vo/MpUserPageReqVO.java | 11 ++-- .../admin/user/vo/MpUserRespVO.java | 37 ++++++----- .../admin/user/vo/MpUserUpdateReqVO.java | 13 ++-- .../src/main/resources/application-local.yaml | 22 +++---- 54 files changed, 412 insertions(+), 448 deletions(-) diff --git a/yudao-module-mp/yudao-module-mp-biz/pom.xml b/yudao-module-mp/yudao-module-mp-biz/pom.xml index ea9681832..f1a217698 100644 --- a/yudao-module-mp/yudao-module-mp-biz/pom.xml +++ b/yudao-module-mp/yudao-module-mp-biz/pom.xml @@ -54,6 +54,11 @@ yudao-spring-boot-starter-security + + org.springframework.boot + spring-boot-starter-validation + + cn.iocoder.boot diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/MpAccountController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/MpAccountController.java index e2192f5c6..62be175ac 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/MpAccountController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/MpAccountController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.mp.controller.admin.account.vo.*; import cn.iocoder.yudao.module.mp.convert.account.MpAccountConvert; import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; import cn.iocoder.yudao.module.mp.service.account.MpAccountService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 公众号账号") +@Tag(name = "管理后台 - 公众号账号") @RestController @RequestMapping("/mp/account") @Validated @@ -29,14 +29,14 @@ public class MpAccountController { private MpAccountService mpAccountService; @PostMapping("/create") - @ApiOperation("创建公众号账号") + @Operation(summary = "创建公众号账号") @PreAuthorize("@ss.hasPermission('mp:account:create')") public CommonResult createAccount(@Valid @RequestBody MpAccountCreateReqVO createReqVO) { return success(mpAccountService.createAccount(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新公众号账号") + @Operation(summary = "更新公众号账号") @PreAuthorize("@ss.hasPermission('mp:account:update')") public CommonResult updateAccount(@Valid @RequestBody MpAccountUpdateReqVO updateReqVO) { mpAccountService.updateAccount(updateReqVO); @@ -44,8 +44,8 @@ public class MpAccountController { } @DeleteMapping("/delete") - @ApiOperation("删除公众号账号") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除公众号账号") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('mp:account:delete')") public CommonResult deleteAccount(@RequestParam("id") Long id) { mpAccountService.deleteAccount(id); @@ -53,8 +53,8 @@ public class MpAccountController { } @GetMapping("/get") - @ApiOperation("获得公众号账号") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得公众号账号") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('mp:account:query')") public CommonResult getAccount(@RequestParam("id") Long id) { MpAccountDO wxAccount = mpAccountService.getAccount(id); @@ -62,7 +62,7 @@ public class MpAccountController { } @GetMapping("/page") - @ApiOperation("获得公众号账号分页") + @Operation(summary = "获得公众号账号分页") @PreAuthorize("@ss.hasPermission('mp:account:query')") public CommonResult> getAccountPage(@Valid MpAccountPageReqVO pageVO) { PageResult pageResult = mpAccountService.getAccountPage(pageVO); @@ -70,7 +70,7 @@ public class MpAccountController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获取公众号账号精简信息列表") + @Operation(summary = "获取公众号账号精简信息列表") @PreAuthorize("@ss.hasPermission('mp:account:query')") public CommonResult> getSimpleAccounts() { List list = mpAccountService.getAccountList(); @@ -78,8 +78,8 @@ public class MpAccountController { } @PutMapping("/generate-qr-code") - @ApiOperation("生成公众号二维码") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "生成公众号二维码") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('mp:account:qr-code')") public CommonResult generateAccountQrCode(@RequestParam("id") Long id) { mpAccountService.generateAccountQrCode(id); @@ -87,8 +87,8 @@ public class MpAccountController { } @PutMapping("/clear-quota") - @ApiOperation("清空公众号 API 配额") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "清空公众号 API 配额") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('mp:account:clear-quota')") public CommonResult clearAccountQuota(@RequestParam("id") Long id) { mpAccountService.clearAccountQuota(id); diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountBaseVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountBaseVO.java index 34176f9b5..cda7ec629 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountBaseVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.mp.controller.admin.account.vo; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -14,30 +14,30 @@ import javax.validation.constraints.NotEmpty; @Data public class MpAccountBaseVO { - @ApiModelProperty(value = "公众号名称", required = true, example = "芋道源码") + @Schema(description = "公众号名称", required = true, example = "芋道源码") @NotEmpty(message = "公众号名称不能为空") private String name; - @ApiModelProperty(value = "公众号微信号", required = true, example = "yudaoyuanma") + @Schema(description = "公众号微信号", required = true, example = "yudaoyuanma") @NotEmpty(message = "公众号微信号不能为空") private String account; - @ApiModelProperty(value = "公众号 appId", required = true, example = "wx5b23ba7a5589ecbb") + @Schema(description = "公众号 appId", required = true, example = "wx5b23ba7a5589ecbb") @NotEmpty(message = "公众号 appId 不能为空") private String appId; - @ApiModelProperty(value = "公众号密钥", required = true, example = "3a7b3b20c537e52e74afd395eb85f61f") + @Schema(description = "公众号密钥", required = true, example = "3a7b3b20c537e52e74afd395eb85f61f") @NotEmpty(message = "公众号密钥不能为空") private String appSecret; - @ApiModelProperty(value = "公众号 token", required = true, example = "kangdayuzhen") + @Schema(description = "公众号 token", required = true, example = "kangdayuzhen") @NotEmpty(message = "公众号 token 不能为空") private String token; - @ApiModelProperty(value = "加密密钥", example = "gjN+Ksei") + @Schema(description = "加密密钥", example = "gjN+Ksei") private String aesKey; - @ApiModelProperty(value = "备注", example = "请关注芋道源码,学习技术") + @Schema(description = "备注", example = "请关注芋道源码,学习技术") private String remark; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountCreateReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountCreateReqVO.java index 57b329b92..b864f16c5 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountCreateReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountCreateReqVO.java @@ -1,11 +1,11 @@ package cn.iocoder.yudao.module.mp.controller.admin.account.vo; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 公众号账号创建 Request VO") +@Schema(description = "管理后台 - 公众号账号创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountPageReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountPageReqVO.java index 23f2c2f0e..93093dc19 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountPageReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountPageReqVO.java @@ -1,22 +1,24 @@ package cn.iocoder.yudao.module.mp.controller.admin.account.vo; -import lombok.*; -import io.swagger.annotations.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; -@ApiModel("管理后台 - 公众号账号分页 Request VO") +@Schema(description = "管理后台 - 公众号账号分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpAccountPageReqVO extends PageParam { - @ApiModelProperty(value = "公众号名称", notes = "模糊匹配") + @Schema(name = "公众号名称", description = "模糊匹配") private String name; - @ApiModelProperty(value = "公众号账号", notes = "模糊匹配") + @Schema(name = "公众号账号", description = "模糊匹配") private String account; - @ApiModelProperty(value = "公众号 appid", notes = "模糊匹配") + @Schema(name = "公众号 appid", description = "模糊匹配") private String appId; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountRespVO.java index 8cda94d9f..9914494ce 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountRespVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.mp.controller.admin.account.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.util.Date; -@ApiModel("管理后台 - 公众号账号 Response VO") +@Schema(description = "管理后台 - 公众号账号 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpAccountRespVO extends MpAccountBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "二维码图片URL", example = "https://www.iocoder.cn/1024.png") + @Schema(description = "二维码图片URL", example = "https://www.iocoder.cn/1024.png") private String qrCodeUrl; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private Date createTime; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountSimpleRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountSimpleRespVO.java index f3826eaa1..6d63f0ef7 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountSimpleRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountSimpleRespVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.mp.controller.admin.account.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("管理后台 - 公众号账号精简信息 Response VO") +@Schema(description = "管理后台 - 公众号账号精简信息 Response VO") @Data public class MpAccountSimpleRespVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "公众号名称", required = true, example = "芋道源码") + @Schema(description = "公众号名称", required = true, example = "芋道源码") private String name; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountUpdateReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountUpdateReqVO.java index f348c22c2..c19e0acac 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountUpdateReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountUpdateReqVO.java @@ -1,16 +1,19 @@ package cn.iocoder.yudao.module.mp.controller.admin.account.vo; -import lombok.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; -@ApiModel("管理后台 - 公众号账号更新 Request VO") +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 公众号账号更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpAccountUpdateReqVO extends MpAccountBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/MpMaterialController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/MpMaterialController.java index efd7b0420..ef175d2af 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/MpMaterialController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/MpMaterialController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.mp.controller.admin.material.vo.*; import cn.iocoder.yudao.module.mp.convert.material.MpMaterialConvert; import cn.iocoder.yudao.module.mp.dal.dataobject.material.MpMaterialDO; import cn.iocoder.yudao.module.mp.service.material.MpMaterialService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import java.io.IOException; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 公众号素材") +@Tag(name = "管理后台 - 公众号素材") @RestController @RequestMapping("/mp/material") @Validated @@ -28,7 +28,7 @@ public class MpMaterialController { @Resource private MpMaterialService mpMaterialService; - @ApiOperation("上传临时素材") + @Operation(summary = "上传临时素材") @PostMapping("/upload-temporary") @PreAuthorize("@ss.hasPermission('mp:material:upload-temporary')") public CommonResult uploadTemporaryMaterial( @@ -37,7 +37,7 @@ public class MpMaterialController { return success(MpMaterialConvert.INSTANCE.convert(material)); } - @ApiOperation("上传永久素材") + @Operation(summary = "上传永久素材") @PostMapping("/upload-permanent") @PreAuthorize("@ss.hasPermission('mp:material:upload-permanent')") public CommonResult uploadPermanentMaterial( @@ -46,16 +46,16 @@ public class MpMaterialController { return success(MpMaterialConvert.INSTANCE.convert(material)); } - @ApiOperation("删除素材") + @Operation(summary = "删除素材") @DeleteMapping("/delete-permanent") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('mp:material:delete')") public CommonResult deleteMaterial(@RequestParam("id") Long id) { mpMaterialService.deleteMaterial(id); return success(true); } - @ApiOperation("上传图文内容中的图片") + @Operation(summary = "上传图文内容中的图片") @PostMapping("/upload-news-image") @PreAuthorize("@ss.hasPermission('mp:material:upload-news-image')") public CommonResult uploadNewsImage(@Valid MpMaterialUploadNewsImageReqVO reqVO) @@ -63,7 +63,7 @@ public class MpMaterialController { return success(mpMaterialService.uploadNewsImage(reqVO)); } - @ApiOperation("获得素材分页") + @Operation(summary = "获得素材分页") @GetMapping("/page") @PreAuthorize("@ss.hasPermission('mp:material:query')") public CommonResult> getMaterialPage(@Valid MpMaterialPageReqVO pageReqVO) { diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialPageReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialPageReqVO.java index 88c087c93..ce3b0f9e7 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialPageReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialPageReqVO.java @@ -1,28 +1,27 @@ package cn.iocoder.yudao.module.mp.controller.admin.material.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号素材的分页 Request VO") +@Schema(description = "管理后台 - 公众号素材的分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpMaterialPageReqVO extends PageParam { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") + @Schema(description = "公众号账号的编号", required = true, example = "2048") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; - @ApiModelProperty(value = "是否永久", example = "true") + @Schema(description = "是否永久", example = "true") private Boolean permanent; - @ApiModelProperty(value = "文件类型", example = "image", notes = "参见 WxConsts.MediaFileType 枚举") + @Schema(description = "文件类型 参见 WxConsts.MediaFileType 枚举", example = "image") private String type; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialRespVO.java index 352d8ba67..a93dfd994 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialRespVO.java @@ -1,48 +1,47 @@ package cn.iocoder.yudao.module.mp.controller.admin.material.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.Date; -@ApiModel("管理后台 - 公众号素材 Response VO") +@Schema(description = "管理后台 - 公众号素材 Response VO") @Data public class MpMaterialRespVO { - @ApiModelProperty(value = "主键", required = true, example = "1024") + @Schema(description = "主键", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1") + @Schema(description = "公众号账号的编号", required = true, example = "1") private Long accountId; - @ApiModelProperty(value = "公众号账号的 appId", required = true, example = "wx1234567890") + @Schema(description = "公众号账号的 appId", required = true, example = "wx1234567890") private String appId; - @ApiModelProperty(value = "素材的 media_id", required = true, example = "123") + @Schema(description = "素材的 media_id", required = true, example = "123") private String mediaId; - @ApiModelProperty(value = "文件类型", required = true, example = "image", notes = "参见 WxConsts.MediaFileType 枚举") + @Schema(description = "文件类型 参见 WxConsts.MediaFileType 枚举", required = true, example = "image") private String type; - @ApiModelProperty(value = "是否永久", required = true, example = "true", notes = "true - 永久;false - 临时") + @Schema(description = "是否永久 true - 永久;false - 临时", required = true, example = "true") private Boolean permanent; - @ApiModelProperty(value = "素材的 URL", required = true, example = "https://www.iocoder.cn/1.png") + @Schema(description = "素材的 URL", required = true, example = "https://www.iocoder.cn/1.png") private String url; - @ApiModelProperty(value = "名字", example = "yunai.png") + @Schema(description = "名字", example = "yunai.png") private String name; - @ApiModelProperty(value = "公众号文件 URL", example = "https://mmbiz.qpic.cn/xxx.mp3", notes = "只有【永久素材】使用") + @Schema(description = "公众号文件 URL 只有【永久素材】使用", example = "https://mmbiz.qpic.cn/xxx.mp3") private String mpUrl; - @ApiModelProperty(value = "视频素材的标题", example = "我是标题", notes = "只有【永久素材】使用") + @Schema(description = "视频素材的标题 只有【永久素材】使用", example = "我是标题") private String title; - @ApiModelProperty(value = "视频素材的描述", example = "我是介绍", notes = "只有【永久素材】使用") + @Schema(description = "视频素材的描述 只有【永久素材】使用", example = "我是介绍") private String introduction; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private Date createTime; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadNewsImageReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadNewsImageReqVO.java index 66aec47f7..5dd689a68 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadNewsImageReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadNewsImageReqVO.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.mp.controller.admin.material.vo; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号素材上传图文内容中的图片 Request VO") +@Schema(description = "管理后台 - 公众号素材上传图文内容中的图片 Request VO") @Data public class MpMaterialUploadNewsImageReqVO { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") + @Schema(description = "公众号账号的编号", required = true, example = "2048") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; - @ApiModelProperty(value = "文件附件", required = true) + @Schema(description = "文件附件", required = true) @NotNull(message = "文件不能为空") @JsonIgnore // 避免被操作日志,进行序列化,导致报错 private MultipartFile file; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadPermanentReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadPermanentReqVO.java index 706f71351..93d0a863e 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadPermanentReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadPermanentReqVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.mp.controller.admin.material.vo; import cn.hutool.core.util.ObjectUtil; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import me.chanjar.weixin.common.api.WxConsts; import org.springframework.web.multipart.MultipartFile; @@ -12,29 +11,29 @@ import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号素材上传永久 Request VO") +@Schema(description = "管理后台 - 公众号素材上传永久 Request VO") @Data public class MpMaterialUploadPermanentReqVO { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") + @Schema(description = "公众号账号的编号", required = true, example = "2048") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; - @ApiModelProperty(value = "文件类型", required = true, example = "image", notes = "参见 WxConsts.MediaFileType 枚举") + @Schema(description = "文件类型 参见 WxConsts.MediaFileType 枚举", required = true, example = "image") @NotEmpty(message = "文件类型不能为空") private String type; - @ApiModelProperty(value = "文件附件", required = true) + @Schema(description = "文件附件", required = true) @NotNull(message = "文件不能为空") @JsonIgnore // 避免被操作日志,进行序列化,导致报错 private MultipartFile file; - @ApiModelProperty(value = "名字", example = "wechat.mp", notes = "如果 name 为空,则使用 file 文件名") + @Schema(description = "名字 如果 name 为空,则使用 file 文件名", example = "wechat.mp") private String name; - @ApiModelProperty(value = "视频素材的标题", example = "视频素材的标题", notes = "文件类型为 video 时,必填") + @Schema(description = "视频素材的标题 文件类型为 video 时,必填", example = "视频素材的标题") private String title; - @ApiModelProperty(value = "视频素材的描述", example = "视频素材的描述", notes = "文件类型为 video 时,必填") + @Schema(description = "视频素材的描述 文件类型为 video 时,必填", example = "视频素材的描述") private String introduction; @AssertTrue(message = "标题不能为空") diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadRespVO.java index 917cc8941..d6a257e03 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadRespVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.mp.controller.admin.material.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("管理后台 - 公众号素材上传结果 Response VO") +@Schema(description = "管理后台 - 公众号素材上传结果 Response VO") @Data public class MpMaterialUploadRespVO { - @ApiModelProperty(value = "素材的 media_id", required = true, example = "123") + @Schema(description = "素材的 media_id", required = true, example = "123") private String mediaId; - @ApiModelProperty(value = "素材的 URL", required = true, example = "https://www.iocoder.cn/1.png") + @Schema(description = "素材的 URL", required = true, example = "https://www.iocoder.cn/1.png") private String url; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadTemporaryReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadTemporaryReqVO.java index f8c73cec2..5d0f7cafe 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadTemporaryReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialUploadTemporaryReqVO.java @@ -1,27 +1,26 @@ package cn.iocoder.yudao.module.mp.controller.admin.material.vo; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.web.multipart.MultipartFile; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号素材上传临时 Request VO") +@Schema(description = "管理后台 - 公众号素材上传临时 Request VO") @Data public class MpMaterialUploadTemporaryReqVO { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") + @Schema(description = "公众号账号的编号", required = true, example = "2048") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; - @ApiModelProperty(value = "文件类型", required = true, example = "image", notes = "参见 WxConsts.MediaFileType 枚举") + @Schema(description = "文件类型 参见 WxConsts.MediaFileType 枚举", required = true, example = "image") @NotEmpty(message = "文件类型不能为空") private String type; - @ApiModelProperty(value = "文件附件", required = true) + @Schema(description = "文件附件", required = true) @NotNull(message = "文件不能为空") @JsonIgnore // 避免被操作日志,进行序列化,导致报错 private MultipartFile file; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/MpMenuController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/MpMenuController.java index f84fee561..b7c883519 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/MpMenuController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/MpMenuController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.mp.controller.admin.menu.vo.MpMenuSaveReqVO; import cn.iocoder.yudao.module.mp.convert.menu.MpMenuConvert; import cn.iocoder.yudao.module.mp.dal.dataobject.menu.MpMenuDO; import cn.iocoder.yudao.module.mp.service.menu.MpMenuService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 公众号菜单") +@Tag(name = "管理后台 - 公众号菜单") @RestController @RequestMapping("/mp/menu") @Validated @@ -29,7 +29,7 @@ public class MpMenuController { private MpMenuService mpMenuService; @PostMapping("/save") - @ApiOperation("保存公众号菜单") + @Operation(summary = "保存公众号菜单") @PreAuthorize("@ss.hasPermission('mp:menu:save')") public CommonResult saveMenu(@Valid @RequestBody MpMenuSaveReqVO createReqVO) { mpMenuService.saveMenu(createReqVO); @@ -37,8 +37,8 @@ public class MpMenuController { } @DeleteMapping("/delete") - @ApiOperation("删除公众号菜单") - @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, example = "10", dataTypeClass = Long.class) + @Operation(summary = "删除公众号菜单") + @Parameter(name = "accountId", description = "公众号账号的编号", required = true, example = "10") @PreAuthorize("@ss.hasPermission('mp:menu:delete')") public CommonResult deleteMenu(@RequestParam("accountId") Long accountId) { mpMenuService.deleteMenuByAccountId(accountId); @@ -46,8 +46,8 @@ public class MpMenuController { } @GetMapping("/list") - @ApiOperation("获得公众号菜单列表") - @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, example = "10", dataTypeClass = Long.class) + @Operation(summary = "获得公众号菜单列表") + @Parameter(name = "accountId", description = "公众号账号的编号", required = true, example = "10") @PreAuthorize("@ss.hasPermission('mp:menu:query')") public CommonResult> getMenuList(@RequestParam("accountId") Long accountId) { List list = mpMenuService.getMenuListByAccountId(accountId); diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuBaseVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuBaseVO.java index 27a9c1c90..cd0e5b2e4 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuBaseVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuBaseVO.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.mp.controller.admin.menu.vo; import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpMessageDO; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import me.chanjar.weixin.common.api.WxConsts; import org.hibernate.validator.constraints.URL; @@ -44,54 +44,53 @@ public class MpMenuBaseVO { */ private String type; - @ApiModelProperty(value = "网页链接", example = "https://www.iocoder.cn/") + @Schema(description = "网页链接", example = "https://www.iocoder.cn/") @NotEmpty(message = "网页链接不能为空", groups = {ViewButtonGroup.class, MiniProgramButtonGroup.class}) @URL(message = "网页链接必须是 URL 格式") private String url; - @ApiModelProperty(value = "小程序的 appId", example = "wx1234567890") + @Schema(description = "小程序的 appId", example = "wx1234567890") @NotEmpty(message = "小程序的 appId 不能为空", groups = MiniProgramButtonGroup.class) private String miniProgramAppId; - @ApiModelProperty(value = "小程序的页面路径", example = "pages/index/index") + @Schema(description = "小程序的页面路径", example = "pages/index/index") @NotEmpty(message = "小程序的页面路径不能为空", groups = MiniProgramButtonGroup.class) private String miniProgramPagePath; - @ApiModelProperty(value ="跳转图文的媒体编号", example = "jCQk93AIIgp8ixClWcW_NXXqBKInNWNmq2XnPeDZl7IMVqWiNeL4FfELtggRXd83") + @Schema(description ="跳转图文的媒体编号", example = "jCQk93AIIgp8ixClWcW_NXXqBKInNWNmq2XnPeDZl7IMVqWiNeL4FfELtggRXd83") @NotEmpty(message = "跳转图文的媒体编号不能为空", groups = ViewLimitedButtonGroup.class) private String articleId; // ========== 消息内容 ========== - @ApiModelProperty(value = "回复的消息类型", example = "text", - notes = "枚举 TEXT、IMAGE、VOICE、VIDEO、NEWS、MUSIC") + @Schema(description = "回复的消息类型 枚举 TEXT、IMAGE、VOICE、VIDEO、NEWS、MUSIC", example = "text") @NotEmpty(message = "回复的消息类型不能为空", groups = {ClickButtonGroup.class, ScanCodeWaitMsgButtonGroup.class}) private String replyMessageType; - @ApiModelProperty(value = "回复的消息内容", example = "欢迎关注") + @Schema(description = "回复的消息内容", example = "欢迎关注") @NotEmpty(message = "回复的消息内容不能为空", groups = TextMessageGroup.class) private String replyContent; - @ApiModelProperty(value = "回复的媒体 id", example = "123456") + @Schema(description = "回复的媒体 id", example = "123456") @NotEmpty(message = "回复的消息 mediaId 不能为空", groups = {ImageMessageGroup.class, VoiceMessageGroup.class, VideoMessageGroup.class}) private String replyMediaId; - @ApiModelProperty(value = "回复的媒体 URL", example = "https://www.iocoder.cn/xxx.jpg") + @Schema(description = "回复的媒体 URL", example = "https://www.iocoder.cn/xxx.jpg") @NotEmpty(message = "回复的消息 mediaId 不能为空", groups = {ImageMessageGroup.class, VoiceMessageGroup.class, VideoMessageGroup.class}) private String replyMediaUrl; - @ApiModelProperty(value = "缩略图的媒体 id", example = "123456") + @Schema(description = "缩略图的媒体 id", example = "123456") @NotEmpty(message = "回复的消息 thumbMediaId 不能为空", groups = {MusicMessageGroup.class}) private String replyThumbMediaId; - @ApiModelProperty(value = "缩略图的媒体 URL",example = "https://www.iocoder.cn/xxx.jpg") + @Schema(description = "缩略图的媒体 URL",example = "https://www.iocoder.cn/xxx.jpg") @NotEmpty(message = "回复的消息 thumbMedia 地址不能为空", groups = {MusicMessageGroup.class}) private String replyThumbMediaUrl; - @ApiModelProperty(value = "回复的标题", example = "视频标题") + @Schema(description = "回复的标题", example = "视频标题") @NotEmpty(message = "回复的消息标题不能为空", groups = VideoMessageGroup.class) private String replyTitle; - @ApiModelProperty(value = "回复的描述", example = "视频描述") + @Schema(description = "回复的描述", example = "视频描述") @NotEmpty(message = "消息描述不能为空", groups = VideoMessageGroup.class) private String replyDescription; @@ -104,11 +103,11 @@ public class MpMenuBaseVO { @Valid private List replyArticles; - @ApiModelProperty(value = "回复的音乐链接", example = "https://www.iocoder.cn/xxx.mp3") + @Schema(description = "回复的音乐链接", example = "https://www.iocoder.cn/xxx.mp3") @NotEmpty(message = "回复的音乐链接不能为空", groups = MusicMessageGroup.class) @URL(message = "回复的高质量音乐链接格式不正确", groups = MusicMessageGroup.class) private String replyMusicUrl; - @ApiModelProperty(value = "高质量音乐链接", example = "https://www.iocoder.cn/xxx.mp3") + @Schema(description = "高质量音乐链接", example = "https://www.iocoder.cn/xxx.mp3") @NotEmpty(message = "回复的高质量音乐链接不能为空", groups = MusicMessageGroup.class) @URL(message = "回复的高质量音乐链接格式不正确", groups = MusicMessageGroup.class) private String replyHqMusicUrl; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuRespVO.java index cd5bfb5a3..0d51b1064 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuRespVO.java @@ -1,29 +1,28 @@ package cn.iocoder.yudao.module.mp.controller.admin.menu.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.util.Date; -@ApiModel("管理后台 - 公众号菜单 Response VO") +@Schema(description = "管理后台 - 公众号菜单 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpMenuRespVO extends MpMenuBaseVO { - @ApiModelProperty(value = "主键", required = true, example = "1024") + @Schema(description = "主键", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") + @Schema(description = "公众号账号的编号", required = true, example = "2048") private Long accountId; - @ApiModelProperty(value = "公众号 appId", required = true, example = "wx1234567890ox") + @Schema(description = "公众号 appId", required = true, example = "wx1234567890ox") private String appId; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private Date createTime; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuSaveReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuSaveReqVO.java index 3c78bdfbb..43b7ff733 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuSaveReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuSaveReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.mp.controller.admin.menu.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.Valid; @@ -9,11 +8,11 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel("管理后台 - 公众号菜单保存 Request VO") +@Schema(description = "管理后台 - 公众号菜单保存 Request VO") @Data public class MpMenuSaveReqVO { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") + @Schema(description = "公众号账号的编号", required = true, example = "2048") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; @@ -21,7 +20,7 @@ public class MpMenuSaveReqVO { @Valid private List

menus; - @ApiModel("管理后台 - 公众号菜单保存时的每个菜单") + @Schema(description = "管理后台 - 公众号菜单保存时的每个菜单") @Data public static class Menu extends MpMenuBaseVO { diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpAutoReplyController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpAutoReplyController.java index 927103157..f6a8b9b38 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpAutoReplyController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpAutoReplyController.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.module.mp.controller.admin.message.vo.message.MpMessageP import cn.iocoder.yudao.module.mp.convert.message.MpAutoReplyConvert; import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpAutoReplyDO; import cn.iocoder.yudao.module.mp.service.message.MpAutoReplyService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -21,7 +21,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 公众号自动回复") +@Tag(name = "管理后台 - 公众号自动回复") @RestController @RequestMapping("/mp/auto-reply") @Validated @@ -31,7 +31,7 @@ public class MpAutoReplyController { private MpAutoReplyService mpAutoReplyService; @GetMapping("/page") - @ApiOperation("获得公众号自动回复分页") + @Operation(summary = "获得公众号自动回复分页") @PreAuthorize("@ss.hasPermission('mp:auto-reply:query')") public CommonResult> getAutoReplyPage(@Valid MpMessagePageReqVO pageVO) { PageResult pageResult = mpAutoReplyService.getAutoReplyPage(pageVO); @@ -39,8 +39,8 @@ public class MpAutoReplyController { } @GetMapping("/get") - @ApiOperation("获得公众号自动回复") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得公众号自动回复") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('mp:auto-reply:query')") public CommonResult getAutoReply(@RequestParam("id") Long id) { MpAutoReplyDO autoReply = mpAutoReplyService.getAutoReply(id); @@ -48,14 +48,14 @@ public class MpAutoReplyController { } @PostMapping("/create") - @ApiOperation("创建公众号自动回复") + @Operation(summary = "创建公众号自动回复") @PreAuthorize("@ss.hasPermission('mp:auto-reply:create')") public CommonResult createAutoReply(@Valid @RequestBody MpAutoReplyCreateReqVO createReqVO) { return success(mpAutoReplyService.createAutoReply(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新公众号自动回复") + @Operation(summary = "更新公众号自动回复") @PreAuthorize("@ss.hasPermission('mp:auto-reply:update')") public CommonResult updateAutoReply(@Valid @RequestBody MpAutoReplyUpdateReqVO updateReqVO) { mpAutoReplyService.updateAutoReply(updateReqVO); @@ -63,8 +63,8 @@ public class MpAutoReplyController { } @DeleteMapping("/delete") - @ApiOperation("删除公众号自动回复") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除公众号自动回复") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('mp:auto-reply:delete')") public CommonResult deleteAutoReply(@RequestParam("id") Long id) { mpAutoReplyService.deleteAutoReply(id); diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpMessageController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpMessageController.java index 41b11c6f0..66befc65e 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpMessageController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/MpMessageController.java @@ -8,8 +8,8 @@ import cn.iocoder.yudao.module.mp.controller.admin.message.vo.message.MpMessageS import cn.iocoder.yudao.module.mp.convert.message.MpMessageConvert; import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpMessageDO; import cn.iocoder.yudao.module.mp.service.message.MpMessageService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 公众号消息") +@Tag(name = "管理后台 - 公众号消息") @RestController @RequestMapping("/mp/message") @Validated @@ -29,7 +29,7 @@ public class MpMessageController { private MpMessageService mpMessageService; @GetMapping("/page") - @ApiOperation("获得公众号消息分页") + @Operation(summary = "获得公众号消息分页") @PreAuthorize("@ss.hasPermission('mp:message:query')") public CommonResult> getMessagePage(@Valid MpMessagePageReqVO pageVO) { PageResult pageResult = mpMessageService.getMessagePage(pageVO); @@ -37,7 +37,7 @@ public class MpMessageController { } @PostMapping("/send") - @ApiOperation("给粉丝发送消息") + @Operation(summary = "给粉丝发送消息") @PreAuthorize("@ss.hasPermission('mp:message:send')") public CommonResult sendMessage(@Valid @RequestBody MpMessageSendReqVO reqVO) { MpMessageDO message = mpMessageService.sendKefuMessage(reqVO); diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyBaseVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyBaseVO.java index fa9ae31c7..4b84254fe 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyBaseVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyBaseVO.java @@ -4,7 +4,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpMessageDO; import cn.iocoder.yudao.module.mp.enums.message.MpAutoReplyTypeEnum; import cn.iocoder.yudao.module.mp.framework.mp.core.util.MpUtils.*; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import me.chanjar.weixin.common.api.WxConsts; import org.hibernate.validator.constraints.URL; @@ -22,51 +22,50 @@ import java.util.List; @Data public class MpAutoReplyBaseVO { - @ApiModelProperty(value = "回复类型", example = "1", notes = "参见 MpAutoReplyTypeEnum 枚举") + @Schema(description = "回复类型 参见 MpAutoReplyTypeEnum 枚举", example = "1") @NotNull(message = "回复类型不能为空") private Integer type; // ==================== 请求消息 ==================== - @ApiModelProperty(value = "请求的关键字", example = "关键字", notes = "当 type 为 MpAutoReplyTypeEnum#KEYWORD 时,必填") + @Schema(description = "请求的关键字 当 type 为 MpAutoReplyTypeEnum#KEYWORD 时,必填", example = "关键字") private String requestKeyword; - @ApiModelProperty(value = "请求的匹配方式", example = "1", notes = "当 type 为 MpAutoReplyTypeEnum#KEYWORD 时,必填") + @Schema(description = "请求的匹配方式 当 type 为 MpAutoReplyTypeEnum#KEYWORD 时,必填", example = "1") private Integer requestMatch; - @ApiModelProperty(value = "请求的消息类型", example = "text", notes = "当 type 为 MpAutoReplyTypeEnum#MESSAGE 时,必填") + @Schema(description = "请求的消息类型 当 type 为 MpAutoReplyTypeEnum#MESSAGE 时,必填", example = "text") private String requestMessageType; // ==================== 响应消息 ==================== - @ApiModelProperty(value = "回复的消息类型", example = "text", - notes = "枚举 TEXT、IMAGE、VOICE、VIDEO、NEWS、MUSIC") + @Schema(description = "回复的消息类型 枚举 TEXT、IMAGE、VOICE、VIDEO、NEWS、MUSIC", example = "text") @NotEmpty(message = "回复的消息类型不能为空") private String responseMessageType; - @ApiModelProperty(value = "回复的消息内容", example = "欢迎关注") + @Schema(description = "回复的消息内容", example = "欢迎关注") @NotEmpty(message = "回复的消息内容不能为空", groups = TextMessageGroup.class) private String responseContent; - @ApiModelProperty(value = "回复的媒体 id", example = "123456") + @Schema(description = "回复的媒体 id", example = "123456") @NotEmpty(message = "回复的消息 mediaId 不能为空", groups = {ImageMessageGroup.class, VoiceMessageGroup.class, VideoMessageGroup.class}) private String responseMediaId; - @ApiModelProperty(value = "回复的媒体 URL", example = "https://www.iocoder.cn/xxx.jpg") + @Schema(description = "回复的媒体 URL", example = "https://www.iocoder.cn/xxx.jpg") @NotEmpty(message = "回复的消息 mediaId 不能为空", groups = {ImageMessageGroup.class, VoiceMessageGroup.class, VideoMessageGroup.class}) private String responseMediaUrl; - @ApiModelProperty(value = "缩略图的媒体 id", example = "123456") + @Schema(description = "缩略图的媒体 id", example = "123456") @NotEmpty(message = "回复的消息 thumbMediaId 不能为空", groups = {MusicMessageGroup.class}) private String responseThumbMediaId; - @ApiModelProperty(value = "缩略图的媒体 URL",example = "https://www.iocoder.cn/xxx.jpg") + @Schema(description = "缩略图的媒体 URL",example = "https://www.iocoder.cn/xxx.jpg") @NotEmpty(message = "回复的消息 thumbMedia 地址不能为空", groups = {MusicMessageGroup.class}) private String responseThumbMediaUrl; - @ApiModelProperty(value = "回复的标题", example = "视频标题") + @Schema(description = "回复的标题", example = "视频标题") @NotEmpty(message = "回复的消息标题不能为空", groups = VideoMessageGroup.class) private String responseTitle; - @ApiModelProperty(value = "回复的描述", example = "视频描述") + @Schema(description = "回复的描述", example = "视频描述") @NotEmpty(message = "消息描述不能为空", groups = VideoMessageGroup.class) private String responseDescription; @@ -79,11 +78,11 @@ public class MpAutoReplyBaseVO { @Valid private List responseArticles; - @ApiModelProperty(value = "回复的音乐链接", example = "https://www.iocoder.cn/xxx.mp3") + @Schema(description = "回复的音乐链接", example = "https://www.iocoder.cn/xxx.mp3") @NotEmpty(message = "回复的音乐链接不能为空", groups = MusicMessageGroup.class) @URL(message = "回复的高质量音乐链接格式不正确", groups = MusicMessageGroup.class) private String responseMusicUrl; - @ApiModelProperty(value = "高质量音乐链接", example = "https://www.iocoder.cn/xxx.mp3") + @Schema(description = "高质量音乐链接", example = "https://www.iocoder.cn/xxx.mp3") @NotEmpty(message = "回复的高质量音乐链接不能为空", groups = MusicMessageGroup.class) @URL(message = "回复的高质量音乐链接格式不正确", groups = MusicMessageGroup.class) private String responseHqMusicUrl; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyCreateReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyCreateReqVO.java index a0020f429..1e2694886 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyCreateReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyCreateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.mp.controller.admin.message.vo.autoreply; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号自动回复的创建 Request VO") +@Schema(description = "管理后台 - 公众号自动回复的创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpAutoReplyCreateReqVO extends MpAutoReplyBaseVO { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1024") + @Schema(description = "公众号账号的编号", required = true, example = "1024") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyPageReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyPageReqVO.java index 20e6af0b3..ee3794f56 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyPageReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyPageReqVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.mp.controller.admin.message.vo.autoreply; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号自动回复的分页 Request VO") +@Schema(description = "管理后台 - 公众号自动回复的分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpAutoReplyPageReqVO extends PageParam { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1") + @Schema(description = "公众号账号的编号", required = true, example = "1") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyRespVO.java index cdef6a31b..9bd1aaaa7 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyRespVO.java @@ -1,28 +1,27 @@ package cn.iocoder.yudao.module.mp.controller.admin.message.vo.autoreply; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.util.Date; -@ApiModel("管理后台 - 公众号自动回复 Response VO") +@Schema(description = "管理后台 - 公众号自动回复 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpAutoReplyRespVO extends MpAutoReplyBaseVO { - @ApiModelProperty(value = "主键", required = true, example = "1024") + @Schema(description = "主键", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1024") + @Schema(description = "公众号账号的编号", required = true, example = "1024") private Long accountId; - @ApiModelProperty(value = "公众号 appId", required = true, example = "wx1234567890") + @Schema(description = "公众号 appId", required = true, example = "wx1234567890") private String appId; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private Date createTime; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyUpdateReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyUpdateReqVO.java index f95ff0ce8..5478c687b 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyUpdateReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.mp.controller.admin.message.vo.autoreply; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号自动回复的更新 Request VO") +@Schema(description = "管理后台 - 公众号自动回复的更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpAutoReplyUpdateReqVO extends MpAutoReplyBaseVO { - @ApiModelProperty(value = "主键", required = true, example = "1024") + @Schema(description = "主键", required = true, example = "1024") @NotNull(message = "主键不能为空") private Long id; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessagePageReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessagePageReqVO.java index 4cf6190c4..b4ead5705 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessagePageReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessagePageReqVO.java @@ -1,9 +1,10 @@ package cn.iocoder.yudao.module.mp.controller.admin.message.vo.message; -import lombok.*; - -import io.swagger.annotations.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.springframework.format.annotation.DateTimeFormat; import javax.validation.constraints.NotNull; @@ -11,24 +12,24 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 公众号消息分页 Request VO") +@Schema(description = "管理后台 - 公众号消息分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpMessagePageReqVO extends PageParam { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1024") + @Schema(description = "公众号账号的编号", required = true, example = "1024") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; - @ApiModelProperty(value = "消息类型", example = "text", notes = "参见 WxConsts.XmlMsgType 枚举") + @Schema(description = "消息类型 参见 WxConsts.XmlMsgType 枚举", example = "text") private String type; - @ApiModelProperty(value = "公众号粉丝标识", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") + @Schema(description = "公众号粉丝标识", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") private String openid; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") + @Schema(description = "创建时间") private LocalDateTime[] createTime; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageRespVO.java index 195e56fbd..3e2bfef60 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageRespVO.java @@ -2,80 +2,77 @@ package cn.iocoder.yudao.module.mp.controller.admin.message.vo.message; import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpMessageDO; import com.baomidou.mybatisplus.annotation.TableField; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import me.chanjar.weixin.common.api.WxConsts; import java.util.Date; import java.util.List; -@ApiModel("管理后台 - 公众号消息 Response VO") +@Schema(description = "管理后台 - 公众号消息 Response VO") @Data public class MpMessageRespVO { - @ApiModelProperty(value = "主键", required = true, example = "1024") + @Schema(description = "主键", required = true, example = "1024") private Integer id; - @ApiModelProperty(value = "微信公众号消息 id", required = true, example = "23953173569869169") + @Schema(description = "微信公众号消息 id", required = true, example = "23953173569869169") private Long msgId; - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1") + @Schema(description = "公众号账号的编号", required = true, example = "1") private Long accountId; - @ApiModelProperty(value = "公众号账号的 appid", required = true, example = "wx1234567890") + @Schema(description = "公众号账号的 appid", required = true, example = "wx1234567890") private String appId; - @ApiModelProperty(value = "公众号粉丝编号", required = true, example = "2048") + @Schema(description = "公众号粉丝编号", required = true, example = "2048") private Long userId; - @ApiModelProperty(value = "公众号粉丝标志", required = true, example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") + @Schema(description = "公众号粉丝标志", required = true, example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") private String openid; - @ApiModelProperty(value = "消息类型", required = true, example = "text", notes = "参见 WxConsts.XmlMsgType 枚举") + @Schema(description = "消息类型 参见 WxConsts.XmlMsgType 枚举", required = true, example = "text") private String type; - @ApiModelProperty(value = "消息来源", required = true, example = "1", notes = "参见 MpMessageSendFromEnum 枚举") + @Schema(description = "消息来源 参见 MpMessageSendFromEnum 枚举", required = true, example = "1") private Integer sendFrom; // ========= 普通消息内容 https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html - @ApiModelProperty(value = "消息内容", example = "你好呀", notes = "消息类型为 text 时,才有值") + @Schema(description = "消息内容 消息类型为 text 时,才有值", example = "你好呀") private String content; - @ApiModelProperty(value = "媒体素材的编号", example = "1234567890", notes = "消息类型为 image、voice、video 时,才有值") + @Schema(description = "媒体素材的编号 消息类型为 image、voice、video 时,才有值", example = "1234567890") private String mediaId; - @ApiModelProperty(value = "媒体文件的 URL", example = "https://www.iocoder.cn/xxx.png", - notes = "消息类型为 image、voice、video 时,才有值") + @Schema(description = "媒体文件的 URL 消息类型为 image、voice、video 时,才有值", example = "https://www.iocoder.cn/xxx.png") private String mediaUrl; - @ApiModelProperty(value = "语音识别后文本", example = "语音识别后文本", notes = "消息类型为 voice 时,才有值") + @Schema(description = "语音识别后文本 消息类型为 voice 时,才有值", example = "语音识别后文本") private String recognition; - @ApiModelProperty(value = "语音格式", example = "amr", notes = "消息类型为 voice 时,才有值") + @Schema(description = "语音格式 消息类型为 voice 时,才有值", example = "amr") private String format; - @ApiModelProperty(value = "标题", example = "我是标题", notes = "消息类型为 video、music、link 时,才有值") + @Schema(description = "标题 消息类型为 video、music、link 时,才有值", example = "我是标题") private String title; - @ApiModelProperty(value = "描述", example = "我是描述", notes = "消息类型为 video、music 时,才有值") + @Schema(description = "描述 消息类型为 video、music 时,才有值", example = "我是描述") private String description; - @ApiModelProperty(value = "缩略图的媒体 id", example = "1234567890", notes = "消息类型为 video、music 时,才有值") + @Schema(description = "缩略图的媒体 id 消息类型为 video、music 时,才有值", example = "1234567890") private String thumbMediaId; - @ApiModelProperty(value = "缩略图的媒体 URL", example = "https://www.iocoder.cn/xxx.png", - notes = "消息类型为 video、music 时,才有值") + @Schema(description = "缩略图的媒体 URL 消息类型为 video、music 时,才有值", example = "https://www.iocoder.cn/xxx.png") private String thumbMediaUrl; - @ApiModelProperty(value = "点击图文消息跳转链接", example = "https://www.iocoder.cn", notes = "消息类型为 link 时,才有值") + @Schema(description = "点击图文消息跳转链接 消息类型为 link 时,才有值", example = "https://www.iocoder.cn") private String url; - @ApiModelProperty(value = "地理位置维度", example = "23.137466", notes = "消息类型为 location 时,才有值") + @Schema(description = "地理位置维度 消息类型为 location 时,才有值", example = "23.137466") private Double locationX; - @ApiModelProperty(value = "地理位置经度", example = "113.352425", notes = "消息类型为 location 时,才有值") + @Schema(description = "地理位置经度 消息类型为 location 时,才有值", example = "113.352425") private Double locationY; - @ApiModelProperty(value = "地图缩放大小", example = "13", notes = "消息类型为 location 时,才有值") + @Schema(description = "地图缩放大小 消息类型为 location 时,才有值", example = "13") private Double scale; - @ApiModelProperty(value = "详细地址", example = "杨浦区黄兴路 221-4 号临", notes = "消息类型为 location 时,才有值") + @Schema(description = "详细地址 消息类型为 location 时,才有值", example = "杨浦区黄兴路 221-4 号临") private String label; /** @@ -86,19 +83,19 @@ public class MpMessageRespVO { @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class) private List articles; - @ApiModelProperty(value = "音乐链接", example = "https://www.iocoder.cn/xxx.mp3", notes = "消息类型为 music 时,才有值") + @Schema(description = "音乐链接 消息类型为 music 时,才有值", example = "https://www.iocoder.cn/xxx.mp3") private String musicUrl; - @ApiModelProperty(value = "高质量音乐链接", example = "https://www.iocoder.cn/xxx.mp3", notes = "消息类型为 music 时,才有值") + @Schema(description = "高质量音乐链接 消息类型为 music 时,才有值", example = "https://www.iocoder.cn/xxx.mp3") private String hqMusicUrl; // ========= 事件推送 https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html - @ApiModelProperty(value = "事件类型", example = "subscribe", notes = "参见 WxConsts.EventType 枚举") + @Schema(description = "事件类型 参见 WxConsts.EventType 枚举", example = "subscribe") private String event; - @ApiModelProperty(value = "事件 Key", example = "qrscene_123456", notes = "参见 WxConsts.EventType 枚举") + @Schema(description = "事件 Key 参见 WxConsts.EventType 枚举", example = "qrscene_123456") private String eventKey; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private Date createTime; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageSendReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageSendReqVO.java index 8b6492484..465cbff60 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageSendReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageSendReqVO.java @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.mp.controller.admin.message.vo.message; import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpMessageDO; import cn.iocoder.yudao.module.mp.framework.mp.core.util.MpUtils.*; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.Valid; @@ -11,49 +10,49 @@ import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel("管理后台 - 公众号消息发送 Request VO") +@Schema(description = "管理后台 - 公众号消息发送 Request VO") @Data public class MpMessageSendReqVO { - @ApiModelProperty(value = "公众号粉丝的编号", required = true, example = "1024") + @Schema(description = "公众号粉丝的编号", required = true, example = "1024") @NotNull(message = "公众号粉丝的编号不能为空") private Long userId; // ========== 消息内容 ========== - @ApiModelProperty(value = "消息类型", required = true, example = "text", notes = "TEXT/IMAGE/VOICE/VIDEO/NEWS") + @Schema(description = "消息类型 TEXT/IMAGE/VOICE/VIDEO/NEWS", required = true, example = "text") @NotEmpty(message = "消息类型不能为空") public String type; - @ApiModelProperty(value = "消息内容", required = true, example = "你好呀") + @Schema(description = "消息内容", required = true, example = "你好呀") @NotEmpty(message = "消息内容不能为空", groups = TextMessageGroup.class) private String content; - @ApiModelProperty(value = "媒体 ID", required = true, example = "qqc_2Fot30Jse-HDoZmo5RrUDijz2nGUkP") + @Schema(description = "媒体 ID", required = true, example = "qqc_2Fot30Jse-HDoZmo5RrUDijz2nGUkP") @NotEmpty(message = "消息内容不能为空", groups = {ImageMessageGroup.class, VoiceMessageGroup.class, VideoMessageGroup.class}) private String mediaId; - @ApiModelProperty(value = "标题", required = true, example = "没有标题") + @Schema(description = "标题", required = true, example = "没有标题") @NotEmpty(message = "消息内容不能为空", groups = VideoMessageGroup.class) private String title; - @ApiModelProperty(value = "描述", required = true, example = "你猜") + @Schema(description = "描述", required = true, example = "你猜") @NotEmpty(message = "消息描述不能为空", groups = VideoMessageGroup.class) private String description; - @ApiModelProperty(value = "缩略图的媒体 id", required = true, example = "qqc_2Fot30Jse-HDoZmo5RrUDijz2nGUkP") + @Schema(description = "缩略图的媒体 id", required = true, example = "qqc_2Fot30Jse-HDoZmo5RrUDijz2nGUkP") @NotEmpty(message = "缩略图的媒体 id 不能为空", groups = MusicMessageGroup.class) private String thumbMediaId; - @ApiModelProperty(value = "图文消息", required = true) + @Schema(description = "图文消息", required = true) @Valid @NotNull(message = "图文消息不能为空", groups = NewsMessageGroup.class) private List articles; - @ApiModelProperty(value = "音乐链接", example = "https://www.iocoder.cn/music.mp3", notes = "消息类型为 MUSIC 时") + @Schema(description = "音乐链接 消息类型为 MUSIC 时", example = "https://www.iocoder.cn/music.mp3") private String musicUrl; - @ApiModelProperty(value = "高质量音乐链接", example = "https://www.iocoder.cn/music.mp3", notes = "消息类型为 MUSIC 时") + @Schema(description = "高质量音乐链接 消息类型为 MUSIC 时", example = "https://www.iocoder.cn/music.mp3") private String hqMusicUrl; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpDraftController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpDraftController.java index 148b5a5fe..c43d6c5d7 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpDraftController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpDraftController.java @@ -9,10 +9,10 @@ import cn.iocoder.yudao.module.mp.controller.admin.news.vo.MpDraftPageReqVO; import cn.iocoder.yudao.module.mp.dal.dataobject.material.MpMaterialDO; import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory; import cn.iocoder.yudao.module.mp.service.material.MpMaterialService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.draft.*; @@ -31,7 +31,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.*; -@Api(tags = "管理后台 - 公众号草稿") +@Tag(name = "管理后台 - 公众号草稿") @RestController @RequestMapping("/mp/draft") @Validated @@ -44,7 +44,7 @@ public class MpDraftController { private MpMaterialService mpMaterialService; @GetMapping("/page") - @ApiOperation("获得草稿分页") + @Operation(summary = "获得草稿分页") @PreAuthorize("@ss.hasPermission('mp:draft:query')") public CommonResult> getDraftPage(MpDraftPageReqVO reqVO) { // 从公众号查询草稿箱 @@ -79,9 +79,8 @@ public class MpDraftController { } @PostMapping("/create") - @ApiOperation("创建草稿") - @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, - example = "1024", dataTypeClass = Long.class) + @Operation(summary = "创建草稿") + @Parameter(name = "accountId", description = "公众号账号的编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('mp:draft:create')") public CommonResult deleteDraft(@RequestParam("accountId") Long accountId, @RequestBody WxMpAddDraft draft) { @@ -95,12 +94,10 @@ public class MpDraftController { } @PutMapping("/update") - @ApiOperation("更新草稿") - @ApiImplicitParams({ - @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, - example = "1024", dataTypeClass = Long.class), - @ApiImplicitParam(name = "mediaId", value = "草稿素材的编号", required = true, - example = "xxx", dataTypeClass = String.class), + @Operation(summary = "更新草稿") + @Parameters({ + @Parameter(name = "accountId", description = "公众号账号的编号", required = true, example = "1024"), + @Parameter(name = "mediaId", description = "草稿素材的编号", required = true, example = "xxx") }) @PreAuthorize("@ss.hasPermission('mp:draft:update')") public CommonResult deleteDraft(@RequestParam("accountId") Long accountId, @@ -119,12 +116,10 @@ public class MpDraftController { } @DeleteMapping("/delete") - @ApiOperation("删除草稿") - @ApiImplicitParams({ - @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, - example = "1024", dataTypeClass = Long.class), - @ApiImplicitParam(name = "mediaId", value = "草稿素材的编号", required = true, - example = "xxx", dataTypeClass = String.class), + @Operation(summary = "删除草稿") + @Parameters({ + @Parameter(name = "accountId", description = "公众号账号的编号", required = true, example = "1024"), + @Parameter(name = "mediaId", description = "草稿素材的编号", required = true, example = "xxx") }) @PreAuthorize("@ss.hasPermission('mp:draft:delete')") public CommonResult deleteDraft(@RequestParam("accountId") Long accountId, diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpFreePublishController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpFreePublishController.java index 6938e3274..e36d7343c 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpFreePublishController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/MpFreePublishController.java @@ -9,10 +9,10 @@ import cn.iocoder.yudao.module.mp.controller.admin.news.vo.MpFreePublishPageReqV import cn.iocoder.yudao.module.mp.dal.dataobject.material.MpMaterialDO; import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory; import cn.iocoder.yudao.module.mp.service.material.MpMaterialService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.freepublish.WxMpFreePublishItem; @@ -32,7 +32,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.*; -@Api(tags = "管理后台 - 公众号发布能力") +@Tag(name = "管理后台 - 公众号发布能力") @RestController @RequestMapping("/mp/free-publish") @Validated @@ -45,7 +45,7 @@ public class MpFreePublishController { private MpMaterialService mpMaterialService; @GetMapping("/page") - @ApiOperation("获得已发布的图文分页") + @Operation(summary = "获得已发布的图文分页") @PreAuthorize("@ss.hasPermission('mp:free-publish:query')") public CommonResult> getFreePublishPage(MpFreePublishPageReqVO reqVO) { // 从公众号查询已发布的图文列表 @@ -81,12 +81,10 @@ public class MpFreePublishController { } @PostMapping("/submit") - @ApiOperation("发布草稿") - @ApiImplicitParams({ - @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, - example = "1024", dataTypeClass = Long.class), - @ApiImplicitParam(name = "mediaId", value = "要发布的草稿的 media_id", required = true, - example = "2048", dataTypeClass = String.class) + @Operation(summary = "发布草稿") + @Parameters({ + @Parameter(name = "accountId", description = "公众号账号的编号", required = true, example = "1024"), + @Parameter(name = "mediaId", description = "要发布的草稿的 media_id", required = true, example = "2048") }) @PreAuthorize("@ss.hasPermission('mp:free-publish:submit')") public CommonResult submitFreePublish(@RequestParam("accountId") Long accountId, @@ -101,12 +99,10 @@ public class MpFreePublishController { } @DeleteMapping("/delete") - @ApiOperation("删除草稿") - @ApiImplicitParams({ - @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, - example = "1024", dataTypeClass = Long.class), - @ApiImplicitParam(name = "articleId", value = "发布记录的编号", required = true, - example = "2048", dataTypeClass = String.class) + @Operation(summary = "删除草稿") + @Parameters({ + @Parameter(name = "accountId", description = "公众号账号的编号", required = true, example = "1024"), + @Parameter(name = "articleId", description = "发布记录的编号", required = true, example = "2048") }) @PreAuthorize("@ss.hasPermission('mp:free-publish:delete')") public CommonResult deleteFreePublish(@RequestParam("accountId") Long accountId, diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/vo/MpDraftPageReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/vo/MpDraftPageReqVO.java index c6a5afbca..5c285f627 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/vo/MpDraftPageReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/vo/MpDraftPageReqVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.mp.controller.admin.news.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号草稿的分页 Request VO") +@Schema(description = "管理后台 - 公众号草稿的分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpDraftPageReqVO extends PageParam { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1024") + @Schema(description = "公众号账号的编号", required = true, example = "1024") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/vo/MpFreePublishPageReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/vo/MpFreePublishPageReqVO.java index 140e029ee..51f2c6c74 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/vo/MpFreePublishPageReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/news/vo/MpFreePublishPageReqVO.java @@ -1,21 +1,20 @@ package cn.iocoder.yudao.module.mp.controller.admin.news.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号已发布列表的分页 Request VO") +@Schema(description = "管理后台 - 公众号已发布列表的分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpFreePublishPageReqVO extends PageParam { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1024") + @Schema(description = "公众号账号的编号", required = true, example = "1024") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/MpOpenController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/MpOpenController.java index 10954d80b..067102e11 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/MpOpenController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/MpOpenController.java @@ -10,8 +10,8 @@ import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory; import cn.iocoder.yudao.module.mp.framework.mp.core.context.MpContextHolder; import cn.iocoder.yudao.module.mp.service.account.MpAccountService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.mp.api.WxMpMessageRouter; import me.chanjar.weixin.mp.api.WxMpService; @@ -23,7 +23,7 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.Objects; -@Api(tags = "管理后台 - 公众号回调") +@Tag(name = "管理后台 - 公众号回调") @RestController @RequestMapping("/mp/open") @Validated @@ -41,7 +41,7 @@ public class MpOpenController { * * 对应 文档 */ - @ApiOperation("校验签名") // 参见 + @Operation(summary = "校验签名") // 参见 @GetMapping(value = "/{appId}", produces = "text/plain;charset=utf-8") public String checkSignature(@PathVariable("appId") String appId, MpOpenCheckSignatureReqVO reqVO) { @@ -61,7 +61,7 @@ public class MpOpenController { * * 文档 */ - @ApiOperation("处理消息") + @Operation(summary = "处理消息") @PostMapping(value = "/{appId}", produces = "application/xml; charset=UTF-8") @OperateLog(enable = false) // 回调地址,无需记录操作日志 public String handleMessage(@PathVariable("appId") String appId, diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/vo/MpOpenCheckSignatureReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/vo/MpOpenCheckSignatureReqVO.java index 23c3ab01d..67dfa6232 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/vo/MpOpenCheckSignatureReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/vo/MpOpenCheckSignatureReqVO.java @@ -1,32 +1,27 @@ package cn.iocoder.yudao.module.mp.controller.admin.open.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.web.bind.annotation.RequestParam; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 公众号校验签名 Request VO") +@Schema(description = "管理后台 - 公众号校验签名 Request VO") @Data public class MpOpenCheckSignatureReqVO { - @ApiModelProperty(value = "微信加密签名", required = true, example = "490eb57f448b87bd5f20ccef58aa4de46aa1908e") + @Schema(description = "微信加密签名", required = true, example = "490eb57f448b87bd5f20ccef58aa4de46aa1908e") @NotEmpty(message = "微信加密签名不能为空") private String signature; - @ApiModelProperty(value = "时间戳", required = true, example = "1672587863") + @Schema(description = "时间戳", required = true, example = "1672587863") @NotEmpty(message = "时间戳不能为空") private String timestamp; - @ApiModelProperty(value = "随机数", required = true, example = "1827365808") + @Schema(description = "随机数", required = true, example = "1827365808") @NotEmpty(message = "随机数不能为空") private String nonce; - @ApiModelProperty(value = "随机字符串", required = true, example = "2721154047828672511") + @Schema(description = "随机字符串", required = true, example = "2721154047828672511") @NotEmpty(message = "随机字符串不能为空") @SuppressWarnings("SpellCheckingInspection") private String echostr; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/vo/MpOpenHandleMessageReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/vo/MpOpenHandleMessageReqVO.java index 36310481a..4f9e51699 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/vo/MpOpenHandleMessageReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/vo/MpOpenHandleMessageReqVO.java @@ -1,38 +1,37 @@ package cn.iocoder.yudao.module.mp.controller.admin.open.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 公众号处理消息 Request VO") +@Schema(description = "管理后台 - 公众号处理消息 Request VO") @Data public class MpOpenHandleMessageReqVO { public static final String ENCRYPT_TYPE_AES = "aes"; - @ApiModelProperty(value = "微信加密签名", required = true, example = "490eb57f448b87bd5f20ccef58aa4de46aa1908e") + @Schema(description = "微信加密签名", required = true, example = "490eb57f448b87bd5f20ccef58aa4de46aa1908e") @NotEmpty(message = "微信加密签名不能为空") private String signature; - @ApiModelProperty(value = "时间戳", required = true, example = "1672587863") + @Schema(description = "时间戳", required = true, example = "1672587863") @NotEmpty(message = "时间戳不能为空") private String timestamp; - @ApiModelProperty(value = "随机数", required = true, example = "1827365808") + @Schema(description = "随机数", required = true, example = "1827365808") @NotEmpty(message = "随机数不能为空") private String nonce; - @ApiModelProperty(value = "粉丝 openid", required = true, example = "oz-Jdtyn-WGm4C4I5Z-nvBMO_ZfY") + @Schema(description = "粉丝 openid", required = true, example = "oz-Jdtyn-WGm4C4I5Z-nvBMO_ZfY") @NotEmpty(message = "粉丝 openid 不能为空") private String openid; - @ApiModelProperty(value = "消息加密类型", example = "aes") + @Schema(description = "消息加密类型", example = "aes") private String encrypt_type; - @ApiModelProperty(value = "微信签名", example = "QW5kcm9pZCBUaGUgQmFzZTY0IGlzIGEgZ2VuZXJhdGVkIHN0cmluZw==") + @Schema(description = "微信签名", example = "QW5kcm9pZCBUaGUgQmFzZTY0IGlzIGEgZ2VuZXJhdGVkIHN0cmluZw==") private String msg_signature; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/MpStatisticsController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/MpStatisticsController.java index 3a5380ec9..8a9df53c3 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/MpStatisticsController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/MpStatisticsController.java @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.mp.controller.admin.statistics.vo.*; import cn.iocoder.yudao.module.mp.convert.statistics.MpStatisticsConvert; import cn.iocoder.yudao.module.mp.service.statistics.MpStatisticsService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import me.chanjar.weixin.mp.bean.datacube.WxDataCubeInterfaceResult; import me.chanjar.weixin.mp.bean.datacube.WxDataCubeMsgResult; import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate; @@ -21,7 +21,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 公众号统计") +@Tag(name = "管理后台 - 公众号统计") @RestController @RequestMapping("/mp/statistics") @Validated @@ -31,7 +31,7 @@ public class MpStatisticsController { private MpStatisticsService mpStatisticsService; @GetMapping("/user-summary") - @ApiOperation("获得粉丝增减数据") + @Operation(summary = "获得粉丝增减数据") @PreAuthorize("@ss.hasPermission('mp:statistics:query')") public CommonResult> getUserSummary(MpStatisticsGetReqVO getReqVO) { List list = mpStatisticsService.getUserSummary( @@ -40,7 +40,7 @@ public class MpStatisticsController { } @GetMapping("/user-cumulate") - @ApiOperation("获得粉丝累计数据") + @Operation(summary = "获得粉丝累计数据") @PreAuthorize("@ss.hasPermission('mp:statistics:query')") public CommonResult> getUserCumulate(MpStatisticsGetReqVO getReqVO) { List list = mpStatisticsService.getUserCumulate( @@ -49,7 +49,7 @@ public class MpStatisticsController { } @GetMapping("/upstream-message") - @ApiOperation("获取消息发送概况数据") + @Operation(summary = "获取消息发送概况数据") @PreAuthorize("@ss.hasPermission('mp:statistics:query')") public CommonResult> getUpstreamMessage(MpStatisticsGetReqVO getReqVO) { List list = mpStatisticsService.getUpstreamMessage( @@ -58,7 +58,7 @@ public class MpStatisticsController { } @GetMapping("/interface-summary") - @ApiOperation("获取消息发送概况数据") + @Operation(summary = "获取消息发送概况数据") @PreAuthorize("@ss.hasPermission('mp:statistics:query')") public CommonResult> getInterfaceSummary(MpStatisticsGetReqVO getReqVO) { List list = mpStatisticsService.getInterfaceSummary( diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsGetReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsGetReqVO.java index 63b514887..19b8537e6 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsGetReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsGetReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -10,15 +9,15 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 获得统计数据 Request VO") +@Schema(description = "管理后台 - 获得统计数据 Request VO") @Data public class MpStatisticsGetReqVO { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1024") + @Schema(description = "公众号账号的编号", required = true, example = "1024") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; - @ApiModelProperty(value = "查询时间范围") + @Schema(description = "查询时间范围") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @NotNull(message = "查询时间范围不能为空") private LocalDateTime[] date; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsInterfaceSummaryRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsInterfaceSummaryRespVO.java index dfcf45fa3..78db7666c 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsInterfaceSummaryRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsInterfaceSummaryRespVO.java @@ -1,28 +1,27 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.Date; -@ApiModel("管理后台 - 某一天的接口分析数据 Response VO") +@Schema(description = "管理后台 - 某一天的接口分析数据 Response VO") @Data public class MpStatisticsInterfaceSummaryRespVO { - @ApiModelProperty(value = "日期", required = true) + @Schema(description = "日期", required = true) private Date refDate; - @ApiModelProperty(value = "通过服务器配置地址获得消息后,被动回复粉丝消息的次数", required = true, example = "10") + @Schema(description = "通过服务器配置地址获得消息后,被动回复粉丝消息的次数", required = true, example = "10") private Integer callbackCount; - @ApiModelProperty(value = "上述动作的失败次数", required = true, example = "20") + @Schema(description = "上述动作的失败次数", required = true, example = "20") private Integer failCount; - @ApiModelProperty(value = "总耗时,除以 callback_count 即为平均耗时", required = true, example = "30") + @Schema(description = "总耗时,除以 callback_count 即为平均耗时", required = true, example = "30") private Integer totalTimeCost; - @ApiModelProperty(value = "最大耗时", required = true, example = "40") + @Schema(description = "最大耗时", required = true, example = "40") private Integer maxTimeCost; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUpstreamMessageRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUpstreamMessageRespVO.java index 8a0386165..0f2a71916 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUpstreamMessageRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUpstreamMessageRespVO.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.Date; -@ApiModel("管理后台 - 某一天的粉丝增减数据 Response VO") +@Schema(description = "管理后台 - 某一天的粉丝增减数据 Response VO") @Data public class MpStatisticsUpstreamMessageRespVO { - @ApiModelProperty(value = "日期", required = true) + @Schema(description = "日期", required = true) private Date refDate; - @ApiModelProperty(value = "上行发送了(向公众号发送了)消息的粉丝数", required = true, example = "10") + @Schema(description = "上行发送了(向公众号发送了)消息的粉丝数", required = true, example = "10") private Integer messageUser; - @ApiModelProperty(value = "上行发送了消息的消息总数", required = true, example = "20") + @Schema(description = "上行发送了消息的消息总数", required = true, example = "20") private Integer messageCount; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserCumulateRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserCumulateRespVO.java index 0db34a790..630c193b5 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserCumulateRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserCumulateRespVO.java @@ -1,19 +1,18 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.Date; -@ApiModel("管理后台 - 某一天的消息发送概况数据 Response VO") +@Schema(description = "管理后台 - 某一天的消息发送概况数据 Response VO") @Data public class MpStatisticsUserCumulateRespVO { - @ApiModelProperty(value = "日期", required = true) + @Schema(description = "日期", required = true) private Date refDate; - @ApiModelProperty(value = "累计粉丝量", required = true, example = "10") + @Schema(description = "累计粉丝量", required = true, example = "10") private Integer cumulateUser; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserSummaryRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserSummaryRespVO.java index c65247cce..b99f554ab 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserSummaryRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserSummaryRespVO.java @@ -1,25 +1,24 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.Date; -@ApiModel("管理后台 - 某一天的粉丝增减数据 Response VO") +@Schema(description = "管理后台 - 某一天的粉丝增减数据 Response VO") @Data public class MpStatisticsUserSummaryRespVO { - @ApiModelProperty(value = "日期", required = true) + @Schema(description = "日期", required = true) private Date refDate; - @ApiModelProperty(value = "粉丝来源", required = true, example = "0") + @Schema(description = "粉丝来源", required = true, example = "0") private Integer userSource; - @ApiModelProperty(value = "新关注的粉丝数量", required = true, example = "10") + @Schema(description = "新关注的粉丝数量", required = true, example = "10") private Integer newUser; - @ApiModelProperty(value = "取消关注的粉丝数量", required = true, example = "20") + @Schema(description = "取消关注的粉丝数量", required = true, example = "20") private Integer cancelUser; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/MpTagController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/MpTagController.java index 1ae7751fe..d7237d282 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/MpTagController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/MpTagController.java @@ -6,9 +6,9 @@ import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.*; import cn.iocoder.yudao.module.mp.convert.tag.MpTagConvert; import cn.iocoder.yudao.module.mp.dal.dataobject.tag.MpTagDO; import cn.iocoder.yudao.module.mp.service.tag.MpTagService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 公众号标签") +@Tag(name = "管理后台 - 公众号标签") @RestController @RequestMapping("/mp/tag") @Validated @@ -29,14 +29,14 @@ public class MpTagController { private MpTagService mpTagService; @PostMapping("/create") - @ApiOperation("创建公众号标签") + @Operation(summary = "创建公众号标签") @PreAuthorize("@ss.hasPermission('mp:tag:create')") public CommonResult createTag(@Valid @RequestBody MpTagCreateReqVO createReqVO) { return success(mpTagService.createTag(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新公众号标签") + @Operation(summary = "更新公众号标签") @PreAuthorize("@ss.hasPermission('mp:tag:update')") public CommonResult updateTag(@Valid @RequestBody MpTagUpdateReqVO updateReqVO) { mpTagService.updateTag(updateReqVO); @@ -44,8 +44,8 @@ public class MpTagController { } @DeleteMapping("/delete") - @ApiOperation("删除公众号标签") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除公众号标签") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('mp:tag:delete')") public CommonResult deleteTag(@RequestParam("id") Long id) { mpTagService.deleteTag(id); @@ -53,7 +53,7 @@ public class MpTagController { } @GetMapping("/page") - @ApiOperation("获取公众号标签分页") + @Operation(summary = "获取公众号标签分页") @PreAuthorize("@ss.hasPermission('mp:tag:query')") public CommonResult> getTagPage(MpTagPageReqVO pageReqVO) { PageResult pageResult = mpTagService.getTagPage(pageReqVO); @@ -61,7 +61,7 @@ public class MpTagController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获取公众号账号精简信息列表") + @Operation(summary = "获取公众号账号精简信息列表") @PreAuthorize("@ss.hasPermission('mp:account:query')") public CommonResult> getSimpleTags() { List list = mpTagService.getTagList(); @@ -69,8 +69,8 @@ public class MpTagController { } @PostMapping("/sync") - @ApiOperation("同步公众号标签") - @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "同步公众号标签") + @Parameter(name = "accountId", description = "公众号账号的编号", required = true) @PreAuthorize("@ss.hasPermission('mp:tag:sync')") public CommonResult syncTag(@RequestParam("accountId") Long accountId) { mpTagService.syncTag(accountId); diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagBaseVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagBaseVO.java index 832faf535..f9cc47c35 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagBaseVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.mp.controller.admin.tag.vo; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -14,7 +14,7 @@ import javax.validation.constraints.NotEmpty; @Data public class MpTagBaseVO { - @ApiModelProperty(value = "标签名", required = true, example = "土豆") + @Schema(description = "标签名", required = true, example = "土豆") @NotEmpty(message = "标签名不能为空") private String name; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagCreateReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagCreateReqVO.java index 24eb0167b..25fc2093e 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagCreateReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagCreateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.mp.controller.admin.tag.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号标签创建 Request VO") +@Schema(description = "管理后台 - 公众号标签创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpTagCreateReqVO extends MpTagBaseVO { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") + @Schema(description = "公众号账号的编号", required = true, example = "2048") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagPageReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagPageReqVO.java index b48481fc2..b2e3a8643 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagPageReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagPageReqVO.java @@ -1,25 +1,24 @@ package cn.iocoder.yudao.module.mp.controller.admin.tag.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotEmpty; -@ApiModel("管理后台 - 公众号标签分页 Request VO") +@Schema(description = "管理后台 - 公众号标签分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpTagPageReqVO extends PageParam { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") + @Schema(description = "公众号账号的编号", required = true, example = "2048") @NotEmpty(message = "公众号账号的编号不能为空") private Long accountId; - @ApiModelProperty(value = "标签名", example = "哈哈", notes = "模糊匹配") + @Schema(description = "标签名 模糊匹配", example = "哈哈") private String name; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagRespVO.java index cae0dab16..3a9a1cd9e 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagRespVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.mp.controller.admin.tag.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import java.util.Date; -@ApiModel("管理后台 - 公众号标签 Response VO") +@Schema(description = "管理后台 - 公众号标签 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpTagRespVO extends MpTagBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "此标签下粉丝数量", required = true, example = "0") + @Schema(description = "此标签下粉丝数量", required = true, example = "0") private Integer count; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private Date createTime; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagSimpleRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagSimpleRespVO.java index 75f68a6c9..9918ef563 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagSimpleRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagSimpleRespVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.mp.controller.admin.tag.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("管理后台 - 公众号标签精简信息 Response VO") +@Schema(description = "管理后台 - 公众号标签精简信息 Response VO") @Data public class MpTagSimpleRespVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "公众号的标签编号", required = true, example = "2048") + @Schema(description = "公众号的标签编号", required = true, example = "2048") private Long tagId; - @ApiModelProperty(value = "标签名称", required = true, example = "快乐") + @Schema(description = "标签名称", required = true, example = "快乐") private String name; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagUpdateReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagUpdateReqVO.java index 873871fd4..c8032ca96 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagUpdateReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagUpdateReqVO.java @@ -1,17 +1,19 @@ package cn.iocoder.yudao.module.mp.controller.admin.tag.vo; -import lombok.*; -import io.swagger.annotations.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; -import javax.validation.constraints.*; +import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号标签更新 Request VO") +@Schema(description = "管理后台 - 公众号标签更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpTagUpdateReqVO extends MpTagBaseVO { - @ApiModelProperty(value = "编号", required = true) + @Schema(description = "编号", required = true) @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/MpUserController.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/MpUserController.java index d446c1cfe..7098bc57e 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/MpUserController.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/MpUserController.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserUpdateReqVO; import cn.iocoder.yudao.module.mp.convert.user.MpUserConvert; import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO; import cn.iocoder.yudao.module.mp.service.user.MpUserService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -20,7 +20,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 公众号粉丝") +@Tag(name = "管理后台 - 公众号粉丝") @RestController @RequestMapping("/mp/user") @Validated @@ -30,7 +30,7 @@ public class MpUserController { private MpUserService mpUserService; @GetMapping("/page") - @ApiOperation("获得公众号粉丝分页") + @Operation(summary = "获得公众号粉丝分页") @PreAuthorize("@ss.hasPermission('mp:user:query')") public CommonResult> getUserPage(@Valid MpUserPageReqVO pageVO) { PageResult pageResult = mpUserService.getUserPage(pageVO); @@ -38,15 +38,15 @@ public class MpUserController { } @GetMapping("/get") - @ApiOperation("获得公众号粉丝") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得公众号粉丝") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('mp:user:query')") public CommonResult getUser(@RequestParam("id") Long id) { return success(MpUserConvert.INSTANCE.convert(mpUserService.getUser(id))); } @PutMapping("/update") - @ApiOperation("更新公众号粉丝") + @Operation(summary = "更新公众号粉丝") @PreAuthorize("@ss.hasPermission('mp:user:update')") public CommonResult updateUser(@Valid @RequestBody MpUserUpdateReqVO updateReqVO) { mpUserService.updateUser(updateReqVO); @@ -54,8 +54,8 @@ public class MpUserController { } @PostMapping("/sync") - @ApiOperation("同步公众号粉丝") - @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "同步公众号粉丝") + @Parameter(name = "accountId", description = "公众号账号的编号", required = true) @PreAuthorize("@ss.hasPermission('mp:user:sync')") public CommonResult syncUser(@RequestParam("accountId") Long accountId) { mpUserService.syncUser(accountId); diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserPageReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserPageReqVO.java index 96b8d7412..c6ef1fad3 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserPageReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserPageReqVO.java @@ -1,28 +1,27 @@ package cn.iocoder.yudao.module.mp.controller.admin.user.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 公众号粉丝分页 Request VO") +@Schema(description = "管理后台 - 公众号粉丝分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MpUserPageReqVO extends PageParam { - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048") + @Schema(description = "公众号账号的编号", required = true, example = "2048") @NotNull(message = "公众号账号的编号不能为空") private Long accountId; - @ApiModelProperty(value = "公众号粉丝标识", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", notes = "模糊匹配") + @Schema(description = "公众号粉丝标识 模糊匹配", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") private String openid; - @ApiModelProperty(value = "公众号粉丝昵称", example = "芋艿", notes = "模糊匹配") + @Schema(description = "公众号粉丝昵称 模糊匹配", example = "芋艿") private String nickname; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserRespVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserRespVO.java index 4fb73840c..af2b1de74 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserRespVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserRespVO.java @@ -1,54 +1,53 @@ package cn.iocoder.yudao.module.mp.controller.admin.user.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; import java.util.Date; import java.util.List; -@ApiModel("管理后台 - 公众号粉丝 Response VO") +@Schema(description = "管理后台 - 公众号粉丝 Response VO") @Data public class MpUserRespVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "公众号粉丝标识", required = true, example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") + @Schema(description = "公众号粉丝标识", required = true, example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M") private String openid; - @ApiModelProperty(value = "关注状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(description = "关注状态 参见 CommonStatusEnum 枚举", required = true, example = "1") private Integer subscribeStatus; - @ApiModelProperty(value = "关注时间", required = true) + @Schema(description = "关注时间", required = true) private LocalDateTime subscribeTime; - @ApiModelProperty(value = "取消关注时间") + @Schema(description = "取消关注时间") private LocalDateTime unsubscribeTime; - @ApiModelProperty(value = "昵称", example = "芋道") + @Schema(description = "昵称", example = "芋道") private String nickname; - @ApiModelProperty(value = "头像地址", example = "https://www.iocoder.cn/1.png") + @Schema(description = "头像地址", example = "https://www.iocoder.cn/1.png") private String headImageUrl; - @ApiModelProperty(value = "语言", example = "zh_CN") + @Schema(description = "语言", example = "zh_CN") private String language; - @ApiModelProperty(value = "国家", example = "中国") + @Schema(description = "国家", example = "中国") private String country; - @ApiModelProperty(value = "省份", example = "广东省") + @Schema(description = "省份", example = "广东省") private String province; - @ApiModelProperty(value = "城市", example = "广州市") + @Schema(description = "城市", example = "广州市") private String city; - @ApiModelProperty(value = "备注", example = "你是一个芋头嘛") + @Schema(description = "备注", example = "你是一个芋头嘛") private String remark; - @ApiModelProperty(value = "标签编号数组", example = "1,2,3") + @Schema(description = "标签编号数组", example = "1,2,3") private List tagIds; - @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1") + @Schema(description = "公众号账号的编号", required = true, example = "1") private Long accountId; - @ApiModelProperty(value = "公众号账号的 appId", required = true, example = "wx1234567890") + @Schema(description = "公众号账号的 appId", required = true, example = "wx1234567890") private String appId; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private Date createTime; } diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserUpdateReqVO.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserUpdateReqVO.java index e367a3ee0..6174f6c4c 100644 --- a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserUpdateReqVO.java +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserUpdateReqVO.java @@ -1,27 +1,26 @@ package cn.iocoder.yudao.module.mp.controller.admin.user.vo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; -@ApiModel("管理后台 - 公众号粉丝更新 Request VO") +@Schema(description = "管理后台 - 公众号粉丝更新 Request VO") @Data public class MpUserUpdateReqVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; - @ApiModelProperty(value = "昵称", example = "芋道") + @Schema(description = "昵称", example = "芋道") private String nickname; - @ApiModelProperty(value = "备注", example = "你是一个芋头嘛") + @Schema(description = "备注", example = "你是一个芋头嘛") private String remark; - @ApiModelProperty(value = "标签编号数组", example = "1,2,3") + @Schema(description = "标签编号数组", example = "1,2,3") private List tagIds; } diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 547efa69a..fc45b357d 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -44,34 +44,34 @@ spring: primary: master datasource: master: - name: ruoyi-vue-pro - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 + name: pro + url: jdbc:mysql://101.201.151.212:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例 - username: root - password: 123456 + username: luoqi + password: luoqikeji # username: sa # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W slave: # 模拟从库,可根据自己需要修改 - name: ruoyi-vue-pro - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 + name: pro + url: jdbc:mysql://101.201.151.212:3306/${spring.datasource.dynamic.datasource.slave.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例 - username: root - password: 123456 + username: luoqi + password: luoqikeji # username: sa # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 redis: - host: 127.0.0.1 # 地址 + host: 39.107.87.6 # 地址 port: 6379 # 端口 - database: 0 # 数据库索引 -# password: 123456 # 密码,建议生产环境开启 + database: 5 # 数据库索引 + password: xingyu4j # 密码,建议生产环境开启 --- #################### 定时任务相关配置 #################### From fa32611fe724939a9f2ebe5c04b6bd32c9a0ae53 Mon Sep 17 00:00:00 2001 From: xingyu Date: Wed, 18 Jan 2023 16:16:52 +0800 Subject: [PATCH 16/59] revert: file --- .../src/main/resources/application-local.yaml | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index fc45b357d..547efa69a 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -44,34 +44,34 @@ spring: primary: master datasource: master: - name: pro - url: jdbc:mysql://101.201.151.212:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 + name: ruoyi-vue-pro + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例 - username: luoqi - password: luoqikeji + username: root + password: 123456 # username: sa # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W slave: # 模拟从库,可根据自己需要修改 - name: pro - url: jdbc:mysql://101.201.151.212:3306/${spring.datasource.dynamic.datasource.slave.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 + name: ruoyi-vue-pro + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?allowMultiQueries=true&useUnicode=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&autoReconnect=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例 - username: luoqi - password: luoqikeji + username: root + password: 123456 # username: sa # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 redis: - host: 39.107.87.6 # 地址 + host: 127.0.0.1 # 地址 port: 6379 # 端口 - database: 5 # 数据库索引 - password: xingyu4j # 密码,建议生产环境开启 + database: 0 # 数据库索引 +# password: 123456 # 密码,建议生产环境开启 --- #################### 定时任务相关配置 #################### From ba65a864fa73eda5941c6edb9068794e3b273288 Mon Sep 17 00:00:00 2001 From: xingyu Date: Wed, 18 Jan 2023 17:40:49 +0800 Subject: [PATCH 17/59] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96Springdoc?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/YudaoSwaggerAutoConfiguration.java | 65 ++++++++++++------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index fec3e21e6..c04a3c51b 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.framework.swagger.config; +import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; @@ -8,7 +9,6 @@ import io.swagger.v3.oas.models.media.IntegerSchema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; -import org.springdoc.core.GroupedOpenApi; import org.springdoc.core.*; import org.springdoc.core.customizers.OpenApiBuilderCustomizer; import org.springdoc.core.customizers.ServerBaseUrlCustomizer; @@ -19,7 +19,9 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.http.HttpHeaders; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; @@ -36,29 +38,14 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_ public class YudaoSwaggerAutoConfiguration { @Bean - public OpenAPI createRestApi(SwaggerProperties properties) { - //信息 - Info info = new Info() - .title(properties.getTitle()) - .description(properties.getDescription()) - .version(properties.getVersion()) - .contact(new Contact().name(properties.getAuthor()).url(properties.getUrl()).email(properties.getEmail())) - .license(new License().name(properties.getLicense()).url(properties.getLicenseUrl())); - return new OpenAPI() - .info(info) - .schemaRequirement(HttpHeaders.AUTHORIZATION, securityScheme()) + public OpenAPI createApi(SwaggerProperties properties) { + Map maps = securityScheme(); + OpenAPI openAPI = new OpenAPI() + .info(buildInfo(properties)) + .components(new Components().securitySchemes(maps)) .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION)); - } - - private SecurityScheme securityScheme() { - SecurityScheme securityScheme = new SecurityScheme(); - //类型 - securityScheme.setType(SecurityScheme.Type.APIKEY); - //请求头的name - securityScheme.setName(HttpHeaders.AUTHORIZATION); - //token所在未知 - securityScheme.setIn(SecurityScheme.In.HEADER); - return securityScheme; + maps.keySet().forEach(key -> openAPI.addSecurityItem(new SecurityRequirement().addList(key))); + return openAPI; } /** @@ -97,6 +84,38 @@ public class YudaoSwaggerAutoConfiguration { .build(); } + /** + * API 摘要信息 + */ + private Info buildInfo(SwaggerProperties properties) { + return new Info() + .title(properties.getTitle()) + .description(properties.getDescription()) + .version(properties.getVersion()) + .contact(new Contact().name(properties.getAuthor()).url(properties.getUrl()).email(properties.getEmail())) + .license(new License().name(properties.getLicense()).url(properties.getLicenseUrl())); + } + + /** + * 安全模式,这里配置通过请求头 Authorization 传递 token 参数 + */ + private Map securityScheme() { + Map map = new HashMap<>(); + SecurityScheme securityScheme = new SecurityScheme() + //类型 + .type(SecurityScheme.Type.APIKEY) + //请求头的name + .name(HttpHeaders.AUTHORIZATION) + //token所在未知 + .in(SecurityScheme.In.HEADER); + map.put(HttpHeaders.AUTHORIZATION, securityScheme); + return map; + } + + /** + * globalHeaderParameter + * @return 多租户参数 + */ private static Parameter globalHeaderParameter() { return new Parameter() .name(HEADER_TENANT_ID) From 711a39b8e9b2fda99c8cf972b9143989bcf5f915 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 19 Jan 2023 15:03:46 +0800 Subject: [PATCH 18/59] =?UTF-8?q?spring=20doc=EF=BC=9A=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=88=86=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/YudaoSwaggerAutoConfiguration.java | 143 ++++++++++-------- .../web/config/BpmWebConfiguration.java | 24 +++ .../bpm/framework/web/package-info.java | 4 + .../web/config/InfraWebConfiguration.java | 24 +++ .../infra/framework/web/package-info.java | 4 + yudao-module-mall/README.md | 4 + yudao-module-mall/yudao-module-mall.zip | Bin 0 -> 426292 bytes .../web/config/MemberWebConfiguration.java | 24 +++ .../member/framework/web/package-info.java | 4 + .../web/config/MpWebConfiguration.java | 24 +++ .../module/mp/framework/web/package-info.java | 4 + .../web/config/PayWebConfiguration.java | 24 +++ .../pay/framework/web/package-info.java | 4 + .../web/config/SystemWebConfiguration.java | 24 +++ .../system/framework/web/package-info.java | 4 + yudao-server/pom.xml | 16 +- .../src/main/resources/application.yaml | 3 +- 17 files changed, 264 insertions(+), 70 deletions(-) create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/package-info.java create mode 100644 yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/config/InfraWebConfiguration.java create mode 100644 yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/package-info.java create mode 100644 yudao-module-mall/README.md create mode 100755 yudao-module-mall/yudao-module-mall.zip create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/MemberWebConfiguration.java create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/package-info.java create mode 100644 yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/config/MpWebConfiguration.java create mode 100644 yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/package-info.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/config/PayWebConfiguration.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/package-info.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/config/SystemWebConfiguration.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/package-info.java diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index c04a3c51b..76e1e52ea 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -6,6 +6,7 @@ import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; import io.swagger.v3.oas.models.media.IntegerSchema; +import io.swagger.v3.oas.models.media.StringSchema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; @@ -27,8 +28,11 @@ import java.util.Optional; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; /** - * springdoc 自动配置类 - * 使用 knife4j.enable=false 禁用 Swagger + * Swagger 自动配置类,基于 OpenAPI + Springdoc 实现。 + * + * 友情提示: + * 1. Springdoc 文档地址:仓库 + * 2. Swagger 规范,于 2015 更名为 OpenAPI 规范,本质是一个东西 * * @author 芋道源码 */ @@ -37,53 +41,21 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_ @EnableConfigurationProperties(SwaggerProperties.class) public class YudaoSwaggerAutoConfiguration { + // ========== 全局 OpenAPI 配置 ========== + @Bean public OpenAPI createApi(SwaggerProperties properties) { - Map maps = securityScheme(); + Map securitySchemas = buildSecuritySchemes(); OpenAPI openAPI = new OpenAPI() + // 接口信息 .info(buildInfo(properties)) - .components(new Components().securitySchemes(maps)) + // 接口安全配置 + .components(new Components().securitySchemes(securitySchemas)) .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION)); - maps.keySet().forEach(key -> openAPI.addSecurityItem(new SecurityRequirement().addList(key))); + securitySchemas.keySet().forEach(key -> openAPI.addSecurityItem(new SecurityRequirement().addList(key))); return openAPI; } - /** - * 自定义 openapi 处理器 - */ - @Bean - public OpenAPIService openApiBuilder(Optional openAPI, - SecurityService securityParser, - SpringDocConfigProperties springDocConfigProperties, - PropertyResolverUtils propertyResolverUtils, - Optional> openApiBuilderCustomisers, - Optional> serverBaseUrlCustomisers, - Optional javadocProvider) { - return new OpenAPIService(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers, javadocProvider); - } - - @Bean - public GroupedOpenApi appApi() { - return GroupedOpenApi.builder() - .group("app") - .addOperationCustomizer((operation, handlerMethod) -> - operation.addParametersItem(globalHeaderParameter()) - ) - .pathsToMatch("/app-api/**") - .build(); - } - - @Bean - public GroupedOpenApi adminApi() { - return GroupedOpenApi.builder() - .group("admin") - .addOperationCustomizer((operation, handlerMethod) -> - operation.addParametersItem(globalHeaderParameter()) - ) - .pathsToMatch("/admin-api/**") - .build(); - } - /** * API 摘要信息 */ @@ -99,33 +71,82 @@ public class YudaoSwaggerAutoConfiguration { /** * 安全模式,这里配置通过请求头 Authorization 传递 token 参数 */ - private Map securityScheme() { - Map map = new HashMap<>(); + private Map buildSecuritySchemes() { + Map securitySchemes = new HashMap<>(); SecurityScheme securityScheme = new SecurityScheme() - //类型 - .type(SecurityScheme.Type.APIKEY) - //请求头的name - .name(HttpHeaders.AUTHORIZATION) - //token所在未知 - .in(SecurityScheme.In.HEADER); - map.put(HttpHeaders.AUTHORIZATION, securityScheme); - return map; + .type(SecurityScheme.Type.APIKEY) // 类型 + .name(HttpHeaders.AUTHORIZATION) // 请求头的 name + .in(SecurityScheme.In.HEADER); // token 所在位置 + securitySchemes.put(HttpHeaders.AUTHORIZATION, securityScheme); + return securitySchemes; } /** - * globalHeaderParameter + * 自定义 OpenAPI 处理器 + */ + @Bean + public OpenAPIService openApiBuilder(Optional openAPI, + SecurityService securityParser, + SpringDocConfigProperties springDocConfigProperties, + PropertyResolverUtils propertyResolverUtils, + Optional> openApiBuilderCustomizers, + Optional> serverBaseUrlCustomizers, + Optional javadocProvider) { + + return new OpenAPIService(openAPI, securityParser, springDocConfigProperties, + propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider); + } + + // ========== 分组 OpenAPI 配置 ========== + + /** + * 所有模块的 API 分组 + */ + @Bean + public GroupedOpenApi allGroupedOpenApi() { + return buildGroupedOpenApi("all", ""); + } + + public static GroupedOpenApi buildGroupedOpenApi(String group) { + return buildGroupedOpenApi(group, group); + } + + public static GroupedOpenApi buildGroupedOpenApi(String group, String path) { + return GroupedOpenApi.builder() + .group(group) + .pathsToMatch("/admin-api/" + path + "/**", "/app-api/" + path + "/**") + .addOperationCustomizer((operation, handlerMethod) -> operation + .addParametersItem(buildTenantHeaderParameter()) + .addParametersItem(buildSecurityHeaderParameter())) + .build(); + } + + /** + * 构建 Tenant 租户编号请求头参数 + * * @return 多租户参数 */ - private static Parameter globalHeaderParameter() { + private static Parameter buildTenantHeaderParameter() { return new Parameter() - .name(HEADER_TENANT_ID) - .description("租户编号") - .in(String.valueOf(SecurityScheme.In.HEADER)) - .schema(new IntegerSchema() - ._default(1L) - .name(HEADER_TENANT_ID) - .description("租户编号") - ); + .name(HEADER_TENANT_ID) // header 名 + .description("租户编号") // 描述 + .in(String.valueOf(SecurityScheme.In.HEADER)) // 请求 header + .schema(new IntegerSchema()._default(1L).name(HEADER_TENANT_ID).description("租户编号")); // 默认:使用租户编号为 1 + } + + /** + * 构建 Authorization 认证请求头参数 + * + * 解决 Knife4j Authorize 未生效,请求header里未包含参数 + * + * @return 认证参数 + */ + private static Parameter buildSecurityHeaderParameter() { + return new Parameter() + .name(HttpHeaders.AUTHORIZATION) // header 名 + .description("认证 Token") // 描述 + .in(String.valueOf(SecurityScheme.In.HEADER)) // 请求 header + .schema(new StringSchema()._default("Bearer test1").name(HEADER_TENANT_ID).description("认证 Token")); // 默认:使用用户编号为 1 } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java new file mode 100644 index 000000000..036e8a12f --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.bpm.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * bpm 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class BpmWebConfiguration { + + /** + * bpm 模块的 API 分组 + */ + @Bean + public GroupedOpenApi bpmGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("bpm"); + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/package-info.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/package-info.java new file mode 100644 index 000000000..c01417081 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * bpm 模块的 web 配置 + */ +package cn.iocoder.yudao.module.bpm.framework.web; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/config/InfraWebConfiguration.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/config/InfraWebConfiguration.java new file mode 100644 index 000000000..09f2c2b3f --- /dev/null +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/config/InfraWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.infra.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * infra 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class InfraWebConfiguration { + + /** + * infra 模块的 API 分组 + */ + @Bean + public GroupedOpenApi infraGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("infra"); + } + +} diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/package-info.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/package-info.java new file mode 100644 index 000000000..6fb49bfde --- /dev/null +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * infra 模块的 web 配置 + */ +package cn.iocoder.yudao.module.infra.framework.web; diff --git a/yudao-module-mall/README.md b/yudao-module-mall/README.md new file mode 100644 index 000000000..6664ebef7 --- /dev/null +++ b/yudao-module-mall/README.md @@ -0,0 +1,4 @@ +mall 后端的代码,暂时归档成一个 yudao-module-mall 的压缩包。 + +精力有限,近期还是以管理后台的工作流、大屏报表等功能为主! + diff --git a/yudao-module-mall/yudao-module-mall.zip b/yudao-module-mall/yudao-module-mall.zip new file mode 100755 index 0000000000000000000000000000000000000000..9f361e3f73c2001b4d89fa2cdbde6b896ae831c7 GIT binary patch literal 426292 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 z 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 z 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 vjS3Q(FjFFS#egzyahS9w^54hB-Eo5&2_4rQ0{w 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 literal 0 HcmV?d00001 diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/MemberWebConfiguration.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/MemberWebConfiguration.java new file mode 100644 index 000000000..82c70034e --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/MemberWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.member.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * member 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class MemberWebConfiguration { + + /** + * member 模块的 API 分组 + */ + @Bean + public GroupedOpenApi memberGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("member"); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/package-info.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/package-info.java new file mode 100644 index 000000000..3a964cfc2 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * member 模块的 web 配置 + */ +package cn.iocoder.yudao.module.member.framework.web; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/config/MpWebConfiguration.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/config/MpWebConfiguration.java new file mode 100644 index 000000000..3e6e1acfc --- /dev/null +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/config/MpWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.mp.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * mp 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class MpWebConfiguration { + + /** + * mp 模块的 API 分组 + */ + @Bean + public GroupedOpenApi mpGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("mp"); + } + +} diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/package-info.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/package-info.java new file mode 100644 index 000000000..a103f1c38 --- /dev/null +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * mp 模块的 web 配置 + */ +package cn.iocoder.yudao.module.mp.framework.web; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/config/PayWebConfiguration.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/config/PayWebConfiguration.java new file mode 100644 index 000000000..febc2bc8a --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/config/PayWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.pay.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * pay 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class PayWebConfiguration { + + /** + * pay 模块的 API 分组 + */ + @Bean + public GroupedOpenApi payGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("pay"); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/package-info.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/package-info.java new file mode 100644 index 000000000..03bfad978 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * pay 模块的 web 配置 + */ +package cn.iocoder.yudao.module.pay.framework.web; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/config/SystemWebConfiguration.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/config/SystemWebConfiguration.java new file mode 100644 index 000000000..5b1b2355b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/config/SystemWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.system.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * system 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class SystemWebConfiguration { + + /** + * system 模块的 API 分组 + */ + @Bean + public GroupedOpenApi systemGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("system"); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/package-info.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/package-info.java new file mode 100644 index 000000000..1a17a3d7c --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * system 模块的 web 配置 + */ +package cn.iocoder.yudao.module.system.framework.web; diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 03cd5c9f6..0d4eceb29 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -41,19 +41,19 @@ yudao-spring-boot-starter-biz-error-code - - - - - - - + + + cn.iocoder.boot + yudao-module-visualization-biz + ${revision} + + - + cn.iocoder.boot yudao-module-pay-biz diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index ecac514f3..6348c7fd4 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -34,8 +34,9 @@ spring: redis: time-to-live: 1h # 设置过期时间为 1 小时 +--- #################### 接口文档配置 #################### + springdoc: - show-actuator: true swagger-ui: enabled: true path: /swagger-ui From d193d2dd4a877b061809f0e2e010e8c1ba111bac Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 19 Jan 2023 15:15:40 +0800 Subject: [PATCH 19/59] =?UTF-8?q?spring=20doc=EF=BC=9A=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=80=9A=E8=BF=87=20springdoc.api-docs=20=E7=A6=81=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../swagger/config/YudaoSwaggerAutoConfiguration.java | 2 ++ yudao-server/src/main/resources/application.yaml | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index 76e1e52ea..2481d2b74 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -16,6 +16,7 @@ import org.springdoc.core.customizers.ServerBaseUrlCustomizer; import org.springdoc.core.providers.JavadocProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpHeaders; @@ -39,6 +40,7 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_ @AutoConfiguration @ConditionalOnClass({OpenAPI.class}) @EnableConfigurationProperties(SwaggerProperties.class) +@ConditionalOnProperty(prefix = "springdoc.api-docs", name = "enabled", havingValue = "true", matchIfMissing = true) // 设置为 false 时,禁用 public class YudaoSwaggerAutoConfiguration { // ========== 全局 OpenAPI 配置 ========== diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 6348c7fd4..1a1119c78 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -37,12 +37,12 @@ spring: --- #################### 接口文档配置 #################### springdoc: - swagger-ui: - enabled: true - path: /swagger-ui api-docs: enabled: true path: /v3/api-docs + swagger-ui: + enabled: true + path: /swagger-ui knife4j: enable: true From 6b1f3140b8eeefe24697fd330c91a69a80567dd1 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 19 Jan 2023 15:22:58 +0800 Subject: [PATCH 20/59] =?UTF-8?q?spring=20doc=EF=BC=9A=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=A4=9A=E4=BD=99=E5=AD=97=E6=AE=B5~?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/framework/swagger/config/SwaggerProperties.java | 5 ----- yudao-server/src/main/resources/application.yaml | 5 ++--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/SwaggerProperties.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/SwaggerProperties.java index 21680cd00..13a156881 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/SwaggerProperties.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/SwaggerProperties.java @@ -34,11 +34,6 @@ public class SwaggerProperties { */ @NotEmpty(message = "版本不能为空") private String version; - /** - * 扫描的包 - */ - @NotEmpty(message = "扫描的 package 不能为空") - private String basePackage; /** * url */ diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 1a1119c78..1e99ba11e 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -114,10 +114,9 @@ yudao: maxOnlineCount: 0 # 最大连接人数 sessionMap: true # 保存sessionMap swagger: - title: 管理后台 - description: 提供管理员管理的所有功能 + title: 芋道快速开发平台 + description: 提供管理后台、用户 App 的所有功能 version: ${yudao.info.version} - base-package: ${yudao.info.base-package} url: ${yudao.web.admin-ui.url} email: xingyu4j@vip.qq.com license: MIT From edbbb1a50a0641be377ba3c82f358cf2f1e7bc20 Mon Sep 17 00:00:00 2001 From: xingyu Date: Sun, 29 Jan 2023 16:24:24 +0800 Subject: [PATCH 21/59] feat: mail springdoc --- .../admin/mail/MailAccountController.java | 25 +++++++------- .../admin/mail/MailLogController.java | 19 ++++------- .../admin/mail/MailTemplateController.java | 27 +++++++-------- .../mail/vo/account/MailAccountBaseVO.java | 14 ++++---- .../vo/account/MailAccountCreateReqVO.java | 7 ++-- .../mail/vo/account/MailAccountPageReqVO.java | 9 +++-- .../mail/vo/account/MailAccountRespVO.java | 9 +++-- .../vo/account/MailAccountSimpleRespVO.java | 9 +++-- .../vo/account/MailAccountUpdateReqVO.java | 7 ++-- .../admin/mail/vo/log/MailLogBaseVO.java | 34 +++++++++---------- .../admin/mail/vo/log/MailLogPageReqVO.java | 20 +++++------ .../admin/mail/vo/log/MailLogRespVO.java | 8 ++--- .../mail/vo/template/MailTemplateBaseVO.java | 19 +++++------ .../vo/template/MailTemplateCreateReqVO.java | 4 +-- .../vo/template/MailTemplatePageReqVO.java | 15 ++++---- .../mail/vo/template/MailTemplateRespVO.java | 11 +++--- .../vo/template/MailTemplateSendReqVO.java | 11 +++--- .../vo/template/MailTemplateSimpleRespVO.java | 9 +++-- .../vo/template/MailTemplateUpdateReqVO.java | 7 ++-- 19 files changed, 120 insertions(+), 144 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailAccountController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailAccountController.java index e2271ceb0..718e4b4fb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailAccountController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailAccountController.java @@ -7,20 +7,19 @@ import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.*; import cn.iocoder.yudao.module.system.convert.mail.MailAccountConvert; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; import cn.iocoder.yudao.module.system.service.mail.MailAccountService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; -import java.util.Comparator; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 邮箱账号") +@Tag(name = "管理后台 - 邮箱账号") @RestController @RequestMapping("/system/mail-account") public class MailAccountController { @@ -29,14 +28,14 @@ public class MailAccountController { private MailAccountService mailAccountService; @PostMapping("/create") - @ApiOperation("创建邮箱账号") + @Operation(summary = "创建邮箱账号") @PreAuthorize("@ss.hasPermission('system:mail-account:create')") public CommonResult createMailAccount(@Valid @RequestBody MailAccountCreateReqVO createReqVO) { return success(mailAccountService.createMailAccount(createReqVO)); } @PutMapping("/update") - @ApiOperation("修改邮箱账号") + @Operation(summary = "修改邮箱账号") @PreAuthorize("@ss.hasPermission('system:mail-account:update')") public CommonResult updateMailAccount(@Valid @RequestBody MailAccountUpdateReqVO updateReqVO) { mailAccountService.updateMailAccount(updateReqVO); @@ -44,8 +43,8 @@ public class MailAccountController { } @DeleteMapping("/delete") - @ApiOperation("删除邮箱账号") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除邮箱账号") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('system:mail-account:delete')") public CommonResult deleteMailAccount(@RequestParam Long id) { mailAccountService.deleteMailAccount(id); @@ -53,8 +52,8 @@ public class MailAccountController { } @GetMapping("/get") - @ApiOperation("获得邮箱账号") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得邮箱账号") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:mail-account:get')") public CommonResult getMailAccount(@RequestParam("id") Long id) { MailAccountDO mailAccountDO = mailAccountService.getMailAccount(id); @@ -62,7 +61,7 @@ public class MailAccountController { } @GetMapping("/page") - @ApiOperation("获得邮箱账号分页") + @Operation(summary = "获得邮箱账号分页") @PreAuthorize("@ss.hasPermission('system:mail-account:query')") public CommonResult> getMailAccountPage(@Valid MailAccountPageReqVO pageReqVO) { PageResult pageResult = mailAccountService.getMailAccountPage(pageReqVO); @@ -70,7 +69,7 @@ public class MailAccountController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获得邮箱账号精简列表") + @Operation(summary = "获得邮箱账号精简列表") public CommonResult> getSimpleMailAccountList() { List list = mailAccountService.getMailAccountList(); return success(MailAccountConvert.INSTANCE.convertList02(list)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailLogController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailLogController.java index 2252c8789..1347f6ac6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailLogController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailLogController.java @@ -1,19 +1,15 @@ package cn.iocoder.yudao.module.system.controller.admin.mail; - import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogRespVO; -import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplateRespVO; import cn.iocoder.yudao.module.system.convert.mail.MailLogConvert; -import cn.iocoder.yudao.module.system.convert.mail.MailTemplateConvert; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailLogDO; -import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; import cn.iocoder.yudao.module.system.service.mail.MailLogService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -25,8 +21,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Api(tags = "管理后台 - 邮件日志") +@Tag(name = "管理后台 - 邮件日志") @RestController @RequestMapping("/system/mail-log") public class MailLogController { @@ -35,7 +30,7 @@ public class MailLogController { private MailLogService mailLogService; @GetMapping("/page") - @ApiOperation("获得邮箱日志分页") + @Operation(summary = "获得邮箱日志分页") @PreAuthorize("@ss.hasPermission('system:mail-log:query')") public CommonResult> getMailLogPage(@Valid MailLogPageReqVO pageVO) { PageResult pageResult = mailLogService.getMailLogPage(pageVO); @@ -43,8 +38,8 @@ public class MailLogController { } @GetMapping("/get") - @ApiOperation("获得邮箱日志") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得邮箱日志") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:mail-log:query')") public CommonResult getMailTemplate(@RequestParam("id") Long id) { MailLogDO mailLogDO = mailLogService.getMailLog(id); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.java index e98b4f084..87b338815 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailTemplateController.java @@ -3,14 +3,13 @@ package cn.iocoder.yudao.module.system.controller.admin.mail; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.*; -import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateSendReqVO; import cn.iocoder.yudao.module.system.convert.mail.MailTemplateConvert; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; import cn.iocoder.yudao.module.system.service.mail.MailSendService; import cn.iocoder.yudao.module.system.service.mail.MailTemplateService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; @@ -20,7 +19,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 邮件模版") +@Tag(name = "管理后台 - 邮件模版") @RestController @RequestMapping("/system/mail-template") public class MailTemplateController { @@ -31,14 +30,14 @@ public class MailTemplateController { private MailSendService mailSendService; @PostMapping("/create") - @ApiOperation("创建邮件模版") + @Operation(summary = "创建邮件模版") @PreAuthorize("@ss.hasPermission('system:mail-template:create')") public CommonResult createMailTemplate(@Valid @RequestBody MailTemplateCreateReqVO createReqVO){ return success(mailTempleService.createMailTemplate(createReqVO)); } @PutMapping("/update") - @ApiOperation("修改邮件模版") + @Operation(summary = "修改邮件模版") @PreAuthorize("@ss.hasPermission('system:mail-template:update')") public CommonResult updateMailTemplate(@Valid @RequestBody MailTemplateUpdateReqVO updateReqVO){ mailTempleService.updateMailTemplate(updateReqVO); @@ -46,8 +45,8 @@ public class MailTemplateController { } @DeleteMapping("/delete") - @ApiOperation("删除邮件模版") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "删除邮件模版") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:mail-template:delete')") public CommonResult deleteMailTemplate(@RequestParam("id") Long id) { mailTempleService.deleteMailTemplate(id); @@ -55,8 +54,8 @@ public class MailTemplateController { } @GetMapping("/get") - @ApiOperation("获得邮件模版") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得邮件模版") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:mail-template:get')") public CommonResult getMailTemplate(@RequestParam("id") Long id) { MailTemplateDO mailTemplateDO = mailTempleService.getMailTemplate(id); @@ -64,7 +63,7 @@ public class MailTemplateController { } @GetMapping("/page") - @ApiOperation("获得邮件模版分页") + @Operation(summary = "获得邮件模版分页") @PreAuthorize("@ss.hasPermission('system:mail-template:query')") public CommonResult> getMailTemplatePage(@Valid MailTemplatePageReqVO pageReqVO) { PageResult pageResult = mailTempleService.getMailTemplatePage(pageReqVO); @@ -72,14 +71,14 @@ public class MailTemplateController { } @GetMapping("/list-all-simple") - @ApiOperation(value = "获得邮件模版精简列表") + @Operation(summary = "获得邮件模版精简列表") public CommonResult> getSimpleTemplateList() { List list = mailTempleService.getMailTemplateList(); return success(MailTemplateConvert.INSTANCE.convertList02(list)); } @PostMapping("/send-mail") - @ApiOperation("发送短信") + @Operation(summary = "发送短信") @PreAuthorize("@ss.hasPermission('system:mail-template:send-mail')") public CommonResult sendMail(@Valid @RequestBody MailTemplateSendReqVO sendReqVO) { return success(mailSendService.sendSingleMailToAdmin(sendReqVO.getMail(), null, diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountBaseVO.java index ef18cb6ac..2778234a0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountBaseVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.account; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.Email; @@ -13,28 +13,28 @@ import javax.validation.constraints.NotNull; @Data public class MailAccountBaseVO { - @ApiModelProperty(value = "邮箱", required = true, example = "yudaoyuanma@123.com") + @Schema(description = "邮箱", required = true, example = "yudaoyuanma@123.com") @NotNull(message = "邮箱不能为空") @Email(message = "必须是 Email 格式") private String mail; - @ApiModelProperty(value = "用户名", required = true, example = "yudao") + @Schema(description = "用户名", required = true, example = "yudao") @NotNull(message = "用户名不能为空") private String username; - @ApiModelProperty(value = "密码", required = true, example = "123456") + @Schema(description = "密码", required = true, example = "123456") @NotNull(message = "密码必填") private String password; - @ApiModelProperty(value = "SMTP 服务器域名", required = true, example = "www.iocoder.cn") + @Schema(description = "SMTP 服务器域名", required = true, example = "www.iocoder.cn") @NotNull(message = "SMTP 服务器域名不能为空") private String host; - @ApiModelProperty(value = "SMTP 服务器端口", required = true, example = "80") + @Schema(description = "SMTP 服务器端口", required = true, example = "80") @NotNull(message = "SMTP 服务器端口不能为空") private Integer port; - @ApiModelProperty(value = "是否开启 ssl", required = true, example = "true") + @Schema(description = "是否开启 ssl", required = true, example = "true") @NotNull(message = "是否开启 ssl 必填") private Boolean sslEnable; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountCreateReqVO.java index 2bcca7850..6776ad9f7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountCreateReqVO.java @@ -1,14 +1,11 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.account; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import javax.validation.constraints.NotNull; - -@ApiModel("管理后台 - 邮箱账号创建 Request VO") +@Schema(description = "管理后台 - 邮箱账号创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountPageReqVO.java index 9e5869172..ae420d1d2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountPageReqVO.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.account; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 邮箱账号分页 Request VO") +@Schema(description = "管理后台 - 邮箱账号分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MailAccountPageReqVO extends PageParam { - @ApiModelProperty(value = "邮箱", required = true, example = "yudaoyuanma@123.com") + @Schema(description = "邮箱", required = true, example = "yudaoyuanma@123.com") private String mail; - @ApiModelProperty(value = "用户名" , required = true , example = "yudao") + @Schema(description = "用户名" , required = true , example = "yudao") private String username; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountRespVO.java index 9eef7281a..2067d6470 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.account; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,17 +8,17 @@ import lombok.ToString; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -@ApiModel("管理后台 - 邮箱账号 Response VO") +@Schema(description ="管理后台 - 邮箱账号 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MailAccountRespVO extends MailAccountBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountSimpleRespVO.java index 96916a715..dd6093ffa 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountSimpleRespVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.account; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("管理后台 - 邮箱账号的精简 Response VO") +@Schema(description = "管理后台 - 邮箱账号的精简 Response VO") @Data public class MailAccountSimpleRespVO { - @ApiModelProperty(value = "邮箱编号", required = true, example = "1024") + @Schema(description = "邮箱编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "邮箱", required = true, example = "768541388@qq.com") + @Schema(description = "邮箱", required = true, example = "768541388@qq.com") private String mail; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountUpdateReqVO.java index 43a13ad18..c6ced00d6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/account/MailAccountUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.account; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 邮箱账号修改 Request VO") +@Schema(description = "管理后台 - 邮箱账号修改 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MailAccountUpdateReqVO extends MailAccountBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogBaseVO.java index 4a06fb893..a7b972af1 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogBaseVO.java @@ -1,11 +1,9 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.log; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; import java.time.LocalDateTime; -import java.time.LocalDateTime; -import java.time.LocalDateTime; -import io.swagger.annotations.*; import javax.validation.constraints.*; import org.springframework.format.annotation.DateTimeFormat; @@ -18,59 +16,59 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class MailLogBaseVO { - @ApiModelProperty(value = "用户编号", example = "30883") + @Schema(description = "用户编号", example = "30883") private Long userId; - @ApiModelProperty(value = "用户类型", example = "2", notes = "参见 UserTypeEnum 枚举") + @Schema(description = "用户类型 - 参见 UserTypeEnum 枚举", example = "2") private Byte userType; - @ApiModelProperty(value = "接收邮箱地址", required = true, example = "76854@qq.com") + @Schema(description = "接收邮箱地址", required = true, example = "76854@qq.com") @NotNull(message = "接收邮箱地址不能为空") private String toMail; - @ApiModelProperty(value = "邮箱账号编号", required = true, example = "18107") + @Schema(description = "邮箱账号编号", required = true, example = "18107") @NotNull(message = "邮箱账号编号不能为空") private Long accountId; - @ApiModelProperty(value = "发送邮箱地址", required = true, example = "85757@qq.com") + @Schema(description = "发送邮箱地址", required = true, example = "85757@qq.com") @NotNull(message = "发送邮箱地址不能为空") private String fromMail; - @ApiModelProperty(value = "模板编号", required = true, example = "5678") + @Schema(description = "模板编号", required = true, example = "5678") @NotNull(message = "模板编号不能为空") private Long templateId; - @ApiModelProperty(value = "模板编码", required = true, example = "test_01") + @Schema(description = "模板编码", required = true, example = "test_01") @NotNull(message = "模板编码不能为空") private String templateCode; - @ApiModelProperty(value = "模版发送人名称", example = "李四") + @Schema(description = "模版发送人名称", example = "李四") private String templateNickname; - @ApiModelProperty(value = "邮件标题", required = true, example = "测试标题") + @Schema(description = "邮件标题", required = true, example = "测试标题") @NotNull(message = "邮件标题不能为空") private String templateTitle; - @ApiModelProperty(value = "邮件内容", required = true, example = "测试内容") + @Schema(description = "邮件内容", required = true, example = "测试内容") @NotNull(message = "邮件内容不能为空") private String templateContent; - @ApiModelProperty(value = "邮件参数", required = true) + @Schema(description = "邮件参数", required = true) @NotNull(message = "邮件参数不能为空") private Map templateParams; - @ApiModelProperty(value = "发送状态", required = true, example = "1", notes = "参见 MailSendStatusEnum 枚举") + @Schema(description = "发送状态 - 参见 MailSendStatusEnum 枚举", required = true, example = "1") @NotNull(message = "发送状态不能为空") private Byte sendStatus; - @ApiModelProperty(value = "发送时间") + @Schema(description = "发送时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime sendTime; - @ApiModelProperty(value = "发送返回的消息 ID", example = "28568") + @Schema(description = "发送返回的消息 ID", example = "28568") private String sendMessageId; - @ApiModelProperty(value = "发送异常") + @Schema(description = "发送异常") private String sendException; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogPageReqVO.java index 1c02a15d0..6fe0244ef 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogPageReqVO.java @@ -1,43 +1,41 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.log; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.springframework.format.annotation.DateTimeFormat; -import java.sql.Timestamp; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 邮箱日志分页 Request VO") +@Schema(description = "管理后台 - 邮箱日志分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MailLogPageReqVO extends PageParam { - @ApiModelProperty(value = "用户编号", example = "30883") + @Schema(description = "用户编号", example = "30883") private Long userId; - @ApiModelProperty(value = "用户类型", example = "2", notes = "参见 UserTypeEnum 枚举") + @Schema(description = "用户类型 - 参见 UserTypeEnum 枚举", example = "2") private Integer userType; - @ApiModelProperty(value = "接收邮箱地址", example = "76854@qq.com", notes = "模糊匹配") + @Schema(description = "接收邮箱地址 模糊匹配", example = "76854@qq.com") private String toMail; - @ApiModelProperty(value = "邮箱账号编号", example = "18107") + @Schema(description = "邮箱账号编号", example = "18107") private Long accountId; - @ApiModelProperty(value = "模板编号", example = "5678") + @Schema(description = "模板编号", example = "5678") private Long templateId; - @ApiModelProperty(value = "发送状态", example = "1", notes = "参见 MailSendStatusEnum 枚举") + @Schema(description = "发送状态 - 参见 MailSendStatusEnum 枚举", example = "1") private Integer sendStatus; - @ApiModelProperty(value = "发送时间") + @Schema(description = "发送时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] sendTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogRespVO.java index b0e10355a..cf1ecb2a1 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/log/MailLogRespVO.java @@ -1,19 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.log; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 邮件日志 Response VO") +@Schema(description = "管理后台 - 邮件日志 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MailLogRespVO extends MailLogBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "31020") + @Schema(description = "编号", required = true, example = "31020") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateBaseVO.java index e2835debd..0b90b2712 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateBaseVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.template; -import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -14,34 +13,34 @@ import javax.validation.constraints.NotNull; @Data public class MailTemplateBaseVO { - @ApiModelProperty(value = "模版名称", required = true, example = "测试名字") + @Schema(description = "模版名称", required = true, example = "测试名字") @NotNull(message = "名称不能为空") private String name; - @ApiModelProperty(value = "模版编号", required = true, example = "test") + @Schema(description = "模版编号", required = true, example = "test") @NotNull(message = "模版编号不能为空") private String code; - @ApiModelProperty(value = "发送的邮箱账号编号", required = true, example = "1") + @Schema(description = "发送的邮箱账号编号", required = true, example = "1") @NotNull(message = "发送的邮箱账号编号不能为空") private Long accountId; - @ApiModelProperty(value = "发送人名称", example = "芋头") + @Schema(description = "发送人名称", example = "芋头") private String nickname; - @ApiModelProperty(value = "标题", required = true, example = "注册成功") + @Schema(description = "标题", required = true, example = "注册成功") @NotEmpty(message = "标题不能为空") private String title; - @ApiModelProperty(value = "内容", required = true, example = "你好,注册成功啦") + @Schema(description = "内容", required = true, example = "你好,注册成功啦") @NotEmpty(message = "内容不能为空") private String content; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态 - 参见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") private Integer status; - @ApiModelProperty(value = "备注", example = "奥特曼") + @Schema(description = "备注", example = "奥特曼") private String remark; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateCreateReqVO.java index 6eab6e9ab..b8b47e3b2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateCreateReqVO.java @@ -1,11 +1,11 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.template; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -@ApiModel("管理后台 - 邮件模版创建 Request VO") +@Schema(description = "管理后台 - 邮件模版创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplatePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplatePageReqVO.java index f3cec08f9..4044b7244 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplatePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplatePageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.template; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,25 +11,25 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 邮件模版分页 Request VO") +@Schema(description = "管理后台 - 邮件模版分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MailTemplatePageReqVO extends PageParam { - @ApiModelProperty(value = "状态", example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态 - 参见 CommonStatusEnum 枚举", example = "1") private Integer status; - @ApiModelProperty(value = "标识", example = "code_1024", notes = "模糊匹配") + @Schema(description = "标识 - 模糊匹配", example = "code_1024") private String code; - @ApiModelProperty(value = "名称", example = "芋头", notes = "模糊匹配") + @Schema(description = "名称 - 模糊匹配", example = "芋头") private String name; - @ApiModelProperty(value = "账号编号", example = "2048") + @Schema(description = "账号编号", example = "2048") private Long accountId; - @ApiModelProperty(value = "创建时间") + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateRespVO.java index a2153f9cd..561512cd7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateRespVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.template; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -9,19 +8,19 @@ import lombok.ToString; import java.time.LocalDateTime; import java.util.List; -@ApiModel("管理后台 - 邮件末班 Response VO") +@Schema(description = "管理后台 - 邮件末班 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MailTemplateRespVO extends MailTemplateBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "参数数组", example = "name,code") + @Schema(description = "参数数组", example = "name,code") private List params; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private LocalDateTime createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateSendReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateSendReqVO.java index ccef59770..5d1d9a00d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateSendReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateSendReqVO.java @@ -1,26 +1,25 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.template; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.Map; -@ApiModel("管理后台 - 邮件发送 Req VO") +@Schema(description = "管理后台 - 邮件发送 Req VO") @Data public class MailTemplateSendReqVO { - @ApiModelProperty(value = "接收邮箱", required = true, example = "7685413@qq.com") + @Schema(description = "接收邮箱", required = true, example = "7685413@qq.com") @NotEmpty(message = "接收邮箱不能为空") private String mail; - @ApiModelProperty(value = "模板编码", required = true, example = "test_01") + @Schema(description = "模板编码", required = true, example = "test_01") @NotNull(message = "模板编码不能为空") private String templateCode; - @ApiModelProperty(value = "模板参数") + @Schema(description = "模板参数") private Map templateParams; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateSimpleRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateSimpleRespVO.java index 2ff488036..3146e8546 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateSimpleRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateSimpleRespVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.template; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel("管理后台 - 邮件模版的精简 Response VO") +@Schema(description = "管理后台 - 邮件模版的精简 Response VO") @Data public class MailTemplateSimpleRespVO { - @ApiModelProperty(value = "模版编号", required = true, example = "1024") + @Schema(description = "模版编号", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "模版名字", required = true, example = "哒哒哒") + @Schema(description = "模版名字", required = true, example = "哒哒哒") private String name; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateUpdateReqVO.java index 5dfa377a2..1f50821ba 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/vo/template/MailTemplateUpdateReqVO.java @@ -1,20 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.mail.vo.template; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import javax.validation.constraints.NotNull; -@ApiModel("管理后台 - 邮件模版修改 Request VO") +@Schema(description = "管理后台 - 邮件模版修改 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MailTemplateUpdateReqVO extends MailTemplateBaseVO { - @ApiModelProperty(value = "编号", required = true, example = "1024") + @Schema(description = "编号", required = true, example = "1024") @NotNull(message = "编号不能为空") private Long id; From 68bdaa7854340731140cb892620ccdd79c2ff7e6 Mon Sep 17 00:00:00 2001 From: xingyu Date: Sun, 29 Jan 2023 16:25:59 +0800 Subject: [PATCH 22/59] feat: swagger-ui --- yudao-ui-admin/src/views/infra/swagger/index.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/yudao-ui-admin/src/views/infra/swagger/index.vue b/yudao-ui-admin/src/views/infra/swagger/index.vue index 70c1deb3f..3cf0d8ab3 100644 --- a/yudao-ui-admin/src/views/infra/swagger/index.vue +++ b/yudao-ui-admin/src/views/infra/swagger/index.vue @@ -11,7 +11,8 @@ export default { components: { iFrame }, data() { return { - url: process.env.VUE_APP_BASE_API + "/doc.html" + // url: process.env.VUE_APP_BASE_API + "/doc.html" + url: process.env.VUE_APP_BASE_API + "/swagger-ui" }; }, }; From fa2977ae9e36fc5f063bb6089eb8cf896ce01265 Mon Sep 17 00:00:00 2001 From: xingyu Date: Mon, 30 Jan 2023 10:24:29 +0800 Subject: [PATCH 23/59] =?UTF-8?q?=E9=80=82=E9=85=8Dspringdoc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/notify/NotifyMessageController.java | 28 +++++++++---------- .../notify/NotifyTemplateController.java | 24 ++++++++-------- .../vo/message/NotifyMessageBaseVO.java | 23 ++++++++------- .../vo/message/NotifyMessageMyPageReqVO.java | 9 +++--- .../vo/message/NotifyMessagePageReqVO.java | 16 +++++------ .../vo/message/NotifyMessageRespVO.java | 8 +++--- .../vo/template/NotifyTemplateBaseVO.java | 16 +++++------ .../template/NotifyTemplateCreateReqVO.java | 4 +-- .../vo/template/NotifyTemplatePageReqVO.java | 14 ++++------ .../vo/template/NotifyTemplateRespVO.java | 10 +++---- .../vo/template/NotifyTemplateSendReqVO.java | 11 ++++---- .../template/NotifyTemplateUpdateReqVO.java | 6 ++-- 12 files changed, 81 insertions(+), 88 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyMessageController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyMessageController.java index 51d236110..c3e5249e8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyMessageController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyMessageController.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyM import cn.iocoder.yudao.module.system.convert.notify.NotifyMessageConvert; import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO; import cn.iocoder.yudao.module.system.service.notify.NotifyMessageService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -23,7 +23,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Api(tags = "管理后台 - 我的站内信") +@Tag(name = "管理后台 - 我的站内信") @RestController @RequestMapping("/system/notify-message") @Validated @@ -35,8 +35,8 @@ public class NotifyMessageController { // ========== 管理所有的站内信 ========== @GetMapping("/get") - @ApiOperation("获得站内信") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得站内信") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:notify-message:query')") public CommonResult getNotifyMessage(@RequestParam("id") Long id) { NotifyMessageDO notifyMessage = notifyMessageService.getNotifyMessage(id); @@ -44,7 +44,7 @@ public class NotifyMessageController { } @GetMapping("/page") - @ApiOperation("获得站内信分页") + @Operation(summary = "获得站内信分页") @PreAuthorize("@ss.hasPermission('system:notify-message:query')") public CommonResult> getNotifyMessagePage(@Valid NotifyMessagePageReqVO pageVO) { PageResult pageResult = notifyMessageService.getNotifyMessagePage(pageVO); @@ -54,7 +54,7 @@ public class NotifyMessageController { // ========== 查看自己的站内信 ========== @GetMapping("/my-page") - @ApiOperation("获得我的站内信分页") + @Operation(summary = "获得我的站内信分页") public CommonResult> getMyMyNotifyMessagePage(@Valid NotifyMessageMyPageReqVO pageVO) { PageResult pageResult = notifyMessageService.getMyMyNotifyMessagePage(pageVO, getLoginUserId(), UserTypeEnum.ADMIN.getValue()); @@ -62,23 +62,23 @@ public class NotifyMessageController { } @PutMapping("/update-read") - @ApiOperation("标记站内信为已读") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) + @Operation(summary = "标记站内信为已读") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") public CommonResult updateNotifyMessageRead(@RequestParam("ids") List ids) { notifyMessageService.updateNotifyMessageRead(ids, getLoginUserId(), UserTypeEnum.ADMIN.getValue()); return success(Boolean.TRUE); } @PutMapping("/update-all-read") - @ApiOperation("标记所有站内信为已读") + @Operation(summary = "标记所有站内信为已读") public CommonResult updateAllNotifyMessageRead() { notifyMessageService.updateAllNotifyMessageRead(getLoginUserId(), UserTypeEnum.ADMIN.getValue()); return success(Boolean.TRUE); } @GetMapping("/get-unread-list") - @ApiOperation("获取当前用户的最新站内信列表,默认 10 条") - @ApiImplicitParam(name = "size", value = "10", defaultValue = "10", dataTypeClass = Integer.class) + @Operation(summary = "获取当前用户的最新站内信列表,默认 10 条") + @Parameter(name = "size", description = "10") public CommonResult> getUnreadNotifyMessageList( @RequestParam(name = "size", defaultValue = "10") Integer size) { List list = notifyMessageService.getUnreadNotifyMessageList( @@ -87,7 +87,7 @@ public class NotifyMessageController { } @GetMapping("/get-unread-count") - @ApiOperation("获得当前用户的未读站内信数量") + @Operation(summary = "获得当前用户的未读站内信数量") public CommonResult getUnreadNotifyMessageCount() { return success(notifyMessageService.getUnreadNotifyMessageCount(getLoginUserId(), UserTypeEnum.ADMIN.getValue())); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyTemplateController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyTemplateController.java index c90145dcd..0299836d7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyTemplateController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyTemplateController.java @@ -7,9 +7,9 @@ import cn.iocoder.yudao.module.system.convert.notify.NotifyTemplateConvert; import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO; import cn.iocoder.yudao.module.system.service.notify.NotifySendService; import cn.iocoder.yudao.module.system.service.notify.NotifyTemplateService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -19,7 +19,7 @@ import javax.validation.Valid; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -@Api(tags = "管理后台 - 站内信模版") +@Tag(name = "管理后台 - 站内信模版") @RestController @RequestMapping("/system/notify-template") @Validated @@ -32,14 +32,14 @@ public class NotifyTemplateController { private NotifySendService notifySendService; @PostMapping("/create") - @ApiOperation("创建站内信模版") + @Operation(summary = "创建站内信模版") @PreAuthorize("@ss.hasPermission('system:notify-template:create')") public CommonResult createNotifyTemplate(@Valid @RequestBody NotifyTemplateCreateReqVO createReqVO) { return success(notifyTemplateService.createNotifyTemplate(createReqVO)); } @PutMapping("/update") - @ApiOperation("更新站内信模版") + @Operation(summary = "更新站内信模版") @PreAuthorize("@ss.hasPermission('system:notify-template:update')") public CommonResult updateNotifyTemplate(@Valid @RequestBody NotifyTemplateUpdateReqVO updateReqVO) { notifyTemplateService.updateNotifyTemplate(updateReqVO); @@ -47,8 +47,8 @@ public class NotifyTemplateController { } @DeleteMapping("/delete") - @ApiOperation("删除站内信模版") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @Operation(summary = "删除站内信模版") + @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('system:notify-template:delete')") public CommonResult deleteNotifyTemplate(@RequestParam("id") Long id) { notifyTemplateService.deleteNotifyTemplate(id); @@ -56,8 +56,8 @@ public class NotifyTemplateController { } @GetMapping("/get") - @ApiOperation("获得站内信模版") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @Operation(summary = "获得站内信模版") + @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:notify-template:query')") public CommonResult getNotifyTemplate(@RequestParam("id") Long id) { NotifyTemplateDO notifyTemplate = notifyTemplateService.getNotifyTemplate(id); @@ -65,7 +65,7 @@ public class NotifyTemplateController { } @GetMapping("/page") - @ApiOperation("获得站内信模版分页") + @Operation(summary = "获得站内信模版分页") @PreAuthorize("@ss.hasPermission('system:notify-template:query')") public CommonResult> getNotifyTemplatePage(@Valid NotifyTemplatePageReqVO pageVO) { PageResult pageResult = notifyTemplateService.getNotifyTemplatePage(pageVO); @@ -73,7 +73,7 @@ public class NotifyTemplateController { } @PostMapping("/send-notify") - @ApiOperation("发送站内信") + @Operation(summary = "发送站内信") @PreAuthorize("@ss.hasPermission('system:notify-template:send-notify')") public CommonResult sendNotify(@Valid @RequestBody NotifyTemplateSendReqVO sendReqVO) { return success(notifySendService.sendSingleNotifyToAdmin(sendReqVO.getUserId(), diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageBaseVO.java index 161fb9331..5cb1e0b45 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageBaseVO.java @@ -1,12 +1,11 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.message; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; -import java.util.Date; import java.util.Map; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @@ -18,43 +17,43 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class NotifyMessageBaseVO { - @ApiModelProperty(value = "用户编号", required = true, example = "25025") + @Schema(description = "用户编号", required = true, example = "25025") @NotNull(message = "用户编号不能为空") private Long userId; - @ApiModelProperty(value = "用户类型", required = true, example = "1", notes = "参见 UserTypeEnum 枚举") + @Schema(description = "用户类型 - 参见 UserTypeEnum 枚举", required = true, example = "1") @NotNull(message = "用户类型不能为空") private Byte userType; - @ApiModelProperty(value = "模版编号", required = true, example = "13013") + @Schema(description = "模版编号", required = true, example = "13013") @NotNull(message = "模版编号不能为空") private Long templateId; - @ApiModelProperty(value = "模板编码", required = true, example = "test_01") + @Schema(description = "模板编码", required = true, example = "test_01") @NotNull(message = "模板编码不能为空") private String templateCode; - @ApiModelProperty(value = "模版发送人名称", required = true, example = "芋艿") + @Schema(description = "模版发送人名称", required = true, example = "芋艿") @NotNull(message = "模版发送人名称不能为空") private String templateNickname; - @ApiModelProperty(value = "模版内容", required = true, example = "测试内容") + @Schema(description = "模版内容", required = true, example = "测试内容") @NotNull(message = "模版内容不能为空") private String templateContent; - @ApiModelProperty(value = "模版类型", required = true, example = "2") + @Schema(description = "模版类型", required = true, example = "2") @NotNull(message = "模版类型不能为空") private Integer templateType; - @ApiModelProperty(value = "模版参数", required = true) + @Schema(description = "模版参数", required = true) @NotNull(message = "模版参数不能为空") private Map templateParams; - @ApiModelProperty(value = "是否已读", required = true, example = "true") + @Schema(description = "是否已读", required = true, example = "true") @NotNull(message = "是否已读不能为空") private Boolean readStatus; - @ApiModelProperty(value = "阅读时间") + @Schema(description = "阅读时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime readTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageMyPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageMyPageReqVO.java index 8d3eac162..213d6e17c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageMyPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageMyPageReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.message; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -12,16 +11,16 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 站内信分页 Request VO") +@Schema(description = "管理后台 - 站内信分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class NotifyMessageMyPageReqVO extends PageParam { - @ApiModelProperty(value = "是否已读", example = "true") + @Schema(description = "是否已读", example = "true") private Boolean readStatus; - @ApiModelProperty(value = "创建时间") + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessagePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessagePageReqVO.java index f705527c4..4e3aea5c9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessagePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessagePageReqVO.java @@ -1,37 +1,35 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.message; import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; -import java.util.Date; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 站内信分页 Request VO") +@Schema(description = "管理后台 - 站内信分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class NotifyMessagePageReqVO extends PageParam { - @ApiModelProperty(value = "用户编号", example = "25025") + @Schema(description = "用户编号", example = "25025") private Long userId; - @ApiModelProperty(value = "用户类型", example = "1") + @Schema(description = "用户类型", example = "1") private Integer userType; - @ApiModelProperty(value = "模板编码", example = "test_01") + @Schema(description = "模板编码", example = "test_01") private String templateCode; - @ApiModelProperty(value = "模版类型", example = "2") + @Schema(description = "模版类型", example = "2") private Integer templateType; - @ApiModelProperty(value = "创建时间") + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageRespVO.java index 26be638a4..f109c36fb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageRespVO.java @@ -1,19 +1,19 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.message; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 站内信 Response VO") +@Schema(description = "管理后台 - 站内信 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class NotifyMessageRespVO extends NotifyMessageBaseVO { - @ApiModelProperty(value = "ID", required = true, example = "1024") + @Schema(description = "ID", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private Date createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateBaseVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateBaseVO.java index 118f55baf..1e8762ca0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateBaseVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateBaseVO.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; @@ -15,32 +15,32 @@ import javax.validation.constraints.NotNull; @Data public class NotifyTemplateBaseVO { - @ApiModelProperty(value = "模版名称", required = true, example = "测试模版") + @Schema(description = "模版名称", required = true, example = "测试模版") @NotEmpty(message = "模版名称不能为空") private String name; - @ApiModelProperty(value = "模版编码", required = true, example = "SEND_TEST") + @Schema(description = "模版编码", required = true, example = "SEND_TEST") @NotNull(message = "模版编码不能为空") private String code; - @ApiModelProperty(value = "模版类型", required = true, example = "1", notes = "对应 system_notify_template_type 字典") + @Schema(description = "模版类型 - 对应 system_notify_template_type 字典", required = true, example = "1") @NotNull(message = "模版类型不能为空") private Integer type; - @ApiModelProperty(value = "发送人名称", required = true, example = "土豆") + @Schema(description = "发送人名称", required = true, example = "土豆") @NotEmpty(message = "发送人名称不能为空") private String nickname; - @ApiModelProperty(value = "模版内容", required = true, example = "我是模版内容") + @Schema(description = "模版内容", required = true, example = "我是模版内容") @NotEmpty(message = "模版内容不能为空") private String content; - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举") + @Schema(description = "状态 - 参见 CommonStatusEnum 枚举", required = true, example = "1") @NotNull(message = "状态不能为空") @InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}") private Integer status; - @ApiModelProperty(value = "备注", example = "我是备注") + @Schema(description = "备注", example = "我是备注") private String remark; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateCreateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateCreateReqVO.java index aa41b4e28..eb080a7bf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateCreateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateCreateReqVO.java @@ -1,9 +1,9 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 站内信模版创建 Request VO") +@Schema(description = "管理后台 - 站内信模版创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplatePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplatePageReqVO.java index 849ce1275..6c3a36bb1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplatePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplatePageReqVO.java @@ -1,32 +1,30 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template; -import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; -import java.util.*; -import io.swagger.annotations.*; import cn.iocoder.yudao.framework.common.pojo.PageParam; import org.springframework.format.annotation.DateTimeFormat; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@ApiModel("管理后台 - 站内信模版分页 Request VO") +@Schema(description = "管理后台 - 站内信模版分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class NotifyTemplatePageReqVO extends PageParam { - @ApiModelProperty(value = "模版编码", example = "test_01") + @Schema(description = "模版编码", example = "test_01") private String code; - @ApiModelProperty(value = "模版名称", example = "我是名称") + @Schema(description = "模版名称", example = "我是名称") private String name; - @ApiModelProperty(value = "状态", example = "1", notes = "参见 CommonStatusEnum 枚举类") + @Schema(description = "状态 - 参见 CommonStatusEnum 枚举类", example = "1") private Integer status; - @ApiModelProperty(value = "创建时间") + @Schema(description = "创建时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateRespVO.java index 4df5b7b64..acfed3013 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateRespVO.java @@ -1,22 +1,22 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; -import io.swagger.annotations.*; -@ApiModel("管理后台 - 站内信模版 Response VO") +@Schema(description = "管理后台 - 站内信模版 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class NotifyTemplateRespVO extends NotifyTemplateBaseVO { - @ApiModelProperty(value = "ID", required = true, example = "1024") + @Schema(description = "ID", required = true, example = "1024") private Long id; - @ApiModelProperty(value = "参数数组", example = "name,code") + @Schema(description = "参数数组", example = "name,code") private List params; - @ApiModelProperty(value = "创建时间", required = true) + @Schema(description = "创建时间", required = true) private Date createTime; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateSendReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateSendReqVO.java index e078fd845..adb73b00c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateSendReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateSendReqVO.java @@ -1,25 +1,24 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.Map; -@ApiModel("管理后台 - 站内信模板的发送 Request VO") +@Schema(description = "管理后台 - 站内信模板的发送 Request VO") @Data public class NotifyTemplateSendReqVO { - @ApiModelProperty(value = "用户id", required = true, example = "01") + @Schema(description = "用户id", required = true, example = "01") @NotNull(message = "用户id不能为空") private Long userId; - @ApiModelProperty(value = "模板编码", required = true, example = "01") + @Schema(description = "模板编码", required = true, example = "01") @NotEmpty(message = "模板编码不能为空") private String templateCode; - @ApiModelProperty(value = "模板参数") + @Schema(description = "模板参数") private Map templateParams; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateUpdateReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateUpdateReqVO.java index 6e75ccf89..cdbeade2d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateUpdateReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateUpdateReqVO.java @@ -1,16 +1,16 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import io.swagger.annotations.*; import javax.validation.constraints.*; -@ApiModel("管理后台 - 站内信模版更新 Request VO") +@Schema(description = "管理后台 - 站内信模版更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class NotifyTemplateUpdateReqVO extends NotifyTemplateBaseVO { - @ApiModelProperty(value = "ID", required = true, example = "1024") + @Schema(description = "ID", required = true, example = "1024") @NotNull(message = "ID 不能为空") private Long id; From ba78d9964ab7423b8f424de67ae6d7537ba25285 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 31 Jan 2023 22:43:50 +0800 Subject: [PATCH 24/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20AdminAuthServiceImpl?= =?UTF-8?q?=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/auth/AdminAuthServiceImpl.java | 16 +- .../service/user/AdminUserServiceImpl.java | 1 + .../auth/AdminAuthServiceImplTest.java | 293 +++++++++++++----- 3 files changed, 222 insertions(+), 88 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java index 490284242..ca34156eb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java @@ -94,7 +94,7 @@ public class AdminAuthServiceImpl implements AdminAuthService { @Override public AuthLoginRespVO login(AuthLoginReqVO reqVO) { // 校验验证码 - verifyCaptcha(reqVO); + validateCaptcha(reqVO); // 使用账号密码,进行登录 AdminUserDO user = authenticate(reqVO.getUsername(), reqVO.getPassword()); @@ -171,14 +171,8 @@ public class AdminAuthServiceImpl implements AdminAuthService { return createTokenAfterLoginSuccess(user.getId(), user.getUsername(), LoginLogTypeEnum.LOGIN_SOCIAL); } - @Override - public AuthLoginRespVO refreshToken(String refreshToken) { - OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.refreshAccessToken(refreshToken, OAuth2ClientConstants.CLIENT_ID_DEFAULT); - return AuthConvert.INSTANCE.convert(accessTokenDO); - } - @VisibleForTesting - void verifyCaptcha(AuthLoginReqVO reqVO) { + void validateCaptcha(AuthLoginReqVO reqVO) { // 如果验证码关闭,则不进行校验 if (!captchaEnable) { return; @@ -206,6 +200,12 @@ public class AdminAuthServiceImpl implements AdminAuthService { return AuthConvert.INSTANCE.convert(accessTokenDO); } + @Override + public AuthLoginRespVO refreshToken(String refreshToken) { + OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.refreshAccessToken(refreshToken, OAuth2ClientConstants.CLIENT_ID_DEFAULT); + return AuthConvert.INSTANCE.convert(accessTokenDO); + } + @Override public void logout(String token, Integer logType) { // 删除访问令牌 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index 1bb180011..50c78c8bd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -43,6 +43,7 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; /** * 后台用户 Service 实现类 + * * @author 芋道源码 */ @Service("adminUserService") diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java index dc607b7ce..16e48ec4a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java @@ -1,31 +1,43 @@ package cn.iocoder.yudao.module.system.service.auth; +import cn.hutool.core.util.ReflectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.framework.test.core.util.AssertUtils; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; +import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import cn.iocoder.yudao.module.system.service.logger.LoginLogService; import cn.iocoder.yudao.module.system.service.member.MemberService; import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService; import cn.iocoder.yudao.module.system.service.social.SocialUserService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; +import com.xingyuv.captcha.model.common.ResponseModel; import com.xingyuv.captcha.service.CaptchaService; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; +import javax.validation.ConstraintViolationException; +import javax.validation.Validation; import javax.validation.Validator; +import static cn.hutool.core.util.RandomUtil.randomEle; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @@ -42,17 +54,24 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { @MockBean private LoginLogService loginLogService; @MockBean - private SocialUserService socialService; + private SocialUserService socialUserService; @MockBean private SmsCodeApi smsCodeApi; @MockBean private OAuth2TokenService oauth2TokenService; @MockBean private MemberService memberService; - @MockBean private Validator validator; + @BeforeEach + public void setUp() { + ReflectUtil.setFieldValue(authService, "captchaEnable", true); + // 注入一个 Validator 对象 + ReflectUtil.setFieldValue(authService, "validator", + Validation.buildDefaultValidatorFactory().getValidator()); + } + @Test public void testAuthenticate_success() { // 准备参数 @@ -78,7 +97,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { String password = randomString(); // 调用, 并断言异常 - AssertUtils.assertServiceException(() -> authService.authenticate(username, password), + assertServiceException(() -> authService.authenticate(username, password), AUTH_LOGIN_BAD_CREDENTIALS); verify(loginLogService).createLoginLog( argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType()) @@ -98,7 +117,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { when(userService.getUserByUsername(eq(username))).thenReturn(user); // 调用, 并断言异常 - AssertUtils.assertServiceException(() -> authService.authenticate(username, password), + assertServiceException(() -> authService.authenticate(username, password), AUTH_LOGIN_BAD_CREDENTIALS); verify(loginLogService).createLoginLog( argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType()) @@ -120,7 +139,7 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { when(userService.isPasswordMatch(eq(password), eq(user.getPassword()))).thenReturn(true); // 调用, 并断言异常 - AssertUtils.assertServiceException(() -> authService.authenticate(username, password), + assertServiceException(() -> authService.authenticate(username, password), AUTH_LOGIN_USER_DISABLED); verify(loginLogService).createLoginLog( argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType()) @@ -129,82 +148,194 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { ); } -// @Test -// public void testCaptcha_success() { -// // 准备参数 -// AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class); -// -// // mock 验证码正确 -// when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode()); -// -// // 调用 -// authService.verifyCaptcha(reqVO); -// // 断言 -// verify(captchaService).deleteCaptchaCode(reqVO.getUuid()); -// } -// -// @Test -// public void testCaptcha_notFound() { -// // 准备参数 -// AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class); -// -// // 调用, 并断言异常 -// assertServiceException(() -> authService.verifyCaptcha(reqVO), AUTH_LOGIN_CAPTCHA_NOT_FOUND); -// // 校验调用参数 -// verify(loginLogService, times(1)).createLoginLog( -// argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType()) -// && o.getResult().equals(LoginResultEnum.CAPTCHA_NOT_FOUND.getResult())) -// ); -// } + @Test + public void testLogin_success() { + // 准备参数 + AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class, o -> + o.setUsername("test_username").setPassword("test_password") + .setSocialType(randomEle(SocialTypeEnum.values()).getType())); -// @Test -// public void testCaptcha_codeError() { -// // 准备参数 -// AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class); -// -// // mock 验证码不正确 -// String code = randomString(); -// when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(code); -// -// // 调用, 并断言异常 -// assertServiceException(() -> authService.verifyCaptcha(reqVO), AUTH_LOGIN_CAPTCHA_CODE_ERROR); -// // 校验调用参数 -// verify(loginLogService).createLoginLog( -// argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType()) -// && o.getResult().equals(LoginResultEnum.CAPTCHA_CODE_ERROR.getResult())) -// ); -// } + // mock 验证码正确 + ReflectUtil.setFieldValue(authService, "captchaEnable", false); + // mock user 数据 + AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(1L).setUsername("test_username") + .setPassword("test_password").setStatus(CommonStatusEnum.ENABLE.getStatus())); + when(userService.getUserByUsername(eq("test_username"))).thenReturn(user); + // mock password 匹配 + when(userService.isPasswordMatch(eq("test_password"), eq(user.getPassword()))).thenReturn(true); + // mock 缓存登录用户到 Redis + OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L) + .setUserType(UserTypeEnum.ADMIN.getValue())); + when(oauth2TokenService.createAccessToken(eq(1L), eq(UserTypeEnum.ADMIN.getValue()), eq("default"), isNull())) + .thenReturn(accessTokenDO); -// @Test -// public void testLogin_success() { -// // 准备参数 -// AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class, o -> -// o.setUsername("test_username").setPassword("test_password")); -// -// // mock 验证码正确 -// when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode()); -// // mock user 数据 -// AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(1L).setUsername("test_username") -// .setPassword("test_password").setStatus(CommonStatusEnum.ENABLE.getStatus())); -// when(userService.getUserByUsername(eq("test_username"))).thenReturn(user); -// // mock password 匹配 -// when(userService.isPasswordMatch(eq("test_password"), eq(user.getPassword()))).thenReturn(true); -// // mock 缓存登录用户到 Redis -// OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L) -// .setUserType(UserTypeEnum.ADMIN.getValue())); -// when(oauth2TokenService.createAccessToken(eq(1L), eq(UserTypeEnum.ADMIN.getValue()), eq("default"), isNull())) -// .thenReturn(accessTokenDO); -// -// // 调用, 并断言异常 -// AuthLoginRespVO loginRespVO = authService.login(reqVO); -// assertPojoEquals(accessTokenDO, loginRespVO); -// // 校验调用参数 -// verify(loginLogService).createLoginLog( -// argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType()) -// && o.getResult().equals(LoginResultEnum.SUCCESS.getResult()) -// && o.getUserId().equals(user.getId())) -// ); -// } + // 调用,并校验 + AuthLoginRespVO loginRespVO = authService.login(reqVO); + assertPojoEquals(accessTokenDO, loginRespVO); + // 校验调用参数 + verify(loginLogService).createLoginLog( + argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType()) + && o.getResult().equals(LoginResultEnum.SUCCESS.getResult()) + && o.getUserId().equals(user.getId())) + ); + verify(socialUserService).bindSocialUser(eq(new SocialUserBindReqDTO( + user.getId(), UserTypeEnum.ADMIN.getValue(), + reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState()))); + } + + @Test + public void testSendSmsCode() { + // 准备参数 + String mobile = randomString(); + Integer scene = randomEle(SmsSceneEnum.values()).getScene(); + AuthSmsSendReqVO reqVO = new AuthSmsSendReqVO(mobile, scene); + // mock 方法(用户信息) + AdminUserDO user = randomPojo(AdminUserDO.class); + when(userService.getUserByMobile(eq(mobile))).thenReturn(user); + + // 调用 + authService.sendSmsCode(reqVO); + // 断言 + verify(smsCodeApi).sendSmsCode(argThat(sendReqDTO -> { + assertEquals(mobile, sendReqDTO.getMobile()); + assertEquals(scene, sendReqDTO.getScene()); + return true; + })); + } + + @Test + public void testSmsLogin_success() { + // 准备参数 + String mobile = randomString(); + String scene = randomString(); + AuthSmsLoginReqVO reqVO = new AuthSmsLoginReqVO(mobile, scene); + // mock 方法(用户信息) + AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(1L)); + when(userService.getUserByMobile(eq(mobile))).thenReturn(user); + // mock 缓存登录用户到 Redis + OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L) + .setUserType(UserTypeEnum.ADMIN.getValue())); + when(oauth2TokenService.createAccessToken(eq(1L), eq(UserTypeEnum.ADMIN.getValue()), eq("default"), isNull())) + .thenReturn(accessTokenDO); + + // 调用,并断言 + AuthLoginRespVO loginRespVO = authService.smsLogin(reqVO); + assertPojoEquals(accessTokenDO, loginRespVO); + // 断言调用 + verify(loginLogService).createLoginLog( + argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_MOBILE.getType()) + && o.getResult().equals(LoginResultEnum.SUCCESS.getResult()) + && o.getUserId().equals(user.getId())) + ); + } + + @Test + public void testSocialLogin_success() { + // 准备参数 + AuthSocialLoginReqVO reqVO = randomPojo(AuthSocialLoginReqVO.class); + // mock 方法(绑定的用户编号) + Long userId = 1L; + when(socialUserService.getBindUserId(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()), + eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(userId); + // mock(用户) + AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId)); + when(userService.getUser(eq(userId))).thenReturn(user); + // mock 缓存登录用户到 Redis + OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L) + .setUserType(UserTypeEnum.ADMIN.getValue())); + when(oauth2TokenService.createAccessToken(eq(1L), eq(UserTypeEnum.ADMIN.getValue()), eq("default"), isNull())) + .thenReturn(accessTokenDO); + + // 调用,并断言 + AuthLoginRespVO loginRespVO = authService.socialLogin(reqVO); + assertPojoEquals(accessTokenDO, loginRespVO); + // 断言调用 + verify(loginLogService).createLoginLog( + argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_SOCIAL.getType()) + && o.getResult().equals(LoginResultEnum.SUCCESS.getResult()) + && o.getUserId().equals(user.getId())) + ); + } + + @Test + public void testValidateCaptcha_successWithEnable() { + // 准备参数 + AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class); + + // mock 验证码打开 + ReflectUtil.setFieldValue(authService, "captchaEnable", true); + // mock 验证通过 + when(captchaService.verification(argThat(captchaVO -> { + assertEquals(reqVO.getCaptchaVerification(), captchaVO.getCaptchaVerification()); + return true; + }))).thenReturn(ResponseModel.success()); + + // 调用,无需断言 + authService.validateCaptcha(reqVO); + } + + @Test + public void testValidateCaptcha_successWithDisable() { + // 准备参数 + AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class); + + // mock 验证码关闭 + ReflectUtil.setFieldValue(authService, "captchaEnable", false); + + // 调用,无需断言 + authService.validateCaptcha(reqVO); + } + + @Test + public void testValidateCaptcha_constraintViolationException() { + // 准备参数 + AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class).setCaptchaVerification(null); + + // mock 验证码打开 + ReflectUtil.setFieldValue(authService, "captchaEnable", true); + + // 调用,并断言异常 + assertThrows(ConstraintViolationException.class, () -> authService.validateCaptcha(reqVO), + "验证码不能为空"); + } + + + @Test + public void testCaptcha_fail() { + // 准备参数 + AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class); + + // mock 验证码打开 + ReflectUtil.setFieldValue(authService, "captchaEnable", true); + // mock 验证通过 + when(captchaService.verification(argThat(captchaVO -> { + assertEquals(reqVO.getCaptchaVerification(), captchaVO.getCaptchaVerification()); + return true; + }))).thenReturn(ResponseModel.errorMsg("就是不对")); + + // 调用, 并断言异常 + assertServiceException(() -> authService.validateCaptcha(reqVO), AUTH_LOGIN_CAPTCHA_CODE_ERROR, "就是不对"); + // 校验调用参数 + verify(loginLogService).createLoginLog( + argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType()) + && o.getResult().equals(LoginResultEnum.CAPTCHA_CODE_ERROR.getResult())) + ); + } + + @Test + public void testRefreshToken() { + // 准备参数 + String refreshToken = randomString(); + // mock 方法 + OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class); + when(oauth2TokenService.refreshAccessToken(eq(refreshToken), eq("default"))) + .thenReturn(accessTokenDO); + + // 调用 + AuthLoginRespVO loginRespVO = authService.refreshToken(refreshToken); + // 断言 + assertPojoEquals(accessTokenDO, loginRespVO); + } @Test public void testLogout_success() { @@ -221,6 +352,8 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { verify(loginLogService).createLoginLog(argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGOUT_SELF.getType()) && o.getResult().equals(LoginResultEnum.SUCCESS.getResult())) ); + // 调用,并校验 + } @Test From 1011de327868cf81e8c40bbee7b591dd559cb2f0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 1 Feb 2023 00:07:34 +0800 Subject: [PATCH 25/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20DeptServiceImpl=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BpmTaskAssignRuleServiceImpl.java | 4 +- .../yudao/module/system/api/dept/DeptApi.java | 6 +- .../module/system/api/dept/DeptApiImpl.java | 8 +- .../controller/admin/dept/DeptController.java | 4 +- .../system/service/dept/DeptService.java | 43 ++--- .../system/service/dept/DeptServiceImpl.java | 60 +++--- .../permission/PermissionServiceImpl.java | 2 +- .../service/user/AdminUserServiceImpl.java | 4 +- ...viceTest.java => DeptServiceImplTest.java} | 173 +++++++++++++----- .../permission/PermissionServiceTest.java | 2 +- .../user/AdminUserServiceImplTest.java | 6 +- 11 files changed, 186 insertions(+), 126 deletions(-) rename yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/{DeptServiceTest.java => DeptServiceImplTest.java} (69%) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index 49bfdac4e..d15e1b6a1 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -216,7 +216,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { roleApi.validRoles(options); } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) { - deptApi.validDepts(options); + deptApi.validateDeptList(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) { postApi.validPosts(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER.getType())) { @@ -293,7 +293,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { } private Set calculateTaskCandidateUsersByDeptLeader(BpmTaskAssignRuleDO rule) { - List depts = deptApi.getDepts(rule.getOptions()); + List depts = deptApi.getDeptList(rule.getOptions()); return convertSet(depts, DeptRespDTO::getLeaderUserId); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java index c9b456b90..c3d143e46 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApi.java @@ -29,7 +29,7 @@ public interface DeptApi { * @param ids 部门编号数组 * @return 部门信息数组 */ - List getDepts(Collection ids); + List getDeptList(Collection ids); /** * 校验部门们是否有效。如下情况,视为无效: @@ -38,7 +38,7 @@ public interface DeptApi { * * @param ids 角色编号数组 */ - void validDepts(Collection ids); + void validateDeptList(Collection ids); /** * 获得指定编号的部门 Map @@ -47,7 +47,7 @@ public interface DeptApi { * @return 部门 Map */ default Map getDeptMap(Set ids) { - List list = getDepts(ids); + List list = getDeptList(ids); return CollectionUtils.convertMap(list, DeptRespDTO::getId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java index 5721030bb..c1676ca53 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java @@ -28,14 +28,14 @@ public class DeptApiImpl implements DeptApi { } @Override - public List getDepts(Collection ids) { - List depts = deptService.getDepts(ids); + public List getDeptList(Collection ids) { + List depts = deptService.getDeptList(ids); return DeptConvert.INSTANCE.convertList03(depts); } @Override - public void validDepts(Collection ids) { - deptService.validDepts(ids); + public void validateDeptList(Collection ids) { + deptService.validateDeptList(ids); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java index 0a292e243..f60415cee 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java @@ -58,7 +58,7 @@ public class DeptController { @ApiOperation("获取部门列表") @PreAuthorize("@ss.hasPermission('system:dept:query')") public CommonResult> listDepts(DeptListReqVO reqVO) { - List list = deptService.getSimpleDepts(reqVO); + List list = deptService.getDeptList(reqVO); list.sort(Comparator.comparing(DeptDO::getSort)); return success(DeptConvert.INSTANCE.convertList(list)); } @@ -69,7 +69,7 @@ public class DeptController { // 获得部门列表,只要开启状态的 DeptListReqVO reqVO = new DeptListReqVO(); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - List list = deptService.getSimpleDepts(reqVO); + List list = deptService.getDeptList(reqVO); // 排序后,返回给前端 list.sort(Comparator.comparing(DeptDO::getSort)); return success(DeptConvert.INSTANCE.convertList02(list)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptService.java index a6c30bc10..87033d4b3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptService.java @@ -52,7 +52,7 @@ public interface DeptService { * @param reqVO 筛选条件请求 VO * @return 部门列表 */ - List getSimpleDepts(DeptListReqVO reqVO); + List getDeptList(DeptListReqVO reqVO); /** * 获得所有子部门,从缓存中 @@ -61,7 +61,7 @@ public interface DeptService { * @param recursive 是否递归获取所有 * @return 子部门列表 */ - List getDeptsByParentIdFromCache(Long parentId, boolean recursive); + List getDeptListByParentIdFromCache(Long parentId, boolean recursive); /** * 获得部门信息数组 @@ -69,7 +69,21 @@ public interface DeptService { * @param ids 部门编号数组 * @return 部门信息数组 */ - List getDepts(Collection ids); + List getDeptList(Collection ids); + + /** + * 获得指定编号的部门 Map + * + * @param ids 部门编号数组 + * @return 部门 Map + */ + default Map getDeptMap(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyMap(); + } + List list = getDeptList(ids); + return CollectionUtils.convertMap(list, DeptDO::getId); + } /** * 获得部门信息 @@ -86,27 +100,6 @@ public interface DeptService { * * @param ids 角色编号数组 */ - void validDepts(Collection ids); + void validateDeptList(Collection ids); - /** - * 获得指定编号的部门列表 - * - * @param ids 部门编号数组 - * @return 部门列表 - */ - List getSimpleDepts(Collection ids); - - /** - * 获得指定编号的部门 Map - * - * @param ids 部门编号数组 - * @return 部门 Map - */ - default Map getDeptMap(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return Collections.emptyMap(); - } - List list = getSimpleDepts(ids); - return CollectionUtils.convertMap(list, DeptDO::getId); - } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java index 6262eaf70..24a93cdf6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java @@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.system.service.dept; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptCreateReqVO; @@ -19,13 +17,11 @@ import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.PostConstruct; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -95,7 +91,7 @@ public class DeptServiceImpl implements DeptService { if (reqVO.getParentId() == null) { reqVO.setParentId(DeptIdEnum.ROOT.getId()); } - checkCreateOrUpdate(null, reqVO.getParentId(), reqVO.getName()); + validateForCreateOrUpdate(null, reqVO.getParentId(), reqVO.getName()); // 插入部门 DeptDO dept = DeptConvert.INSTANCE.convert(reqVO); deptMapper.insert(dept); @@ -110,7 +106,7 @@ public class DeptServiceImpl implements DeptService { if (reqVO.getParentId() == null) { reqVO.setParentId(DeptIdEnum.ROOT.getId()); } - checkCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName()); + validateForCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName()); // 更新部门 DeptDO updateObj = DeptConvert.INSTANCE.convert(reqVO); deptMapper.updateById(updateObj); @@ -121,10 +117,10 @@ public class DeptServiceImpl implements DeptService { @Override public void deleteDept(Long id) { // 校验是否存在 - checkDeptExists(id); + validateDeptExists(id); // 校验是否有子部门 if (deptMapper.selectCountByParentId(id) > 0) { - throw ServiceExceptionUtil.exception(DEPT_EXITS_CHILDREN); + throw exception(DEPT_EXITS_CHILDREN); } // 删除部门 deptMapper.deleteById(id); @@ -133,16 +129,16 @@ public class DeptServiceImpl implements DeptService { } @Override - public List getSimpleDepts(DeptListReqVO reqVO) { + public List getDeptList(DeptListReqVO reqVO) { return deptMapper.selectList(reqVO); } @Override - public List getDeptsByParentIdFromCache(Long parentId, boolean recursive) { + public List getDeptListByParentIdFromCache(Long parentId, boolean recursive) { if (parentId == null) { return Collections.emptyList(); } - List result = new ArrayList<>(); // TODO 芋艿:待优化,新增缓存,避免每次遍历的计算 + List result = new ArrayList<>(); // 递归,简单粗暴 this.getDeptsByParentIdFromCache(result, parentId, recursive ? Integer.MAX_VALUE : 1, // 如果递归获取,则无限;否则,只递归 1 次 @@ -182,65 +178,65 @@ public class DeptServiceImpl implements DeptService { recursiveCount - 1, parentDeptMap)); } - private void checkCreateOrUpdate(Long id, Long parentId, String name) { + private void validateForCreateOrUpdate(Long id, Long parentId, String name) { // 校验自己存在 - checkDeptExists(id); + validateDeptExists(id); // 校验父部门的有效性 - checkParentDeptEnable(id, parentId); + validateParentDeptEnable(id, parentId); // 校验部门名的唯一性 - checkDeptNameUnique(id, parentId, name); + validateDeptNameUnique(id, parentId, name); } - private void checkParentDeptEnable(Long id, Long parentId) { + private void validateParentDeptEnable(Long id, Long parentId) { if (parentId == null || DeptIdEnum.ROOT.getId().equals(parentId)) { return; } // 不能设置自己为父部门 if (parentId.equals(id)) { - throw ServiceExceptionUtil.exception(DEPT_PARENT_ERROR); + throw exception(DEPT_PARENT_ERROR); } // 父岗位不存在 DeptDO dept = deptMapper.selectById(parentId); if (dept == null) { - throw ServiceExceptionUtil.exception(DEPT_PARENT_NOT_EXITS); + throw exception(DEPT_PARENT_NOT_EXITS); } // 父部门被禁用 if (!CommonStatusEnum.ENABLE.getStatus().equals(dept.getStatus())) { - throw ServiceExceptionUtil.exception(DEPT_NOT_ENABLE); + throw exception(DEPT_NOT_ENABLE); } // 父部门不能是原来的子部门 - List children = this.getDeptsByParentIdFromCache(id, true); + List children = this.getDeptListByParentIdFromCache(id, true); if (children.stream().anyMatch(dept1 -> dept1.getId().equals(parentId))) { - throw ServiceExceptionUtil.exception(DEPT_PARENT_IS_CHILD); + throw exception(DEPT_PARENT_IS_CHILD); } } - private void checkDeptExists(Long id) { + private void validateDeptExists(Long id) { if (id == null) { return; } DeptDO dept = deptMapper.selectById(id); if (dept == null) { - throw ServiceExceptionUtil.exception(DEPT_NOT_FOUND); + throw exception(DEPT_NOT_FOUND); } } - private void checkDeptNameUnique(Long id, Long parentId, String name) { + private void validateDeptNameUnique(Long id, Long parentId, String name) { DeptDO menu = deptMapper.selectByParentIdAndName(parentId, name); if (menu == null) { return; } // 如果 id 为空,说明不用比较是否为相同 id 的岗位 if (id == null) { - throw ServiceExceptionUtil.exception(DEPT_NAME_DUPLICATE); + throw exception(DEPT_NAME_DUPLICATE); } if (!menu.getId().equals(id)) { - throw ServiceExceptionUtil.exception(DEPT_NAME_DUPLICATE); + throw exception(DEPT_NAME_DUPLICATE); } } @Override - public List getDepts(Collection ids) { + public List getDeptList(Collection ids) { return deptMapper.selectBatchIds(ids); } @@ -250,13 +246,12 @@ public class DeptServiceImpl implements DeptService { } @Override - public void validDepts(Collection ids) { + public void validateDeptList(Collection ids) { if (CollUtil.isEmpty(ids)) { return; } // 获得科室信息 - List depts = deptMapper.selectBatchIds(ids); - Map deptMap = CollectionUtils.convertMap(depts, DeptDO::getId); + Map deptMap = getDeptMap(ids); // 校验 ids.forEach(id -> { DeptDO dept = deptMap.get(id); @@ -269,9 +264,4 @@ public class DeptServiceImpl implements DeptService { }); } - @Override - public List getSimpleDepts(Collection ids) { - return deptMapper.selectBatchIds(ids); - } - } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java index c40a8e31c..59ab61e79 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java @@ -418,7 +418,7 @@ public class PermissionServiceImpl implements PermissionService { } // 情况四,DEPT_DEPT_AND_CHILD if (Objects.equals(role.getDataScope(), DataScopeEnum.DEPT_AND_CHILD.getScope())) { - List depts = deptService.getDeptsByParentIdFromCache(userDeptIdCache.get(), true); + List depts = deptService.getDeptListByParentIdFromCache(userDeptIdCache.get(), true); CollUtil.addAll(result.getDeptIds(), CollectionUtils.convertList(depts, DeptDO::getId)); // 添加本身部门编号 CollUtil.addAll(result.getDeptIds(), userDeptIdCache.get()); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index 50c78c8bd..ef6f9757c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -299,7 +299,7 @@ public class AdminUserServiceImpl implements AdminUserService { if (deptId == null) { return Collections.emptySet(); } - Set deptIds = convertSet(deptService.getDeptsByParentIdFromCache( + Set deptIds = convertSet(deptService.getDeptListByParentIdFromCache( deptId, true), DeptDO::getId); deptIds.add(deptId); // 包括自身 return deptIds; @@ -317,7 +317,7 @@ public class AdminUserServiceImpl implements AdminUserService { // 校验邮箱唯一 checkEmailUnique(id, email); // 校验部门处于开启状态 - deptService.validDepts(CollectionUtils.singleton(deptId)); + deptService.validateDeptList(CollectionUtils.singleton(deptId)); // 校验岗位处于开启状态 postService.validPosts(postIds); } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImplTest.java similarity index 69% rename from yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java rename to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImplTest.java index 6b4ff1028..593c2cb04 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImplTest.java @@ -19,6 +19,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -28,8 +29,8 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; /** @@ -38,7 +39,7 @@ import static org.mockito.Mockito.verify; * @author niudehua */ @Import(DeptServiceImpl.class) -public class DeptServiceTest extends BaseDbUnitTest { +public class DeptServiceImplTest extends BaseDbUnitTest { @Resource private DeptServiceImpl deptService; @@ -76,7 +77,7 @@ public class DeptServiceTest extends BaseDbUnitTest { } @Test - void testListDepts() { + public void testListDepts() { // mock 数据 DeptDO dept = randomPojo(DeptDO.class, o -> { // 等会查询到 o.setName("开发部"); @@ -91,21 +92,22 @@ public class DeptServiceTest extends BaseDbUnitTest { DeptListReqVO reqVO = new DeptListReqVO(); reqVO.setName("开"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + // 调用 - List sysDeptDOS = deptService.getSimpleDepts(reqVO); + List sysDeptDOS = deptService.getDeptList(reqVO); // 断言 assertEquals(1, sysDeptDOS.size()); assertPojoEquals(dept, sysDeptDOS.get(0)); } @Test - void testCreateDept_success() { + public void testCreateDept_success() { // 准备参数 - DeptCreateReqVO reqVO = randomPojo(DeptCreateReqVO.class, - o -> { - o.setParentId(DeptIdEnum.ROOT.getId()); - o.setStatus(randomCommonStatus()); - }); + DeptCreateReqVO reqVO = randomPojo(DeptCreateReqVO.class, o -> { + o.setParentId(DeptIdEnum.ROOT.getId()); + o.setStatus(randomCommonStatus()); + }); + // 调用 Long deptId = deptService.createDept(reqVO); // 断言 @@ -114,11 +116,11 @@ public class DeptServiceTest extends BaseDbUnitTest { DeptDO deptDO = deptMapper.selectById(deptId); assertPojoEquals(reqVO, deptDO); // 校验调用 - verify(deptProducer, times(1)).sendDeptRefreshMessage(); + verify(deptProducer).sendDeptRefreshMessage(); } @Test - void testUpdateDept_success() { + public void testUpdateDept_success() { // mock 数据 DeptDO dbDeptDO = randomPojo(DeptDO.class, o -> o.setStatus(randomCommonStatus())); deptMapper.insert(dbDeptDO);// @Sql: 先插入出一条存在的数据 @@ -129,28 +131,34 @@ public class DeptServiceTest extends BaseDbUnitTest { o.setId(dbDeptDO.getId()); o.setStatus(randomCommonStatus()); }); + // 调用 deptService.updateDept(reqVO); // 校验是否更新正确 DeptDO deptDO = deptMapper.selectById(reqVO.getId()); // 获取最新的 assertPojoEquals(reqVO, deptDO); + // 校验调用 + verify(deptProducer).sendDeptRefreshMessage(); } @Test - void testDeleteDept_success() { + public void testDeleteDept_success() { // mock 数据 DeptDO dbDeptDO = randomPojo(DeptDO.class, o -> o.setStatus(randomCommonStatus())); deptMapper.insert(dbDeptDO);// @Sql: 先插入出一条存在的数据 // 准备参数 Long id = dbDeptDO.getId(); + // 调用 deptService.deleteDept(id); // 校验数据不存在了 assertNull(deptMapper.selectById(id)); + // 校验调用 + verify(deptProducer).sendDeptRefreshMessage(); } @Test - void testCheckDept_nameDuplicateForUpdate() { + public void testValidateDept_nameDuplicateForUpdate() { // mock 数据 DeptDO deptDO = randomDeptDO(); // 设置根节点部门 @@ -162,37 +170,40 @@ public class DeptServiceTest extends BaseDbUnitTest { nameDeptDO.setParentId(DeptIdEnum.ROOT.getId()); deptMapper.insert(nameDeptDO); // 准备参数 - DeptUpdateReqVO reqVO = randomPojo(DeptUpdateReqVO.class, - o -> { - // 设置根节点部门 - o.setParentId(DeptIdEnum.ROOT.getId()); - // 设置更新的 ID - o.setId(deptDO.getId()); - // 模拟 name 重复 - o.setName(nameDeptDO.getName()); - }); + DeptUpdateReqVO reqVO = randomPojo(DeptUpdateReqVO.class, o -> { + // 设置根节点部门 + o.setParentId(DeptIdEnum.ROOT.getId()); + // 设置更新的 ID + o.setId(deptDO.getId()); + // 模拟 name 重复 + o.setName(nameDeptDO.getName()); + }); + // 调用, 并断言异常 assertServiceException(() -> deptService.updateDept(reqVO), DEPT_NAME_DUPLICATE); } @Test - void testCheckDept_parentNotExitsForCreate() { + public void testValidateDept_parentNotExitsForCreate() { + // 准备参数 DeptCreateReqVO reqVO = randomPojo(DeptCreateReqVO.class, o -> o.setStatus(randomCommonStatus())); + // 调用,并断言异常 assertServiceException(() -> deptService.createDept(reqVO), DEPT_PARENT_NOT_EXITS); } @Test - void testCheckDept_notFoundForDelete() { + public void testValidateDept_notFoundForDelete() { // 准备参数 Long id = randomLongId(); + // 调用, 并断言异常 assertServiceException(() -> deptService.deleteDept(id), DEPT_NOT_FOUND); } @Test - void testCheckDept_exitsChildrenForDelete() { + public void testValidateDept_exitsChildrenForDelete() { // mock 数据 DeptDO parentDept = randomPojo(DeptDO.class, o -> o.setStatus(randomCommonStatus())); deptMapper.insert(parentDept);// @Sql: 先插入出一条存在的数据 @@ -208,39 +219,39 @@ public class DeptServiceTest extends BaseDbUnitTest { } @Test - void testCheckDept_parentErrorForUpdate() { + public void testValidateDept_parentErrorForUpdate() { // mock 数据 DeptDO dbDeptDO = randomPojo(DeptDO.class, o -> o.setStatus(randomCommonStatus())); deptMapper.insert(dbDeptDO); // 准备参数 - DeptUpdateReqVO reqVO = randomPojo(DeptUpdateReqVO.class, - o -> { - // 设置自己为父部门 - o.setParentId(dbDeptDO.getId()); - // 设置更新的 ID - o.setId(dbDeptDO.getId()); - }); + DeptUpdateReqVO reqVO = randomPojo(DeptUpdateReqVO.class, o -> { + // 设置自己为父部门 + o.setParentId(dbDeptDO.getId()); + // 设置更新的 ID + o.setId(dbDeptDO.getId()); + }); + // 调用, 并断言异常 assertServiceException(() -> deptService.updateDept(reqVO), DEPT_PARENT_ERROR); } @Test - void testCheckDept_notEnableForCreate() { + public void testValidateDept_notEnableForCreate() { // mock 数据 DeptDO deptDO = randomPojo(DeptDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())); deptMapper.insert(deptDO); // 准备参数 - DeptCreateReqVO reqVO = randomPojo(DeptCreateReqVO.class, - o -> { - // 设置未启用的部门为副部门 - o.setParentId(deptDO.getId()); - }); + DeptCreateReqVO reqVO = randomPojo(DeptCreateReqVO.class, o -> { + // 设置未启用的部门为父部门 + o.setParentId(deptDO.getId()); + }); + // 调用, 并断言异常 assertServiceException(() -> deptService.createDept(reqVO), DEPT_NOT_ENABLE); } @Test - void testCheckDept_parentIsChildForUpdate() { + public void testCheckDept_parentIsChildForUpdate() { // mock 数据 DeptDO parentDept = randomPojo(DeptDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); deptMapper.insert(parentDept); @@ -251,18 +262,84 @@ public class DeptServiceTest extends BaseDbUnitTest { deptMapper.insert(childDept); // 初始化本地缓存 deptService.initLocalCache(); + // 准备参数 - DeptUpdateReqVO reqVO = randomPojo(DeptUpdateReqVO.class, - o -> { - // 设置自己的子部门为父部门 - o.setParentId(childDept.getId()); - // 设置更新的 ID - o.setId(parentDept.getId()); - }); + DeptUpdateReqVO reqVO = randomPojo(DeptUpdateReqVO.class, o -> { + // 设置自己的子部门为父部门 + o.setParentId(childDept.getId()); + // 设置更新的 ID + o.setId(parentDept.getId()); + }); + // 调用, 并断言异常 assertServiceException(() -> deptService.updateDept(reqVO), DEPT_PARENT_IS_CHILD); } + @Test + public void testGetDeptList() { + // mock 数据 + DeptDO deptDO01 = randomDeptDO(); + deptMapper.insert(deptDO01); + DeptDO deptDO02 = randomDeptDO(); + deptMapper.insert(deptDO02); + // 准备参数 + List ids = Arrays.asList(deptDO01.getId(), deptDO02.getId()); + + // 调用 + List deptDOList = deptService.getDeptList(ids); + // 断言 + assertEquals(2, deptDOList.size()); + assertEquals(deptDO01, deptDOList.get(0)); + assertEquals(deptDO02, deptDOList.get(1)); + } + + @Test + public void testGetDept() { + // mock 数据 + DeptDO deptDO = randomDeptDO(); + deptMapper.insert(deptDO); + // 准备参数 + Long id = deptDO.getId(); + + // 调用 + DeptDO dbDept = deptService.getDept(id); + // 断言 + assertEquals(deptDO, dbDept); + } + + @Test + public void testValidateDeptList_success() { + // mock 数据 + DeptDO deptDO = randomDeptDO().setStatus(CommonStatusEnum.ENABLE.getStatus()); + deptMapper.insert(deptDO); + // 准备参数 + List ids = singletonList(deptDO.getId()); + + // 调用,无需断言 + deptService.validateDeptList(ids); + } + + @Test + public void testValidateDeptList_notFound() { + // 准备参数 + List ids = singletonList(randomLongId()); + + // 调用, 并断言异常 + assertServiceException(() -> deptService.validateDeptList(ids), DEPT_NOT_FOUND); + } + + @Test + public void testValidateDeptList_notEnable() { + // mock 数据 + DeptDO deptDO = randomDeptDO().setStatus(CommonStatusEnum.DISABLE.getStatus()); + deptMapper.insert(deptDO); + // 准备参数 + List ids = singletonList(deptDO.getId()); + + // 调用, 并断言异常 + assertServiceException(() -> deptService.validateDeptList(ids), DEPT_NOT_ENABLE); + } + @SafeVarargs private static DeptDO randomDeptDO(Consumer... consumers) { Consumer consumer = (o) -> { diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java index afc4c0ced..93e521beb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java @@ -509,7 +509,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L), null, null); // 最后返回 null 的目的,看看会不会重复调用 // mock 方法(部门) DeptDO deptDO = randomPojo(DeptDO.class); - when(deptService.getDeptsByParentIdFromCache(eq(3L), eq(true))) + when(deptService.getDeptListByParentIdFromCache(eq(3L), eq(true))) .thenReturn(singletonList(deptDO)); // 调用 diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java index 2822789e3..c78efcc72 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java @@ -299,7 +299,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { reqVO.setDeptId(1L); // 其中,1L 是 2L 的父部门 // mock 方法 List deptList = newArrayList(randomPojo(DeptDO.class, o -> o.setId(2L))); - when(deptService.getDeptsByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList); + when(deptService.getDeptListByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList); // 调用 PageResult pageResult = userService.getUserPage(reqVO); @@ -322,7 +322,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { reqVO.setDeptId(1L); // 其中,1L 是 2L 的父部门 // mock 方法 List deptList = newArrayList(randomPojo(DeptDO.class, o -> o.setId(2L))); - when(deptService.getDeptsByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList); + when(deptService.getDeptListByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList); // 调用 List list = userService.getUsers(reqVO); @@ -366,7 +366,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> { }); // mock 方法,模拟失败 - doThrow(new ServiceException(DEPT_NOT_FOUND)).when(deptService).validDepts(any()); + doThrow(new ServiceException(DEPT_NOT_FOUND)).when(deptService).validateDeptList(any()); // 调用 UserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true); From bef06ef940394574a96be525d09fa1a2fcd1af46 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 1 Feb 2023 00:42:38 +0800 Subject: [PATCH 26/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20PostServiceImpl=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BpmTaskAssignRuleServiceImpl.java | 2 +- .../yudao/module/system/api/dept/PostApi.java | 2 +- .../system/enums/ErrorCodeConstants.java | 2 +- .../module/system/api/dept/PostApiImpl.java | 5 +- .../controller/admin/dept/PostController.java | 4 +- .../admin/oauth2/OAuth2UserController.java | 2 +- .../admin/user/UserProfileController.java | 2 +- .../system/service/dept/PostService.java | 10 +- .../system/service/dept/PostServiceImpl.java | 108 ++++----- .../service/user/AdminUserServiceImpl.java | 2 +- .../service/dept/DeptServiceImplTest.java | 2 +- ...viceTest.java => PostServiceImplTest.java} | 228 +++++++++++------- .../user/AdminUserServiceImplTest.java | 4 +- 13 files changed, 217 insertions(+), 156 deletions(-) rename yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/{PostServiceTest.java => PostServiceImplTest.java} (61%) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index d15e1b6a1..bc8cd3151 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -218,7 +218,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) { deptApi.validateDeptList(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) { - postApi.validPosts(options); + postApi.validPostList(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER.getType())) { adminUserApi.validUsers(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_GROUP.getType())) { diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/PostApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/PostApi.java index d1e3d47a1..57db07cc2 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/PostApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dept/PostApi.java @@ -16,6 +16,6 @@ public interface PostApi { * * @param ids 岗位编号数组 */ - void validPosts(Collection ids); + void validPostList(Collection ids); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index e5e416d0e..bb8567c94 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -50,7 +50,7 @@ public interface ErrorCodeConstants { ErrorCode DEPT_EXITS_CHILDREN = new ErrorCode(1002004003, "存在子部门,无法删除"); ErrorCode DEPT_PARENT_ERROR = new ErrorCode(1002004004, "不能设置自己为父部门"); ErrorCode DEPT_EXISTS_USER = new ErrorCode(1002004005, "部门中存在员工,无法删除"); - ErrorCode DEPT_NOT_ENABLE = new ErrorCode(1002004006, "部门不处于开启状态,不允许选择"); + ErrorCode DEPT_NOT_ENABLE = new ErrorCode(1002004006, "部门({})不处于开启状态,不允许选择"); ErrorCode DEPT_PARENT_IS_CHILD = new ErrorCode(1002004007, "不能设置自己的子部门为父部门"); // ========== 岗位模块 1002005000 ========== diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/PostApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/PostApiImpl.java index 9454193e7..3d8cdf997 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/PostApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dept/PostApiImpl.java @@ -18,7 +18,8 @@ public class PostApiImpl implements PostApi { private PostService postService; @Override - public void validPosts(Collection ids) { - postService.validPosts(ids); + public void validPostList(Collection ids) { + postService.validatePostList(ids); } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java index 5275dc0c4..52fa8edb2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java @@ -72,7 +72,7 @@ public class PostController { @ApiOperation(value = "获取岗位精简信息列表", notes = "只包含被开启的岗位,主要用于前端的下拉选项") public CommonResult> getSimplePosts() { // 获得岗位列表,只要开启状态的 - List list = postService.getPosts(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus())); + List list = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus())); // 排序后,返回给前端 list.sort(Comparator.comparing(PostDO::getSort)); return success(PostConvert.INSTANCE.convertList02(list)); @@ -90,7 +90,7 @@ public class PostController { @PreAuthorize("@ss.hasPermission('system:post:export')") @OperateLog(type = EXPORT) public void export(HttpServletResponse response, @Validated PostExportReqVO reqVO) throws IOException { - List posts = postService.getPosts(reqVO); + List posts = postService.getPostList(reqVO); List data = PostConvert.INSTANCE.convertList03(posts); // 输出 ExcelUtils.write(response, "岗位数据.xls", "岗位列表", PostExcelVO.class, data); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java index 39b6125ab..b31ea671c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2UserController.java @@ -61,7 +61,7 @@ public class OAuth2UserController { } // 获得岗位信息 if (CollUtil.isNotEmpty(user.getPostIds())) { - List posts = postService.getPosts(user.getPostIds()); + List posts = postService.getPostList(user.getPostIds()); resp.setPosts(OAuth2UserConvert.INSTANCE.convertList(posts)); } return success(resp); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java index d65994379..00ca373e2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java @@ -72,7 +72,7 @@ public class UserProfileController { } // 获得岗位信息 if (CollUtil.isNotEmpty(user.getPostIds())) { - List posts = postService.getPosts(user.getPostIds()); + List posts = postService.getPostList(user.getPostIds()); resp.setPosts(UserConvert.INSTANCE.convertList02(posts)); } // 获得社交用户信息 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostService.java index fc74c944a..c1b84c011 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostService.java @@ -49,8 +49,8 @@ public interface PostService { * @param ids 岗位编号数组。如果为空,不进行筛选 * @return 部门列表 */ - default List getPosts(@Nullable Collection ids) { - return getPosts(ids, asSet(CommonStatusEnum.ENABLE.getStatus(), CommonStatusEnum.DISABLE.getStatus())); + default List getPostList(@Nullable Collection ids) { + return getPostList(ids, asSet(CommonStatusEnum.ENABLE.getStatus(), CommonStatusEnum.DISABLE.getStatus())); } /** @@ -60,7 +60,7 @@ public interface PostService { * @param statuses 状态数组。如果为空,不进行筛选 * @return 部门列表 */ - List getPosts(@Nullable Collection ids, @Nullable Collection statuses); + List getPostList(@Nullable Collection ids, @Nullable Collection statuses); /** * 获得岗位分页列表 @@ -76,7 +76,7 @@ public interface PostService { * @param reqVO 查询条件 * @return 部门列表 */ - List getPosts(PostExportReqVO reqVO); + List getPostList(PostExportReqVO reqVO); /** * 获得岗位信息 @@ -93,6 +93,6 @@ public interface PostService { * * @param ids 岗位编号数组 */ - void validPosts(Collection ids); + void validatePostList(Collection ids); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java index 81e003152..3266a0c92 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.system.service.dept; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostExportReqVO; @@ -38,7 +37,8 @@ public class PostServiceImpl implements PostService { @Override public Long createPost(PostCreateReqVO reqVO) { // 校验正确性 - this.checkCreateOrUpdate(null, reqVO.getName(), reqVO.getCode()); + validatePostForCreateOrUpdate(null, reqVO.getName(), reqVO.getCode()); + // 插入岗位 PostDO post = PostConvert.INSTANCE.convert(reqVO); postMapper.insert(post); @@ -48,7 +48,8 @@ public class PostServiceImpl implements PostService { @Override public void updatePost(PostUpdateReqVO reqVO) { // 校验正确性 - this.checkCreateOrUpdate(reqVO.getId(), reqVO.getName(), reqVO.getCode()); + validatePostForCreateOrUpdate(reqVO.getId(), reqVO.getName(), reqVO.getCode()); + // 更新岗位 PostDO updateObj = PostConvert.INSTANCE.convert(reqVO); postMapper.updateById(updateObj); @@ -57,13 +58,59 @@ public class PostServiceImpl implements PostService { @Override public void deletePost(Long id) { // 校验是否存在 - this.checkPostExists(id); + validatePostExists(id); // 删除部门 postMapper.deleteById(id); } + private void validatePostForCreateOrUpdate(Long id, String name, String code) { + // 校验自己存在 + validatePostExists(id); + // 校验岗位名的唯一性 + validatePostNameUnique(id, name); + // 校验岗位编码的唯一性 + validatePostCodeUnique(id, code); + } + + private void validatePostNameUnique(Long id, String name) { + PostDO post = postMapper.selectByName(name); + if (post == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的岗位 + if (id == null) { + throw exception(POST_NAME_DUPLICATE); + } + if (!post.getId().equals(id)) { + throw exception(POST_NAME_DUPLICATE); + } + } + + private void validatePostCodeUnique(Long id, String code) { + PostDO post = postMapper.selectByCode(code); + if (post == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的岗位 + if (id == null) { + throw exception(POST_CODE_DUPLICATE); + } + if (!post.getId().equals(id)) { + throw exception(POST_CODE_DUPLICATE); + } + } + + private void validatePostExists(Long id) { + if (id == null) { + return; + } + if (postMapper.selectById(id) == null) { + throw exception(POST_NOT_FOUND); + } + } + @Override - public List getPosts(Collection ids, Collection statuses) { + public List getPostList(Collection ids, Collection statuses) { return postMapper.selectList(ids, statuses); } @@ -73,7 +120,7 @@ public class PostServiceImpl implements PostService { } @Override - public List getPosts(PostExportReqVO reqVO) { + public List getPostList(PostExportReqVO reqVO) { return postMapper.selectList(reqVO); } @@ -82,55 +129,8 @@ public class PostServiceImpl implements PostService { return postMapper.selectById(id); } - private void checkCreateOrUpdate(Long id, String name, String code) { - // 校验自己存在 - checkPostExists(id); - // 校验岗位名的唯一性 - checkPostNameUnique(id, name); - // 校验岗位编码的唯一性 - checkPostCodeUnique(id, code); - } - - private void checkPostNameUnique(Long id, String name) { - PostDO post = postMapper.selectByName(name); - if (post == null) { - return; - } - // 如果 id 为空,说明不用比较是否为相同 id 的岗位 - if (id == null) { - throw ServiceExceptionUtil.exception(POST_NAME_DUPLICATE); - } - if (!post.getId().equals(id)) { - throw ServiceExceptionUtil.exception(POST_NAME_DUPLICATE); - } - } - - private void checkPostCodeUnique(Long id, String code) { - PostDO post = postMapper.selectByCode(code); - if (post == null) { - return; - } - // 如果 id 为空,说明不用比较是否为相同 id 的岗位 - if (id == null) { - throw ServiceExceptionUtil.exception(POST_CODE_DUPLICATE); - } - if (!post.getId().equals(id)) { - throw ServiceExceptionUtil.exception(POST_CODE_DUPLICATE); - } - } - - private void checkPostExists(Long id) { - if (id == null) { - return; - } - PostDO post = postMapper.selectById(id); - if (post == null) { - throw ServiceExceptionUtil.exception(POST_NOT_FOUND); - } - } - @Override - public void validPosts(Collection ids) { + public void validatePostList(Collection ids) { if (CollUtil.isEmpty(ids)) { return; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index ef6f9757c..913c0d15a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -319,7 +319,7 @@ public class AdminUserServiceImpl implements AdminUserService { // 校验部门处于开启状态 deptService.validateDeptList(CollectionUtils.singleton(deptId)); // 校验岗位处于开启状态 - postService.validPosts(postIds); + postService.validatePostList(postIds); } @VisibleForTesting diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImplTest.java index 593c2cb04..3771fc33e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImplTest.java @@ -337,7 +337,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest { List ids = singletonList(deptDO.getId()); // 调用, 并断言异常 - assertServiceException(() -> deptService.validateDeptList(ids), DEPT_NOT_ENABLE); + assertServiceException(() -> deptService.validateDeptList(ids), DEPT_NOT_ENABLE, deptDO.getName()); } @SafeVarargs diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/PostServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImplTest.java similarity index 61% rename from yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/PostServiceTest.java rename to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImplTest.java index 30e546f66..87c44b346 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/PostServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImplTest.java @@ -1,41 +1,136 @@ package cn.iocoder.yudao.module.system.service.dept; -import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostUpdateReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO; import cn.iocoder.yudao.module.system.dal.mysql.dept.PostMapper; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; import javax.annotation.Resource; +import java.util.Arrays; import java.util.List; import java.util.function.Consumer; import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.*; +/** + * {@link PostServiceImpl} 的单元测试类 + * + * @author niudehua + */ @Import(PostServiceImpl.class) -public class PostServiceTest extends BaseDbUnitTest { +public class PostServiceImplTest extends BaseDbUnitTest { @Resource private PostServiceImpl postService; + @Resource private PostMapper postMapper; @Test - void testPagePosts() { + public void testCreatePost_success() { + // 准备参数 + PostCreateReqVO reqVO = randomPojo(PostCreateReqVO.class, + o -> o.setStatus(randomEle(CommonStatusEnum.values()).getStatus())); + // 调用 + Long postId = postService.createPost(reqVO); + + // 断言 + assertNotNull(postId); + // 校验记录的属性是否正确 + PostDO post = postMapper.selectById(postId); + assertPojoEquals(reqVO, post); + } + + @Test + public void testUpdatePost_success() { + // mock 数据 + PostDO postDO = randomPostDO(); + postMapper.insert(postDO);// @Sql: 先插入出一条存在的数据 + // 准备参数 + PostUpdateReqVO reqVO = randomPojo(PostUpdateReqVO.class, o -> { + // 设置更新的 ID + o.setId(postDO.getId()); + o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); + }); + + // 调用 + postService.updatePost(reqVO); + // 校验是否更新正确 + PostDO post = postMapper.selectById(reqVO.getId()); + assertPojoEquals(reqVO, post); + } + + @Test + public void testDeletePost_success() { + // mock 数据 + PostDO postDO = randomPostDO(); + postMapper.insert(postDO); + // 准备参数 + Long id = postDO.getId(); + + // 调用 + postService.deletePost(id); + assertNull(postMapper.selectById(id)); + } + + @Test + public void testValidatePost_notFoundForDelete() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> postService.deletePost(id), POST_NOT_FOUND); + } + + @Test + public void testValidatePost_nameDuplicateForCreate() { + // mock 数据 + PostDO postDO = randomPostDO(); + postMapper.insert(postDO);// @Sql: 先插入出一条存在的数据 + // 准备参数 + PostCreateReqVO reqVO = randomPojo(PostCreateReqVO.class, + // 模拟 name 重复 + o -> o.setName(postDO.getName())); + assertServiceException(() -> postService.createPost(reqVO), POST_NAME_DUPLICATE); + } + + @Test + public void testValidatePost_codeDuplicateForUpdate() { + // mock 数据 + PostDO postDO = randomPostDO(); + postMapper.insert(postDO); + // mock 数据:稍后模拟重复它的 code + PostDO codePostDO = randomPostDO(); + postMapper.insert(codePostDO); + // 准备参数 + PostUpdateReqVO reqVO = randomPojo(PostUpdateReqVO.class, o -> { + // 设置更新的 ID + o.setId(postDO.getId()); + // 模拟 code 重复 + o.setCode(codePostDO.getCode()); + }); + + // 调用, 并断言异常 + assertServiceException(() -> postService.updatePost(reqVO), POST_CODE_DUPLICATE); + } + + @Test + public void testGetPostPage() { // mock 数据 PostDO postDO = randomPojo(PostDO.class, o -> { o.setName("码仔"); @@ -43,10 +138,9 @@ public class PostServiceTest extends BaseDbUnitTest { }); postMapper.insert(postDO); // 测试 name 不匹配 - postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setName("程序员"))); + postMapper.insert(cloneIgnoreId(postDO, o -> o.setName("程序员"))); // 测试 status 不匹配 - postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); - + postMapper.insert(cloneIgnoreId(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); // 准备参数 PostPageReqVO reqVO = new PostPageReqVO(); reqVO.setName("码"); @@ -54,7 +148,6 @@ public class PostServiceTest extends BaseDbUnitTest { // 调用 PageResult pageResult = postService.getPostPage(reqVO); - // 断言 assertEquals(1, pageResult.getTotal()); assertEquals(1, pageResult.getList().size()); @@ -62,7 +155,7 @@ public class PostServiceTest extends BaseDbUnitTest { } @Test - void testListPosts() { + public void testGetPostList_export() { // mock 数据 PostDO postDO = randomPojo(PostDO.class, o -> { o.setName("码仔"); @@ -70,23 +163,41 @@ public class PostServiceTest extends BaseDbUnitTest { }); postMapper.insert(postDO); // 测试 name 不匹配 - postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setName("程序员"))); + postMapper.insert(cloneIgnoreId(postDO, o -> o.setName("程序员"))); // 测试 status 不匹配 - postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + postMapper.insert(cloneIgnoreId(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); // 准备参数 PostExportReqVO reqVO = new PostExportReqVO(); reqVO.setName("码"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 调用 - List list = postService.getPosts(reqVO); + List list = postService.getPostList(reqVO); // 断言 assertEquals(1, list.size()); assertPojoEquals(postDO, list.get(0)); } @Test - void testGetPost() { + public void testGetPostList() { + // mock 数据 + PostDO postDO01 = randomPojo(PostDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + postMapper.insert(postDO01); + // 测试 status 不匹配 + PostDO postDO02 = randomPojo(PostDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())); + postMapper.insert(postDO02); + // 准备参数 + List ids = Arrays.asList(postDO01.getId(), postDO02.getId()); + + // 调用 + List list = postService.getPostList(ids, singletonList(CommonStatusEnum.ENABLE.getStatus())); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(postDO01, list.get(0)); + } + + @Test + public void testGetPost() { // mock 数据 PostDO dbPostDO = randomPostDO(); postMapper.insert(dbPostDO); @@ -100,94 +211,43 @@ public class PostServiceTest extends BaseDbUnitTest { } @Test - void testCreatePost_success() { - // 准备参数 - PostCreateReqVO reqVO = randomPojo(PostCreateReqVO.class, - o -> o.setStatus(randomEle(CommonStatusEnum.values()).getStatus())); - // 调用 - Long postId = postService.createPost(reqVO); - // 断言 - assertNotNull(postId); - // 校验记录的属性是否正确 - PostDO post = postMapper.selectById(postId); - assertPojoEquals(reqVO, post); - } - - @Test - void testUpdatePost_success() { + public void testValidatePostList_success() { // mock 数据 - PostDO postDO = randomPostDO(); - postMapper.insert(postDO);// @Sql: 先插入出一条存在的数据 - // 准备参数 - PostUpdateReqVO reqVO = randomPojo(PostUpdateReqVO.class, - o -> { - // 设置更新的 ID - o.setId(postDO.getId()); - o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); - }); - // 调用 - postService.updatePost(reqVO); - // 校验是否更新正确 - PostDO post = postMapper.selectById(reqVO.getId());// 获取最新的 - assertPojoEquals(reqVO, post); - } - - @Test - void testDeletePost_success() { - // mock 数据 - PostDO postDO = randomPostDO(); + PostDO postDO = randomPostDO().setStatus(CommonStatusEnum.ENABLE.getStatus()); postMapper.insert(postDO); // 准备参数 - Long id = postDO.getId(); - // 调用 - postService.deletePost(id); - assertNull(postMapper.selectById(id)); + List ids = singletonList(postDO.getId()); + + // 调用,无需断言 + postService.validatePostList(ids); } @Test - void testCheckPost_notFoundForDelete() { + public void testValidatePostList_notFound() { // 准备参数 - Long id = randomLongId(); + List ids = singletonList(randomLongId()); + // 调用, 并断言异常 - assertServiceException(() -> postService.deletePost(id), POST_NOT_FOUND); + assertServiceException(() -> postService.validatePostList(ids), POST_NOT_FOUND); } @Test - void testCheckPost_nameDuplicateForCreate() { + public void testValidatePostList_notEnable() { // mock 数据 - PostDO postDO = randomPostDO(); - postMapper.insert(postDO);// @Sql: 先插入出一条存在的数据 - // 准备参数 - PostCreateReqVO reqVO = randomPojo(PostCreateReqVO.class, - // 模拟 name 重复 - o -> o.setName(postDO.getName())); - assertServiceException(() -> postService.createPost(reqVO), POST_NAME_DUPLICATE); - } - - @Test - void testCheckPost_codeDuplicateForUpdate() { - // mock 数据 - PostDO postDO = randomPostDO(); + PostDO postDO = randomPostDO().setStatus(CommonStatusEnum.DISABLE.getStatus()); postMapper.insert(postDO); - // mock 数据 稍后模拟重复它的 code - PostDO codePostDO = randomPostDO(); - postMapper.insert(codePostDO); // 准备参数 - PostUpdateReqVO reqVO = randomPojo(PostUpdateReqVO.class, - o -> { - // 设置更新的 ID - o.setId(postDO.getId()); - // 模拟 code 重复 - o.setCode(codePostDO.getCode()); - }); + List ids = singletonList(postDO.getId()); + // 调用, 并断言异常 - assertServiceException(() -> postService.updatePost(reqVO), POST_CODE_DUPLICATE); + assertServiceException(() -> postService.validatePostList(ids), POST_NOT_ENABLE, + postDO.getName()); } @SafeVarargs private static PostDO randomPostDO(Consumer... consumers) { Consumer consumer = (o) -> { - o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 + o.setStatus(randomCommonStatus()); // 保证 status 的范围 }; return randomPojo(PostDO.class, ArrayUtils.append(consumer, consumers)); } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java index c78efcc72..54b042c44 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java @@ -102,7 +102,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { o.setId(postId); o.setStatus(CommonStatusEnum.ENABLE.getStatus()); })); - when(postService.getPosts(eq(reqVO.getPostIds()), isNull())).thenReturn(posts); + when(postService.getPostList(eq(reqVO.getPostIds()), isNull())).thenReturn(posts); // mock passwordEncoder 的方法 when(passwordEncoder.encode(eq(reqVO.getPassword()))).thenReturn("yudaoyuanma"); @@ -160,7 +160,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { o.setId(postId); o.setStatus(CommonStatusEnum.ENABLE.getStatus()); })); - when(postService.getPosts(eq(reqVO.getPostIds()), isNull())).thenReturn(posts); + when(postService.getPostList(eq(reqVO.getPostIds()), isNull())).thenReturn(posts); // 调用 userService.updateUser(reqVO); From 05374216552e0178ebb04f6ce37e49aae42bddf8 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 1 Feb 2023 07:34:57 +0800 Subject: [PATCH 27/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20DictDataServiceImpl?= =?UTF-8?q?=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BpmTaskAssignRuleServiceImpl.java | 2 +- .../module/system/api/dict/DictDataApi.java | 2 +- .../system/api/dict/DictDataApiImpl.java | 4 +- .../admin/dict/DictDataController.java | 4 +- .../system/service/dict/DictDataService.java | 6 +- .../service/dict/DictDataServiceImpl.java | 27 ++- ...Test.java => DictDataServiceImplTest.java} | 170 +++++++++++++++--- 7 files changed, 166 insertions(+), 49 deletions(-) rename yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/{DictDataServiceTest.java => DictDataServiceImplTest.java} (55%) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index bc8cd3151..742489e41 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -224,7 +224,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_GROUP.getType())) { userGroupService.validUserGroups(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) { - dictDataApi.validDictDatas(DictTypeConstants.TASK_ASSIGN_SCRIPT, + dictDataApi.validateDictDataList(DictTypeConstants.TASK_ASSIGN_SCRIPT, CollectionUtils.convertSet(options, String::valueOf)); } else { throw new IllegalArgumentException(format("未知的规则类型({})", type)); diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApi.java index 5ba3dfd75..3bc28c89e 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApi.java @@ -19,7 +19,7 @@ public interface DictDataApi { * @param dictType 字典类型 * @param values 字典数据值的数组 */ - void validDictDatas(String dictType, Collection values); + void validateDictDataList(String dictType, Collection values); /** * 获得指定的字典数据,从缓存中 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApiImpl.java index 7de1a43b3..e88771fa7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/dict/DictDataApiImpl.java @@ -21,8 +21,8 @@ public class DictDataApiImpl implements DictDataApi { private DictDataService dictDataService; @Override - public void validDictDatas(String dictType, Collection values) { - dictDataService.validDictDatas(dictType, values); + public void validateDictDataList(String dictType, Collection values) { + dictDataService.validateDictDataList(dictType, values); } @Override diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java index 124e5fd05..4b14be80e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java @@ -62,7 +62,7 @@ public class DictDataController { @ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地") // 无需添加权限认证,因为前端全局都需要 public CommonResult> getSimpleDictDatas() { - List list = dictDataService.getDictDatas(); + List list = dictDataService.getDictDataList(); return success(DictDataConvert.INSTANCE.convertList(list)); } @@ -86,7 +86,7 @@ public class DictDataController { @PreAuthorize("@ss.hasPermission('system:dict:export')") @OperateLog(type = EXPORT) public void export(HttpServletResponse response, @Valid DictDataExportReqVO reqVO) throws IOException { - List list = dictDataService.getDictDatas(reqVO); + List list = dictDataService.getDictDataList(reqVO); List data = DictDataConvert.INSTANCE.convertList02(list); // 输出 ExcelUtils.write(response, "字典数据.xls", "数据列表", DictDataExcelVO.class, data); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataService.java index 610fe2a33..d2eb8c519 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataService.java @@ -44,7 +44,7 @@ public interface DictDataService { * * @return 字典数据全列表 */ - List getDictDatas(); + List getDictDataList(); /** * 获得字典数据分页列表 @@ -60,7 +60,7 @@ public interface DictDataService { * @param reqVO 列表请求 * @return 字典数据列表 */ - List getDictDatas(DictDataExportReqVO reqVO); + List getDictDataList(DictDataExportReqVO reqVO); /** * 获得字典数据详情 @@ -86,7 +86,7 @@ public interface DictDataService { * @param dictType 字典类型 * @param values 字典数据值的数组 */ - void validDictDatas(String dictType, Collection values); + void validateDictDataList(String dictType, Collection values); /** * 获得指定的字典数据 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImpl.java index 0cfdb2b99..eccd2c219 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImpl.java @@ -48,7 +48,7 @@ public class DictDataServiceImpl implements DictDataService { private DictDataMapper dictDataMapper; @Override - public List getDictDatas() { + public List getDictDataList() { List list = dictDataMapper.selectList(); list.sort(COMPARATOR_TYPE_AND_SORT); return list; @@ -60,7 +60,7 @@ public class DictDataServiceImpl implements DictDataService { } @Override - public List getDictDatas(DictDataExportReqVO reqVO) { + public List getDictDataList(DictDataExportReqVO reqVO) { List list = dictDataMapper.selectList(reqVO); list.sort(COMPARATOR_TYPE_AND_SORT); return list; @@ -74,7 +74,7 @@ public class DictDataServiceImpl implements DictDataService { @Override public Long createDictData(DictDataCreateReqVO reqVO) { // 校验正确性 - checkCreateOrUpdate(null, reqVO.getValue(), reqVO.getDictType()); + validateDictDataForCreateOrUpdate(null, reqVO.getValue(), reqVO.getDictType()); // 插入字典类型 DictDataDO dictData = DictDataConvert.INSTANCE.convert(reqVO); @@ -85,7 +85,7 @@ public class DictDataServiceImpl implements DictDataService { @Override public void updateDictData(DictDataUpdateReqVO reqVO) { // 校验正确性 - checkCreateOrUpdate(reqVO.getId(), reqVO.getValue(), reqVO.getDictType()); + validateDictDataForCreateOrUpdate(reqVO.getId(), reqVO.getValue(), reqVO.getDictType()); // 更新字典类型 DictDataDO updateObj = DictDataConvert.INSTANCE.convert(reqVO); @@ -95,7 +95,7 @@ public class DictDataServiceImpl implements DictDataService { @Override public void deleteDictData(Long id) { // 校验是否存在 - checkDictDataExists(id); + validateDictDataExists(id); // 删除字典数据 dictDataMapper.deleteById(id); @@ -106,18 +106,17 @@ public class DictDataServiceImpl implements DictDataService { return dictDataMapper.selectCountByDictType(dictType); } - - private void checkCreateOrUpdate(Long id, String value, String dictType) { + private void validateDictDataForCreateOrUpdate(Long id, String value, String dictType) { // 校验自己存在 - checkDictDataExists(id); + validateDictDataExists(id); // 校验字典类型有效 - checkDictTypeValid(dictType); + validateDictTypeExists(dictType); // 校验字典数据的值的唯一性 - checkDictDataValueUnique(id, dictType, value); + validateDictDataValueUnique(id, dictType, value); } @VisibleForTesting - public void checkDictDataValueUnique(Long id, String dictType, String value) { + public void validateDictDataValueUnique(Long id, String dictType, String value) { DictDataDO dictData = dictDataMapper.selectByDictTypeAndValue(dictType, value); if (dictData == null) { return; @@ -132,7 +131,7 @@ public class DictDataServiceImpl implements DictDataService { } @VisibleForTesting - public void checkDictDataExists(Long id) { + public void validateDictDataExists(Long id) { if (id == null) { return; } @@ -143,7 +142,7 @@ public class DictDataServiceImpl implements DictDataService { } @VisibleForTesting - public void checkDictTypeValid(String type) { + public void validateDictTypeExists(String type) { DictTypeDO dictType = dictTypeService.getDictType(type); if (dictType == null) { throw exception(DICT_TYPE_NOT_EXISTS); @@ -154,7 +153,7 @@ public class DictDataServiceImpl implements DictDataService { } @Override - public void validDictDatas(String dictType, Collection values) { + public void validateDictDataList(String dictType, Collection values) { if (CollUtil.isEmpty(values)) { return; } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImplTest.java similarity index 55% rename from yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceTest.java rename to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImplTest.java index 02fba6c21..1e4dc9f90 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImplTest.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.system.service.dict; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataExportReqVO; @@ -20,16 +19,18 @@ import javax.annotation.Resource; import java.util.List; import java.util.function.Consumer; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @Import(DictDataServiceImpl.class) -public class DictDataServiceTest extends BaseDbUnitTest { +public class DictDataServiceImplTest extends BaseDbUnitTest { @Resource private DictDataServiceImpl dictDataService; @@ -39,6 +40,23 @@ public class DictDataServiceTest extends BaseDbUnitTest { @MockBean private DictTypeService dictTypeService; + @Test + public void testGetDictDataList() { + // mock 数据 + DictDataDO dictDataDO01 = randomDictDataDO().setDictType("yunai").setSort(2); + dictDataMapper.insert(dictDataDO01); + DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setSort(1); + dictDataMapper.insert(dictDataDO02); + // 准备参数 + + // 调用 + List dictDataDOList = dictDataService.getDictDataList(); + // 断言 + assertEquals(2, dictDataDOList.size()); + assertPojoEquals(dictDataDO02, dictDataDOList.get(0)); + assertPojoEquals(dictDataDO01, dictDataDOList.get(1)); + } + @Test public void testGetDictDataPage() { // mock 数据 @@ -49,11 +67,11 @@ public class DictDataServiceTest extends BaseDbUnitTest { }); dictDataMapper.insert(dbDictData); // 测试 label 不匹配 - dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setLabel("艿"))); + dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setLabel("艿"))); // 测试 dictType 不匹配 - dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setDictType("nai"))); + dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setDictType("nai"))); // 测试 status 不匹配 - dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); // 准备参数 DictDataPageReqVO reqVO = new DictDataPageReqVO(); reqVO.setLabel("芋"); @@ -69,7 +87,7 @@ public class DictDataServiceTest extends BaseDbUnitTest { } @Test - public void testGetDictDataList() { + public void testGetDictDataList_export() { // mock 数据 DictDataDO dbDictData = randomPojo(DictDataDO.class, o -> { // 等会查询到 o.setLabel("芋艿"); @@ -78,11 +96,11 @@ public class DictDataServiceTest extends BaseDbUnitTest { }); dictDataMapper.insert(dbDictData); // 测试 label 不匹配 - dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setLabel("艿"))); + dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setLabel("艿"))); // 测试 dictType 不匹配 - dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setDictType("nai"))); + dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setDictType("nai"))); // 测试 status 不匹配 - dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); // 准备参数 DictDataExportReqVO reqVO = new DictDataExportReqVO(); reqVO.setLabel("芋"); @@ -90,12 +108,26 @@ public class DictDataServiceTest extends BaseDbUnitTest { reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 调用 - List list = dictDataService.getDictDatas(reqVO); + List list = dictDataService.getDictDataList(reqVO); // 断言 assertEquals(1, list.size()); assertPojoEquals(dbDictData, list.get(0)); } + @Test + public void testGetDictData() { + // mock 数据 + DictDataDO dbDictData = randomDictDataDO(); + dictDataMapper.insert(dbDictData); + // 准备参数 + Long id = dbDictData.getId(); + + // 调用 + DictDataDO dictData = dictDataService.getDictData(id); + // 断言 + assertPojoEquals(dbDictData, dictData); + } + @Test public void testCreateDictData_success() { // 准备参数 @@ -148,54 +180,54 @@ public class DictDataServiceTest extends BaseDbUnitTest { } @Test - public void testCheckDictDataExists_success() { + public void testValidateDictDataExists_success() { // mock 数据 DictDataDO dbDictData = randomDictDataDO(); dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据 // 调用成功 - dictDataService.checkDictDataExists(dbDictData.getId()); + dictDataService.validateDictDataExists(dbDictData.getId()); } @Test - public void testCheckDictDataExists_notExists() { - assertServiceException(() -> dictDataService.checkDictDataExists(randomLongId()), DICT_DATA_NOT_EXISTS); + public void testValidateDictDataExists_notExists() { + assertServiceException(() -> dictDataService.validateDictDataExists(randomLongId()), DICT_DATA_NOT_EXISTS); } @Test - public void testCheckDictTypeValid_success() { + public void testValidateDictTypeExists_success() { // mock 方法,数据类型被禁用 String type = randomString(); when(dictTypeService.getDictType(eq(type))).thenReturn(randomDictTypeDO(type)); // 调用, 成功 - dictDataService.checkDictTypeValid(type); + dictDataService.validateDictTypeExists(type); } @Test - public void testCheckDictTypeValid_notExists() { - assertServiceException(() -> dictDataService.checkDictTypeValid(randomString()), DICT_TYPE_NOT_EXISTS); + public void testValidateDictTypeExists_notExists() { + assertServiceException(() -> dictDataService.validateDictTypeExists(randomString()), DICT_TYPE_NOT_EXISTS); } @Test - public void testCheckDictTypeValid_notEnable() { + public void testValidateDictTypeExists_notEnable() { // mock 方法,数据类型被禁用 String dictType = randomString(); when(dictTypeService.getDictType(eq(dictType))).thenReturn( randomPojo(DictTypeDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); // 调用, 并断言异常 - assertServiceException(() -> dictDataService.checkDictTypeValid(dictType), DICT_TYPE_NOT_ENABLE); + assertServiceException(() -> dictDataService.validateDictTypeExists(dictType), DICT_TYPE_NOT_ENABLE); } @Test - public void testCheckDictDataValueUnique_success() { + public void testValidateDictDataValueUnique_success() { // 调用,成功 - dictDataService.checkDictDataValueUnique(randomLongId(), randomString(), randomString()); + dictDataService.validateDictDataValueUnique(randomLongId(), randomString(), randomString()); } @Test - public void testCheckDictDataValueUnique_valueDuplicateForCreate() { + public void testValidateDictDataValueUnique_valueDuplicateForCreate() { // 准备参数 String dictType = randomString(); String value = randomString(); @@ -206,12 +238,12 @@ public class DictDataServiceTest extends BaseDbUnitTest { })); // 调用,校验异常 - assertServiceException(() -> dictDataService.checkDictDataValueUnique(null, dictType, value), + assertServiceException(() -> dictDataService.validateDictDataValueUnique(null, dictType, value), DICT_DATA_VALUE_DUPLICATE); } @Test - public void testCheckDictDataValueUnique_valueDuplicateForUpdate() { + public void testValidateDictDataValueUnique_valueDuplicateForUpdate() { // 准备参数 Long id = randomLongId(); String dictType = randomString(); @@ -223,10 +255,96 @@ public class DictDataServiceTest extends BaseDbUnitTest { })); // 调用,校验异常 - assertServiceException(() -> dictDataService.checkDictDataValueUnique(id, dictType, value), + assertServiceException(() -> dictDataService.validateDictDataValueUnique(id, dictType, value), DICT_DATA_VALUE_DUPLICATE); } + @Test + public void testCountByDictType() { + // mock 数据 + dictDataMapper.insert(randomDictDataDO(o -> o.setDictType("yunai"))); + dictDataMapper.insert(randomDictDataDO(o -> o.setDictType("tudou"))); + dictDataMapper.insert(randomDictDataDO(o -> o.setDictType("yunai"))); + // 准备参数 + String dictType = "yunai"; + + // 调用 + long count = dictDataService.countByDictType(dictType); + // 校验 + assertEquals(2L, count); + } + + @Test + public void testValidateDictDataList_success() { + // mock 数据 + DictDataDO dictDataDO = randomDictDataDO().setStatus(CommonStatusEnum.ENABLE.getStatus()); + dictDataMapper.insert(dictDataDO); + // 准备参数 + String dictType = dictDataDO.getDictType(); + List values = singletonList(dictDataDO.getValue()); + + // 调用,无需断言 + dictDataService.validateDictDataList(dictType, values); + } + + @Test + public void testValidateDictDataList_notFound() { + // 准备参数 + String dictType = randomString(); + List values = singletonList(randomString()); + + // 调用, 并断言异常 + assertServiceException(() -> dictDataService.validateDictDataList(dictType, values), DICT_DATA_NOT_EXISTS); + } + + @Test + public void testValidateDictDataList_notEnable() { + // mock 数据 + DictDataDO dictDataDO = randomDictDataDO().setStatus(CommonStatusEnum.DISABLE.getStatus()); + dictDataMapper.insert(dictDataDO); + // 准备参数 + String dictType = dictDataDO.getDictType(); + List values = singletonList(dictDataDO.getValue()); + + // 调用, 并断言异常 + assertServiceException(() -> dictDataService.validateDictDataList(dictType, values), + DICT_DATA_NOT_ENABLE, dictDataDO.getLabel()); + } + + @Test + public void testGetDictData_dictType() { + // mock 数据 + DictDataDO dictDataDO = randomDictDataDO().setDictType("yunai").setValue("1"); + dictDataMapper.insert(dictDataDO); + DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setValue("2"); + dictDataMapper.insert(dictDataDO02); + // 准备参数 + String dictType = "yunai"; + String value = "1"; + + // 调用 + DictDataDO dbDictData = dictDataService.getDictData(dictType, value); + // 断言 + assertEquals(dictDataDO, dbDictData); + } + + @Test + public void testParseDictData() { + // mock 数据 + DictDataDO dictDataDO = randomDictDataDO().setDictType("yunai").setLabel("1"); + dictDataMapper.insert(dictDataDO); + DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setLabel("2"); + dictDataMapper.insert(dictDataDO02); + // 准备参数 + String dictType = "yunai"; + String label = "1"; + + // 调用 + DictDataDO dbDictData = dictDataService.parseDictData(dictType, label); + // 断言 + assertEquals(dictDataDO, dbDictData); + } + // ========== 随机对象 ========== @SafeVarargs From fed9feb05fa69ec35a7209c1bda0bcf394bccf91 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 1 Feb 2023 07:45:57 +0800 Subject: [PATCH 28/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20DictTypeServiceImpl?= =?UTF-8?q?=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/util/date/LocalDateTimeUtils.java | 5 + .../service/dict/DictTypeServiceImpl.java | 22 ++-- ...Test.java => DictTypeServiceImplTest.java} | 104 ++++++++++++------ 3 files changed, 85 insertions(+), 46 deletions(-) rename yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/{DictTypeServiceTest.java => DictTypeServiceImplTest.java} (70%) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java index a29d5fb2e..62e0e4441 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java @@ -41,6 +41,11 @@ public class LocalDateTimeUtils { return LocalDateTime.of(year, mouth, day, 0, 0, 0); } + public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1, + int year2, int mouth2, int day2) { + return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)}; + } + /** * 判断当前时间是否在该时间范围内 * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImpl.java index 07fcf40f3..cc731affe 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImpl.java @@ -57,7 +57,8 @@ public class DictTypeServiceImpl implements DictTypeService { @Override public Long createDictType(DictTypeCreateReqVO reqVO) { // 校验正确性 - checkCreateOrUpdate(null, reqVO.getName(), reqVO.getType()); + validateDictTypeForCreateOrUpdate(null, reqVO.getName(), reqVO.getType()); + // 插入字典类型 DictTypeDO dictType = DictTypeConvert.INSTANCE.convert(reqVO) .setDeletedTime(LocalDateTimeUtils.EMPTY); // 唯一索引,避免 null 值 @@ -68,7 +69,8 @@ public class DictTypeServiceImpl implements DictTypeService { @Override public void updateDictType(DictTypeUpdateReqVO reqVO) { // 校验正确性 - checkCreateOrUpdate(reqVO.getId(), reqVO.getName(), null); + validateDictTypeForCreateOrUpdate(reqVO.getId(), reqVO.getName(), null); + // 更新字典类型 DictTypeDO updateObj = DictTypeConvert.INSTANCE.convert(reqVO); dictTypeMapper.updateById(updateObj); @@ -77,7 +79,7 @@ public class DictTypeServiceImpl implements DictTypeService { @Override public void deleteDictType(Long id) { // 校验是否存在 - DictTypeDO dictType = checkDictTypeExists(id); + DictTypeDO dictType = validateDictTypeExists(id); // 校验是否有字典数据 if (dictDataService.countByDictType(dictType.getType()) > 0) { throw exception(DICT_TYPE_HAS_CHILDREN); @@ -91,17 +93,17 @@ public class DictTypeServiceImpl implements DictTypeService { return dictTypeMapper.selectList(); } - private void checkCreateOrUpdate(Long id, String name, String type) { + private void validateDictTypeForCreateOrUpdate(Long id, String name, String type) { // 校验自己存在 - checkDictTypeExists(id); + validateDictTypeExists(id); // 校验字典类型的名字的唯一性 - checkDictTypeNameUnique(id, name); + validateDictTypeNameUnique(id, name); // 校验字典类型的类型的唯一性 - checkDictTypeUnique(id, type); + validateDictTypeUnique(id, type); } @VisibleForTesting - public void checkDictTypeNameUnique(Long id, String name) { + void validateDictTypeNameUnique(Long id, String name) { DictTypeDO dictType = dictTypeMapper.selectByName(name); if (dictType == null) { return; @@ -116,7 +118,7 @@ public class DictTypeServiceImpl implements DictTypeService { } @VisibleForTesting - public void checkDictTypeUnique(Long id, String type) { + void validateDictTypeUnique(Long id, String type) { if (StrUtil.isEmpty(type)) { return; } @@ -134,7 +136,7 @@ public class DictTypeServiceImpl implements DictTypeService { } @VisibleForTesting - public DictTypeDO checkDictTypeExists(Long id) { + DictTypeDO validateDictTypeExists(Long id) { if (id == null) { return null; } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImplTest.java similarity index 70% rename from yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceTest.java rename to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImplTest.java index 5c39b32e6..fc9387019 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImplTest.java @@ -2,36 +2,36 @@ package cn.iocoder.yudao.module.system.service.dict; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeCreateReqVO; -import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeUpdateReqVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypePageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeUpdateReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO; import cn.iocoder.yudao.module.system.dal.mysql.dict.DictTypeMapper; -import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.List; import java.util.function.Consumer; import static cn.hutool.core.util.RandomUtil.randomEle; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @Import(DictTypeServiceImpl.class) -public class DictTypeServiceTest extends BaseDbUnitTest { +public class DictTypeServiceImplTest extends BaseDbUnitTest { @Resource private DictTypeServiceImpl dictTypeService; @@ -52,19 +52,19 @@ public class DictTypeServiceTest extends BaseDbUnitTest { }); dictTypeMapper.insert(dbDictType); // 测试 name 不匹配 - dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setName("tudou"))); + dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setName("tudou"))); // 测试 type 不匹配 - dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setType("土豆"))); + dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setType("土豆"))); // 测试 status 不匹配 - dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); // 测试 createTime 不匹配 - dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1)))); + dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1)))); // 准备参数 DictTypePageReqVO reqVO = new DictTypePageReqVO(); reqVO.setName("nai"); reqVO.setType("艿"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 1, 10),buildTime(2021, 1, 20)})); + reqVO.setCreateTime(buildBetweenTime(2021, 1, 10, 2021, 1, 20)); // 调用 PageResult pageResult = dictTypeService.getDictTypePage(reqVO); @@ -75,7 +75,7 @@ public class DictTypeServiceTest extends BaseDbUnitTest { } @Test - public void testGetDictTypeList() { + public void testGetDictTypeList_export() { // mock 数据 DictTypeDO dbDictType = randomPojo(DictTypeDO.class, o -> { // 等会查询到 o.setName("yunai"); @@ -85,19 +85,19 @@ public class DictTypeServiceTest extends BaseDbUnitTest { }); dictTypeMapper.insert(dbDictType); // 测试 name 不匹配 - dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setName("tudou"))); + dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setName("tudou"))); // 测试 type 不匹配 - dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setType("土豆"))); + dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setType("土豆"))); // 测试 status 不匹配 - dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); // 测试 createTime 不匹配 - dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1)))); + dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1)))); // 准备参数 DictTypeExportReqVO reqVO = new DictTypeExportReqVO(); reqVO.setName("nai"); reqVO.setType("艿"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 1, 10),buildTime(2021, 1, 20)})); + reqVO.setCreateTime(buildBetweenTime(2021, 1, 10, 2021, 1, 20)); // 调用 List list = dictTypeService.getDictTypeList(reqVO); @@ -107,7 +107,22 @@ public class DictTypeServiceTest extends BaseDbUnitTest { } @Test - public void testGetDictType() { + public void testGetDictType_id() { + // mock 数据 + DictTypeDO dbDictType = randomDictTypeDO(); + dictTypeMapper.insert(dbDictType); + // 准备参数 + Long id = dbDictType.getId(); + + // 调用 + DictTypeDO dictType = dictTypeService.getDictType(id); + // 断言 + assertNotNull(dictType); + assertPojoEquals(dbDictType, dictType); + } + + @Test + public void testGetDictType_type() { // mock 数据 DictTypeDO dbDictType = randomDictTypeDO(); dictTypeMapper.insert(dbDictType); @@ -183,40 +198,57 @@ public class DictTypeServiceTest extends BaseDbUnitTest { } @Test - public void testCheckDictDataExists_success() { + public void testGetDictTypeList() { + // 准备参数 + DictTypeDO dictTypeDO01 = randomDictTypeDO(); + dictTypeMapper.insert(dictTypeDO01); + DictTypeDO dictTypeDO02 = randomDictTypeDO(); + dictTypeMapper.insert(dictTypeDO02); + // mock 方法 + + // 调用 + List dictTypeDOList = dictTypeService.getDictTypeList(); + // 断言 + assertEquals(2, dictTypeDOList.size()); + assertPojoEquals(dictTypeDO01, dictTypeDOList.get(0)); + assertPojoEquals(dictTypeDO02, dictTypeDOList.get(1)); + } + + @Test + public void testValidateDictDataExists_success() { // mock 数据 DictTypeDO dbDictType = randomDictTypeDO(); dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据 // 调用成功 - dictTypeService.checkDictTypeExists(dbDictType.getId()); + dictTypeService.validateDictTypeExists(dbDictType.getId()); } @Test - public void testCheckDictDataExists_notExists() { - assertServiceException(() -> dictTypeService.checkDictTypeExists(randomLongId()), DICT_TYPE_NOT_EXISTS); + public void testValidateDictDataExists_notExists() { + assertServiceException(() -> dictTypeService.validateDictTypeExists(randomLongId()), DICT_TYPE_NOT_EXISTS); } @Test - public void testCheckDictTypeUnique_success() { + public void testValidateDictTypeUnique_success() { // 调用,成功 - dictTypeService.checkDictTypeUnique(randomLongId(), randomString()); + dictTypeService.validateDictTypeUnique(randomLongId(), randomString()); } @Test - public void testCheckDictTypeUnique_valueDuplicateForCreate() { + public void testValidateDictTypeUnique_valueDuplicateForCreate() { // 准备参数 String type = randomString(); // mock 数据 dictTypeMapper.insert(randomDictTypeDO(o -> o.setType(type))); // 调用,校验异常 - assertServiceException(() -> dictTypeService.checkDictTypeUnique(null, type), + assertServiceException(() -> dictTypeService.validateDictTypeUnique(null, type), DICT_TYPE_TYPE_DUPLICATE); } @Test - public void testCheckDictTypeUnique_valueDuplicateForUpdate() { + public void testValidateDictTypeUnique_valueDuplicateForUpdate() { // 准备参数 Long id = randomLongId(); String type = randomString(); @@ -224,30 +256,30 @@ public class DictTypeServiceTest extends BaseDbUnitTest { dictTypeMapper.insert(randomDictTypeDO(o -> o.setType(type))); // 调用,校验异常 - assertServiceException(() -> dictTypeService.checkDictTypeUnique(id, type), + assertServiceException(() -> dictTypeService.validateDictTypeUnique(id, type), DICT_TYPE_TYPE_DUPLICATE); } @Test - public void testCheckDictTypNameUnique_success() { + public void testValidateDictTypNameUnique_success() { // 调用,成功 - dictTypeService.checkDictTypeNameUnique(randomLongId(), randomString()); + dictTypeService.validateDictTypeNameUnique(randomLongId(), randomString()); } @Test - public void testCheckDictTypeNameUnique_nameDuplicateForCreate() { + public void testValidateDictTypeNameUnique_nameDuplicateForCreate() { // 准备参数 String name = randomString(); // mock 数据 dictTypeMapper.insert(randomDictTypeDO(o -> o.setName(name))); // 调用,校验异常 - assertServiceException(() -> dictTypeService.checkDictTypeNameUnique(null, name), + assertServiceException(() -> dictTypeService.validateDictTypeNameUnique(null, name), DICT_TYPE_NAME_DUPLICATE); } @Test - public void testCheckDictTypeNameUnique_nameDuplicateForUpdate() { + public void testValidateDictTypeNameUnique_nameDuplicateForUpdate() { // 准备参数 Long id = randomLongId(); String name = randomString(); @@ -255,7 +287,7 @@ public class DictTypeServiceTest extends BaseDbUnitTest { dictTypeMapper.insert(randomDictTypeDO(o -> o.setName(name))); // 调用,校验异常 - assertServiceException(() -> dictTypeService.checkDictTypeNameUnique(id, name), + assertServiceException(() -> dictTypeService.validateDictTypeNameUnique(id, name), DICT_TYPE_NAME_DUPLICATE); } From 9ca793919de904631c75663d9126d69ced514f4a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 1 Feb 2023 08:04:36 +0800 Subject: [PATCH 29/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20ErrorCodeServiceImpl?= =?UTF-8?q?=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/dal/mysql/dept/DeptMapper.java | 5 +- .../system/dal/mysql/dept/PostMapper.java | 30 ++++---- .../system/dal/mysql/dept/UserPostMapper.java | 2 +- .../system/dal/mysql/dict/DictDataMapper.java | 6 +- .../dal/mysql/errorcode/ErrorCodeMapper.java | 4 +- .../errorcode/ErrorCodeServiceImpl.java | 6 +- .../errorcode/ErrorCodeServiceTest.java | 74 ++++++++++++++----- 7 files changed, 79 insertions(+), 48 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java index a7050a182..def79df69 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; import java.util.List; @@ -19,9 +18,7 @@ public interface DeptMapper extends BaseMapperX { } default DeptDO selectByParentIdAndName(Long parentId, String name) { - return selectOne(new LambdaQueryWrapper() - .eq(DeptDO::getParentId, parentId) - .eq(DeptDO::getName, name)); + return selectOne(DeptDO::getParentId, parentId, DeptDO::getName, name); } default Long selectCountByParentId(Long parentId) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/PostMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/PostMapper.java index 6bcb8e2fd..ba062a2c0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/PostMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/PostMapper.java @@ -2,11 +2,10 @@ package cn.iocoder.yudao.module.system.dal.mysql.dept; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.apache.ibatis.annotations.Mapper; import java.util.Collection; @@ -16,31 +15,32 @@ import java.util.List; public interface PostMapper extends BaseMapperX { default List selectList(Collection ids, Collection statuses) { - return selectList(new QueryWrapperX().inIfPresent("id", ids) - .inIfPresent("status", statuses)); + return selectList(new LambdaQueryWrapperX() + .inIfPresent(PostDO::getId, ids) + .inIfPresent(PostDO::getStatus, statuses)); } default PageResult selectPage(PostPageReqVO reqVO) { - return selectPage(reqVO, new QueryWrapperX() - .likeIfPresent("code", reqVO.getCode()) - .likeIfPresent("name", reqVO.getName()) - .eqIfPresent("status", reqVO.getStatus()) - .orderByDesc("id")); + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(PostDO::getCode, reqVO.getCode()) + .likeIfPresent(PostDO::getName, reqVO.getName()) + .eqIfPresent(PostDO::getStatus, reqVO.getStatus()) + .orderByDesc(PostDO::getId)); } default List selectList(PostExportReqVO reqVO) { - return selectList(new QueryWrapperX() - .likeIfPresent("code", reqVO.getCode()) - .likeIfPresent("name", reqVO.getName()) - .eqIfPresent("status", reqVO.getStatus())); + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(PostDO::getCode, reqVO.getCode()) + .likeIfPresent(PostDO::getName, reqVO.getName()) + .eqIfPresent(PostDO::getStatus, reqVO.getStatus())); } default PostDO selectByName(String name) { - return selectOne(new QueryWrapper().eq("name", name)); + return selectOne(PostDO::getName, name); } default PostDO selectByCode(String code) { - return selectOne(new QueryWrapper().eq("code", code)); + return selectOne(PostDO::getCode, code); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java index 9d2601e8f..9d74a7beb 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java @@ -28,7 +28,7 @@ public interface UserPostMapper extends BaseMapperX { .in(UserPostDO::getPostId, postIds)); } - default void deleteByUserId(Long userId){ + default void deleteByUserId(Long userId) { delete(Wrappers.lambdaUpdate(UserPostDO.class).eq(UserPostDO::getUserId, userId)); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dict/DictDataMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dict/DictDataMapper.java index 951ef87af..244825093 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dict/DictDataMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dict/DictDataMapper.java @@ -17,13 +17,11 @@ import java.util.List; public interface DictDataMapper extends BaseMapperX { default DictDataDO selectByDictTypeAndValue(String dictType, String value) { - return selectOne(new LambdaQueryWrapper().eq(DictDataDO::getDictType, dictType) - .eq(DictDataDO::getValue, value)); + return selectOne(DictDataDO::getDictType, dictType, DictDataDO::getValue, value); } default DictDataDO selectByDictTypeAndLabel(String dictType, String label) { - return selectOne(new LambdaQueryWrapper().eq(DictDataDO::getDictType, dictType) - .eq(DictDataDO::getLabel, label)); + return selectOne(DictDataDO::getDictType, dictType, DictDataDO::getLabel, label); } default List selectByDictTypeAndValues(String dictType, Collection values) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/errorcode/ErrorCodeMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/errorcode/ErrorCodeMapper.java index 3cb6bc8af..93baced06 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/errorcode/ErrorCodeMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/errorcode/ErrorCodeMapper.java @@ -36,11 +36,11 @@ public interface ErrorCodeMapper extends BaseMapperX { } default List selectListByCodes(Collection codes) { - return selectList(new LambdaQueryWrapperX().in(ErrorCodeDO::getCode, codes)); + return selectList(ErrorCodeDO::getCode, codes); } default ErrorCodeDO selectByCode(Integer code) { - return selectOne(new LambdaQueryWrapperX().eq(ErrorCodeDO::getCode, code)); + return selectOne(ErrorCodeDO::getCode, code); } default List selectListByApplicationNameAndUpdateTimeGt(String applicationName, LocalDateTime minUpdateTime) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceImpl.java index d28f2baed..ed0712a90 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceImpl.java @@ -58,7 +58,7 @@ public class ErrorCodeServiceImpl implements ErrorCodeService { @Override public void updateErrorCode(ErrorCodeUpdateReqVO updateReqVO) { // 校验存在 - this.validateErrorCodeExists(updateReqVO.getId()); + validateErrorCodeExists(updateReqVO.getId()); // 校验 code 重复 validateCodeDuplicate(updateReqVO.getCode(), updateReqVO.getId()); @@ -71,7 +71,7 @@ public class ErrorCodeServiceImpl implements ErrorCodeService { @Override public void deleteErrorCode(Long id) { // 校验存在 - this.validateErrorCodeExists(id); + validateErrorCodeExists(id); // 删除 errorCodeMapper.deleteById(id); } @@ -100,7 +100,7 @@ public class ErrorCodeServiceImpl implements ErrorCodeService { } @VisibleForTesting - public void validateErrorCodeExists(Long id) { + void validateErrorCodeExists(Long id) { if (errorCodeMapper.selectById(id) == null) { throw exception(ERROR_CODE_NOT_EXISTS); } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceTest.java index 163a2cda3..cd5e01307 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/errorcode/ErrorCodeServiceTest.java @@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.system.service.errorcode; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeAutoGenerateReqDTO; +import cn.iocoder.yudao.module.system.api.errorcode.dto.ErrorCodeRespDTO; import cn.iocoder.yudao.module.system.controller.admin.errorcode.vo.ErrorCodeCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.errorcode.vo.ErrorCodeExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.errorcode.vo.ErrorCodePageReqVO; @@ -22,7 +22,9 @@ import java.util.List; import java.util.function.Consumer; import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; @@ -57,7 +59,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { @Test public void testUpdateErrorCode_success() { // mock 数据 - ErrorCodeDO dbErrorCode = randomInfErrorCodeDO(); + ErrorCodeDO dbErrorCode = randomErrorCodeDO(); errorCodeMapper.insert(dbErrorCode);// @Sql: 先插入出一条存在的数据 // 准备参数 ErrorCodeUpdateReqVO reqVO = randomPojo(ErrorCodeUpdateReqVO.class, o -> { @@ -75,7 +77,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { @Test public void testDeleteErrorCode_success() { // mock 数据 - ErrorCodeDO dbErrorCode = randomInfErrorCodeDO(); + ErrorCodeDO dbErrorCode = randomErrorCodeDO(); errorCodeMapper.insert(dbErrorCode);// @Sql: 先插入出一条存在的数据 // 准备参数 Long id = dbErrorCode.getId(); @@ -96,7 +98,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { reqVO.setApplicationName("tu"); reqVO.setCode(1); reqVO.setMessage("ma"); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2020, 11, 1),buildTime(2020, 11, 30)})); + reqVO.setCreateTime(buildBetweenTime(2020, 11, 1, 2020, 11, 30)); // 调用 PageResult pageResult = errorCodeService.getErrorCodePage(reqVO); @@ -110,7 +112,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { * 初始化 getErrorCodePage 方法的测试数据 */ private ErrorCodeDO initGetErrorCodePage() { - ErrorCodeDO dbErrorCode = randomInfErrorCodeDO(o -> { // 等会查询到 + ErrorCodeDO dbErrorCode = randomErrorCodeDO(o -> { // 等会查询到 o.setType(ErrorCodeTypeEnum.AUTO_GENERATION.getType()); o.setApplicationName("tudou"); o.setCode(1); @@ -119,20 +121,20 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { }); errorCodeMapper.insert(dbErrorCode); // 测试 type 不匹配 - errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setType(ErrorCodeTypeEnum.MANUAL_OPERATION.getType()))); + errorCodeMapper.insert(cloneIgnoreId(dbErrorCode, o -> o.setType(ErrorCodeTypeEnum.MANUAL_OPERATION.getType()))); // 测试 applicationName 不匹配 - errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setApplicationName("yuan"))); + errorCodeMapper.insert(cloneIgnoreId(dbErrorCode, o -> o.setApplicationName("yuan"))); // 测试 code 不匹配 - errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setCode(2))); + errorCodeMapper.insert(cloneIgnoreId(dbErrorCode, o -> o.setCode(2))); // 测试 message 不匹配 - errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setMessage("nai"))); + errorCodeMapper.insert(cloneIgnoreId(dbErrorCode, o -> o.setMessage("nai"))); // 测试 createTime 不匹配 - errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setCreateTime(buildTime(2020, 12, 12)))); + errorCodeMapper.insert(cloneIgnoreId(dbErrorCode, o -> o.setCreateTime(buildTime(2020, 12, 12)))); return dbErrorCode; } @Test - public void testGetErrorCodeList() { + public void testGetErrorCodeList_export() { // mock 数据 ErrorCodeDO dbErrorCode = initGetErrorCodePage(); // 准备参数 @@ -141,7 +143,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { reqVO.setApplicationName("tu"); reqVO.setCode(1); reqVO.setMessage("ma"); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2020, 11, 1),buildTime(2020, 11, 30)})); + reqVO.setCreateTime(buildBetweenTime(2020, 11, 1, 2020, 11, 30)); // 调用 List list = errorCodeService.getErrorCodeList(reqVO); @@ -155,7 +157,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { // 准备参数 Integer code = randomInteger(); // mock 数据 - errorCodeMapper.insert(randomInfErrorCodeDO(o -> o.setCode(code))); + errorCodeMapper.insert(randomErrorCodeDO(o -> o.setCode(code))); // 调用,校验异常 assertServiceException(() -> errorCodeService.validateCodeDuplicate(code, null), @@ -168,7 +170,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { Long id = randomLongId(); Integer code = randomInteger(); // mock 数据 - errorCodeMapper.insert(randomInfErrorCodeDO(o -> o.setCode(code))); + errorCodeMapper.insert(randomErrorCodeDO(o -> o.setCode(code))); // 调用,校验异常 assertServiceException(() -> errorCodeService.validateCodeDuplicate(code, id), @@ -204,7 +206,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { @Test public void testAutoGenerateErrorCodes_021() { // mock 数据 - ErrorCodeDO dbErrorCode = randomInfErrorCodeDO(o -> o.setType(ErrorCodeTypeEnum.MANUAL_OPERATION.getType())); + ErrorCodeDO dbErrorCode = randomErrorCodeDO(o -> o.setType(ErrorCodeTypeEnum.MANUAL_OPERATION.getType())); errorCodeMapper.insert(dbErrorCode); // 准备参数 ErrorCodeAutoGenerateReqDTO generateReqDTO = randomPojo(ErrorCodeAutoGenerateReqDTO.class, @@ -224,7 +226,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { @Test public void testAutoGenerateErrorCodes_022() { // mock 数据 - ErrorCodeDO dbErrorCode = randomInfErrorCodeDO(o -> o.setType(ErrorCodeTypeEnum.AUTO_GENERATION.getType())); + ErrorCodeDO dbErrorCode = randomErrorCodeDO(o -> o.setType(ErrorCodeTypeEnum.AUTO_GENERATION.getType())); errorCodeMapper.insert(dbErrorCode); // 准备参数 ErrorCodeAutoGenerateReqDTO generateReqDTO = randomPojo(ErrorCodeAutoGenerateReqDTO.class, @@ -244,7 +246,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { @Test public void testAutoGenerateErrorCodes_023() { // mock 数据 - ErrorCodeDO dbErrorCode = randomInfErrorCodeDO(o -> o.setType(ErrorCodeTypeEnum.AUTO_GENERATION.getType())); + ErrorCodeDO dbErrorCode = randomErrorCodeDO(o -> o.setType(ErrorCodeTypeEnum.AUTO_GENERATION.getType())); errorCodeMapper.insert(dbErrorCode); // 准备参数 ErrorCodeAutoGenerateReqDTO generateReqDTO = randomPojo(ErrorCodeAutoGenerateReqDTO.class, @@ -265,7 +267,7 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { @Test public void testAutoGenerateErrorCodes_024() { // mock 数据 - ErrorCodeDO dbErrorCode = randomInfErrorCodeDO(o -> o.setType(ErrorCodeTypeEnum.AUTO_GENERATION.getType())); + ErrorCodeDO dbErrorCode = randomErrorCodeDO(o -> o.setType(ErrorCodeTypeEnum.AUTO_GENERATION.getType())); errorCodeMapper.insert(dbErrorCode); // 准备参数 ErrorCodeAutoGenerateReqDTO generateReqDTO = randomPojo(ErrorCodeAutoGenerateReqDTO.class, @@ -279,10 +281,44 @@ public class ErrorCodeServiceTest extends BaseDbUnitTest { assertPojoEquals(generateReqDTO, errorCode); } + @Test + public void testGetErrorCode() { + // 准备参数 + ErrorCodeDO errorCodeDO = randomErrorCodeDO(); + errorCodeMapper.insert(errorCodeDO); + // mock 方法 + Long id = errorCodeDO.getId(); + + // 调用 + ErrorCodeDO dbErrorCode = errorCodeService.getErrorCode(id); + // 断言 + assertPojoEquals(errorCodeDO, dbErrorCode); + } + + @Test + public void testGetErrorCodeList() { + // 准备参数 + ErrorCodeDO errorCodeDO01 = randomErrorCodeDO( + o -> o.setApplicationName("yunai_server").setUpdateTime(buildTime(2022, 1, 10))); + errorCodeMapper.insert(errorCodeDO01); + ErrorCodeDO errorCodeDO02 = randomErrorCodeDO( + o -> o.setApplicationName("yunai_server").setUpdateTime(buildTime(2022, 1, 12))); + errorCodeMapper.insert(errorCodeDO02); + // mock 方法 + String applicationName = "yunai_server"; + LocalDateTime minUpdateTime = buildTime(2022, 1, 11); + + // 调用 + List errorCodeList = errorCodeService.getErrorCodeList(applicationName, minUpdateTime); + // 断言 + assertEquals(1, errorCodeList.size()); + assertPojoEquals(errorCodeDO02, errorCodeList.get(0)); + } + // ========== 随机对象 ========== @SafeVarargs - private static ErrorCodeDO randomInfErrorCodeDO(Consumer... consumers) { + private static ErrorCodeDO randomErrorCodeDO(Consumer... consumers) { Consumer consumer = (o) -> { o.setType(randomEle(ErrorCodeTypeEnum.values()).getType()); // 保证 key 的范围 }; From 987fcd366c3f432acfd652a8d7d2dcbb9adb795c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 1 Feb 2023 08:17:03 +0800 Subject: [PATCH 30/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20LoginLogServiceImplT?= =?UTF-8?q?est=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/test/core/util/RandomUtils.java | 2 +- .../logger/LoginLogServiceImplTest.java | 124 +++++++----------- 2 files changed, 47 insertions(+), 79 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java b/yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java index 8664dae42..f4255566b 100644 --- a/yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java @@ -47,7 +47,7 @@ public class RandomUtils { } // 如果是 type、status 结尾的字段,返回 tinyint 范围 if (StrUtil.endWithAnyIgnoreCase(attributeMetadata.getAttributeName(), - "type", "status", "category", "scope")) { + "type", "status", "category", "scope", "result")) { return RandomUtil.randomInt(0, TINYINT_MAX + 1); } return RandomUtil.randomInt(); diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/LoginLogServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/LoginLogServiceImplTest.java index 101abe7d3..66eebc0bd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/LoginLogServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/LoginLogServiceImplTest.java @@ -1,29 +1,25 @@ package cn.iocoder.yudao.module.system.service.logger; -import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.framework.test.core.util.RandomUtils; import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.loginlog.LoginLogExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.loginlog.LoginLogPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.logger.LoginLogDO; import cn.iocoder.yudao.module.system.dal.mysql.logger.LoginLogMapper; -import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.List; -import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum.CAPTCHA_CODE_ERROR; +import static cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum.SUCCESS; import static org.junit.jupiter.api.Assertions.assertEquals; @Import(LoginLogServiceImpl.class) @@ -37,42 +33,31 @@ public class LoginLogServiceImplTest extends BaseDbUnitTest { @Test public void testGetLoginLogPage() { - // 构造测试数据 - // 登录成功的 - LoginLogDO loginLogDO = RandomUtils.randomPojo(LoginLogDO.class, logDO -> { - logDO.setLogType(RandomUtil.randomEle(cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum.values()).getType()); - logDO.setTraceId(TracerUtils.getTraceId()); - logDO.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue()); - - logDO.setUserIp("192.168.199.16"); - logDO.setUsername("wangkai"); - logDO.setCreateTime(buildTime(2021, 3, 6)); - logDO.setResult(SUCCESS.getResult()); + // mock 数据 + LoginLogDO loginLogDO = randomPojo(LoginLogDO.class, o -> { + o.setUserIp("192.168.199.16"); + o.setUsername("wang"); + o.setResult(SUCCESS.getResult()); + o.setCreateTime(buildTime(2021, 3, 6)); }); loginLogMapper.insert(loginLogDO); - - // 下面几个都是不匹配的数据 - // 登录失败的 - loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setResult(CAPTCHA_CODE_ERROR.getResult()))); - // 不同ip段的 - loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUserIp("192.168.128.18"))); - // 不同username - loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUsername("yunai"))); - // 构造一个早期时间 2021-02-06 00:00:00 - loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setCreateTime(buildTime(2021, 2, 6)))); - - + // 测试 status 不匹配 + loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setResult(CAPTCHA_CODE_ERROR.getResult()))); + // 测试 ip 不匹配 + loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setUserIp("192.168.128.18"))); + // 测试 username 不匹配 + loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setUsername("yunai"))); + // 测试 createTime 不匹配 + loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setCreateTime(buildTime(2021, 2, 6)))); // 构造调用参数 LoginLogPageReqVO reqVO = new LoginLogPageReqVO(); - reqVO.setUsername("wangkai"); + reqVO.setUsername("wang"); reqVO.setUserIp("192.168.199"); reqVO.setStatus(true); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 3, 5), - buildTime(2021, 3, 7)})); + reqVO.setCreateTime(buildBetweenTime(2021, 3, 5, 2021, 3, 7)); - // 调用service方法 + // 调用 PageResult pageResult = loginLogService.getLoginLogPage(reqVO); - // 断言,只查到了一条符合条件的 assertEquals(1, pageResult.getTotal()); assertEquals(1, pageResult.getList().size()); @@ -81,62 +66,45 @@ public class LoginLogServiceImplTest extends BaseDbUnitTest { @Test public void testGetLoginLogList() { - // 构造测试数据 - - // 登录成功的 - LoginLogDO loginLogDO = RandomUtils.randomPojo(LoginLogDO.class, logDO -> { - logDO.setLogType(RandomUtil.randomEle(cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum.values()).getType()); - logDO.setTraceId(TracerUtils.getTraceId()); - logDO.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue()); - - logDO.setUserIp("192.168.111.16"); - logDO.setUsername("wangxiaokai"); - logDO.setCreateTime(buildTime(2021, 3, 6)); - logDO.setResult(SUCCESS.getResult()); + // mock 数据 + LoginLogDO loginLogDO = randomPojo(LoginLogDO.class, o -> { + o.setUserIp("192.168.199.16"); + o.setUsername("wang"); + o.setResult(SUCCESS.getResult()); + o.setCreateTime(buildTime(2021, 3, 6)); }); loginLogMapper.insert(loginLogDO); - - // 下面几个都是不匹配的数据 - // 登录失败的 - loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setResult(CAPTCHA_CODE_ERROR.getResult()))); - // 不同ip段的 - loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUserIp("192.168.128.18"))); - // 不同username - loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUsername("yunai"))); - // 构造一个早期时间 2021-02-06 00:00:00 - loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setCreateTime(buildTime(2021, 2, 6)))); - + // 测试 status 不匹配 + loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setResult(CAPTCHA_CODE_ERROR.getResult()))); + // 测试 ip 不匹配 + loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setUserIp("192.168.128.18"))); + // 测试 username 不匹配 + loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setUsername("yunai"))); + // 测试 createTime 不匹配 + loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setCreateTime(buildTime(2021, 2, 6)))); // 构造调用参数 LoginLogExportReqVO reqVO = new LoginLogExportReqVO(); - reqVO.setUsername("wangxiaokai"); - reqVO.setUserIp("192.168.111"); + reqVO.setUsername("wang"); + reqVO.setUserIp("192.168.199"); reqVO.setStatus(true); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 3, 5), - buildTime(2021, 3, 7)})); + reqVO.setCreateTime(buildBetweenTime(2021, 3, 5, 2021, 3, 7)); // 调用service方法 - List loginLogList = loginLogService.getLoginLogList(reqVO); - + List list = loginLogService.getLoginLogList(reqVO); // 断言 - assertEquals(1, loginLogList.size()); - assertPojoEquals(loginLogDO, loginLogList.get(0)); + assertEquals(1, list.size()); + assertPojoEquals(loginLogDO, list.get(0)); } @Test public void testCreateLoginLog() { - LoginLogCreateReqDTO reqDTO = RandomUtils.randomPojo(LoginLogCreateReqDTO.class, vo -> { - // 指定随机的范围,避免超出范围入库失败 - vo.setUserType(randomEle(UserTypeEnum.values()).getValue()); - vo.setLogType(randomEle(LoginLogTypeEnum.values()).getType()); - vo.setResult(randomEle(values()).getResult()); - vo.setTraceId(TracerUtils.getTraceId()); - }); + LoginLogCreateReqDTO reqDTO = randomPojo(LoginLogCreateReqDTO.class); // 调用 loginLogService.createLoginLog(reqDTO); - // 断言,忽略基本字段 - LoginLogDO sysLoginLogDO = loginLogMapper.selectOne(null); - assertPojoEquals(reqDTO, sysLoginLogDO); + // 断言 + LoginLogDO loginLogDO = loginLogMapper.selectOne(null); + assertPojoEquals(reqDTO, loginLogDO); } } From aa37c2cd7c86406bc711d48f8354f0487e4a87ef Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 1 Feb 2023 08:27:02 +0800 Subject: [PATCH 31/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20OperateLogServiceImp?= =?UTF-8?q?l=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/logger/OperateLogController.java | 2 +- .../service/logger/OperateLogService.java | 4 +- .../service/logger/OperateLogServiceImpl.java | 2 +- .../logger/OperateLogServiceImplTest.java | 110 ++++++++---------- 4 files changed, 51 insertions(+), 67 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java index d23477eb8..ca3551e64 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java @@ -71,7 +71,7 @@ public class OperateLogController { @PreAuthorize("@ss.hasPermission('system:operate-log:export')") @OperateLog(type = EXPORT) public void exportOperateLog(HttpServletResponse response, @Valid OperateLogExportReqVO reqVO) throws IOException { - List list = operateLogService.getOperateLogs(reqVO); + List list = operateLogService.getOperateLogList(reqVO); // 获得拼接需要的数据 Collection userIds = CollectionUtils.convertList(list, OperateLogDO::getUserId); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java index 224a83f19..434ecbc46 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java @@ -1,8 +1,6 @@ package cn.iocoder.yudao.module.system.service.logger; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.operatelog.core.service.OperateLog; -import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService; import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO; @@ -38,6 +36,6 @@ public interface OperateLogService { * @param reqVO 列表条件 * @return 日志列表 */ - List getOperateLogs(OperateLogExportReqVO reqVO); + List getOperateLogList(OperateLogExportReqVO reqVO); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java index 8ae3d139b..fbf983b43 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java @@ -59,7 +59,7 @@ public class OperateLogServiceImpl implements OperateLogService { } @Override - public List getOperateLogs(OperateLogExportReqVO reqVO) { + public List getOperateLogList(OperateLogExportReqVO reqVO) { // 处理基于用户昵称的查询 Collection userIds = null; if (StrUtil.isNotEmpty(reqVO.getUserNickname())) { diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImplTest.java index 86be2a8bd..cb1085d3a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImplTest.java @@ -5,8 +5,6 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.framework.test.core.util.RandomUtils; @@ -16,20 +14,20 @@ import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.Oper import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.mysql.logger.OperateLogMapper; -import cn.iocoder.yudao.module.system.enums.common.SexEnum; import cn.iocoder.yudao.module.system.service.user.AdminUserService; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.Collections; import java.util.List; import static cn.hutool.core.util.RandomUtil.randomEle; import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -49,34 +47,28 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest { @Test public void testCreateOperateLogAsync() { - String traceId = TracerUtils.getTraceId(); - OperateLogCreateReqDTO reqVO = RandomUtils.randomPojo(OperateLogCreateReqDTO.class, o -> { - o.setTraceId(traceId); - o.setUserId(randomLongId()); - o.setUserType(randomEle(UserTypeEnum.values()).getValue()); - o.setExts(MapUtil.builder("orderId", randomLongId()).build()); - }); + OperateLogCreateReqDTO reqVO = RandomUtils.randomPojo(OperateLogCreateReqDTO.class, + o -> o.setExts(MapUtil.builder("orderId", randomLongId()).build())); - // 执行service方法 + // 调研 operateLogServiceImpl.createOperateLog(reqVO); - // 断言插入是否正确 - OperateLogDO sysOperateLogDO = operateLogMapper.selectOne("trace_id", traceId); - assertPojoEquals(reqVO, sysOperateLogDO); + // 断言 + OperateLogDO operateLogDO = operateLogMapper.selectOne(null); + assertPojoEquals(reqVO, operateLogDO); } @Test public void testGetOperateLogPage() { - // 构造测试数据 - // 先构造用户 + // mock(用户信息) AdminUserDO user = RandomUtils.randomPojo(AdminUserDO.class, o -> { - o.setNickname("wangkai"); - o.setSex(SexEnum.MALE.getSex()); + o.setNickname("wang"); o.setStatus(CommonStatusEnum.ENABLE.getStatus()); }); - when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user)); + when(userService.getUsersByNickname("wang")).thenReturn(Collections.singletonList(user)); Long userId = user.getId(); + // 构造操作日志 - OperateLogDO sysOperateLogDO = RandomUtils.randomPojo(OperateLogDO.class, o -> { + OperateLogDO operateLogDO = RandomUtils.randomPojo(OperateLogDO.class, o -> { o.setUserId(userId); o.setUserType(randomEle(UserTypeEnum.values()).getValue()); o.setModule("order"); @@ -85,50 +77,46 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest { o.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode()); o.setExts(MapUtil.builder("orderId", randomLongId()).build()); }); - operateLogMapper.insert(sysOperateLogDO); - - // 下面几个是不匹配的数据 - // 随机 userId - operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1))); - // module 不同 - operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setModule("user"))); - // type 不同 - operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType()))); - // createTime 不同 - operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6)))); - // resultCode 不同 - operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setResultCode(BAD_REQUEST.getCode()))); + operateLogMapper.insert(operateLogDO); + // 测试 userId 不匹配 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setUserId(userId + 1))); + // 测试 module 不匹配 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setModule("user"))); + // 测试 type 不匹配 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setType(OperateTypeEnum.IMPORT.getType()))); + // 测试 createTime 不匹配 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setStartTime(buildTime(2021, 2, 6)))); + // 测试 resultCode 不匹配 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setResultCode(BAD_REQUEST.getCode()))); // 构造调用参数 OperateLogPageReqVO reqVO = new OperateLogPageReqVO(); - reqVO.setUserNickname("wangkai"); + reqVO.setUserNickname("wang"); reqVO.setModule("order"); reqVO.setType(OperateTypeEnum.CREATE.getType()); - reqVO.setStartTime((new LocalDateTime[]{buildTime(2021, 3, 5), - buildTime(2021, 3, 7)})); + reqVO.setStartTime(buildBetweenTime(2021, 3, 5, 2021, 3, 7)); reqVO.setSuccess(true); - // 调用service方法 + // 调用 PageResult pageResult = operateLogServiceImpl.getOperateLogPage(reqVO); // 断言,只查到了一条符合条件的 assertEquals(1, pageResult.getTotal()); assertEquals(1, pageResult.getList().size()); - assertPojoEquals(sysOperateLogDO, pageResult.getList().get(0)); + assertPojoEquals(operateLogDO, pageResult.getList().get(0)); } @Test public void testGetOperateLogs() { - // 构造测试数据 - // 先构造用户 + // mock(用户信息) AdminUserDO user = RandomUtils.randomPojo(AdminUserDO.class, o -> { - o.setNickname("wangkai"); - o.setSex(SexEnum.MALE.getSex()); + o.setNickname("wang"); o.setStatus(CommonStatusEnum.ENABLE.getStatus()); }); - when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user)); + when(userService.getUsersByNickname("wang")).thenReturn(Collections.singletonList(user)); Long userId = user.getId(); + // 构造操作日志 - OperateLogDO sysOperateLogDO = RandomUtils.randomPojo(OperateLogDO.class, o -> { + OperateLogDO operateLogDO = RandomUtils.randomPojo(OperateLogDO.class, o -> { o.setUserId(userId); o.setUserType(randomEle(UserTypeEnum.values()).getValue()); o.setModule("order"); @@ -137,33 +125,31 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest { o.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode()); o.setExts(MapUtil.builder("orderId", randomLongId()).build()); }); - operateLogMapper.insert(sysOperateLogDO); - - // 下面几个是不匹配的数据 - // 随机 userId - operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1))); - // module 不同 - operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setModule("user"))); - // type 不同 - operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType()))); - // createTime 不同 - operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6)))); - // resultCode 不同 - operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setResultCode(BAD_REQUEST.getCode()))); + operateLogMapper.insert(operateLogDO); + // 测试 userId 不匹配 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setUserId(userId + 1))); + // 测试 module 不匹配 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setModule("user"))); + // 测试 type 不匹配 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setType(OperateTypeEnum.IMPORT.getType()))); + // 测试 createTime 不匹配 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setStartTime(buildTime(2021, 2, 6)))); + // 测试 resultCode 不匹配 + operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setResultCode(BAD_REQUEST.getCode()))); // 构造调用参数 OperateLogExportReqVO reqVO = new OperateLogExportReqVO(); - reqVO.setUserNickname("wangkai"); + reqVO.setUserNickname("wang"); reqVO.setModule("order"); reqVO.setType(OperateTypeEnum.CREATE.getType()); - reqVO.setStartTime((new LocalDateTime[]{buildTime(2021, 3, 5),buildTime(2021, 3, 7)})); + reqVO.setStartTime(buildBetweenTime(2021, 3, 5, 2021, 3, 7)); reqVO.setSuccess(true); // 调用 service 方法 - List list = operateLogServiceImpl.getOperateLogs(reqVO); + List list = operateLogServiceImpl.getOperateLogList(reqVO); // 断言,只查到了一条符合条件的 assertEquals(1, list.size()); - assertPojoEquals(sysOperateLogDO, list.get(0)); + assertPojoEquals(operateLogDO, list.get(0)); } } From 96e8df03984a23a82fd6afb92ecac9eb86747fab Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 1 Feb 2023 21:04:18 +0800 Subject: [PATCH 32/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20NoticeServiceImpl=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/notice/NoticeController.java | 4 +- .../system/service/notice/NoticeService.java | 2 +- .../service/notice/NoticeServiceImpl.java | 14 +-- .../service/notice/NoticeServiceImplTest.java | 105 ++++++------------ 4 files changed, 46 insertions(+), 79 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java index d14cfb733..7b5070bcd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/NoticeController.java @@ -57,8 +57,8 @@ public class NoticeController { @GetMapping("/page") @ApiOperation("获取通知公告列表") @PreAuthorize("@ss.hasPermission('system:notice:query')") - public CommonResult> pageNotices(@Validated NoticePageReqVO reqVO) { - return success(NoticeConvert.INSTANCE.convertPage(noticeService.pageNotices(reqVO))); + public CommonResult> getNoticePage(@Validated NoticePageReqVO reqVO) { + return success(NoticeConvert.INSTANCE.convertPage(noticeService.getNoticePage(reqVO))); } @GetMapping("/get") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notice/NoticeService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notice/NoticeService.java index 264fc3048..432fe876e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notice/NoticeService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notice/NoticeService.java @@ -39,7 +39,7 @@ public interface NoticeService { * @param reqVO 分页条件 * @return 部门分页列表 */ - PageResult pageNotices(NoticePageReqVO reqVO); + PageResult getNoticePage(NoticePageReqVO reqVO); /** * 获得岗位公告公告信息 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notice/NoticeServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notice/NoticeServiceImpl.java index 2b796e28c..1930e64c1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notice/NoticeServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notice/NoticeServiceImpl.java @@ -1,18 +1,18 @@ package cn.iocoder.yudao.module.system.service.notice; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeUpdateReqVO; import cn.iocoder.yudao.module.system.convert.notice.NoticeConvert; -import cn.iocoder.yudao.module.system.dal.mysql.notice.NoticeMapper; import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO; +import cn.iocoder.yudao.module.system.dal.mysql.notice.NoticeMapper; import com.google.common.annotations.VisibleForTesting; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTICE_NOT_FOUND; /** @@ -36,7 +36,7 @@ public class NoticeServiceImpl implements NoticeService { @Override public void updateNotice(NoticeUpdateReqVO reqVO) { // 校验是否存在 - this.checkNoticeExists(reqVO.getId()); + validateNoticeExists(reqVO.getId()); // 更新通知公告 NoticeDO updateObj = NoticeConvert.INSTANCE.convert(reqVO); noticeMapper.updateById(updateObj); @@ -45,13 +45,13 @@ public class NoticeServiceImpl implements NoticeService { @Override public void deleteNotice(Long id) { // 校验是否存在 - this.checkNoticeExists(id); + validateNoticeExists(id); // 删除通知公告 noticeMapper.deleteById(id); } @Override - public PageResult pageNotices(NoticePageReqVO reqVO) { + public PageResult getNoticePage(NoticePageReqVO reqVO) { return noticeMapper.selectPage(reqVO); } @@ -61,13 +61,13 @@ public class NoticeServiceImpl implements NoticeService { } @VisibleForTesting - public void checkNoticeExists(Long id) { + public void validateNoticeExists(Long id) { if (id == null) { return; } NoticeDO notice = noticeMapper.selectById(id); if (notice == null) { - throw ServiceExceptionUtil.exception(NOTICE_NOT_FOUND); + throw exception(NOTICE_NOT_FOUND); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notice/NoticeServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notice/NoticeServiceImplTest.java index a2af9545b..b4727096a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notice/NoticeServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notice/NoticeServiceImplTest.java @@ -2,75 +2,67 @@ package cn.iocoder.yudao.module.system.service.notice; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeUpdateReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO; import cn.iocoder.yudao.module.system.dal.mysql.notice.NoticeMapper; -import cn.iocoder.yudao.module.system.enums.notice.NoticeTypeEnum; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.util.function.Consumer; - -import static cn.hutool.core.util.RandomUtil.randomEle; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTICE_NOT_FOUND; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTICE_NOT_FOUND; import static org.junit.jupiter.api.Assertions.*; @Import(NoticeServiceImpl.class) class NoticeServiceImplTest extends BaseDbUnitTest { @Resource - private NoticeServiceImpl sysNoticeService; + private NoticeServiceImpl noticeService; @Resource - private NoticeMapper sysNoticeMapper; + private NoticeMapper noticeMapper; @Test - public void testPageNotices_success() { + public void testGetNoticePage_success() { // 插入前置数据 NoticeDO dbNotice = randomPojo(NoticeDO.class, o -> { o.setTitle("尼古拉斯赵四来啦!"); o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setType(randomEle(NoticeTypeEnum.values()).getType()); }); - sysNoticeMapper.insert(dbNotice); - + noticeMapper.insert(dbNotice); // 测试 title 不匹配 - sysNoticeMapper.insert(ObjectUtils.cloneIgnoreId(dbNotice, o -> o.setTitle("尼古拉斯凯奇也来啦!"))); + noticeMapper.insert(cloneIgnoreId(dbNotice, o -> o.setTitle("尼古拉斯凯奇也来啦!"))); // 测试 status 不匹配 - sysNoticeMapper.insert(ObjectUtils.cloneIgnoreId(dbNotice, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); - - - // 查询 + noticeMapper.insert(cloneIgnoreId(dbNotice, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + // 准备参数 NoticePageReqVO reqVO = new NoticePageReqVO(); reqVO.setTitle("尼古拉斯赵四来啦!"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - PageResult pageResult = sysNoticeService.pageNotices(reqVO); + // 调用 + PageResult pageResult = noticeService.getNoticePage(reqVO); // 验证查询结果经过筛选 assertEquals(1, pageResult.getTotal()); assertEquals(1, pageResult.getList().size()); assertPojoEquals(dbNotice, pageResult.getList().get(0)); - } @Test public void testGetNotice_success() { // 插入前置数据 - NoticeDO dbNotice = randomNoticeDO(); - sysNoticeMapper.insert(dbNotice); + NoticeDO dbNotice = randomPojo(NoticeDO.class); + noticeMapper.insert(dbNotice); // 查询 - NoticeDO notice = sysNoticeService.getNotice(dbNotice.getId()); + NoticeDO notice = noticeService.getNotice(dbNotice.getId()); // 验证插入与读取对象是否一致 assertNotNull(notice); @@ -80,84 +72,59 @@ class NoticeServiceImplTest extends BaseDbUnitTest { @Test public void testCreateNotice_success() { // 准备参数 - NoticeCreateReqVO reqVO = randomNoticeCreateReqVO(); - - // 校验插入是否成功 - Long noticeId = sysNoticeService.createNotice(reqVO); - assertNotNull(noticeId); + NoticeCreateReqVO reqVO = randomPojo(NoticeCreateReqVO.class); + // 调用 + Long noticeId = noticeService.createNotice(reqVO); // 校验插入属性是否正确 - NoticeDO notice = sysNoticeMapper.selectById(noticeId); + assertNotNull(noticeId); + NoticeDO notice = noticeMapper.selectById(noticeId); assertPojoEquals(reqVO, notice); } @Test public void testUpdateNotice_success() { // 插入前置数据 - NoticeDO dbNoticeDO = randomNoticeDO(); - sysNoticeMapper.insert(dbNoticeDO); + NoticeDO dbNoticeDO = randomPojo(NoticeDO.class); + noticeMapper.insert(dbNoticeDO); // 准备更新参数 - NoticeUpdateReqVO reqVO = randomNoticeUpdateReqVO(o -> o.setId(dbNoticeDO.getId())); + NoticeUpdateReqVO reqVO = randomPojo(NoticeUpdateReqVO.class, o -> o.setId(dbNoticeDO.getId())); // 更新 - sysNoticeService.updateNotice(reqVO); - + noticeService.updateNotice(reqVO); // 检验是否更新成功 - NoticeDO notice = sysNoticeMapper.selectById(reqVO.getId()); + NoticeDO notice = noticeMapper.selectById(reqVO.getId()); assertPojoEquals(reqVO, notice); } @Test public void testDeleteNotice_success() { // 插入前置数据 - NoticeDO dbNotice = randomNoticeDO(); - sysNoticeMapper.insert(dbNotice); + NoticeDO dbNotice = randomPojo(NoticeDO.class); + noticeMapper.insert(dbNotice); // 删除 - sysNoticeService.deleteNotice(dbNotice.getId()); + noticeService.deleteNotice(dbNotice.getId()); // 检查是否删除成功 - assertNull(sysNoticeMapper.selectById(dbNotice.getId())); + assertNull(noticeMapper.selectById(dbNotice.getId())); } @Test - public void checkNoticeExists_success() { + public void testValidateNoticeExists_success() { // 插入前置数据 - NoticeDO dbNotice = randomNoticeDO(); - sysNoticeMapper.insert(dbNotice); + NoticeDO dbNotice = randomPojo(NoticeDO.class); + noticeMapper.insert(dbNotice); // 成功调用 - sysNoticeService.checkNoticeExists(dbNotice.getId()); + noticeService.validateNoticeExists(dbNotice.getId()); } @Test - public void checkNoticeExists_noExists() { - assertServiceException(() -> sysNoticeService.checkNoticeExists(randomLongId()), NOTICE_NOT_FOUND); + public void testValidateNoticeExists_noExists() { + assertServiceException(() -> + noticeService.validateNoticeExists(randomLongId()), NOTICE_NOT_FOUND); } - @SafeVarargs - private static NoticeDO randomNoticeDO(Consumer... consumers) { - NoticeDO notice = randomPojo(NoticeDO.class, consumers); - notice.setType(randomEle(NoticeTypeEnum.values()).getType()); - notice.setStatus(CommonStatusEnum.ENABLE.getStatus()); - return notice; - } - - @SafeVarargs - private static NoticeUpdateReqVO randomNoticeUpdateReqVO(Consumer... consumers) { - NoticeUpdateReqVO reqVO = randomPojo(NoticeUpdateReqVO.class, consumers); - reqVO.setType(randomEle(NoticeTypeEnum.values()).getType()); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - return reqVO; - } - - private static NoticeCreateReqVO randomNoticeCreateReqVO() { - NoticeCreateReqVO reqVO = randomPojo(NoticeCreateReqVO.class); - reqVO.setType(randomEle(NoticeTypeEnum.values()).getType()); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - return reqVO; - } - - } From 3470b38de246d223d4c1bcd768a5c3e84c15c4ff Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 1 Feb 2023 21:05:40 +0800 Subject: [PATCH 33/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20OAuth2ClientServiceI?= =?UTF-8?q?mpl=E3=80=81OAuth2GrantServiceImpl=20=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth2/OAuth2ClientServiceImplTest.java | 18 +++++++++++++++++- .../oauth2/OAuth2GrantServiceImplTest.java | 8 ++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java index 50401cf97..3a671b0b9 100755 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2ClientServiceImplTest.java @@ -153,6 +153,19 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest { assertServiceException(() -> oauth2ClientService.validateClientIdExists(null, clientId), OAUTH2_CLIENT_EXISTS); } + @Test + public void testGetOAuth2Client() { + // mock 数据 + OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class); + oauth2ClientMapper.insert(clientDO); + // 准备参数 + Long id = clientDO.getId(); + + // 调用,并断言 + OAuth2ClientDO dbClientDO = oauth2ClientService.getOAuth2Client(id); + assertPojoEquals(clientDO, dbClientDO); + } + @Test public void testGetOAuth2ClientPage() { // mock 数据 @@ -203,10 +216,13 @@ public class OAuth2ClientServiceImplTest extends BaseDbUnitTest { null, null, Collections.singleton(randomString()), null), OAUTH2_CLIENT_SCOPE_OVER); assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default", null, null, null, "test"), OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH, "test"); - // 成功调用 + // 成功调用(1:参数完整) OAuth2ClientDO result = oauth2ClientService.validOAuthClientFromCache(client.getClientId(), client.getSecret(), client.getAuthorizedGrantTypes().get(0), client.getScopes(), client.getRedirectUris().get(0)); assertPojoEquals(client, result); + // 成功调用(2:只有 clientId 参数) + result = oauth2ClientService.validOAuthClientFromCache(client.getClientId()); + assertPojoEquals(client, result); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImplTest.java index 944086671..52c722831 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImplTest.java @@ -16,6 +16,7 @@ import java.util.List; import static cn.hutool.core.util.RandomUtil.randomEle; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static java.util.Collections.emptyList; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -134,6 +135,13 @@ public class OAuth2GrantServiceImplTest extends BaseMockitoUnitTest { refreshToken, clientId)); } + @Test + public void testGrantClientCredentials() { + assertThrows(UnsupportedOperationException.class, + () -> oauth2GrantService.grantClientCredentials(randomString(), emptyList()), + "暂时不支持 client_credentials 授权模式"); + } + @Test public void testRevokeToken_clientIdError() { // 准备参数 From 3aeebef03618b87dfcb1af1d81c6247c26384a0d Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 1 Feb 2023 23:33:59 +0800 Subject: [PATCH 34/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20MenuServiceImplTest?= =?UTF-8?q?=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../system/enums/permission/MenuIdEnum.java | 20 - .../admin/permission/MenuController.java | 8 +- .../system/convert/auth/AuthConvert.java | 8 +- .../dal/dataobject/permission/MenuDO.java | 7 +- .../dal/mysql/permission/MenuMapper.java | 7 +- .../service/permission/MenuService.java | 6 +- .../service/permission/MenuServiceImpl.java | 36 +- .../permission/PermissionServiceImpl.java | 2 +- .../service/tenant/TenantServiceImpl.java | 2 +- .../permission/MenuServiceImplTest.java | 407 ++++++++++++++++++ .../service/permission/MenuServiceTest.java | 384 ----------------- .../permission/PermissionServiceTest.java | 2 +- .../service/tenant/TenantServiceImplTest.java | 2 +- yudao-server/pom.xml | 10 +- 15 files changed, 456 insertions(+), 447 deletions(-) delete mode 100644 yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImplTest.java delete mode 100644 yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceTest.java diff --git a/pom.xml b/pom.xml index 86eabaec7..439f56046 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ yudao-module-system yudao-module-infra yudao-module-pay - + yudao-module-bpm diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java deleted file mode 100644 index fc2b72ac4..000000000 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.module.system.enums.permission; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * Menu 编号枚举 - */ -@Getter -@AllArgsConstructor -public enum MenuIdEnum { - - /** - * 根节点 - */ - ROOT(0L); - - private final Long id; - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java index 9813d8c0a..56b685b89 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java @@ -57,8 +57,8 @@ public class MenuController { @GetMapping("/list") @ApiOperation(value = "获取菜单列表", notes = "用于【菜单管理】界面") @PreAuthorize("@ss.hasPermission('system:menu:query')") - public CommonResult> getMenus(MenuListReqVO reqVO) { - List list = menuService.getMenus(reqVO); + public CommonResult> getMenuList(MenuListReqVO reqVO) { + List list = menuService.getMenuList(reqVO); list.sort(Comparator.comparing(MenuDO::getSort)); return success(MenuConvert.INSTANCE.convertList(list)); } @@ -66,11 +66,11 @@ public class MenuController { @GetMapping("/list-all-simple") @ApiOperation(value = "获取菜单精简信息列表", notes = "只包含被开启的菜单,用于【角色分配菜单】功能的选项。" + "在多租户的场景下,会只返回租户所在套餐有的菜单") - public CommonResult> getSimpleMenus() { + public CommonResult> getSimpleMenuList() { // 获得菜单列表,只要开启状态的 MenuListReqVO reqVO = new MenuListReqVO(); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - List list = menuService.getTenantMenus(reqVO); + List list = menuService.getMenuListByTenant(reqVO); // 排序后,返回给前端 list.sort(Comparator.comparing(MenuDO::getSort)); return success(MenuConvert.INSTANCE.convertList02(list)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java index 38e84ea1d..12fd35b1c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java @@ -9,13 +9,15 @@ import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; -import cn.iocoder.yudao.module.system.enums.permission.MenuIdEnum; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; import org.slf4j.LoggerFactory; import java.util.*; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; +import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; + @Mapper public interface AuthConvert { @@ -47,7 +49,7 @@ public interface AuthConvert { Map treeNodeMap = new LinkedHashMap<>(); menuList.forEach(menu -> treeNodeMap.put(menu.getId(), AuthConvert.INSTANCE.convertTreeNode(menu))); // 处理父子关系 - treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach(childNode -> { + treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(ID_ROOT)).forEach(childNode -> { // 获得父节点 AuthMenuRespVO parentNode = treeNodeMap.get(childNode.getParentId()); if (parentNode == null) { @@ -62,7 +64,7 @@ public interface AuthConvert { parentNode.getChildren().add(childNode); }); // 获得到所有的根节点 - return CollectionUtils.filterList(treeNodeMap.values(), node -> MenuIdEnum.ROOT.getId().equals(node.getParentId())); + return filterList(treeNodeMap.values(), node -> ID_ROOT.equals(node.getParentId())); } SocialUserBindReqDTO convert(Long userId, Integer userType, AuthSocialLoginReqVO reqVO); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/MenuDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/MenuDO.java index 5d77c50da..91e46bbff 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/MenuDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/MenuDO.java @@ -21,7 +21,12 @@ import lombok.EqualsAndHashCode; public class MenuDO extends BaseDO { /** - * 菜单ID + * 菜单编号 - 根节点 + */ + public static final Long ID_ROOT = 0L; + + /** + * 菜单编号 */ @TableId private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java index cdab84b53..3d645bdf2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; import java.util.List; @@ -13,8 +12,7 @@ import java.util.List; public interface MenuMapper extends BaseMapperX { default MenuDO selectByParentIdAndName(Long parentId, String name) { - return selectOne(new LambdaQueryWrapper().eq(MenuDO::getParentId, parentId) - .eq(MenuDO::getName, name)); + return selectOne(MenuDO::getParentId, parentId, MenuDO::getName, name); } default Long selectCountByParentId(Long parentId) { @@ -22,7 +20,8 @@ public interface MenuMapper extends BaseMapperX { } default List selectList(MenuListReqVO reqVO) { - return selectList(new LambdaQueryWrapperX().likeIfPresent(MenuDO::getName, reqVO.getName()) + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(MenuDO::getName, reqVO.getName()) .eqIfPresent(MenuDO::getStatus, reqVO.getStatus())); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java index 2bc192683..02418c077 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java @@ -47,7 +47,7 @@ public interface MenuService { * * @return 菜单列表 */ - List getMenus(); + List getMenuList(); /** * 基于租户,筛选菜单列表 @@ -56,7 +56,7 @@ public interface MenuService { * @param reqVO 筛选条件请求 VO * @return 菜单列表 */ - List getTenantMenus(MenuListReqVO reqVO); + List getMenuListByTenant(MenuListReqVO reqVO); /** * 筛选菜单列表 @@ -64,7 +64,7 @@ public interface MenuService { * @param reqVO 筛选条件请求 VO * @return 菜单列表 */ - List getMenus(MenuListReqVO reqVO); + List getMenuList(MenuListReqVO reqVO); /** * 获得所有菜单,从缓存中 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java index 32466d592..62e796784 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUp import cn.iocoder.yudao.module.system.convert.permission.MenuConvert; import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper; -import cn.iocoder.yudao.module.system.enums.permission.MenuIdEnum; import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer; import cn.iocoder.yudao.module.system.service.tenant.TenantService; @@ -19,6 +18,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -31,6 +31,7 @@ import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; +import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; /** @@ -49,6 +50,7 @@ public class MenuServiceImpl implements MenuService { * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 */ @Getter + @Setter private volatile Map menuCache; /** * 权限与菜单缓存 @@ -58,6 +60,7 @@ public class MenuServiceImpl implements MenuService { * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 */ @Getter + @Setter private volatile Multimap permissionMenuCache; @Resource @@ -97,9 +100,10 @@ public class MenuServiceImpl implements MenuService { @Override public Long createMenu(MenuCreateReqVO reqVO) { // 校验父菜单存在 - checkParentResource(reqVO.getParentId(), null); + validateParentMenu(reqVO.getParentId(), null); // 校验菜单(自己) - checkResource(reqVO.getParentId(), reqVO.getName(), null); + validateMenu(reqVO.getParentId(), reqVO.getName(), null); + // 插入数据库 MenuDO menu = MenuConvert.INSTANCE.convert(reqVO); initMenuProperty(menu); @@ -117,9 +121,10 @@ public class MenuServiceImpl implements MenuService { throw ServiceExceptionUtil.exception(MENU_NOT_EXISTS); } // 校验父菜单存在 - checkParentResource(reqVO.getParentId(), reqVO.getId()); + validateParentMenu(reqVO.getParentId(), reqVO.getId()); // 校验菜单(自己) - checkResource(reqVO.getParentId(), reqVO.getName(), reqVO.getId()); + validateMenu(reqVO.getParentId(), reqVO.getName(), reqVO.getId()); + // 更新到数据库 MenuDO updateObject = MenuConvert.INSTANCE.convert(reqVO); initMenuProperty(updateObject); @@ -128,13 +133,8 @@ public class MenuServiceImpl implements MenuService { menuProducer.sendMenuRefreshMessage(); } - /** - * 删除菜单 - * - * @param menuId 菜单编号 - */ - @Transactional(rollbackFor = Exception.class) @Override + @Transactional(rollbackFor = Exception.class) public void deleteMenu(Long menuId) { // 校验是否还有子菜单 if (menuMapper.selectCountByParentId(menuId) > 0) { @@ -160,20 +160,20 @@ public class MenuServiceImpl implements MenuService { } @Override - public List getMenus() { + public List getMenuList() { return menuMapper.selectList(); } @Override - public List getTenantMenus(MenuListReqVO reqVO) { - List menus = getMenus(reqVO); + public List getMenuListByTenant(MenuListReqVO reqVO) { + List menus = getMenuList(reqVO); // 开启多租户的情况下,需要过滤掉未开通的菜单 tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId()))); return menus; } @Override - public List getMenus(MenuListReqVO reqVO) { + public List getMenuList(MenuListReqVO reqVO) { return menuMapper.selectList(reqVO); } @@ -223,8 +223,8 @@ public class MenuServiceImpl implements MenuService { * @param childId 当前菜单编号 */ @VisibleForTesting - public void checkParentResource(Long parentId, Long childId) { - if (parentId == null || MenuIdEnum.ROOT.getId().equals(parentId)) { + void validateParentMenu(Long parentId, Long childId) { + if (parentId == null || ID_ROOT.equals(parentId)) { return; } // 不能设置自己为父菜单 @@ -253,7 +253,7 @@ public class MenuServiceImpl implements MenuService { * @param id 菜单编号 */ @VisibleForTesting - public void checkResource(Long parentId, String name, Long id) { + void validateMenu(Long parentId, String name, Long id) { MenuDO menu = menuMapper.selectByParentIdAndName(parentId, name); if (menu == null) { return; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java index 59ab61e79..e46c08db2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java @@ -190,7 +190,7 @@ public class PermissionServiceImpl implements PermissionService { public Set getRoleMenuIds(Long roleId) { // 如果是管理员的情况下,获取全部菜单编号 if (roleService.hasAnySuperAdmin(Collections.singleton(roleId))) { - return convertSet(menuService.getMenus(), MenuDO::getId); + return convertSet(menuService.getMenuList(), MenuDO::getId); } // 如果是非管理员的情况下,获得拥有的菜单编号 return convertSet(roleMenuMapper.selectListByRoleId(roleId), RoleMenuDO::getMenuId); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java index dc4a67ef0..4bfc19d9d 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java @@ -248,7 +248,7 @@ public class TenantServiceImpl implements TenantService { TenantDO tenant = getTenant(TenantContextHolder.getRequiredTenantId()); Set menuIds; if (isSystemTenant(tenant)) { // 系统租户,菜单是全量的 - menuIds = CollectionUtils.convertSet(menuService.getMenus(), MenuDO::getId); + menuIds = CollectionUtils.convertSet(menuService.getMenuList(), MenuDO::getId); } else { menuIds = tenantPackageService.getTenantPackage(tenant.getPackageId()).getMenuIds(); } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImplTest.java new file mode 100644 index 000000000..d643c5501 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImplTest.java @@ -0,0 +1,407 @@ +package cn.iocoder.yudao.module.system.service.permission; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUpdateReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; +import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper; +import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; +import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer; +import cn.iocoder.yudao.module.system.service.tenant.TenantService; +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.Multimap; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.verify; + +@Import(MenuServiceImpl.class) +public class MenuServiceImplTest extends BaseDbUnitTest { + + @Resource + private MenuServiceImpl menuService; + + @Resource + private MenuMapper menuMapper; + + @MockBean + private PermissionService permissionService; + @MockBean + private MenuProducer menuProducer; + @MockBean + private TenantService tenantService; + + @Test + public void testInitLocalCache_success() { + MenuDO menuDO1 = randomPojo(MenuDO.class); + menuMapper.insert(menuDO1); + MenuDO menuDO2 = randomPojo(MenuDO.class); + menuMapper.insert(menuDO2); + + // 调用 + menuService.initLocalCache(); + // 校验 menuCache 缓存 + Map menuCache = menuService.getMenuCache(); + assertEquals(2, menuCache.size()); + assertPojoEquals(menuDO1, menuCache.get(menuDO1.getId())); + assertPojoEquals(menuDO2, menuCache.get(menuDO2.getId())); + // 校验 permissionMenuCache 缓存 + Multimap permissionMenuCache = menuService.getPermissionMenuCache(); + assertEquals(2, permissionMenuCache.size()); + assertPojoEquals(menuDO1, permissionMenuCache.get(menuDO1.getPermission())); + assertPojoEquals(menuDO2, permissionMenuCache.get(menuDO2.getPermission())); + } + + @Test + public void testCreateMenu_success() { + // mock 数据(构造父菜单) + MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, + "parent", 0L); + menuMapper.insert(menuDO); + Long parentId = menuDO.getId(); + // 准备参数 + MenuCreateReqVO reqVO = randomPojo(MenuCreateReqVO.class, o -> { + o.setParentId(parentId); + o.setName("testSonName"); + o.setType(MenuTypeEnum.MENU.getType()); + }); + Long menuId = menuService.createMenu(reqVO); + + // 校验记录的属性是否正确 + MenuDO dbMenu = menuMapper.selectById(menuId); + assertPojoEquals(reqVO, dbMenu); + // 校验调用 + verify(menuProducer).sendMenuRefreshMessage(); + } + + @Test + public void testUpdateMenu_success() { + // mock 数据(构造父子菜单) + MenuDO sonMenuDO = initParentAndSonMenu(); + Long sonId = sonMenuDO.getId(); + // 准备参数 + MenuUpdateReqVO reqVO = randomPojo(MenuUpdateReqVO.class, o -> { + o.setId(sonId); + o.setName("testSonName"); // 修改名字 + o.setParentId(sonMenuDO.getParentId()); + o.setType(MenuTypeEnum.MENU.getType()); + }); + + // 调用 + menuService.updateMenu(reqVO); + // 校验记录的属性是否正确 + MenuDO dbMenu = menuMapper.selectById(sonId); + assertPojoEquals(reqVO, dbMenu); + // 校验调用 + verify(menuProducer).sendMenuRefreshMessage(); + } + + @Test + public void testUpdateMenu_sonIdNotExist() { + // 准备参数 + MenuUpdateReqVO reqVO = randomPojo(MenuUpdateReqVO.class); + // 调用,并断言异常 + assertServiceException(() -> menuService.updateMenu(reqVO), MENU_NOT_EXISTS); + } + + @Test + public void testDeleteMenu_success() { + // mock 数据 + MenuDO menuDO = randomPojo(MenuDO.class); + menuMapper.insert(menuDO); + // 准备参数 + Long id = menuDO.getId(); + + // 调用 + menuService.deleteMenu(id); + // 断言 + MenuDO dbMenuDO = menuMapper.selectById(id); + assertNull(dbMenuDO); + verify(permissionService).processMenuDeleted(id); + verify(menuProducer).sendMenuRefreshMessage(); + } + + @Test + public void testDeleteMenu_menuNotExist() { + assertServiceException(() -> menuService.deleteMenu(randomLongId()), + MENU_NOT_EXISTS); + } + + @Test + public void testDeleteMenu_existChildren() { + // mock 数据(构造父子菜单) + MenuDO sonMenu = initParentAndSonMenu(); + // 准备参数 + Long parentId = sonMenu.getParentId(); + + // 调用并断言异常 + assertServiceException(() -> menuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN); + } + + @Test + public void testGetMenuList_all() { + // mock 数据 + MenuDO menu100 = randomPojo(MenuDO.class); + menuMapper.insert(menu100); + MenuDO menu101 = randomPojo(MenuDO.class); + menuMapper.insert(menu101); + // 准备参数 + + // 调用 + List list = menuService.getMenuList(); + // 断言 + assertEquals(2, list.size()); + assertPojoEquals(menu100, list.get(0)); + assertPojoEquals(menu101, list.get(1)); + } + + @Test + public void testGetMenuList() { + // mock 数据 + MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setName("芋艿").setStatus(CommonStatusEnum.ENABLE.getStatus())); + menuMapper.insert(menuDO); + // 测试 status 不匹配 + menuMapper.insert(cloneIgnoreId(menuDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + // 测试 name 不匹配 + menuMapper.insert(cloneIgnoreId(menuDO, o -> o.setName("艿"))); + // 准备参数 + MenuListReqVO reqVO = new MenuListReqVO().setName("芋").setStatus(CommonStatusEnum.ENABLE.getStatus()); + + // 调用 + List result = menuService.getMenuList(reqVO); + // 断言 + assertEquals(1, result.size()); + assertPojoEquals(menuDO, result.get(0)); + } + + @Test + public void testGetMenuListByTenant() { + // mock 数据 + MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus())); + menuMapper.insert(menu100); + MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus())); + menuMapper.insert(menu101); + MenuDO menu102 = randomPojo(MenuDO.class, o -> o.setId(102L).setStatus(CommonStatusEnum.ENABLE.getStatus())); + menuMapper.insert(menu102); + // mock 过滤菜单 + Set menuIds = asSet(100L, 101L); + doNothing().when(tenantService).handleTenantMenu(argThat(handler -> { + handler.handle(menuIds); + return true; + })); + // 准备参数 + MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()); + + // 调用 + List result = menuService.getMenuListByTenant(reqVO); + // 断言 + assertEquals(1, result.size()); + assertPojoEquals(menu100, result.get(0)); + } + + @Test + public void testListMenusFromCache_withoutId() { + // mock 缓存 + Map menuCache = new HashMap<>(); + // 可被匹配 + MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setId(1L) + .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus())); + menuCache.put(menuDO.getId(), menuDO); + // 测试 type 不匹配 + menuCache.put(3L, randomPojo(MenuDO.class, o -> o.setId(3L) + .setType(MenuTypeEnum.BUTTON.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus()))); + // 测试 status 不匹配 + menuCache.put(4L, randomPojo(MenuDO.class, o -> o.setId(4L) + .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.DISABLE.getStatus()))); + menuService.setMenuCache(menuCache); + // 准备参数 + Collection menuTypes = singletonList(MenuTypeEnum.MENU.getType()); + Collection menusStatuses = singletonList(CommonStatusEnum.ENABLE.getStatus()); + + // 调用 + List list = menuService.getMenuListFromCache(menuTypes, menusStatuses); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(menuDO, list.get(0)); + } + + @Test + public void testListMenusFromCache_withId() { + // mock 缓存 + Map menuCache = new HashMap<>(); + // 可被匹配 + MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setId(1L) + .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus())); + menuCache.put(menuDO.getId(), menuDO); + // 测试 id 不匹配 + menuCache.put(2L, randomPojo(MenuDO.class, o -> o.setId(2L) + .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus()))); + // 测试 type 不匹配 + menuCache.put(3L, randomPojo(MenuDO.class, o -> o.setId(3L) + .setType(MenuTypeEnum.BUTTON.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus()))); + // 测试 status 不匹配 + menuCache.put(4L, randomPojo(MenuDO.class, o -> o.setId(4L) + .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.DISABLE.getStatus()))); + menuService.setMenuCache(menuCache); + // 准备参数 + Collection menuIds = asList(1L, 3L, 4L); + Collection menuTypes = singletonList(MenuTypeEnum.MENU.getType()); + Collection menusStatuses = singletonList(CommonStatusEnum.ENABLE.getStatus()); + + // 调用 + List list = menuService.getMenuListFromCache(menuIds, menuTypes, menusStatuses); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(menuDO, list.get(0)); + } + + @Test + public void testGetMenuListByPermissionFromCache() { + // mock 缓存 + Multimap permissionMenuCache = LinkedListMultimap.create(); + // 可被匹配 + MenuDO menuDO01 = randomPojo(MenuDO.class, o -> o.setId(1L).setPermission("123")); + permissionMenuCache.put(menuDO01.getPermission(), menuDO01); + MenuDO menuDO02 = randomPojo(MenuDO.class, o -> o.setId(2L).setPermission("123")); + permissionMenuCache.put(menuDO02.getPermission(), menuDO02); + // 不可匹配 + permissionMenuCache.put("456", randomPojo(MenuDO.class, o -> o.setId(3L).setPermission("456"))); + menuService.setPermissionMenuCache(permissionMenuCache); + // 准备参数 + String permission = "123"; + + // 调用 + List list = menuService.getMenuListByPermissionFromCache(permission); + // 断言 + assertEquals(2, list.size()); + assertPojoEquals(menuDO01, list.get(0)); + assertPojoEquals(menuDO02, list.get(1)); + } + + @Test + public void testGetMenu() { + // mock 数据 + MenuDO menu = randomPojo(MenuDO.class); + menuMapper.insert(menu); + // 准备参数 + Long id = menu.getId(); + + // 调用 + MenuDO dbMenu = menuService.getMenu(id); + // 断言 + assertPojoEquals(menu, dbMenu); + } + + @Test + public void testValidateParentMenu_success() { + // mock 数据 + MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); + menuMapper.insert(menuDO); + // 准备参数 + Long parentId = menuDO.getId(); + + // 调用,无需断言 + menuService.validateParentMenu(parentId, null); + } + + @Test + public void testValidateParentMenu_canNotSetSelfToBeParent() { + // 调用,并断言异常 + assertServiceException(() -> menuService.validateParentMenu(1L, 1L), + MENU_PARENT_ERROR); + } + + @Test + public void testValidateParentMenu_parentNotExist() { + // 调用,并断言异常 + assertServiceException(() -> menuService.validateParentMenu(randomLongId(), null), + MENU_PARENT_NOT_EXISTS); + } + + @Test + public void testValidateParentMenu_parentTypeError() { + // mock 数据 + MenuDO menuDO = createMenuDO(MenuTypeEnum.BUTTON, "parent", 0L); + menuMapper.insert(menuDO); + // 准备参数 + Long parentId = menuDO.getId(); + + // 调用,并断言异常 + assertServiceException(() -> menuService.validateParentMenu(parentId, null), + MENU_PARENT_NOT_DIR_OR_MENU); + } + + @Test + public void testValidateMenu_success() { + // mock 父子菜单 + MenuDO sonMenu = initParentAndSonMenu(); + // 准备参数 + Long parentId = sonMenu.getParentId(); + Long otherSonMenuId = randomLongId(); + String otherSonMenuName = randomString(); + + // 调用,无需断言 + menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId); + } + + @Test + public void testValidateMenu_sonMenuNameDuplicate() { + // mock 父子菜单 + MenuDO sonMenu = initParentAndSonMenu(); + // 准备参数 + Long parentId = sonMenu.getParentId(); + Long otherSonMenuId = randomLongId(); + String otherSonMenuName = sonMenu.getName(); //相同名称 + + // 调用,并断言异常 + assertServiceException(() -> menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId), + MENU_NAME_DUPLICATE); + } + + // ====================== 初始化方法 ====================== + + /** + * 构造父子菜单,返回子菜单 + * + * @return 子菜单 + */ + private MenuDO initParentAndSonMenu() { + // 构造父子菜单 + MenuDO parentMenuDO = createMenuDO(MenuTypeEnum.MENU, "parent", ID_ROOT); + menuMapper.insert(parentMenuDO); + // 构建子菜单 + MenuDO sonMenuDO = createMenuDO(MenuTypeEnum.MENU, "testSonName", + parentMenuDO.getParentId()); + menuMapper.insert(sonMenuDO); + return sonMenuDO; + } + + private MenuDO createMenuDO(MenuTypeEnum type, String name, Long parentId) { + return createMenuDO(type, name, parentId, randomCommonStatus()); + } + + private MenuDO createMenuDO(MenuTypeEnum type, String name, Long parentId, Integer status) { + return randomPojo(MenuDO.class, o -> o.setId(null).setName(name).setParentId(parentId) + .setType(type.getType()).setStatus(status)); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceTest.java deleted file mode 100644 index eae4633b1..000000000 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceTest.java +++ /dev/null @@ -1,384 +0,0 @@ -package cn.iocoder.yudao.module.system.service.permission; - -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.util.spring.SpringAopUtils; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO; -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUpdateReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; -import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper; -import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; -import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer; -import cn.iocoder.yudao.module.system.service.tenant.TenantService; -import com.google.common.collect.Multimap; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.util.*; - -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.verify; - -// TODO @芋艿:单测的代码质量可以提升下 -@Import(MenuServiceImpl.class) -public class MenuServiceTest extends BaseDbUnitTest { - - @Resource - private MenuServiceImpl menuService; - - @Resource - private MenuMapper menuMapper; - - @MockBean - private PermissionService permissionService; - @MockBean - private MenuProducer menuProducer; - @MockBean - private TenantService tenantService; - - @Test - public void testInitLocalCache_success() { - MenuDO menuDO1 = randomPojo(MenuDO.class); - menuMapper.insert(menuDO1); - MenuDO menuDO2 = randomPojo(MenuDO.class); - menuMapper.insert(menuDO2); - - // 调用 - menuService.initLocalCache(); - // 校验 menuCache 缓存 - Map menuCache = menuService.getMenuCache(); - Assert.isTrue(menuCache.size() == 2); - assertPojoEquals(menuDO1, menuCache.get(menuDO1.getId())); - assertPojoEquals(menuDO2, menuCache.get(menuDO2.getId())); - // 校验 permissionMenuCache 缓存 - Multimap permissionMenuCache = menuService.getPermissionMenuCache(); - Assert.isTrue(permissionMenuCache.size() == 2); - assertPojoEquals(menuDO1, permissionMenuCache.get(menuDO1.getPermission())); - assertPojoEquals(menuDO2, permissionMenuCache.get(menuDO2.getPermission())); - } - - @Test - public void testCreateMenu_success() { - //构造父目录 - MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); - menuMapper.insert(menuDO); - Long parentId = menuDO.getId(); - - //调用 - MenuCreateReqVO vo = randomPojo(MenuCreateReqVO.class, o -> { - o.setParentId(parentId); - o.setName("testSonName"); - o.setType(MenuTypeEnum.MENU.getType()); - o.setStatus(randomCommonStatus()); - }); - Long menuId = menuService.createMenu(vo); - - //断言 - assertNotNull(menuId); - // 校验记录的属性是否正确 - MenuDO ret = menuMapper.selectById(menuId); - assertPojoEquals(vo, ret); - // 校验调用 - verify(menuProducer).sendMenuRefreshMessage(); - } - - @Test - public void testUpdateMenu_success() { - //构造父子目录 - MenuDO sonMenuDO = initParentAndSonMenuDO(); - Long sonId = sonMenuDO.getId(); - Long parentId = sonMenuDO.getParentId(); - - //调用 - MenuUpdateReqVO vo = randomPojo(MenuUpdateReqVO.class, o -> { - o.setId(sonId); - o.setParentId(parentId); - o.setType(MenuTypeEnum.MENU.getType()); - o.setStatus(randomCommonStatus()); - o.setName("pppppp"); //修改名字 - }); - menuService.updateMenu(vo); - - //断言 - // 校验记录的属性是否正确 - MenuDO ret = menuMapper.selectById(sonId); - assertPojoEquals(vo, ret); - // 校验调用 - verify(menuProducer).sendMenuRefreshMessage(); - } - - @Test - public void testUpdateMenu_sonIdNotExist() { - Long sonId = 99999L; - Long parentId = 10000L; - - //调用 - MenuUpdateReqVO vo = randomPojo(MenuUpdateReqVO.class, o -> { - o.setId(sonId); - o.setParentId(parentId); - o.setType(MenuTypeEnum.MENU.getType()); - o.setStatus(randomCommonStatus()); - }); - //断言 - assertServiceException(() -> menuService.updateMenu(vo), MENU_NOT_EXISTS); - } - - @Test - public void testDeleteMenu_success() { - MenuDO sonMenuDO = initParentAndSonMenuDO(); - Long sonId = sonMenuDO.getId(); - - // 调用 - menuService.deleteMenu(sonId); - - // 断言 - MenuDO menuDO = menuMapper.selectById(sonId); - assertNull(menuDO); - verify(permissionService).processMenuDeleted(sonId); - verify(menuProducer).sendMenuRefreshMessage(); - } - - @Test - public void testDeleteMenu_menuNotExist() { - Long sonId = 99999L; - - assertServiceException(() -> menuService.deleteMenu(sonId), MENU_NOT_EXISTS); - } - - @Test - public void testDeleteMenu_existChildren() { - MenuDO sonMenu = initParentAndSonMenuDO(); - Long parentId = sonMenu.getParentId(); - - assertServiceException(() -> menuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN); - } - - @Test - public void testGetMenus() { - // mock 数据 - MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus())); - menuMapper.insert(menu100); - MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus())); - menuMapper.insert(menu101); - // 准备参数 - MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()); - - // 调用 - List result = menuService.getMenus(reqVO); - // 断言 - assertEquals(1, result.size()); - assertPojoEquals(menu100, result.get(0)); - } - - @Test - public void testTenantMenus() { - // mock 数据 - MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus())); - menuMapper.insert(menu100); - MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus())); - menuMapper.insert(menu101); - MenuDO menu102 = randomPojo(MenuDO.class, o -> o.setId(102L).setStatus(CommonStatusEnum.ENABLE.getStatus())); - menuMapper.insert(menu102); - // mock 过滤菜单 - // mock 账户额度充足 - Set menuIds = asSet(100L, 101L); - doNothing().when(tenantService).handleTenantMenu(argThat(handler -> { - handler.handle(menuIds); - return true; - })); - // 准备参数 - MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()); - - // 调用 - List result = menuService.getTenantMenus(reqVO); - // 断言 - assertEquals(1, result.size()); - assertPojoEquals(menu100, result.get(0)); - } - - @Test - public void testGetMenusReqVo_success() { - Map idMenuMap = new HashMap<>(); - // 用于验证可以模糊搜索名称包含"name",状态为1的menu - MenuDO menu = createMenuDO(MenuTypeEnum.MENU, "name2", 0L, 1); - menuMapper.insert(menu); - idMenuMap.put(menu.getId(), menu); - - menu = createMenuDO(MenuTypeEnum.MENU, "11name111", 0L, 1); - menuMapper.insert(menu); - idMenuMap.put(menu.getId(), menu); - - menu = createMenuDO(MenuTypeEnum.MENU, "name", 0L, 1); - menuMapper.insert(menu); - idMenuMap.put(menu.getId(), menu); - - // 以下是不符合搜索条件的的menu - menu = createMenuDO(MenuTypeEnum.MENU, "xxxxxx", 0L, 1); - menuMapper.insert(menu); - menu = createMenuDO(MenuTypeEnum.MENU, "name", 0L, 2); - menuMapper.insert(menu); - - // 调用 - MenuListReqVO reqVO = new MenuListReqVO(); - reqVO.setStatus(1); - reqVO.setName("name"); - List menuDOS = menuService.getMenus(reqVO); - - // 断言 - assertEquals(menuDOS.size(), idMenuMap.size()); - menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m)); - } - - @Test - public void testListMenusFromCache_success() throws Exception { - Map mockCacheMap = new HashMap<>(); - // 获取代理对象 - MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService); - BeanUtil.setFieldValue(target, "menuCache", mockCacheMap); - - Map idMenuMap = new HashMap<>(); - // 用于验证搜索类型为MENU,状态为1的menu - MenuDO menuDO = createMenuDO(1L, MenuTypeEnum.MENU, "name", 0L, 1); - mockCacheMap.put(menuDO.getId(), menuDO); - idMenuMap.put(menuDO.getId(), menuDO); - - menuDO = createMenuDO(2L, MenuTypeEnum.MENU, "name", 0L, 1); - mockCacheMap.put(menuDO.getId(), menuDO); - idMenuMap.put(menuDO.getId(), menuDO); - - // 以下是不符合搜索条件的menu - menuDO = createMenuDO(3L, MenuTypeEnum.BUTTON, "name", 0L, 1); - mockCacheMap.put(menuDO.getId(), menuDO); - menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2); - mockCacheMap.put(menuDO.getId(), menuDO); - - List menuDOS = menuService.getMenuListFromCache(Collections.singletonList(MenuTypeEnum.MENU.getType()), - Collections.singletonList(CommonStatusEnum.DISABLE.getStatus())); - assertEquals(menuDOS.size(), idMenuMap.size()); - menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m)); - } - - @Test - public void testListMenusFromCache2_success() throws Exception { - Map mockCacheMap = new HashMap<>(); - // 获取代理对象 - MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService); - BeanUtil.setFieldValue(target, "menuCache", mockCacheMap); - - Map idMenuMap = new HashMap<>(); - // 验证搜索id为1, 类型为MENU, 状态为1 的menu - MenuDO menuDO = createMenuDO(1L, MenuTypeEnum.MENU, "name", 0L, 1); - mockCacheMap.put(menuDO.getId(), menuDO); - idMenuMap.put(menuDO.getId(), menuDO); - - // 以下是不符合搜索条件的menu - menuDO = createMenuDO(2L, MenuTypeEnum.MENU, "name", 0L, 1); - mockCacheMap.put(menuDO.getId(), menuDO); - menuDO = createMenuDO(3L, MenuTypeEnum.BUTTON, "name", 0L, 1); - mockCacheMap.put(menuDO.getId(), menuDO); - menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2); - mockCacheMap.put(menuDO.getId(), menuDO); - - List menuDOS = menuService.getMenuListFromCache(Collections.singletonList(1L), - Collections.singletonList(MenuTypeEnum.MENU.getType()), Collections.singletonList(1)); - assertEquals(menuDOS.size(), idMenuMap.size()); - menuDOS.forEach(menu -> assertPojoEquals(idMenuMap.get(menu.getId()), menu)); - } - - @Test - public void testCheckParentResource_success() { - MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); - menuMapper.insert(menuDO); - Long parentId = menuDO.getId(); - - menuService.checkParentResource(parentId, null); - } - - @Test - public void testCheckParentResource_canNotSetSelfToBeParent() { - assertServiceException(() -> menuService.checkParentResource(1L, 1L), MENU_PARENT_ERROR); - } - - @Test - public void testCheckParentResource_parentNotExist() { - assertServiceException(() -> menuService.checkParentResource(randomLongId(), null), MENU_PARENT_NOT_EXISTS); - } - - @Test - public void testCheckParentResource_parentTypeError() { - MenuDO menuDO = createMenuDO(MenuTypeEnum.BUTTON, "parent", 0L); - menuMapper.insert(menuDO); - Long parentId = menuDO.getId(); - - assertServiceException(() -> menuService.checkParentResource(parentId, null), MENU_PARENT_NOT_DIR_OR_MENU); - } - - @Test - public void testCheckResource_success() { - MenuDO sonMenu = initParentAndSonMenuDO(); - Long parentId = sonMenu.getParentId(); - - Long otherSonMenuId = randomLongId(); - String otherSonMenuName = randomString(); - - menuService.checkResource(parentId, otherSonMenuName, otherSonMenuId); - } - - @Test - public void testCheckResource_sonMenuNameDuplicate(){ - MenuDO sonMenu=initParentAndSonMenuDO(); - Long parentId=sonMenu.getParentId(); - - Long otherSonMenuId=randomLongId(); - String otherSonMenuName=sonMenu.getName(); //相同名称 - - assertServiceException(() -> menuService.checkResource(parentId, otherSonMenuName, otherSonMenuId), MENU_NAME_DUPLICATE); - } - - /** - * 构造父子目录,返回子目录 - * - * @return - */ - private MenuDO initParentAndSonMenuDO() { - //构造父子目录 - MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); - menuMapper.insert(menuDO); - Long parentId = menuDO.getId(); - - MenuDO sonMenuDO = createMenuDO(MenuTypeEnum.MENU, "testSonName", parentId); - menuMapper.insert(sonMenuDO); - return sonMenuDO; - } - - private MenuDO createMenuDO(MenuTypeEnum typeEnum, String menuName, Long parentId) { - return createMenuDO(typeEnum, menuName, parentId, randomCommonStatus()); - } - - private MenuDO createMenuDO(MenuTypeEnum typeEnum, String menuName, Long parentId, Integer status) { - return createMenuDO(null, typeEnum, menuName, parentId, status); - } - - private MenuDO createMenuDO(Long id, MenuTypeEnum typeEnum, String menuName, Long parentId, Integer status) { - return randomPojo(MenuDO.class, o -> { - o.setId(id); - o.setParentId(parentId); - o.setType(typeEnum.getType()); - o.setStatus(status); - o.setName(menuName); - }); - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java index 93e521beb..a5a9970c8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java @@ -163,7 +163,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { // mock 方法 when(roleService.hasAnySuperAdmin(eq(singleton(100L)))).thenReturn(true); List menuList = singletonList(randomPojo(MenuDO.class).setId(1L)); - when(menuService.getMenus()).thenReturn(menuList); + when(menuService.getMenuList()).thenReturn(menuList); // 调用 Set menuIds = permissionService.getRoleMenuIds(roleId); diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java index dfaebdbb7..e2cce6a33 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java @@ -453,7 +453,7 @@ public class TenantServiceImplTest extends BaseDbUnitTest { tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据 TenantContextHolder.setTenantId(dbTenant.getId()); // mock 菜单 - when(menuService.getMenus()).thenReturn(Arrays.asList(randomPojo(MenuDO.class, o -> o.setId(100L)), + when(menuService.getMenuList()).thenReturn(Arrays.asList(randomPojo(MenuDO.class, o -> o.setId(100L)), randomPojo(MenuDO.class, o -> o.setId(101L)))); // 调用 diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 546eff421..c7ded6f52 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -48,11 +48,11 @@ - - - - - + + cn.iocoder.boot + yudao-module-bpm-biz + ${revision} + cn.iocoder.boot From 96e8fa42169b9ae0226ade63a15a612be19dcb34 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Feb 2023 09:13:14 +0800 Subject: [PATCH 35/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20RoleServiceImpl=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BpmTaskAssignRuleServiceImpl.java | 2 +- .../module/system/api/permission/RoleApi.java | 2 +- .../system/api/permission/RoleApiImpl.java | 4 +- .../controller/admin/auth/AuthController.java | 2 +- .../admin/permission/RoleController.java | 6 +- .../admin/user/UserProfileController.java | 2 +- .../permission/PermissionServiceImpl.java | 6 +- .../service/permission/RoleService.java | 8 +- .../service/permission/RoleServiceImpl.java | 40 +- .../service/tenant/TenantServiceImpl.java | 2 +- .../permission/PermissionServiceTest.java | 14 +- .../permission/RoleServiceImplTest.java | 399 ++++++++++++++++++ .../service/permission/RoleServiceTest.java | 301 ------------- .../service/tenant/TenantServiceImplTest.java | 2 +- 14 files changed, 444 insertions(+), 346 deletions(-) create mode 100644 yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java delete mode 100644 yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index 742489e41..146de14d0 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -213,7 +213,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { private void validTaskAssignRuleOptions(Integer type, Set options) { if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.ROLE.getType())) { - roleApi.validRoles(options); + roleApi.validRoleList(options); } else if (ObjectUtils.equalsAny(type, BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType())) { deptApi.validateDeptList(options); diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/RoleApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/RoleApi.java index 14133e9d9..309c9ef6e 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/RoleApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/RoleApi.java @@ -16,6 +16,6 @@ public interface RoleApi { * * @param ids 角色编号数组 */ - void validRoles(Collection ids); + void validRoleList(Collection ids); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/RoleApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/RoleApiImpl.java index 2c4f94737..d8622a29a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/RoleApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/RoleApiImpl.java @@ -18,7 +18,7 @@ public class RoleApiImpl implements RoleApi { private RoleService roleService; @Override - public void validRoles(Collection ids) { - roleService.validRoles(ids); + public void validRoleList(Collection ids) { + roleService.validateRoleList(ids); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java index 9a9c0a95e..c28360326 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java @@ -97,7 +97,7 @@ public class AuthController { } // 获得角色列表 Set roleIds = permissionService.getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); - List roleList = roleService.getRolesFromCache(roleIds); + List roleList = roleService.getRoleListFromCache(roleIds); // 获得菜单列表 List menuList = permissionService.getRoleMenuListFromCache(roleIds, SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()), diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java index 3716c8e7c..a8262c7d5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java @@ -20,12 +20,12 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; -import java.util.Collections; import java.util.Comparator; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; +import static java.util.Collections.singleton; @Api(tags = "管理后台 - 角色") @RestController @@ -85,9 +85,9 @@ public class RoleController { @GetMapping("/list-all-simple") @ApiOperation(value = "获取角色精简信息列表", notes = "只包含被开启的角色,主要用于前端的下拉选项") - public CommonResult> getSimpleRoles() { + public CommonResult> getSimpleRoleList() { // 获得角色列表,只要开启状态的 - List list = roleService.getRoles(Collections.singleton(CommonStatusEnum.ENABLE.getStatus())); + List list = roleService.getRoleListByStatus(singleton(CommonStatusEnum.ENABLE.getStatus())); // 排序后,返回给前端 list.sort(Comparator.comparing(RoleDO::getSort)); return success(RoleConvert.INSTANCE.convertList02(list)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java index 00ca373e2..ce6954694 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java @@ -63,7 +63,7 @@ public class UserProfileController { AdminUserDO user = userService.getUser(getLoginUserId()); UserProfileRespVO resp = UserConvert.INSTANCE.convert03(user); // 获得用户角色 - List userRoles = roleService.getRolesFromCache(permissionService.getUserRoleIdListByUserId(user.getId())); + List userRoles = roleService.getRoleListFromCache(permissionService.getUserRoleIdListByUserId(user.getId())); resp.setRoles(UserConvert.INSTANCE.convertList(userRoles)); // 获得部门信息 if (user.getDeptId() != null) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java index e46c08db2..43365cf46 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java @@ -158,7 +158,7 @@ public class PermissionServiceImpl implements PermissionService { } // 判断角色是否包含超级管理员。如果是超级管理员,获取到全部 - List roleList = roleService.getRolesFromCache(roleIds); + List roleList = roleService.getRoleListFromCache(roleIds); if (roleService.hasAnySuperAdmin(roleList)) { return menuService.getMenuListFromCache(menuTypes, menusStatuses); } @@ -371,7 +371,7 @@ public class PermissionServiceImpl implements PermissionService { if (roleService.hasAnySuperAdmin(roleIds)) { return true; } - Set userRoles = convertSet(roleService.getRolesFromCache(roleIds), + Set userRoles = convertSet(roleService.getRoleListFromCache(roleIds), RoleDO::getCode); return CollUtil.containsAny(userRoles, Sets.newHashSet(roles)); } @@ -388,7 +388,7 @@ public class PermissionServiceImpl implements PermissionService { result.setSelf(true); return result; } - List roles = roleService.getRolesFromCache(roleIds); + List roles = roleService.getRoleListFromCache(roleIds); // 获得用户的部门编号的缓存,通过 Guava 的 Suppliers 惰性求值,即有且仅有第一次发起 DB 的查询 Supplier userDeptIdCache = Suppliers.memoize(() -> userService.getUser(userId).getDeptId()); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java index a06095844..70acbdcb7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java @@ -79,7 +79,7 @@ public interface RoleService { * @param statuses 筛选的状态。允许空,空时不筛选 * @return 角色列表 */ - List getRoles(@Nullable Collection statuses); + List getRoleListByStatus(@Nullable Collection statuses); /** * 获得角色数组,从缓存中 @@ -87,7 +87,7 @@ public interface RoleService { * @param ids 角色编号数组 * @return 角色数组 */ - List getRolesFromCache(Collection ids); + List getRoleListFromCache(Collection ids); /** * 判断角色数组中,是否有超级管理员 @@ -104,7 +104,7 @@ public interface RoleService { * @return 是否有管理员 */ default boolean hasAnySuperAdmin(Set ids) { - return hasAnySuperAdmin(getRolesFromCache(ids)); + return hasAnySuperAdmin(getRoleListFromCache(ids)); } /** @@ -138,6 +138,6 @@ public interface RoleService { * * @param ids 角色编号数组 */ - void validRoles(Collection ids); + void validateRoleList(Collection ids); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java index 3f9ee1351..30ac2daa0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java @@ -5,7 +5,6 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleExportReqVO; @@ -34,6 +33,7 @@ import java.util.*; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; /** @@ -76,7 +76,7 @@ public class RoleServiceImpl implements RoleService { log.info("[initLocalCache][缓存角色,数量为:{}]", roleList.size()); // 第二步:构建缓存 - roleCache = CollectionUtils.convertMap(roleList, RoleDO::getId); + roleCache = convertMap(roleList, RoleDO::getId); }); } @@ -84,7 +84,7 @@ public class RoleServiceImpl implements RoleService { @Transactional public Long createRole(RoleCreateReqVO reqVO, Integer type) { // 校验角色 - checkDuplicateRole(reqVO.getName(), reqVO.getCode(), null); + validateRoleDuplicate(reqVO.getName(), reqVO.getCode(), null); // 插入到数据库 RoleDO role = RoleConvert.INSTANCE.convert(reqVO); role.setType(ObjectUtil.defaultIfNull(type, RoleTypeEnum.CUSTOM.getType())); @@ -105,13 +105,13 @@ public class RoleServiceImpl implements RoleService { @Override public void updateRole(RoleUpdateReqVO reqVO) { // 校验是否可以更新 - checkUpdateRole(reqVO.getId()); + validateRoleForUpdate(reqVO.getId()); // 校验角色的唯一字段是否重复 - checkDuplicateRole(reqVO.getName(), reqVO.getCode(), reqVO.getId()); + validateRoleDuplicate(reqVO.getName(), reqVO.getCode(), reqVO.getId()); // 更新到数据库 - RoleDO updateObject = RoleConvert.INSTANCE.convert(reqVO); - roleMapper.updateById(updateObject); + RoleDO updateObj = RoleConvert.INSTANCE.convert(reqVO); + roleMapper.updateById(updateObj); // 发送刷新消息 roleProducer.sendRoleRefreshMessage(); } @@ -119,12 +119,11 @@ public class RoleServiceImpl implements RoleService { @Override public void updateRoleStatus(Long id, Integer status) { // 校验是否可以更新 - checkUpdateRole(id); + validateRoleForUpdate(id); + // 更新状态 - RoleDO updateObject = new RoleDO(); - updateObject.setId(id); - updateObject.setStatus(status); - roleMapper.updateById(updateObject); + RoleDO updateObj = new RoleDO().setId(id).setStatus(status); + roleMapper.updateById(updateObj); // 发送刷新消息 roleProducer.sendRoleRefreshMessage(); } @@ -132,7 +131,8 @@ public class RoleServiceImpl implements RoleService { @Override public void updateRoleDataScope(Long id, Integer dataScope, Set dataScopeDeptIds) { // 校验是否可以更新 - checkUpdateRole(id); + validateRoleForUpdate(id); + // 更新数据范围 RoleDO updateObject = new RoleDO(); updateObject.setId(id); @@ -147,7 +147,7 @@ public class RoleServiceImpl implements RoleService { @Transactional(rollbackFor = Exception.class) public void deleteRole(Long id) { // 校验是否可以更新 - this.checkUpdateRole(id); + validateRoleForUpdate(id); // 标记删除 roleMapper.deleteById(id); // 删除相关数据 @@ -169,7 +169,7 @@ public class RoleServiceImpl implements RoleService { } @Override - public List getRoles(@Nullable Collection statuses) { + public List getRoleListByStatus(@Nullable Collection statuses) { if (CollUtil.isEmpty(statuses)) { return roleMapper.selectList(); } @@ -177,7 +177,7 @@ public class RoleServiceImpl implements RoleService { } @Override - public List getRolesFromCache(Collection ids) { + public List getRoleListFromCache(Collection ids) { if (CollectionUtil.isEmpty(ids)) { return Collections.emptyList(); } @@ -219,7 +219,7 @@ public class RoleServiceImpl implements RoleService { * @param id 角色编号 */ @VisibleForTesting - public void checkDuplicateRole(String name, String code, Long id) { + void validateRoleDuplicate(String name, String code, Long id) { // 0. 超级管理员,不允许创建 if (RoleCodeEnum.isSuperAdmin(code)) { throw exception(ROLE_ADMIN_CODE_ERROR, code); @@ -246,7 +246,7 @@ public class RoleServiceImpl implements RoleService { * @param id 角色编号 */ @VisibleForTesting - public void checkUpdateRole(Long id) { + void validateRoleForUpdate(Long id) { RoleDO roleDO = roleMapper.selectById(id); if (roleDO == null) { throw exception(ROLE_NOT_EXISTS); @@ -258,13 +258,13 @@ public class RoleServiceImpl implements RoleService { } @Override - public void validRoles(Collection ids) { + public void validateRoleList(Collection ids) { if (CollUtil.isEmpty(ids)) { return; } // 获得角色信息 List roles = roleMapper.selectBatchIds(ids); - Map roleMap = CollectionUtils.convertMap(roles, RoleDO::getId); + Map roleMap = convertMap(roles, RoleDO::getId); // 校验 ids.forEach(id -> { RoleDO role = roleMap.get(id); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java index 4bfc19d9d..35f100210 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java @@ -156,7 +156,7 @@ public class TenantServiceImpl implements TenantService { public void updateTenantRoleMenu(Long tenantId, Set menuIds) { TenantUtils.execute(tenantId, () -> { // 获得所有角色 - List roles = roleService.getRoles(null); + List roles = roleService.getRoleListByStatus(null); roles.forEach(role -> Assert.isTrue(tenantId.equals(role.getTenantId()), "角色({}/{}) 租户不匹配", role.getId(), role.getTenantId(), tenantId)); // 兜底校验 // 重新分配每个角色的权限 diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java index a5a9970c8..35b250208 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java @@ -106,7 +106,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { Collection menusStatuses = asList(0, 1); // mock 方法 List roleList = singletonList(randomPojo(RoleDO.class, o -> o.setId(100L))); - when(roleService.getRolesFromCache(eq(roleIds))).thenReturn(roleList); + when(roleService.getRoleListFromCache(eq(roleIds))).thenReturn(roleList); when(roleService.hasAnySuperAdmin(same(roleList))).thenReturn(true); List menuList = randomPojoList(MenuDO.class); when(menuService.getMenuListFromCache(eq(menuTypes), eq(menusStatuses))).thenReturn(menuList); @@ -419,7 +419,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { .setStatus(CommonStatusEnum.ENABLE.getStatus())); when(roleService.getRoleFromCache(eq(100L))).thenReturn(role); // mock 其它方法 - when(roleService.getRolesFromCache(eq(asSet(100L)))).thenReturn(singletonList(role)); + when(roleService.getRoleListFromCache(eq(asSet(100L)))).thenReturn(singletonList(role)); // 调用 boolean has = permissionService.hasAnyRoles(userId, roles); @@ -436,7 +436,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { // mock 获得用户的角色 RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.ALL.getScope()) .setStatus(CommonStatusEnum.ENABLE.getStatus())); - when(roleService.getRolesFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO)); + when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO)); when(roleService.getRoleFromCache(eq(2L))).thenReturn(roleDO); // 调用 @@ -456,7 +456,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { // mock 获得用户的角色 RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_CUSTOM.getScope()) .setStatus(CommonStatusEnum.ENABLE.getStatus())); - when(roleService.getRolesFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO)); + when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO)); when(roleService.getRoleFromCache(eq(2L))).thenReturn(roleDO); // mock 部门的返回 when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L), null, null); // 最后返回 null 的目的,看看会不会重复调用 @@ -480,7 +480,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { // mock 获得用户的角色 RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_ONLY.getScope()) .setStatus(CommonStatusEnum.ENABLE.getStatus())); - when(roleService.getRolesFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO)); + when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO)); when(roleService.getRoleFromCache(eq(2L))).thenReturn(roleDO); // mock 部门的返回 when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L), null, null); // 最后返回 null 的目的,看看会不会重复调用 @@ -503,7 +503,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { // mock 获得用户的角色 RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_AND_CHILD.getScope()) .setStatus(CommonStatusEnum.ENABLE.getStatus())); - when(roleService.getRolesFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO)); + when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO)); when(roleService.getRoleFromCache(eq(2L))).thenReturn(roleDO); // mock 部门的返回 when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L), null, null); // 最后返回 null 的目的,看看会不会重复调用 @@ -531,7 +531,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { // mock 获得用户的角色 RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.SELF.getScope()) .setStatus(CommonStatusEnum.ENABLE.getStatus())); - when(roleService.getRolesFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO)); + when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(singletonList(roleDO)); when(roleService.getRoleFromCache(eq(2L))).thenReturn(roleDO); // 调用 diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java new file mode 100644 index 000000000..a114556c4 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java @@ -0,0 +1,399 @@ +package cn.iocoder.yudao.module.system.service.permission; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleExportReqVO; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleUpdateReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; +import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMapper; +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; +import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum; +import cn.iocoder.yudao.module.system.mq.producer.permission.RoleProducer; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.verify; + +@Import(RoleServiceImpl.class) +public class RoleServiceImplTest extends BaseDbUnitTest { + + @Resource + private RoleServiceImpl roleService; + + @Resource + private RoleMapper roleMapper; + + @MockBean + private PermissionService permissionService; + @MockBean + private RoleProducer roleProducer; + + @Test + public void testInitLocalCache() { + RoleDO roleDO1 = randomPojo(RoleDO.class); + roleMapper.insert(roleDO1); + RoleDO roleDO2 = randomPojo(RoleDO.class); + roleMapper.insert(roleDO2); + + // 调用 + roleService.initLocalCache(); + // 断言 roleCache 缓存 + Map roleCache = roleService.getRoleCache(); + assertPojoEquals(roleDO1, roleCache.get(roleDO1.getId())); + assertPojoEquals(roleDO2, roleCache.get(roleDO2.getId())); + } + + @Test + public void testCreateRole_success() { + // 准备参数 + RoleCreateReqVO reqVO = randomPojo(RoleCreateReqVO.class); + + // 调用 + Long roleId = roleService.createRole(reqVO, null); + // 断言 + RoleDO roleDO = roleMapper.selectById(roleId); + assertPojoEquals(reqVO, roleDO); + assertEquals(RoleTypeEnum.CUSTOM.getType(), roleDO.getType()); + assertEquals(CommonStatusEnum.ENABLE.getStatus(), roleDO.getStatus()); + assertEquals(DataScopeEnum.ALL.getScope(), roleDO.getDataScope()); + // verify 发送刷新消息 + verify(roleProducer).sendRoleRefreshMessage(); + } + + @Test + public void testUpdateRole_success() { + // mock 数据 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setType(RoleTypeEnum.CUSTOM.getType())); + roleMapper.insert(roleDO); + // 准备参数 + Long id = roleDO.getId(); + RoleUpdateReqVO reqVO = randomPojo(RoleUpdateReqVO.class, o -> o.setId(id)); + + // 调用 + roleService.updateRole(reqVO); + // 断言 + RoleDO newRoleDO = roleMapper.selectById(id); + assertPojoEquals(reqVO, newRoleDO); + // verify 发送刷新消息 + verify(roleProducer).sendRoleRefreshMessage(); + } + + @Test + public void testUpdateRoleStatus_success() { + // mock 数据 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()) + .setType(RoleTypeEnum.CUSTOM.getType())); + roleMapper.insert(roleDO); + + // 准备参数 + Long roleId = roleDO.getId(); + + // 调用 + roleService.updateRoleStatus(roleId, CommonStatusEnum.DISABLE.getStatus()); + // 断言 + RoleDO dbRoleDO = roleMapper.selectById(roleId); + assertEquals(CommonStatusEnum.DISABLE.getStatus(), dbRoleDO.getStatus()); + // verify 发送刷新消息 + verify(roleProducer).sendRoleRefreshMessage(); + } + + @Test + public void testUpdateRoleDataScope_success() { + // mock 数据 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setType(RoleTypeEnum.CUSTOM.getType())); + roleMapper.insert(roleDO); + // 准备参数 + Long id = roleDO.getId(); + Integer dataScope = randomEle(DataScopeEnum.values()).getScope(); + Set dataScopeRoleIds = randomSet(Long.class); + + // 调用 + roleService.updateRoleDataScope(id, dataScope, dataScopeRoleIds); + // 断言 + RoleDO dbRoleDO = roleMapper.selectById(id); + assertEquals(dataScope, dbRoleDO.getDataScope()); + assertEquals(dataScopeRoleIds, dbRoleDO.getDataScopeDeptIds()); + // verify 发送刷新消息 + verify(roleProducer).sendRoleRefreshMessage(); + } + + @Test + public void testDeleteRole_success() { + // mock 数据 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setType(RoleTypeEnum.CUSTOM.getType())); + roleMapper.insert(roleDO); + // 参数准备 + Long id = roleDO.getId(); + + // 调用 + roleService.deleteRole(id); + // 断言 + assertNull(roleMapper.selectById(id)); + // verify 删除相关数据 + verify(permissionService).processRoleDeleted(id); + // verify 发送刷新消息 + verify(roleProducer).sendRoleRefreshMessage(); + } + + @Test + public void testGetRoleFromCache() { + // mock 数据(缓存) + RoleDO roleDO = randomPojo(RoleDO.class); + roleMapper.insert(roleDO); + roleService.initLocalCache(); + // 参数准备 + Long id = roleDO.getId(); + + // 调用 + RoleDO dbRoleDO = roleService.getRoleFromCache(id); + // 断言 + assertPojoEquals(roleDO, dbRoleDO); + } + + @Test + public void testGetRole() { + // mock 数据 + RoleDO roleDO = randomPojo(RoleDO.class); + roleMapper.insert(roleDO); + // 参数准备 + Long id = roleDO.getId(); + + // 调用 + RoleDO dbRoleDO = roleService.getRole(id); + // 断言 + assertPojoEquals(roleDO, dbRoleDO); + } + + @Test + public void testGetRoleListByStatus_statusNotEmpty() { + // mock 数据 + RoleDO dbRole = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + roleMapper.insert(dbRole); + // 测试 status 不匹配 + roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + + // 调用 + List list = roleService.getRoleListByStatus(singleton(CommonStatusEnum.ENABLE.getStatus())); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbRole, list.get(0)); + } + + @Test + public void testGetRoleListByStatus_statusEmpty() { + // mock 数据 + RoleDO dbRole01 = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + roleMapper.insert(dbRole01); + RoleDO dbRole02 = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())); + roleMapper.insert(dbRole02); + + // 调用 + List list = roleService.getRoleListByStatus(null); + // 断言 + assertEquals(2, list.size()); + assertPojoEquals(dbRole01, list.get(0)); + assertPojoEquals(dbRole02, list.get(1)); + } + + @Test + public void testGetRoleListFromCache() { + // mock 数据 + RoleDO dbRole = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + roleMapper.insert(dbRole); + // 测试 id 不匹配 + roleMapper.insert(cloneIgnoreId(dbRole, o -> {})); + roleService.initLocalCache(); + // 准备参数 + Collection ids = singleton(dbRole.getId()); + + // 调用 + List list = roleService.getRoleListFromCache(ids); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbRole, list.get(0)); + } + + @Test + public void testGetRoleList() { + // mock 数据 + RoleDO dbRole = randomPojo(RoleDO.class, o -> { // 等会查询到 + o.setName("土豆"); + o.setCode("tudou"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setCreateTime(buildTime(2022, 2, 8)); + }); + roleMapper.insert(dbRole); + // 测试 name 不匹配 + roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setName("红薯"))); + // 测试 code 不匹配 + roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCode("hong"))); + // 测试 createTime 不匹配 + roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCreateTime(buildTime(2022, 2, 16)))); + // 准备参数 + RoleExportReqVO reqVO = new RoleExportReqVO(); + reqVO.setName("土豆"); + reqVO.setCode("tu"); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setCreateTime(buildBetweenTime(2022, 2, 1, 2022, 2, 12)); + + // 调用 + List list = roleService.getRoleList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbRole, list.get(0)); + } + + @Test + public void testGetRolePage() { + // mock 数据 + RoleDO dbRole = randomPojo(RoleDO.class, o -> { // 等会查询到 + o.setName("土豆"); + o.setCode("tudou"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setCreateTime(buildTime(2022, 2, 8)); + }); + roleMapper.insert(dbRole); + // 测试 name 不匹配 + roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setName("红薯"))); + // 测试 code 不匹配 + roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCode("hong"))); + // 测试 createTime 不匹配 + roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCreateTime(buildTime(2022, 2, 16)))); + // 准备参数 + RolePageReqVO reqVO = new RolePageReqVO(); + reqVO.setName("土豆"); + reqVO.setCode("tu"); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setCreateTime(buildBetweenTime(2022, 2, 1, 2022, 2, 12)); + + // 调用 + PageResult pageResult = roleService.getRolePage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbRole, pageResult.getList().get(0)); + } + + @Test + public void testHasAnySuperAdmin() { + // 是超级 + assertTrue(roleService.hasAnySuperAdmin(singletonList(randomPojo(RoleDO.class, + o -> o.setCode("super_admin"))))); + // 非超级 + assertFalse(roleService.hasAnySuperAdmin(singletonList(randomPojo(RoleDO.class, + o -> o.setCode("tenant_admin"))))); + } + + @Test + public void testValidateRoleDuplicate_success() { + // 调用,不会抛异常 + roleService.validateRoleDuplicate(randomString(), randomString(), null); + } + + @Test + public void testValidateRoleDuplicate_nameDuplicate() { + // mock 数据 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setName("role_name")); + roleMapper.insert(roleDO); + // 准备参数 + String name = "role_name"; + + // 调用,并断言异常 + assertServiceException(() -> roleService.validateRoleDuplicate(name, randomString(), null), + ROLE_NAME_DUPLICATE, name); + } + + @Test + public void testValidateRoleDuplicate_codeDuplicate() { + // mock 数据 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setCode("code")); + roleMapper.insert(roleDO); + // 准备参数 + String code = "code"; + + // 调用,并断言异常 + assertServiceException(() -> roleService.validateRoleDuplicate(randomString(), code, null), + ROLE_CODE_DUPLICATE, code); + } + + @Test + public void testValidateUpdateRole_success() { + RoleDO roleDO = randomPojo(RoleDO.class); + roleMapper.insert(roleDO); + // 准备参数 + Long id = roleDO.getId(); + + // 调用,无异常 + roleService.validateRoleForUpdate(id); + } + + @Test + public void testValidateUpdateRole_roleIdNotExist() { + assertServiceException(() -> roleService.validateRoleForUpdate(randomLongId()), ROLE_NOT_EXISTS); + } + + @Test + public void testValidateUpdateRole_systemRoleCanNotBeUpdate() { + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setType(RoleTypeEnum.SYSTEM.getType())); + roleMapper.insert(roleDO); + // 准备参数 + Long id = roleDO.getId(); + + assertServiceException(() -> roleService.validateRoleForUpdate(id), + ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE); + } + + @Test + public void testValidateRoleList_success() { + // mock 数据 + RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + roleMapper.insert(roleDO); + // 准备参数 + List ids = singletonList(roleDO.getId()); + + // 调用,无需断言 + roleService.validateRoleList(ids); + } + + @Test + public void testValidateRoleList_notFound() { + // 准备参数 + List ids = singletonList(randomLongId()); + + // 调用, 并断言异常 + assertServiceException(() -> roleService.validateRoleList(ids), ROLE_NOT_EXISTS); + } + + @Test + public void testValidateRoleList_notEnable() { + // mock 数据 + RoleDO RoleDO = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())); + roleMapper.insert(RoleDO); + // 准备参数 + List ids = singletonList(RoleDO.getId()); + + // 调用, 并断言异常 + assertServiceException(() -> roleService.validateRoleList(ids), ROLE_IS_DISABLE, RoleDO.getName()); + } +} diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java deleted file mode 100644 index a0d6c79a0..000000000 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceTest.java +++ /dev/null @@ -1,301 +0,0 @@ -package cn.iocoder.yudao.module.system.service.permission; - -import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO; -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleExportReqVO; -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleUpdateReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; -import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMapper; -import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; -import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum; -import cn.iocoder.yudao.module.system.mq.producer.permission.RoleProducer; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.time.LocalDateTime; -import java.util.*; - -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.verify; - -// TODO @芋艿:单测的代码质量可以提升下 -@Import(RoleServiceImpl.class) -public class RoleServiceTest extends BaseDbUnitTest { - - @Resource - private RoleServiceImpl roleService; - - @Resource - private RoleMapper roleMapper; - - @MockBean - private PermissionService permissionService; - @MockBean - private RoleProducer roleProducer; - - @Test - public void testInitLocalCache() { - RoleDO roleDO1 = randomRole(); - roleMapper.insert(roleDO1); - RoleDO roleDO2 = randomRole(); - roleMapper.insert(roleDO2); - - // 调用 - roleService.initLocalCache(); - // 断言 roleCache 缓存 - Map roleCache = roleService.getRoleCache(); - assertPojoEquals(roleDO1, roleCache.get(roleDO1.getId())); - assertPojoEquals(roleDO2, roleCache.get(roleDO2.getId())); - } - - @Test - public void testCreateRole_success() { - // 准备参数 - RoleCreateReqVO reqVO = randomPojo(RoleCreateReqVO.class); - - // 调用 - Long roleId = roleService.createRole(reqVO, null); - // 断言 - assertNotNull(roleId); - RoleDO roleDO = roleMapper.selectById(roleId); - assertPojoEquals(reqVO, roleDO); - assertEquals(RoleTypeEnum.CUSTOM.getType(), roleDO.getType()); - assertEquals(CommonStatusEnum.ENABLE.getStatus(), roleDO.getStatus()); - assertEquals(DataScopeEnum.ALL.getScope(), roleDO.getDataScope()); - // verify 发送刷新消息 - verify(roleProducer).sendRoleRefreshMessage(); - } - - @Test - public void testUpdateRole_success() { - // mock 数据 - RoleDO roleDO = createRoleDO("role_name", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL); - roleMapper.insert(roleDO); - Long roleId = roleDO.getId(); - - //调用 - RoleUpdateReqVO reqVO = randomPojo(RoleUpdateReqVO.class, o -> { - o.setId(roleId); - o.setCode("role_code"); - o.setName("update_name"); - o.setSort(999); - }); - roleService.updateRole(reqVO); - - //断言 - RoleDO newRoleDO = roleMapper.selectById(roleId); - assertPojoEquals(reqVO, newRoleDO); - - verify(roleProducer).sendRoleRefreshMessage(); - } - - @Test - public void testUpdateRoleStatus_success() { - RoleDO roleDO = createRoleDO("role_name", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL, CommonStatusEnum.ENABLE.getStatus()); - roleMapper.insert(roleDO); - Long roleId = roleDO.getId(); - - //调用 - roleService.updateRoleStatus(roleId, CommonStatusEnum.DISABLE.getStatus()); - - //断言 - RoleDO newRoleDO = roleMapper.selectById(roleId); - assertEquals(CommonStatusEnum.DISABLE.getStatus(), newRoleDO.getStatus()); - - verify(roleProducer).sendRoleRefreshMessage(); - } - - @Test - public void testUpdateRoleDataScope_success() { - RoleDO roleDO = createRoleDO("role_name", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL); - roleMapper.insert(roleDO); - Long roleId = roleDO.getId(); - - //调用 - Set deptIdSet = new HashSet<>(Arrays.asList(1L, 2L, 3L, 4L, 5L)); - roleService.updateRoleDataScope(roleId, DataScopeEnum.DEPT_CUSTOM.getScope(), deptIdSet); - - //断言 - RoleDO newRoleDO = roleMapper.selectById(roleId); - assertEquals(DataScopeEnum.DEPT_CUSTOM.getScope(), newRoleDO.getDataScope()); - - Set newDeptIdSet = newRoleDO.getDataScopeDeptIds(); - assertEquals(deptIdSet.size(), newDeptIdSet.size()); - deptIdSet.stream().forEach(d -> assertTrue(newDeptIdSet.contains(d))); - - verify(roleProducer).sendRoleRefreshMessage(); - } - - @Test - public void testDeleteRole_success() { - RoleDO roleDO = createRoleDO("role_name", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL); - roleMapper.insert(roleDO); - Long roleId = roleDO.getId(); - - //调用 - roleService.deleteRole(roleId); - - //断言 - RoleDO newRoleDO = roleMapper.selectById(roleId); - assertNull(newRoleDO); - - verify(roleProducer).sendRoleRefreshMessage(); - } - - @Test - public void testGetRoles() { - // mock 数据 - RoleDO dbRole = randomPojo(RoleDO.class, o -> { // 等会查询到 - o.setName("土豆"); - o.setCode("tudou"); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setCreateTime(buildTime(2022, 2, 8)); - }); - roleMapper.insert(dbRole); - // 测试 name 不匹配 - roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setName("红薯"))); - // 测试 code 不匹配 - roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCode("hong"))); - // 测试 createTime 不匹配 - roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCreateTime(buildTime(2022, 2, 16)))); - // 准备参数 - RoleExportReqVO reqVO = new RoleExportReqVO(); - reqVO.setName("土豆"); - reqVO.setCode("tu"); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2022, 2, 1),buildTime(2022, 2, 12)})); - - // 调用 - List list = roleService.getRoleList(reqVO); - // 断言 - assertEquals(1, list.size()); - assertPojoEquals(dbRole, list.get(0)); - } - - @Test - public void testGetRolePage() { - // mock 数据 - RoleDO dbRole = randomPojo(RoleDO.class, o -> { // 等会查询到 - o.setName("土豆"); - o.setCode("tudou"); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setCreateTime(buildTime(2022, 2, 8)); - }); - roleMapper.insert(dbRole); - // 测试 name 不匹配 - roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setName("红薯"))); - // 测试 code 不匹配 - roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCode("hong"))); - // 测试 createTime 不匹配 - roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCreateTime(buildTime(2022, 2, 16)))); - // 准备参数 - RolePageReqVO reqVO = new RolePageReqVO(); - reqVO.setName("土豆"); - reqVO.setCode("tu"); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2022, 2, 1),buildTime(2022, 2, 12)})); - - // 调用 - PageResult pageResult = roleService.getRolePage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbRole, pageResult.getList().get(0)); - } - - @Test - public void testCheckDuplicateRole_success() { - roleService.checkDuplicateRole(randomString(), randomString(), null); - } - - @Test - public void testCheckDuplicateRole_nameDuplicate() { - RoleDO roleDO = createRoleDO("role_name", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL); - roleMapper.insert(roleDO); - - String duplicateName = "role_name"; - - assertServiceException(() -> roleService.checkDuplicateRole(duplicateName, randomString(), null), ROLE_NAME_DUPLICATE, duplicateName); - } - - @Test - public void testCheckDuplicateRole_codeDuplicate() { - RoleDO roleDO = randomPojo(RoleDO.class, o -> { - o.setName("role_999"); - o.setCode("code"); - o.setType(RoleTypeEnum.CUSTOM.getType()); - o.setStatus(1); - o.setDataScope(DataScopeEnum.ALL.getScope()); - }); - roleMapper.insert(roleDO); - - String randomName = randomString(); - String duplicateCode = "code"; - - assertServiceException(() -> roleService.checkDuplicateRole(randomName, duplicateCode, null), ROLE_CODE_DUPLICATE, duplicateCode); - } - - @Test - public void testCheckUpdateRole_success() { - RoleDO roleDO = createRoleDO("role_name", RoleTypeEnum.CUSTOM, DataScopeEnum.ALL); - roleMapper.insert(roleDO); - Long roleId = roleDO.getId(); - - roleService.checkUpdateRole(roleId); - } - - @Test - public void testCheckUpdateRole_roleIdNotExist() { - assertServiceException(() -> roleService.checkUpdateRole(randomLongId()), ROLE_NOT_EXISTS); - } - - @Test - public void testCheckUpdateRole_systemRoleCanNotBeUpdate() { - RoleDO roleDO = createRoleDO("role_name", RoleTypeEnum.SYSTEM, DataScopeEnum.ALL); - roleMapper.insert(roleDO); - Long roleId = roleDO.getId(); - - assertServiceException(() -> roleService.checkUpdateRole(roleId), ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE); - } - - private RoleDO createRoleDO(String name, RoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status) { - return createRoleDO( name, typeEnum, scopeEnum, status, randomString()); - } - - private RoleDO createRoleDO(String name, RoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status, String code) { - return createRoleDO(null, name, typeEnum, scopeEnum, status, code); - } - - private RoleDO createRoleDO(String name, RoleTypeEnum typeEnum, DataScopeEnum scopeEnum) { - return createRoleDO(null, name, typeEnum, scopeEnum, randomCommonStatus(), randomString()); - } - - private RoleDO createRoleDO(Long id, String name, RoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status, String code) { - return randomPojo(RoleDO.class, o -> { - o.setId(id); - o.setName(name); - o.setType(typeEnum.getType()); - o.setStatus(status); - o.setDataScope(scopeEnum.getScope()); - o.setCode(code); - }); - } - - private RoleDO randomRole() { - return randomPojo(RoleDO.class, - o -> o.setDataScope(RandomUtil.randomEle(DataScopeEnum.values()).getScope())); - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java index e2cce6a33..8cee678db 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java @@ -196,7 +196,7 @@ public class TenantServiceImplTest extends BaseDbUnitTest { role100.setTenantId(dbTenant.getId()); RoleDO role101 = randomPojo(RoleDO.class, o -> o.setId(101L)); role101.setTenantId(dbTenant.getId()); - when(roleService.getRoles(isNull())).thenReturn(asList(role100, role101)); + when(roleService.getRoleList(isNull())).thenReturn(asList(role100, role101)); // mock 每个角色的权限 when(permissionService.getRoleMenuIds(eq(101L))).thenReturn(asSet(201L, 202L)); From d7f86afd6cfb51264085b5164d904165c5c29158 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Feb 2023 21:03:25 +0800 Subject: [PATCH 36/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20SensitiveWordService?= =?UTF-8?q?Impl=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SensitiveWordServiceImpl.java | 17 ++++---- .../SensitiveWordServiceImplTest.java | 39 ++++++++++++++++--- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java index 53357753f..868ef6f6f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java @@ -25,6 +25,7 @@ import javax.annotation.Resource; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_WORD_EXISTS; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_WORD_NOT_EXISTS; @@ -85,7 +86,7 @@ public class SensitiveWordServiceImpl implements SensitiveWordService { private void initSensitiveWordTrie(List wordDOs) { // 过滤禁用的敏感词 - wordDOs = CollectionUtils.filterList(wordDOs, word -> word.getStatus().equals(CommonStatusEnum.ENABLE.getStatus())); + wordDOs = filterList(wordDOs, word -> word.getStatus().equals(CommonStatusEnum.ENABLE.getStatus())); // 初始化默认的 defaultSensitiveWordTrie this.defaultSensitiveWordTrie = new SimpleTrie(CollectionUtils.convertList(wordDOs, SensitiveWordDO::getName)); @@ -107,7 +108,8 @@ public class SensitiveWordServiceImpl implements SensitiveWordService { @Override public Long createSensitiveWord(SensitiveWordCreateReqVO createReqVO) { // 校验唯一性 - checkSensitiveWordNameUnique(null, createReqVO.getName()); + validateSensitiveWordNameUnique(null, createReqVO.getName()); + // 插入 SensitiveWordDO sensitiveWord = SensitiveWordConvert.INSTANCE.convert(createReqVO); sensitiveWordMapper.insert(sensitiveWord); @@ -119,8 +121,9 @@ public class SensitiveWordServiceImpl implements SensitiveWordService { @Override public void updateSensitiveWord(SensitiveWordUpdateReqVO updateReqVO) { // 校验唯一性 - checkSensitiveWordExists(updateReqVO.getId()); - checkSensitiveWordNameUnique(updateReqVO.getId(), updateReqVO.getName()); + validateSensitiveWordExists(updateReqVO.getId()); + validateSensitiveWordNameUnique(updateReqVO.getId(), updateReqVO.getName()); + // 更新 SensitiveWordDO updateObj = SensitiveWordConvert.INSTANCE.convert(updateReqVO); sensitiveWordMapper.updateById(updateObj); @@ -131,14 +134,14 @@ public class SensitiveWordServiceImpl implements SensitiveWordService { @Override public void deleteSensitiveWord(Long id) { // 校验存在 - checkSensitiveWordExists(id); + validateSensitiveWordExists(id); // 删除 sensitiveWordMapper.deleteById(id); // 发送消息,刷新缓存 sensitiveWordProducer.sendSensitiveWordRefreshMessage(); } - private void checkSensitiveWordNameUnique(Long id, String name) { + private void validateSensitiveWordNameUnique(Long id, String name) { SensitiveWordDO word = sensitiveWordMapper.selectByName(name); if (word == null) { return; @@ -152,7 +155,7 @@ public class SensitiveWordServiceImpl implements SensitiveWordService { } } - private void checkSensitiveWordExists(Long id) { + private void validateSensitiveWordExists(Long id) { if (sensitiveWordMapper.selectById(id) == null) { throw exception(SENSITIVE_WORD_NOT_EXISTS); } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java index 273e74b4a..40a080b6a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java @@ -16,13 +16,12 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; @@ -135,6 +134,36 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { assertServiceException(() -> sensitiveWordService.deleteSensitiveWord(id), SENSITIVE_WORD_NOT_EXISTS); } + @Test + public void testGetSensitiveWord() { + // mock 数据 + SensitiveWordDO sensitiveWord = randomPojo(SensitiveWordDO.class); + sensitiveWordMapper.insert(sensitiveWord); + // 准备参数 + Long id = sensitiveWord.getId(); + + // 调用 + SensitiveWordDO dbSensitiveWord = sensitiveWordService.getSensitiveWord(id); + // 断言 + assertPojoEquals(sensitiveWord, dbSensitiveWord); + } + + @Test + public void testGetSensitiveWordList() { + // mock 数据 + SensitiveWordDO sensitiveWord01 = randomPojo(SensitiveWordDO.class); + sensitiveWordMapper.insert(sensitiveWord01); + SensitiveWordDO sensitiveWord02 = randomPojo(SensitiveWordDO.class); + sensitiveWordMapper.insert(sensitiveWord02); + + // 调用 + List list = sensitiveWordService.getSensitiveWordList(); + // 断言 + assertEquals(2, list.size()); + assertEquals(sensitiveWord01, list.get(0)); + assertEquals(sensitiveWord02, list.get(1)); + } + @Test public void testGetSensitiveWordPage() { // mock 数据 @@ -156,7 +185,7 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { reqVO.setName("笨"); reqVO.setTag("论坛"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2022, 2, 1),buildTime(2022, 2, 12)})); + reqVO.setCreateTime(buildBetweenTime(2022, 2, 1, 2022, 2, 12)); // 调用 PageResult pageResult = sensitiveWordService.getSensitiveWordPage(reqVO); @@ -167,7 +196,7 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { } @Test - public void testGetSensitiveWordList() { + public void testGetSensitiveWordList_export() { // mock 数据 SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class, o -> { // 等会查询到 o.setName("笨蛋"); @@ -187,7 +216,7 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { reqVO.setName("笨"); reqVO.setTag("论坛"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2022, 2, 1),buildTime(2022, 2, 12)})); + reqVO.setCreateTime(buildBetweenTime(2022, 2, 1, 2022, 2, 12)); // 调用 List list = sensitiveWordService.getSensitiveWordList(reqVO); From 97fd7a7187d916cd1f16a3e200b18213f3e4a046 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Feb 2023 21:05:58 +0800 Subject: [PATCH 37/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20SmsChannelServiceImp?= =?UTF-8?q?l=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/sms/SmsChannelController.java | 2 +- .../system/service/sms/SmsChannelService.java | 11 +--- .../service/sms/SmsChannelServiceImpl.java | 6 -- .../service/sms/SmsChannelServiceTest.java | 66 ++++++++++++------- 4 files changed, 44 insertions(+), 41 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsChannelController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsChannelController.java index 638140d21..57e7ed81f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsChannelController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsChannelController.java @@ -70,7 +70,7 @@ public class SmsChannelController { @GetMapping("/list-all-simple") @ApiOperation(value = "获得短信渠道精简列表", notes = "包含被禁用的短信渠道") - public CommonResult> getSimpleSmsChannels() { + public CommonResult> getSimpleSmsChannelList() { List list = smsChannelService.getSmsChannelList(); // 排序后,返回给前端 list.sort(Comparator.comparing(SmsChannelDO::getId)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelService.java index fb0b707d7..c0bb3f8cd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelService.java @@ -1,13 +1,12 @@ package cn.iocoder.yudao.module.system.service.sms; -import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelUpdateReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO; import javax.validation.Valid; -import java.util.Collection; import java.util.List; /** @@ -53,14 +52,6 @@ public interface SmsChannelService { */ SmsChannelDO getSmsChannel(Long id); - /** - * 获得短信渠道列表 - * - * @param ids 编号 - * @return 短信渠道列表 - */ - List getSmsChannelList(Collection ids); - /** * 获得所有短信渠道列表 * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java index d126fbf0f..47b3b0fdc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java @@ -15,7 +15,6 @@ import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.Resource; -import java.util.Collection; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -102,11 +101,6 @@ public class SmsChannelServiceImpl implements SmsChannelService { return smsChannelMapper.selectById(id); } - @Override - public List getSmsChannelList(Collection ids) { - return smsChannelMapper.selectBatchIds(ids); - } - @Override public List getSmsChannelList() { return smsChannelMapper.selectList(); diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceTest.java index 4fe433d90..dabb9aa75 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceTest.java @@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.system.service.sms; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelCreateReqVO; @@ -17,11 +15,12 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.time.LocalDateTime; -import java.util.function.Consumer; -import static cn.hutool.core.util.RandomUtil.randomEle; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_HAS_CHILDREN; @@ -49,9 +48,9 @@ public class SmsChannelServiceTest extends BaseDbUnitTest { @Test public void testInitLocalCache_success() { // mock 数据 - SmsChannelDO smsChannelDO01 = randomSmsChannelDO(); + SmsChannelDO smsChannelDO01 = randomPojo(SmsChannelDO.class); smsChannelMapper.insert(smsChannelDO01); - SmsChannelDO smsChannelDO02 = randomSmsChannelDO(); + SmsChannelDO smsChannelDO02 = randomPojo(SmsChannelDO.class); smsChannelMapper.insert(smsChannelDO02); // 调用 @@ -82,7 +81,7 @@ public class SmsChannelServiceTest extends BaseDbUnitTest { @Test public void testUpdateSmsChannel_success() { // mock 数据 - SmsChannelDO dbSmsChannel = randomSmsChannelDO(); + SmsChannelDO dbSmsChannel = randomPojo(SmsChannelDO.class); smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据 // 准备参数 SmsChannelUpdateReqVO reqVO = randomPojo(SmsChannelUpdateReqVO.class, o -> { @@ -112,7 +111,7 @@ public class SmsChannelServiceTest extends BaseDbUnitTest { @Test public void testDeleteSmsChannel_success() { // mock 数据 - SmsChannelDO dbSmsChannel = randomSmsChannelDO(); + SmsChannelDO dbSmsChannel = randomPojo(SmsChannelDO.class); smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据 // 准备参数 Long id = dbSmsChannel.getId(); @@ -137,7 +136,7 @@ public class SmsChannelServiceTest extends BaseDbUnitTest { @Test public void testDeleteSmsChannel_hasChildren() { // mock 数据 - SmsChannelDO dbSmsChannel = randomSmsChannelDO(); + SmsChannelDO dbSmsChannel = randomPojo(SmsChannelDO.class); smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据 // 准备参数 Long id = dbSmsChannel.getId(); @@ -148,6 +147,35 @@ public class SmsChannelServiceTest extends BaseDbUnitTest { assertServiceException(() -> smsChannelService.deleteSmsChannel(id), SMS_CHANNEL_HAS_CHILDREN); } + @Test + public void testGetSmsChannel() { + // mock 数据 + SmsChannelDO dbSmsChannel = randomPojo(SmsChannelDO.class); + smsChannelMapper.insert(dbSmsChannel); // @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbSmsChannel.getId(); + + // 调用,并断言 + assertPojoEquals(dbSmsChannel, smsChannelService.getSmsChannel(id)); + } + + @Test + public void testGetSmsChannelList() { + // mock 数据 + SmsChannelDO dbSmsChannel01 = randomPojo(SmsChannelDO.class); + smsChannelMapper.insert(dbSmsChannel01); + SmsChannelDO dbSmsChannel02 = randomPojo(SmsChannelDO.class); + smsChannelMapper.insert(dbSmsChannel02); + // 准备参数 + + // 调用 + List list = smsChannelService.getSmsChannelList(); + // 断言 + assertEquals(2, list.size()); + assertPojoEquals(dbSmsChannel01, list.get(0)); + assertPojoEquals(dbSmsChannel02, list.get(1)); + } + @Test public void testGetSmsChannelPage() { // mock 数据 @@ -158,16 +186,16 @@ public class SmsChannelServiceTest extends BaseDbUnitTest { }); smsChannelMapper.insert(dbSmsChannel); // 测试 signature 不匹配 - smsChannelMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsChannel, o -> o.setSignature("源码"))); + smsChannelMapper.insert(cloneIgnoreId(dbSmsChannel, o -> o.setSignature("源码"))); // 测试 status 不匹配 - smsChannelMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsChannel, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + smsChannelMapper.insert(cloneIgnoreId(dbSmsChannel, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); // 测试 createTime 不匹配 - smsChannelMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsChannel, o -> o.setCreateTime(buildTime(2020, 11, 11)))); + smsChannelMapper.insert(cloneIgnoreId(dbSmsChannel, o -> o.setCreateTime(buildTime(2020, 11, 11)))); // 准备参数 SmsChannelPageReqVO reqVO = new SmsChannelPageReqVO(); reqVO.setSignature("芋道"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2020, 12, 1),buildTime(2020, 12, 24)})); + reqVO.setCreateTime(buildBetweenTime(2020, 12, 1, 2020, 12, 24)); // 调用 PageResult pageResult = smsChannelService.getSmsChannelPage(reqVO); @@ -177,14 +205,4 @@ public class SmsChannelServiceTest extends BaseDbUnitTest { assertPojoEquals(dbSmsChannel, pageResult.getList().get(0)); } - // ========== 随机对象 ========== - - @SafeVarargs - private static SmsChannelDO randomSmsChannelDO(Consumer... consumers) { - Consumer consumer = (o) -> { - o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 - }; - return randomPojo(SmsChannelDO.class, ArrayUtils.append(consumer, consumers)); - } - } From e7d0b8da35bafd2786b72b93bc5470571e6e3f5a Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Feb 2023 21:08:33 +0800 Subject: [PATCH 38/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20SmsLogServiceImpl=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/service/sms/SmsLogServiceTest.java | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceTest.java index 5a31892f5..546867867 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceTest.java @@ -1,7 +1,11 @@ package cn.iocoder.yudao.module.system.service.sms; import cn.hutool.core.map.MapUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsLogDO; @@ -10,11 +14,6 @@ import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsLogMapper; import cn.iocoder.yudao.module.system.enums.sms.SmsReceiveStatusEnum; import cn.iocoder.yudao.module.system.enums.sms.SmsSendStatusEnum; import cn.iocoder.yudao.module.system.enums.sms.SmsTemplateTypeEnum; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; @@ -26,7 +25,9 @@ import java.util.function.Consumer; import static cn.hutool.core.util.RandomUtil.randomBoolean; import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -55,30 +56,28 @@ public class SmsLogServiceTest extends BaseDbUnitTest { }); smsLogMapper.insert(dbSmsLog); // 测试 channelId 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setChannelId(2L))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setChannelId(2L))); // 测试 templateId 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setTemplateId(20L))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setTemplateId(20L))); // 测试 mobile 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setMobile("18818260999"))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setMobile("18818260999"))); // 测试 sendStatus 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendStatus(SmsSendStatusEnum.IGNORE.getStatus()))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setSendStatus(SmsSendStatusEnum.IGNORE.getStatus()))); // 测试 sendTime 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12)))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12)))); // 测试 receiveStatus 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveStatus(SmsReceiveStatusEnum.SUCCESS.getStatus()))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setReceiveStatus(SmsReceiveStatusEnum.SUCCESS.getStatus()))); // 测试 receiveTime 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12)))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12)))); // 准备参数 SmsLogPageReqVO reqVO = new SmsLogPageReqVO(); reqVO.setChannelId(1L); reqVO.setTemplateId(10L); reqVO.setMobile("156"); reqVO.setSendStatus(SmsSendStatusEnum.INIT.getStatus()); - reqVO.setSendTime((new LocalDateTime[]{buildTime(2020, 11, 1), - buildTime(2020, 11, 30)})); + reqVO.setSendTime(buildBetweenTime(2020, 11, 1, 2020, 11, 30)); reqVO.setReceiveStatus(SmsReceiveStatusEnum.INIT.getStatus()); - reqVO.setReceiveTime((new LocalDateTime[]{buildTime(2021, 11, 1), - buildTime(2021, 11, 30)})); + reqVO.setReceiveTime(buildBetweenTime(2021, 11, 1, 2021, 11, 30)); // 调用 PageResult pageResult = smsLogService.getSmsLogPage(reqVO); @@ -102,30 +101,28 @@ public class SmsLogServiceTest extends BaseDbUnitTest { }); smsLogMapper.insert(dbSmsLog); // 测试 channelId 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setChannelId(2L))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setChannelId(2L))); // 测试 templateId 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setTemplateId(20L))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setTemplateId(20L))); // 测试 mobile 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setMobile("18818260999"))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setMobile("18818260999"))); // 测试 sendStatus 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendStatus(SmsSendStatusEnum.IGNORE.getStatus()))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setSendStatus(SmsSendStatusEnum.IGNORE.getStatus()))); // 测试 sendTime 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12)))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12)))); // 测试 receiveStatus 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveStatus(SmsReceiveStatusEnum.SUCCESS.getStatus()))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setReceiveStatus(SmsReceiveStatusEnum.SUCCESS.getStatus()))); // 测试 receiveTime 不匹配 - smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12)))); + smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12)))); // 准备参数 SmsLogExportReqVO reqVO = new SmsLogExportReqVO(); reqVO.setChannelId(1L); reqVO.setTemplateId(10L); reqVO.setMobile("156"); reqVO.setSendStatus(SmsSendStatusEnum.INIT.getStatus()); - reqVO.setSendTime((new LocalDateTime[]{buildTime(2020, 11, 1), - buildTime(2020, 11, 30)})); + reqVO.setSendTime(buildBetweenTime(2020, 11, 1, 2020, 11, 30)); reqVO.setReceiveStatus(SmsReceiveStatusEnum.INIT.getStatus()); - reqVO.setReceiveTime((new LocalDateTime[]{buildTime(2021, 11, 1), - buildTime(2021, 11, 30)})); + reqVO.setReceiveTime(buildBetweenTime(2021, 11, 1, 2021, 11, 30)); // 调用 List list = smsLogService.getSmsLogList(reqVO); From a332d5f893dbb04f0d16c10b0d92ec496da5a4dc Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Feb 2023 21:15:23 +0800 Subject: [PATCH 39/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20SmsSendServiceImpl?= =?UTF-8?q?=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/sms/SmsSendServiceImpl.java | 18 ++-- .../service/sms/SmsSendServiceTest.java | 101 ++++++++++++++++-- 2 files changed, 102 insertions(+), 17 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImpl.java index 85fee7ff4..9df628670 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImpl.java @@ -66,7 +66,7 @@ public class SmsSendServiceImpl implements SmsSendService { } } // 执行发送 - return this.sendSingleSms(mobile, userId, UserTypeEnum.ADMIN.getValue(), templateCode, templateParams); + return sendSingleSms(mobile, userId, UserTypeEnum.ADMIN.getValue(), templateCode, templateParams); } @Override @@ -76,19 +76,19 @@ public class SmsSendServiceImpl implements SmsSendService { mobile = memberService.getMemberUserMobile(userId); } // 执行发送 - return this.sendSingleSms(mobile, userId, UserTypeEnum.MEMBER.getValue(), templateCode, templateParams); + return sendSingleSms(mobile, userId, UserTypeEnum.MEMBER.getValue(), templateCode, templateParams); } @Override public Long sendSingleSms(String mobile, Long userId, Integer userType, String templateCode, Map templateParams) { // 校验短信模板是否合法 - SmsTemplateDO template = this.checkSmsTemplateValid(templateCode); + SmsTemplateDO template = validateSmsTemplate(templateCode); // 校验短信渠道是否合法 - SmsChannelDO smsChannel = this.checkSmsChannelValid(template.getChannelId()); + SmsChannelDO smsChannel = validateSmsChannel(template.getChannelId()); // 校验手机号码是否存在 - mobile = this.checkMobile(mobile); + mobile = validateMobile(mobile); // 构建有序的模板参数。为什么放在这个位置,是提前保证模板参数的正确性,而不是到了插入发送日志 List> newTemplateParams = this.buildTemplateParams(template, templateParams); @@ -108,7 +108,7 @@ public class SmsSendServiceImpl implements SmsSendService { } @VisibleForTesting - public SmsChannelDO checkSmsChannelValid(Long channelId) { + SmsChannelDO validateSmsChannel(Long channelId) { // 获得短信模板。考虑到效率,从缓存中获取 SmsChannelDO channelDO = smsChannelService.getSmsChannel(channelId); // 短信模板不存在 @@ -119,7 +119,7 @@ public class SmsSendServiceImpl implements SmsSendService { } @VisibleForTesting - public SmsTemplateDO checkSmsTemplateValid(String templateCode) { + SmsTemplateDO validateSmsTemplate(String templateCode) { // 获得短信模板。考虑到效率,从缓存中获取 SmsTemplateDO template = smsTemplateService.getSmsTemplateByCodeFromCache(templateCode); // 短信模板不存在 @@ -139,7 +139,7 @@ public class SmsSendServiceImpl implements SmsSendService { * @return 处理后的参数 */ @VisibleForTesting - public List> buildTemplateParams(SmsTemplateDO template, Map templateParams) { + List> buildTemplateParams(SmsTemplateDO template, Map templateParams) { return template.getParams().stream().map(key -> { Object value = templateParams.get(key); if (value == null) { @@ -150,7 +150,7 @@ public class SmsSendServiceImpl implements SmsSendService { } @VisibleForTesting - public String checkMobile(String mobile) { + public String validateMobile(String mobile) { if (StrUtil.isEmpty(mobile)) { throw exception(SMS_SEND_MOBILE_NOT_EXISTS); } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceTest.java index 890924e14..37b361449 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceTest.java @@ -1,10 +1,6 @@ package cn.iocoder.yudao.module.system.service.sms; import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO; -import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO; -import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage; -import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer; import cn.iocoder.yudao.framework.common.core.KeyValue; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; @@ -14,6 +10,13 @@ import cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult; import cn.iocoder.yudao.framework.sms.core.client.dto.SmsReceiveRespDTO; import cn.iocoder.yudao.framework.sms.core.client.dto.SmsSendRespDTO; import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO; +import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; +import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage; +import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer; +import cn.iocoder.yudao.module.system.service.member.MemberService; +import cn.iocoder.yudao.module.system.service.user.AdminUserService; import org.assertj.core.util.Lists; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -36,6 +39,10 @@ public class SmsSendServiceTest extends BaseMockitoUnitTest { @InjectMocks private SmsSendServiceImpl smsService; + @Mock + private AdminUserService adminUserService; + @Mock + private MemberService memberService; @Mock private SmsChannelService smsChannelService; @Mock @@ -48,6 +55,84 @@ public class SmsSendServiceTest extends BaseMockitoUnitTest { @Mock private SmsClientFactory smsClientFactory; + @Test + public void testSendSingleSmsToAdmin() { + // 准备参数 + Long userId = randomLongId(); + String templateCode = randomString(); + Map templateParams = MapUtil.builder().put("code", "1234") + .put("op", "login").build(); + // mock adminUserService 的方法 + AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setMobile("15601691300")); + when(adminUserService.getUser(eq(userId))).thenReturn(user); + + // mock SmsTemplateService 的方法 + SmsTemplateDO template = randomPojo(SmsTemplateDO.class, o -> { + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setContent("验证码为{code}, 操作为{op}"); + o.setParams(Lists.newArrayList("code", "op")); + }); + when(smsTemplateService.getSmsTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); + String content = randomString(); + when(smsTemplateService.formatSmsTemplateContent(eq(template.getContent()), eq(templateParams))) + .thenReturn(content); + // mock SmsChannelService 的方法 + SmsChannelDO smsChannel = randomPojo(SmsChannelDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + when(smsChannelService.getSmsChannel(eq(template.getChannelId()))).thenReturn(smsChannel); + // mock SmsLogService 的方法 + Long smsLogId = randomLongId(); + when(smsLogService.createSmsLog(eq(user.getMobile()), eq(userId), eq(UserTypeEnum.ADMIN.getValue()), eq(Boolean.TRUE), eq(template), + eq(content), eq(templateParams))).thenReturn(smsLogId); + + // 调用 + Long resultSmsLogId = smsService.sendSingleSmsToAdmin(null, userId, templateCode, templateParams); + // 断言 + assertEquals(smsLogId, resultSmsLogId); + // 断言调用 + verify(smsProducer).sendSmsSendMessage(eq(smsLogId), eq(user.getMobile()), + eq(template.getChannelId()), eq(template.getApiTemplateId()), + eq(Lists.newArrayList(new KeyValue<>("code", "1234"), new KeyValue<>("op", "login")))); + } + + @Test + public void testSendSingleSmsToUser() { + // 准备参数 + Long userId = randomLongId(); + String templateCode = randomString(); + Map templateParams = MapUtil.builder().put("code", "1234") + .put("op", "login").build(); + // mock adminUserService 的方法 + String mobile = "15601691300"; + when(memberService.getMemberUserMobile(eq(userId))).thenReturn(mobile); + + // mock SmsTemplateService 的方法 + SmsTemplateDO template = randomPojo(SmsTemplateDO.class, o -> { + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setContent("验证码为{code}, 操作为{op}"); + o.setParams(Lists.newArrayList("code", "op")); + }); + when(smsTemplateService.getSmsTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); + String content = randomString(); + when(smsTemplateService.formatSmsTemplateContent(eq(template.getContent()), eq(templateParams))) + .thenReturn(content); + // mock SmsChannelService 的方法 + SmsChannelDO smsChannel = randomPojo(SmsChannelDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + when(smsChannelService.getSmsChannel(eq(template.getChannelId()))).thenReturn(smsChannel); + // mock SmsLogService 的方法 + Long smsLogId = randomLongId(); + when(smsLogService.createSmsLog(eq(mobile), eq(userId), eq(UserTypeEnum.MEMBER.getValue()), eq(Boolean.TRUE), eq(template), + eq(content), eq(templateParams))).thenReturn(smsLogId); + + // 调用 + Long resultSmsLogId = smsService.sendSingleSmsToMember(null, userId, templateCode, templateParams); + // 断言 + assertEquals(smsLogId, resultSmsLogId); + // 断言调用 + verify(smsProducer).sendSmsSendMessage(eq(smsLogId), eq(mobile), + eq(template.getChannelId()), eq(template.getApiTemplateId()), + eq(Lists.newArrayList(new KeyValue<>("code", "1234"), new KeyValue<>("op", "login")))); + } + /** * 发送成功,当短信模板开启时 */ @@ -83,7 +168,7 @@ public class SmsSendServiceTest extends BaseMockitoUnitTest { // 断言 assertEquals(smsLogId, resultSmsLogId); // 断言调用 - verify(smsProducer, times(1)).sendSmsSendMessage(eq(smsLogId), eq(mobile), + verify(smsProducer).sendSmsSendMessage(eq(smsLogId), eq(mobile), eq(template.getChannelId()), eq(template.getApiTemplateId()), eq(Lists.newArrayList(new KeyValue<>("code", "1234"), new KeyValue<>("op", "login")))); } @@ -134,7 +219,7 @@ public class SmsSendServiceTest extends BaseMockitoUnitTest { // mock 方法 // 调用,并断言异常 - assertServiceException(() -> smsService.checkSmsTemplateValid(templateCode), + assertServiceException(() -> smsService.validateSmsTemplate(templateCode), SMS_SEND_TEMPLATE_NOT_EXISTS); } @@ -157,7 +242,7 @@ public class SmsSendServiceTest extends BaseMockitoUnitTest { // mock 方法 // 调用,并断言异常 - assertServiceException(() -> smsService.checkMobile(null), + assertServiceException(() -> smsService.validateMobile(null), SMS_SEND_MOBILE_NOT_EXISTS); } @@ -177,7 +262,7 @@ public class SmsSendServiceTest extends BaseMockitoUnitTest { // 调用 smsService.doSendSms(message); // 断言 - verify(smsLogService, times(1)).updateSmsSendResult(eq(message.getLogId()), + verify(smsLogService).updateSmsSendResult(eq(message.getLogId()), eq(sendResult.getCode()), eq(sendResult.getMsg()), eq(sendResult.getApiCode()), eq(sendResult.getApiMsg()), eq(sendResult.getApiRequestId()), eq(sendResult.getData().getSerialNo())); } From d897f8fb103945b4ad679079dfe969120c8e192c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Feb 2023 23:16:35 +0800 Subject: [PATCH 40/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20SmsCodeServiceImpl?= =?UTF-8?q?=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/system/api/sms/SmsCodeApi.java | 4 +- ...ReqDTO.java => SmsCodeValidateReqDTO.java} | 2 +- .../module/system/api/sms/SmsCodeApiImpl.java | 6 +- .../system/service/sms/SmsCodeService.java | 4 +- .../service/sms/SmsCodeServiceImpl.java | 30 ++- .../service/sms/SmsCodeServiceImplTest.java | 209 ++++++++++++++++++ ...ceTest.java => SmsLogServiceImplTest.java} | 2 +- ...eTest.java => SmsSendServiceImplTest.java} | 2 +- ...t.java => SmsTemplateServiceImplTest.java} | 4 +- .../src/test/resources/sql/clean.sql | 1 + .../src/test/resources/sql/create_tables.sql | 18 ++ 11 files changed, 253 insertions(+), 29 deletions(-) rename yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/{SmsCodeCheckReqDTO.java => SmsCodeValidateReqDTO.java} (95%) create mode 100644 yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImplTest.java rename yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/{SmsLogServiceTest.java => SmsLogServiceImplTest.java} (99%) rename yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/{SmsSendServiceTest.java => SmsSendServiceImplTest.java} (99%) rename yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/{SmsTemplateServiceTest.java => SmsTemplateServiceImplTest.java} (98%) diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApi.java index ffcf46dc0..98d4cdeef 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApi.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.system.api.sms; import cn.iocoder.yudao.framework.common.exception.ServiceException; -import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO; +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; @@ -35,6 +35,6 @@ public interface SmsCodeApi { * * @param reqDTO 校验请求 */ - void checkSmsCode(@Valid SmsCodeCheckReqDTO reqDTO); + void validateSmsCode(@Valid SmsCodeValidateReqDTO reqDTO); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeCheckReqDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeValidateReqDTO.java similarity index 95% rename from yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeCheckReqDTO.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeValidateReqDTO.java index 92895bb4d..e7808354c 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeCheckReqDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/sms/dto/code/SmsCodeValidateReqDTO.java @@ -14,7 +14,7 @@ import javax.validation.constraints.NotNull; * @author 芋道源码 */ @Data -public class SmsCodeCheckReqDTO { +public class SmsCodeValidateReqDTO { /** * 手机号 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApiImpl.java index 81957e082..23c5e4b3f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/sms/SmsCodeApiImpl.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.system.api.sms; -import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO; +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; import cn.iocoder.yudao.module.system.service.sms.SmsCodeService; @@ -32,8 +32,8 @@ public class SmsCodeApiImpl implements SmsCodeApi { } @Override - public void checkSmsCode(SmsCodeCheckReqDTO reqDTO) { - smsCodeService.checkSmsCode(reqDTO); + public void validateSmsCode(SmsCodeValidateReqDTO reqDTO) { + smsCodeService.validateSmsCode(reqDTO); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeService.java index f71b8a6bd..c310949b2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeService.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.system.service.sms; import cn.iocoder.yudao.framework.common.exception.ServiceException; -import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO; +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; @@ -35,6 +35,6 @@ public interface SmsCodeService { * * @param reqDTO 校验请求 */ - void checkSmsCode(@Valid SmsCodeCheckReqDTO reqDTO); + void validateSmsCode(@Valid SmsCodeValidateReqDTO reqDTO); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImpl.java index 778445dd9..682b89eff 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImpl.java @@ -3,11 +3,9 @@ package cn.iocoder.yudao.module.system.service.sms; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; -import cn.iocoder.yudao.framework.common.util.date.DateUtils; -import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeCheckReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO; import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO; import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsCodeMapper; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; @@ -16,11 +14,11 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; - import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; import static cn.hutool.core.util.RandomUtil.randomInt; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.isToday; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; /** @@ -58,11 +56,11 @@ public class SmsCodeServiceImpl implements SmsCodeService { if (lastSmsCode != null) { if (LocalDateTimeUtil.between(lastSmsCode.getCreateTime(), LocalDateTime.now()).toMillis() < smsCodeProperties.getSendFrequency().toMillis()) { // 发送过于频繁 - throw ServiceExceptionUtil.exception(SMS_CODE_SEND_TOO_FAST); + throw exception(SMS_CODE_SEND_TOO_FAST); } - if (DateUtils.isToday(lastSmsCode.getCreateTime()) && // 必须是今天,才能计算超过当天的上限 + if (isToday(lastSmsCode.getCreateTime()) && // 必须是今天,才能计算超过当天的上限 lastSmsCode.getTodayIndex() >= smsCodeProperties.getSendMaximumQuantityPerDay()) { // 超过当天发送的上限。 - throw ServiceExceptionUtil.exception(SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY); + throw exception(SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY); } // TODO 芋艿:提升,每个 IP 每天可发送数量 // TODO 芋艿:提升,每个 IP 每小时可发送数量 @@ -71,7 +69,7 @@ public class SmsCodeServiceImpl implements SmsCodeService { // 创建验证码记录 String code = String.valueOf(randomInt(smsCodeProperties.getBeginCode(), smsCodeProperties.getEndCode() + 1)); SmsCodeDO newSmsCode = SmsCodeDO.builder().mobile(mobile).code(code).scene(scene) - .todayIndex(lastSmsCode != null && DateUtils.isToday(lastSmsCode.getCreateTime()) ? lastSmsCode.getTodayIndex() + 1 : 1) + .todayIndex(lastSmsCode != null && isToday(lastSmsCode.getCreateTime()) ? lastSmsCode.getTodayIndex() + 1 : 1) .createIp(ip).used(false).build(); smsCodeMapper.insert(newSmsCode); return code; @@ -80,32 +78,32 @@ public class SmsCodeServiceImpl implements SmsCodeService { @Override public void useSmsCode(SmsCodeUseReqDTO reqDTO) { // 检测验证码是否有效 - SmsCodeDO lastSmsCode = this.checkSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene()); + SmsCodeDO lastSmsCode = validateSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene()); // 使用验证码 smsCodeMapper.updateById(SmsCodeDO.builder().id(lastSmsCode.getId()) .used(true).usedTime(LocalDateTime.now()).usedIp(reqDTO.getUsedIp()).build()); } @Override - public void checkSmsCode(SmsCodeCheckReqDTO reqDTO) { - checkSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene()); + public void validateSmsCode(SmsCodeValidateReqDTO reqDTO) { + validateSmsCode0(reqDTO.getMobile(), reqDTO.getCode(), reqDTO.getScene()); } - public SmsCodeDO checkSmsCode0(String mobile, String code, Integer scene) { + private SmsCodeDO validateSmsCode0(String mobile, String code, Integer scene) { // 校验验证码 SmsCodeDO lastSmsCode = smsCodeMapper.selectLastByMobile(mobile, code, scene); // 若验证码不存在,抛出异常 if (lastSmsCode == null) { - throw ServiceExceptionUtil.exception(SMS_CODE_NOT_FOUND); + throw exception(SMS_CODE_NOT_FOUND); } // 超过时间 if (LocalDateTimeUtil.between(lastSmsCode.getCreateTime(), LocalDateTime.now()).toMillis() >= smsCodeProperties.getExpireTimes().toMillis()) { // 验证码已过期 - throw ServiceExceptionUtil.exception(SMS_CODE_EXPIRED); + throw exception(SMS_CODE_EXPIRED); } // 判断验证码是否已被使用 if (Boolean.TRUE.equals(lastSmsCode.getUsed())) { - throw ServiceExceptionUtil.exception(SMS_CODE_USED); + throw exception(SMS_CODE_USED); } return lastSmsCode; } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImplTest.java new file mode 100644 index 000000000..e50d025af --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsCodeServiceImplTest.java @@ -0,0 +1,209 @@ +package cn.iocoder.yudao.module.system.service.sms; + +import cn.hutool.core.map.MapUtil; +import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; +import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO; +import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO; +import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsCodeMapper; +import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; +import cn.iocoder.yudao.module.system.framework.sms.SmsCodeProperties; +import com.baomidou.mybatisplus.annotation.DbType; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.time.Duration; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@Import(SmsCodeServiceImpl.class) +public class SmsCodeServiceImplTest extends BaseDbUnitTest { + + @Resource + private SmsCodeServiceImpl smsCodeService; + + @Resource + private SmsCodeMapper smsCodeMapper; + + @MockBean + private SmsCodeProperties smsCodeProperties; + @MockBean + private SmsSendService smsSendService; + + @BeforeEach + public void setUp() { + when(smsCodeProperties.getExpireTimes()).thenReturn(Duration.ofMinutes(5)); + when(smsCodeProperties.getSendFrequency()).thenReturn(Duration.ofMinutes(1)); + when(smsCodeProperties.getSendMaximumQuantityPerDay()).thenReturn(10); + when(smsCodeProperties.getBeginCode()).thenReturn(9999); + when(smsCodeProperties.getEndCode()).thenReturn(9999); + } + + @Test + public void sendSmsCode_success() { + // 准备参数 + SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> { + o.setMobile("15601691300"); + o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene()); + }); + // mock 方法 + SqlConstants.init(DbType.MYSQL); + + // 调用 + smsCodeService.sendSmsCode(reqDTO); + // 断言 code 验证码 + SmsCodeDO smsCodeDO = smsCodeMapper.selectOne(null); + assertPojoEquals(reqDTO, smsCodeDO); + assertEquals("9999", smsCodeDO.getCode()); + assertEquals(1, smsCodeDO.getTodayIndex()); + assertFalse(smsCodeDO.getUsed()); + // 断言调用 + verify(smsSendService).sendSingleSms(eq(reqDTO.getMobile()), isNull(), isNull(), + eq("user-sms-login"), eq(MapUtil.of("code", "9999"))); + } + + @Test + public void sendSmsCode_tooFast() { + // mock 数据 + SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class, + o -> o.setMobile("15601691300").setTodayIndex(1)); + smsCodeMapper.insert(smsCodeDO); + // 准备参数 + SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> { + o.setMobile("15601691300"); + o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene()); + }); + // mock 方法 + SqlConstants.init(DbType.MYSQL); + + // 调用,并断言异常 + assertServiceException(() -> smsCodeService.sendSmsCode(reqDTO), + SMS_CODE_SEND_TOO_FAST); + } + + @Test + public void sendSmsCode_exceedDay() { + // mock 数据 + SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class, + o -> o.setMobile("15601691300").setTodayIndex(10).setCreateTime(LocalDateTime.now())); + smsCodeMapper.insert(smsCodeDO); + // 准备参数 + SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> { + o.setMobile("15601691300"); + o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene()); + }); + // mock 方法 + SqlConstants.init(DbType.MYSQL); + when(smsCodeProperties.getSendFrequency()).thenReturn(Duration.ofMillis(0)); + + // 调用,并断言异常 + assertServiceException(() -> smsCodeService.sendSmsCode(reqDTO), + SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY); + } + + @Test + public void testUseSmsCode_success() { + // 准备参数 + SmsCodeUseReqDTO reqDTO = randomPojo(SmsCodeUseReqDTO.class, o -> { + o.setMobile("15601691300"); + o.setScene(randomEle(SmsSceneEnum.values()).getScene()); + }); + // mock 数据 + SqlConstants.init(DbType.MYSQL); + smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> { + o.setMobile(reqDTO.getMobile()).setScene(reqDTO.getScene()) + .setCode(reqDTO.getCode()).setUsed(false); + })); + + // 调用 + smsCodeService.useSmsCode(reqDTO); + // 断言 + SmsCodeDO smsCodeDO = smsCodeMapper.selectOne(null); + assertTrue(smsCodeDO.getUsed()); + assertNotNull(smsCodeDO.getUsedTime()); + assertEquals(reqDTO.getUsedIp(), smsCodeDO.getUsedIp()); + } + + @Test + public void validateSmsCode_success() { + // 准备参数 + SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> { + o.setMobile("15601691300"); + o.setScene(randomEle(SmsSceneEnum.values()).getScene()); + }); + // mock 数据 + SqlConstants.init(DbType.MYSQL); + smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile()) + .setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(false))); + + // 调用 + smsCodeService.validateSmsCode(reqDTO); + } + + @Test + public void validateSmsCode_notFound() { + // 准备参数 + SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> { + o.setMobile("15601691300"); + o.setScene(randomEle(SmsSceneEnum.values()).getScene()); + }); + // mock 数据 + SqlConstants.init(DbType.MYSQL); + + // 调用,并断言异常 + assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO), + SMS_CODE_NOT_FOUND); + } + + @Test + public void validateSmsCode_expired() { + // 准备参数 + SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> { + o.setMobile("15601691300"); + o.setScene(randomEle(SmsSceneEnum.values()).getScene()); + }); + // mock 数据 + SqlConstants.init(DbType.MYSQL); + smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile()) + .setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(false) + .setCreateTime(LocalDateTime.now().minusMinutes(6)))); + + // 调用,并断言异常 + assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO), + SMS_CODE_EXPIRED); + } + + @Test + public void validateSmsCode_used() { + // 准备参数 + SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> { + o.setMobile("15601691300"); + o.setScene(randomEle(SmsSceneEnum.values()).getScene()); + }); + // mock 数据 + SqlConstants.init(DbType.MYSQL); + smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile()) + .setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(true) + .setCreateTime(LocalDateTime.now()))); + + // 调用,并断言异常 + assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO), + SMS_CODE_USED); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceImplTest.java similarity index 99% rename from yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceTest.java rename to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceImplTest.java index 546867867..2380ca09e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsLogServiceImplTest.java @@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @Import(SmsLogServiceImpl.class) -public class SmsLogServiceTest extends BaseDbUnitTest { +public class SmsLogServiceImplTest extends BaseDbUnitTest { @Resource private SmsLogServiceImpl smsLogService; diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImplTest.java similarity index 99% rename from yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceTest.java rename to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImplTest.java index 37b361449..868ae7865 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImplTest.java @@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; -public class SmsSendServiceTest extends BaseMockitoUnitTest { +public class SmsSendServiceImplTest extends BaseMockitoUnitTest { @InjectMocks private SmsSendServiceImpl smsService; diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java similarity index 98% rename from yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceTest.java rename to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java index a89d1b2e1..b72880285 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java @@ -30,9 +30,7 @@ import java.util.List; import java.util.Map; import java.util.function.Consumer; -import static cn.hutool.core.bean.BeanUtil.getFieldValue; import static cn.hutool.core.util.RandomUtil.randomEle; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; @@ -43,7 +41,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @Import(SmsTemplateServiceImpl.class) -public class SmsTemplateServiceTest extends BaseDbUnitTest { +public class SmsTemplateServiceImplTest extends BaseDbUnitTest { @Resource private SmsTemplateServiceImpl smsTemplateService; diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql index 1be69f28b..6d9dbf4b9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql @@ -14,6 +14,7 @@ DELETE FROM "system_users"; DELETE FROM "system_sms_channel"; DELETE FROM "system_sms_template"; DELETE FROM "system_sms_log"; +DELETE FROM "system_sms_code"; DELETE FROM "system_error_code"; DELETE FROM "system_social_user"; DELETE FROM "system_social_user_bind"; diff --git a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql index bf135f39e..89074492c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql @@ -377,6 +377,24 @@ CREATE TABLE IF NOT EXISTS "system_sms_log" ( PRIMARY KEY ("id") ) COMMENT '短信日志'; +CREATE TABLE IF NOT EXISTS "system_sms_code" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "mobile" varchar(11) NOT NULL, + "code" varchar(11) NOT NULL, + "scene" bigint NOT NULL, + "create_ip" varchar NOT NULL, + "today_index" int NOT NULL, + "used" bit NOT NULL DEFAULT FALSE, + "used_time" timestamp DEFAULT NULL, + "used_ip" varchar NULL, + "creator" varchar(64) DEFAULT '', + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '短信日志'; + CREATE TABLE IF NOT EXISTS "system_error_code" ( "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "type" tinyint NOT NULL DEFAULT '0', From 83003021e192cace1a19b689ea9101898f93f602 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Feb 2023 23:35:56 +0800 Subject: [PATCH 41/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20TenantPackageService?= =?UTF-8?q?Impl=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/service/dept/DeptServiceImpl.java | 8 ++-- .../service/sms/SmsChannelServiceImpl.java | 4 +- .../service/sms/SmsSendServiceImpl.java | 2 +- .../service/sms/SmsTemplateServiceImpl.java | 4 +- .../tenant/TenantPackageServiceImpl.java | 4 +- .../sms/SmsTemplateServiceImplTest.java | 26 ++++++------- ...st.java => SocialUserServiceImplTest.java} | 2 +- .../tenant/TenantPackageServiceImplTest.java | 37 +++++++++++++++++-- 8 files changed, 59 insertions(+), 28 deletions(-) rename yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/{SocialUserServiceTest.java => SocialUserServiceImplTest.java} (99%) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java index 24a93cdf6..1b2bbec04 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dept/DeptServiceImpl.java @@ -140,9 +140,9 @@ public class DeptServiceImpl implements DeptService { } List result = new ArrayList<>(); // 递归,简单粗暴 - this.getDeptsByParentIdFromCache(result, parentId, - recursive ? Integer.MAX_VALUE : 1, // 如果递归获取,则无限;否则,只递归 1 次 - parentDeptCache); + getDeptsByParentIdFromCache(result, parentId, + recursive ? Integer.MAX_VALUE : 1, // 如果递归获取,则无限;否则,只递归 1 次 + parentDeptCache); return result; } @@ -205,7 +205,7 @@ public class DeptServiceImpl implements DeptService { throw exception(DEPT_NOT_ENABLE); } // 父部门不能是原来的子部门 - List children = this.getDeptListByParentIdFromCache(id, true); + List children = getDeptListByParentIdFromCache(id, true); if (children.stream().anyMatch(dept1 -> dept1.getId().equals(parentId))) { throw exception(DEPT_PARENT_IS_CHILD); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java index 47b3b0fdc..d6f8aa004 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsChannelServiceImpl.java @@ -68,7 +68,7 @@ public class SmsChannelServiceImpl implements SmsChannelService { @Override public void updateSmsChannel(SmsChannelUpdateReqVO updateReqVO) { // 校验存在 - this.validateSmsChannelExists(updateReqVO.getId()); + validateSmsChannelExists(updateReqVO.getId()); // 更新 SmsChannelDO updateObj = SmsChannelConvert.INSTANCE.convert(updateReqVO); smsChannelMapper.updateById(updateObj); @@ -79,7 +79,7 @@ public class SmsChannelServiceImpl implements SmsChannelService { @Override public void deleteSmsChannel(Long id) { // 校验存在 - this.validateSmsChannelExists(id); + validateSmsChannelExists(id); // 校验是否有在使用该账号的模版 if (smsTemplateService.countByChannelId(id) > 0) { throw exception(SMS_CHANNEL_HAS_CHILDREN); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImpl.java index 9df628670..af4aa32fc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImpl.java @@ -90,7 +90,7 @@ public class SmsSendServiceImpl implements SmsSendService { // 校验手机号码是否存在 mobile = validateMobile(mobile); // 构建有序的模板参数。为什么放在这个位置,是提前保证模板参数的正确性,而不是到了插入发送日志 - List> newTemplateParams = this.buildTemplateParams(template, templateParams); + List> newTemplateParams = buildTemplateParams(template, templateParams); // 创建发送日志。如果模板被禁用,则不发送短信,只记录日志 Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus()) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java index 031edb7cc..25fe0031f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java @@ -125,7 +125,7 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { @Override public void updateSmsTemplate(SmsTemplateUpdateReqVO updateReqVO) { // 校验存在 - this.validateSmsTemplateExists(updateReqVO.getId()); + validateSmsTemplateExists(updateReqVO.getId()); // 校验短信渠道 SmsChannelDO channelDO = checkSmsChannel(updateReqVO.getChannelId()); // 校验短信编码是否重复 @@ -145,7 +145,7 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { @Override public void deleteSmsTemplate(Long id) { // 校验存在 - this.validateSmsTemplateExists(id); + validateSmsTemplateExists(id); // 更新 smsTemplateMapper.deleteById(id); // 发送刷新消息 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImpl.java index 2528cb905..4e6e60198 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImpl.java @@ -64,9 +64,9 @@ public class TenantPackageServiceImpl implements TenantPackageService { @Override public void deleteTenantPackage(Long id) { // 校验存在 - this.validateTenantPackageExists(id); + validateTenantPackageExists(id); // 校验正在使用 - this.validateTenantUsed(id); + validateTenantUsed(id); // 删除 tenantPackageMapper.deleteById(id); } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java index b72880285..f0c4df40a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java @@ -1,14 +1,5 @@ package cn.iocoder.yudao.module.system.service.sms; -import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateCreateReqVO; -import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateExportReqVO; -import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplatePageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateUpdateReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO; -import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO; -import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsTemplateMapper; -import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer; -import cn.iocoder.yudao.module.system.enums.sms.SmsTemplateTypeEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -19,23 +10,32 @@ import cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory; import cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult; import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateCreateReqVO; +import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateExportReqVO; +import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplatePageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateUpdateReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO; +import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO; +import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsTemplateMapper; +import cn.iocoder.yudao.module.system.enums.sms.SmsTemplateTypeEnum; +import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer; import com.google.common.collect.Lists; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.List; import java.util.Map; import java.util.function.Consumer; import static cn.hutool.core.util.RandomUtil.randomEle; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @@ -224,7 +224,7 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { reqVO.setContent("芋道"); reqVO.setApiTemplateId("yu"); reqVO.setChannelId(1L); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 11, 1),buildTime(2021, 12, 1)})); + reqVO.setCreateTime(buildBetweenTime(2021, 11, 1, 2021, 12, 1)); // 调用 PageResult pageResult = smsTemplateService.getSmsTemplatePage(reqVO); @@ -269,7 +269,7 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { reqVO.setContent("芋道"); reqVO.setApiTemplateId("yu"); reqVO.setChannelId(1L); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 11, 1),buildTime(2021, 12, 1)})); + reqVO.setCreateTime(buildBetweenTime(2021, 11, 1, 2021, 12, 1)); // 调用 List list = smsTemplateService.getSmsTemplateList(reqVO); diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java similarity index 99% rename from yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceTest.java rename to yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java index 6a3e76bdf..48f914a1a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java @@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; @Import(SocialUserServiceImpl.class) -public class SocialUserServiceTest extends BaseDbAndRedisUnitTest { +public class SocialUserServiceImplTest extends BaseDbAndRedisUnitTest { @Resource private SocialUserServiceImpl socialUserService; diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImplTest.java index 8277cdea5..9f80a1014 100755 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantPackageServiceImplTest.java @@ -2,21 +2,22 @@ package cn.iocoder.yudao.module.system.service.tenant; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageUpdateReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO; import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO; import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantPackageMapper; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.time.LocalDateTime; +import java.util.List; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; @@ -158,7 +159,7 @@ public class TenantPackageServiceImplTest extends BaseDbUnitTest { reqVO.setName("芋道"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); reqVO.setRemark("源码"); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2022, 10, 9),buildTime(2022, 10, 11)})); + reqVO.setCreateTime(buildBetweenTime(2022, 10, 9, 2022, 10, 11)); // 调用 PageResult pageResult = tenantPackageService.getTenantPackagePage(reqVO); @@ -201,4 +202,34 @@ public class TenantPackageServiceImplTest extends BaseDbUnitTest { assertServiceException(() -> tenantPackageService.validTenantPackage(dbTenantPackage.getId()), TENANT_PACKAGE_DISABLE, dbTenantPackage.getName()); } + + @Test + public void testGetTenantPackage() { + // mock 数据 + TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class); + tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据 + + // 调用 + TenantPackageDO result = tenantPackageService.getTenantPackage(dbTenantPackage.getId()); + // 断言 + assertPojoEquals(result, dbTenantPackage); + } + + @Test + public void testGetTenantPackageListByStatus() { + // mock 数据 + TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class, + o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + tenantPackageMapper.insert(dbTenantPackage); + // 测试 status 不匹配 + tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage, + o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + + // 调用 + List list = tenantPackageService.getTenantPackageListByStatus( + CommonStatusEnum.ENABLE.getStatus()); + assertEquals(1, list.size()); + assertPojoEquals(dbTenantPackage, list.get(0)); + } + } From 1d3ca8a990603071f9be8ac882cf9a8bdb7008d3 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 2 Feb 2023 23:47:17 +0800 Subject: [PATCH 42/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20TenantServiceImpl=20?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/system/service/tenant/TenantServiceImpl.java | 6 +++--- .../module/system/service/tenant/TenantServiceImplTest.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java index 35f100210..3045e7573 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java @@ -138,7 +138,7 @@ public class TenantServiceImpl implements TenantService { @Transactional(rollbackFor = Exception.class) public void updateTenant(TenantUpdateReqVO updateReqVO) { // 校验存在 - TenantDO tenant = checkUpdateTenant(updateReqVO.getId()); + TenantDO tenant = validateUpdateTenant(updateReqVO.getId()); // 校验套餐被禁用 TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(updateReqVO.getPackageId()); @@ -179,12 +179,12 @@ public class TenantServiceImpl implements TenantService { @Override public void deleteTenant(Long id) { // 校验存在 - checkUpdateTenant(id); + validateUpdateTenant(id); // 删除 tenantMapper.deleteById(id); } - private TenantDO checkUpdateTenant(Long id) { + private TenantDO validateUpdateTenant(Long id) { TenantDO tenant = tenantMapper.selectById(id); if (tenant == null) { throw exception(TENANT_NOT_EXISTS); diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java index 8cee678db..9e33f87fa 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java @@ -196,7 +196,7 @@ public class TenantServiceImplTest extends BaseDbUnitTest { role100.setTenantId(dbTenant.getId()); RoleDO role101 = randomPojo(RoleDO.class, o -> o.setId(101L)); role101.setTenantId(dbTenant.getId()); - when(roleService.getRoleList(isNull())).thenReturn(asList(role100, role101)); + when(roleService.getRoleListByStatus(isNull())).thenReturn(asList(role100, role101)); // mock 每个角色的权限 when(permissionService.getRoleMenuIds(eq(101L))).thenReturn(asSet(201L, 202L)); From 3d3c88dd4f52922c79692c9ceed6d3d6f30ad124 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 3 Feb 2023 22:10:05 +0800 Subject: [PATCH 43/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20AdminUserServiceImpl?= =?UTF-8?q?=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/util/DataPermissionUtils.java | 43 +++ .../core/util/DataPermissionUtilsTest.java | 15 + .../BpmTaskAssignRuleServiceImpl.java | 4 +- .../BpmTaskAssignRuleServiceImplTest.java | 2 +- .../module/system/api/user/AdminUserApi.java | 9 +- .../system/api/user/AdminUserApiImpl.java | 15 +- .../controller/admin/user/UserController.java | 14 +- .../dal/mysql/user/AdminUserMapper.java | 11 +- .../service/logger/OperateLogServiceImpl.java | 4 +- .../system/service/user/AdminUserService.java | 26 +- .../service/user/AdminUserServiceImpl.java | 91 +++--- .../logger/OperateLogServiceImplTest.java | 4 +- .../user/AdminUserServiceImplTest.java | 261 +++++++++++++++--- 13 files changed, 357 insertions(+), 142 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/util/DataPermissionUtils.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/util/DataPermissionUtilsTest.java diff --git a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/util/DataPermissionUtils.java b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/util/DataPermissionUtils.java new file mode 100644 index 000000000..c154bd5f5 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/util/DataPermissionUtils.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.framework.datapermission.core.util; + +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; +import cn.iocoder.yudao.framework.datapermission.core.aop.DataPermissionContextHolder; +import lombok.SneakyThrows; + +/** + * 数据权限 Util + * + * @author 芋道源码 + */ +public class DataPermissionUtils { + + private static DataPermission DATA_PERMISSION_DISABLE; + + @DataPermission(enable = false) + @SneakyThrows + private static DataPermission getDisableDataPermissionDisable() { + if (DATA_PERMISSION_DISABLE == null) { + DATA_PERMISSION_DISABLE = DataPermissionUtils.class + .getDeclaredMethod("getDisableDataPermissionDisable") + .getAnnotation(DataPermission.class); + } + return DATA_PERMISSION_DISABLE; + } + + /** + * 忽略数据权限,执行对应的逻辑 + * + * @param runnable 逻辑 + */ + public static void executeIgnore(Runnable runnable) { + DataPermission dataPermission = getDisableDataPermissionDisable(); + DataPermissionContextHolder.add(dataPermission); + try { + // 执行 runnable + runnable.run(); + } finally { + DataPermissionContextHolder.remove(); + } + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/util/DataPermissionUtilsTest.java b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/util/DataPermissionUtilsTest.java new file mode 100644 index 000000000..1cc57c258 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/util/DataPermissionUtilsTest.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.framework.datapermission.core.util; + +import cn.iocoder.yudao.framework.datapermission.core.aop.DataPermissionContextHolder; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +public class DataPermissionUtilsTest { + + @Test + public void testExecuteIgnore() { + DataPermissionUtils.executeIgnore(() -> assertFalse(DataPermissionContextHolder.get().enable())); + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index 146de14d0..508af962d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -220,7 +220,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.POST.getType())) { postApi.validPostList(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER.getType())) { - adminUserApi.validUsers(options); + adminUserApi.validateUserList(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_GROUP.getType())) { userGroupService.validUserGroups(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) { @@ -288,7 +288,7 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { } private Set calculateTaskCandidateUsersByDeptMember(BpmTaskAssignRuleDO rule) { - List users = adminUserApi.getUsersByDeptIds(rule.getOptions()); + List users = adminUserApi.getUserListByDeptIds(rule.getOptions()); return convertSet(users, AdminUserRespDTO::getId); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImplTest.java b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImplTest.java index ff163663d..7c1eb0f84 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImplTest.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImplTest.java @@ -86,7 +86,7 @@ public class BpmTaskAssignRuleServiceImplTest extends BaseDbUnitTest { // mock 方法 List users = CollectionUtils.convertList(asSet(11L, 22L), id -> new AdminUserRespDTO().setId(id)); - when(adminUserApi.getUsersByDeptIds(eq(rule.getOptions()))).thenReturn(users); + when(adminUserApi.getUserListByDeptIds(eq(rule.getOptions()))).thenReturn(users); mockGetUserMap(asSet(11L, 22L)); // 调用 diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java index 6c0b7e9d9..35e11f02d 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Set; /** * Admin 用户 API 接口 @@ -29,7 +28,7 @@ public interface AdminUserApi { * @param ids 用户 ID 们 * @return 用户对象信息 */ - List getUsers(Collection ids); + List getUserList(Collection ids); /** * 获得指定部门的用户数组 @@ -37,7 +36,7 @@ public interface AdminUserApi { * @param deptIds 部门数组 * @return 用户数组 */ - List getUsersByDeptIds(Collection deptIds); + List getUserListByDeptIds(Collection deptIds); /** * 获得指定岗位的用户数组 @@ -54,7 +53,7 @@ public interface AdminUserApi { * @return 用户 Map */ default Map getUserMap(Collection ids) { - List users = getUsers(ids); + List users = getUserList(ids); return CollectionUtils.convertMap(users, AdminUserRespDTO::getId); } @@ -65,6 +64,6 @@ public interface AdminUserApi { * * @param ids 用户编号数组 */ - void validUsers(Set ids); + void validateUserList(Collection ids); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java index d493b747a..2271420c4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java @@ -9,7 +9,6 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Collection; import java.util.List; -import java.util.Set; /** * Admin 用户 API 实现类 @@ -29,26 +28,26 @@ public class AdminUserApiImpl implements AdminUserApi { } @Override - public List getUsers(Collection ids) { - List users = userService.getUsers(ids); + public List getUserList(Collection ids) { + List users = userService.getUserList(ids); return UserConvert.INSTANCE.convertList4(users); } @Override - public List getUsersByDeptIds(Collection deptIds) { - List users = userService.getUsersByDeptIds(deptIds); + public List getUserListByDeptIds(Collection deptIds) { + List users = userService.getUserListByDeptIds(deptIds); return UserConvert.INSTANCE.convertList4(users); } @Override public List getUsersByPostIds(Collection postIds) { - List users = userService.getUsersByPostIds(postIds); + List users = userService.getUserListByPostIds(postIds); return UserConvert.INSTANCE.convertList4(users); } @Override - public void validUsers(Set ids) { - userService.validUsers(ids); + public void validateUserList(Collection ids) { + userService.validateUserList(ids); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index a2369ae24..2662631a4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java @@ -111,9 +111,9 @@ public class UserController { @GetMapping("/list-all-simple") @ApiOperation(value = "获取用户精简信息列表", notes = "只包含被开启的用户,主要用于前端的下拉选项") - public CommonResult> getSimpleUsers() { + public CommonResult> getSimpleUserList() { // 获用户列表,只要开启状态的 - List list = userService.getUsersByStatus(CommonStatusEnum.ENABLE.getStatus()); + List list = userService.getUserListByStatus(CommonStatusEnum.ENABLE.getStatus()); // 排序后,返回给前端 return success(UserConvert.INSTANCE.convertList04(list)); } @@ -122,7 +122,7 @@ public class UserController { @ApiOperation("获得用户详情") @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) @PreAuthorize("@ss.hasPermission('system:user:query')") - public CommonResult getInfo(@RequestParam("id") Long id) { + public CommonResult getUser(@RequestParam("id") Long id) { return success(UserConvert.INSTANCE.convert(userService.getUser(id))); } @@ -130,10 +130,10 @@ public class UserController { @ApiOperation("导出用户") @PreAuthorize("@ss.hasPermission('system:user:export')") @OperateLog(type = EXPORT) - public void exportUsers(@Validated UserExportReqVO reqVO, - HttpServletResponse response) throws IOException { + public void exportUserList(@Validated UserExportReqVO reqVO, + HttpServletResponse response) throws IOException { // 获得用户列表 - List users = userService.getUsers(reqVO); + List users = userService.getUserList(reqVO); // 获得拼接需要的数据 Collection deptIds = convertList(users, AdminUserDO::getDeptId); @@ -183,7 +183,7 @@ public class UserController { public CommonResult importExcel(@RequestParam("file") MultipartFile file, @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { List list = ExcelUtils.read(file, UserImportExcelVO.class); - return success(userService.importUsers(list, updateSupport)); + return success(userService.importUserList(list, updateSupport)); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java index e6713bacb..4e0827210 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.apache.ibatis.annotations.Mapper; import java.util.Collection; @@ -16,15 +15,15 @@ import java.util.List; public interface AdminUserMapper extends BaseMapperX { default AdminUserDO selectByUsername(String username) { - return selectOne(new LambdaQueryWrapper().eq(AdminUserDO::getUsername, username)); + return selectOne(AdminUserDO::getUsername, username); } default AdminUserDO selectByEmail(String email) { - return selectOne(new LambdaQueryWrapper().eq(AdminUserDO::getEmail, email)); + return selectOne(AdminUserDO::getEmail, email); } default AdminUserDO selectByMobile(String mobile) { - return selectOne(new LambdaQueryWrapper().eq(AdminUserDO::getMobile, mobile)); + return selectOne(AdminUserDO::getMobile, mobile); } default PageResult selectPage(UserPageReqVO reqVO, Collection deptIds) { @@ -50,10 +49,6 @@ public interface AdminUserMapper extends BaseMapperX { return selectList(new LambdaQueryWrapperX().like(AdminUserDO::getNickname, nickname)); } - default List selectListByUsername(String username) { - return selectList(new LambdaQueryWrapperX().like(AdminUserDO::getUsername, username)); - } - default List selectListByStatus(Integer status) { return selectList(AdminUserDO::getStatus, status); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java index fbf983b43..c899696ac 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java @@ -49,7 +49,7 @@ public class OperateLogServiceImpl implements OperateLogService { // 处理基于用户昵称的查询 Collection userIds = null; if (StrUtil.isNotEmpty(reqVO.getUserNickname())) { - userIds = convertSet(userService.getUsersByNickname(reqVO.getUserNickname()), AdminUserDO::getId); + userIds = convertSet(userService.getUserListByNickname(reqVO.getUserNickname()), AdminUserDO::getId); if (CollUtil.isEmpty(userIds)) { return PageResult.empty(); } @@ -63,7 +63,7 @@ public class OperateLogServiceImpl implements OperateLogService { // 处理基于用户昵称的查询 Collection userIds = null; if (StrUtil.isNotEmpty(reqVO.getUserNickname())) { - userIds = convertSet(userService.getUsersByNickname(reqVO.getUserNickname()), AdminUserDO::getId); + userIds = convertSet(userService.getUserListByNickname(reqVO.getUserNickname()), AdminUserDO::getId); if (CollUtil.isEmpty(userIds)) { return Collections.emptyList(); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java index ae3245de2..e10b9e997 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java @@ -127,7 +127,7 @@ public interface AdminUserService { * @param deptIds 部门数组 * @return 用户数组 */ - List getUsersByDeptIds(Collection deptIds); + List getUserListByDeptIds(Collection deptIds); /** * 获得指定岗位的用户数组 @@ -135,7 +135,7 @@ public interface AdminUserService { * @param postIds 岗位数组 * @return 用户数组 */ - List getUsersByPostIds(Collection postIds); + List getUserListByPostIds(Collection postIds); /** * 获得用户列表 @@ -143,7 +143,7 @@ public interface AdminUserService { * @param ids 用户编号数组 * @return 用户列表 */ - List getUsers(Collection ids); + List getUserList(Collection ids); /** * 校验用户们是否有效。如下情况,视为无效: @@ -152,7 +152,7 @@ public interface AdminUserService { * * @param ids 用户编号数组 */ - void validUsers(Set ids); + void validateUserList(Collection ids); /** * 获得用户 Map @@ -164,7 +164,7 @@ public interface AdminUserService { if (CollUtil.isEmpty(ids)) { return new HashMap<>(); } - return CollectionUtils.convertMap(getUsers(ids), AdminUserDO::getId); + return CollectionUtils.convertMap(getUserList(ids), AdminUserDO::getId); } /** @@ -173,7 +173,7 @@ public interface AdminUserService { * @param reqVO 列表请求 * @return 用户列表 */ - List getUsers(UserExportReqVO reqVO); + List getUserList(UserExportReqVO reqVO); /** * 获得用户列表,基于昵称模糊匹配 @@ -181,15 +181,7 @@ public interface AdminUserService { * @param nickname 昵称 * @return 用户列表 */ - List getUsersByNickname(String nickname); - - /** - * 获得用户列表,基于用户账号模糊匹配 - * - * @param username 用户账号 - * @return 用户列表 - */ - List getUsersByUsername(String username); + List getUserListByNickname(String nickname); /** * 批量导入用户 @@ -198,7 +190,7 @@ public interface AdminUserService { * @param isUpdateSupport 是否支持更新 * @return 导入结果 */ - UserImportRespVO importUsers(List importUsers, boolean isUpdateSupport); + UserImportRespVO importUserList(List importUsers, boolean isUpdateSupport); /** * 获得指定状态的用户们 @@ -206,7 +198,7 @@ public interface AdminUserService { * @param status 状态 * @return 用户们 */ - List getUsersByStatus(Integer status); + List getUserListByStatus(Integer status); /** * 判断密码是否匹配 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index 913c0d15a..bb43a89c2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; +import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils; import cn.iocoder.yudao.module.infra.api.file.FileApi; import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO; import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO; @@ -74,10 +74,6 @@ public class AdminUserServiceImpl implements AdminUserService { @Resource private FileApi fileApi; - @Resource - @Lazy // 循环依赖(自己依赖自己),避免报错 - private AdminUserServiceImpl self; - @Override @Transactional(rollbackFor = Exception.class) public Long createUser(UserCreateReqVO reqVO) { @@ -89,7 +85,7 @@ public class AdminUserServiceImpl implements AdminUserService { } }); // 校验正确性 - self.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), + validateUserForCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), reqVO.getDeptId(), reqVO.getPostIds()); // 插入用户 AdminUserDO user = UserConvert.INSTANCE.convert(reqVO); @@ -108,7 +104,7 @@ public class AdminUserServiceImpl implements AdminUserService { @Transactional(rollbackFor = Exception.class) public void updateUser(UserUpdateReqVO reqVO) { // 校验正确性 - self.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), + validateUserForCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(), reqVO.getDeptId(), reqVO.getPostIds()); // 更新用户 AdminUserDO updateObj = UserConvert.INSTANCE.convert(reqVO); @@ -142,9 +138,9 @@ public class AdminUserServiceImpl implements AdminUserService { @Override public void updateUserProfile(Long id, UserProfileUpdateReqVO reqVO) { // 校验正确性 - checkUserExists(id); - checkEmailUnique(id, reqVO.getEmail()); - checkMobileUnique(id, reqVO.getMobile()); + validateUserExists(id); + validateEmailUnique(id, reqVO.getEmail()); + validateMobileUnique(id, reqVO.getMobile()); // 执行更新 userMapper.updateById(UserConvert.INSTANCE.convert(reqVO).setId(id)); } @@ -152,7 +148,7 @@ public class AdminUserServiceImpl implements AdminUserService { @Override public void updateUserPassword(Long id, UserProfileUpdatePasswordReqVO reqVO) { // 校验旧密码密码 - checkOldPassword(id, reqVO.getOldPassword()); + validateOldPassword(id, reqVO.getOldPassword()); // 执行更新 AdminUserDO updateObj = new AdminUserDO().setId(id); updateObj.setPassword(encodePassword(reqVO.getNewPassword())); // 加密密码 @@ -161,7 +157,7 @@ public class AdminUserServiceImpl implements AdminUserService { @Override public String updateUserAvatar(Long id, InputStream avatarFile) throws Exception { - checkUserExists(id); + validateUserExists(id); // 存储文件 String avatar = fileApi.createFile(IoUtil.readBytes(avatarFile)); // 更新路径 @@ -175,7 +171,7 @@ public class AdminUserServiceImpl implements AdminUserService { @Override public void updateUserPassword(Long id, String password) { // 校验用户存在 - checkUserExists(id); + validateUserExists(id); // 更新密码 AdminUserDO updateObj = new AdminUserDO(); updateObj.setId(id); @@ -186,7 +182,7 @@ public class AdminUserServiceImpl implements AdminUserService { @Override public void updateUserStatus(Long id, Integer status) { // 校验用户存在 - checkUserExists(id); + validateUserExists(id); // 更新状态 AdminUserDO updateObj = new AdminUserDO(); updateObj.setId(id); @@ -198,7 +194,7 @@ public class AdminUserServiceImpl implements AdminUserService { @Transactional(rollbackFor = Exception.class) public void deleteUser(Long id) { // 校验用户存在 - checkUserExists(id); + validateUserExists(id); // 删除用户 userMapper.deleteById(id); // 删除用户关联数据 @@ -228,7 +224,7 @@ public class AdminUserServiceImpl implements AdminUserService { } @Override - public List getUsersByDeptIds(Collection deptIds) { + public List getUserListByDeptIds(Collection deptIds) { if (CollUtil.isEmpty(deptIds)) { return Collections.emptyList(); } @@ -236,7 +232,7 @@ public class AdminUserServiceImpl implements AdminUserService { } @Override - public List getUsersByPostIds(Collection postIds) { + public List getUserListByPostIds(Collection postIds) { if (CollUtil.isEmpty(postIds)) { return Collections.emptyList(); } @@ -248,7 +244,7 @@ public class AdminUserServiceImpl implements AdminUserService { } @Override - public List getUsers(Collection ids) { + public List getUserList(Collection ids) { if (CollUtil.isEmpty(ids)) { return Collections.emptyList(); } @@ -256,7 +252,7 @@ public class AdminUserServiceImpl implements AdminUserService { } @Override - public void validUsers(Set ids) { + public void validateUserList(Collection ids) { if (CollUtil.isEmpty(ids)) { return; } @@ -276,20 +272,15 @@ public class AdminUserServiceImpl implements AdminUserService { } @Override - public List getUsers(UserExportReqVO reqVO) { + public List getUserList(UserExportReqVO reqVO) { return userMapper.selectList(reqVO, getDeptCondition(reqVO.getDeptId())); } @Override - public List getUsersByNickname(String nickname) { + public List getUserListByNickname(String nickname) { return userMapper.selectListByNickname(nickname); } - @Override - public List getUsersByUsername(String username) { - return userMapper.selectListByUsername(username); - } - /** * 获得部门条件:查询指定部门的子部门编号们,包括自身 * @param deptId 部门编号 @@ -305,25 +296,27 @@ public class AdminUserServiceImpl implements AdminUserService { return deptIds; } - @DataPermission(enable = false) // 关闭数据权限,避免因为没有数据权限,查询不到数据,进而导致唯一校验不正确 - public void checkCreateOrUpdate(Long id, String username, String mobile, String email, - Long deptId, Set postIds) { - // 校验用户存在 - checkUserExists(id); - // 校验用户名唯一 - checkUsernameUnique(id, username); - // 校验手机号唯一 - checkMobileUnique(id, mobile); - // 校验邮箱唯一 - checkEmailUnique(id, email); - // 校验部门处于开启状态 - deptService.validateDeptList(CollectionUtils.singleton(deptId)); - // 校验岗位处于开启状态 - postService.validatePostList(postIds); + private void validateUserForCreateOrUpdate(Long id, String username, String mobile, String email, + Long deptId, Set postIds) { + // 关闭数据权限,避免因为没有数据权限,查询不到数据,进而导致唯一校验不正确 + DataPermissionUtils.executeIgnore(() -> { + // 校验用户存在 + validateUserExists(id); + // 校验用户名唯一 + validateUsernameUnique(id, username); + // 校验手机号唯一 + validateMobileUnique(id, mobile); + // 校验邮箱唯一 + validateEmailUnique(id, email); + // 校验部门处于开启状态 + deptService.validateDeptList(CollectionUtils.singleton(deptId)); + // 校验岗位处于开启状态 + postService.validatePostList(postIds); + }); } @VisibleForTesting - public void checkUserExists(Long id) { + void validateUserExists(Long id) { if (id == null) { return; } @@ -334,7 +327,7 @@ public class AdminUserServiceImpl implements AdminUserService { } @VisibleForTesting - public void checkUsernameUnique(Long id, String username) { + void validateUsernameUnique(Long id, String username) { if (StrUtil.isBlank(username)) { return; } @@ -352,7 +345,7 @@ public class AdminUserServiceImpl implements AdminUserService { } @VisibleForTesting - public void checkEmailUnique(Long id, String email) { + void validateEmailUnique(Long id, String email) { if (StrUtil.isBlank(email)) { return; } @@ -370,7 +363,7 @@ public class AdminUserServiceImpl implements AdminUserService { } @VisibleForTesting - public void checkMobileUnique(Long id, String mobile) { + void validateMobileUnique(Long id, String mobile) { if (StrUtil.isBlank(mobile)) { return; } @@ -393,7 +386,7 @@ public class AdminUserServiceImpl implements AdminUserService { * @param oldPassword 旧密码 */ @VisibleForTesting - public void checkOldPassword(Long id, String oldPassword) { + void validateOldPassword(Long id, String oldPassword) { AdminUserDO user = userMapper.selectById(id); if (user == null) { throw exception(USER_NOT_EXISTS); @@ -405,7 +398,7 @@ public class AdminUserServiceImpl implements AdminUserService { @Override @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入 - public UserImportRespVO importUsers(List importUsers, boolean isUpdateSupport) { + public UserImportRespVO importUserList(List importUsers, boolean isUpdateSupport) { if (CollUtil.isEmpty(importUsers)) { throw exception(USER_IMPORT_LIST_IS_EMPTY); } @@ -414,7 +407,7 @@ public class AdminUserServiceImpl implements AdminUserService { importUsers.forEach(importUser -> { // 校验,判断是否有不符合的原因 try { - checkCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(), + validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(), importUser.getDeptId(), null); } catch (ServiceException ex) { respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage()); @@ -442,7 +435,7 @@ public class AdminUserServiceImpl implements AdminUserService { } @Override - public List getUsersByStatus(Integer status) { + public List getUserListByStatus(Integer status) { return userMapper.selectListByStatus(status); } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImplTest.java index cb1085d3a..14b007e25 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImplTest.java @@ -64,7 +64,7 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest { o.setNickname("wang"); o.setStatus(CommonStatusEnum.ENABLE.getStatus()); }); - when(userService.getUsersByNickname("wang")).thenReturn(Collections.singletonList(user)); + when(userService.getUserListByNickname("wang")).thenReturn(Collections.singletonList(user)); Long userId = user.getId(); // 构造操作日志 @@ -112,7 +112,7 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest { o.setNickname("wang"); o.setStatus(CommonStatusEnum.ENABLE.getStatus()); }); - when(userService.getUsersByNickname("wang")).thenReturn(Collections.singletonList(user)); + when(userService.getUserListByNickname("wang")).thenReturn(Collections.singletonList(user)); Long userId = user.getId(); // 构造操作日志 diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java index 54b042c44..a5e0183a4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImplTest.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.infra.api.file.FileApi; import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO; @@ -32,23 +31,25 @@ import org.springframework.security.crypto.password.PasswordEncoder; import javax.annotation.Resource; import java.io.ByteArrayInputStream; -import java.time.LocalDateTime; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.function.Consumer; import static cn.hutool.core.util.RandomUtil.randomBytes; import static cn.hutool.core.util.RandomUtil.randomEle; import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; import static org.assertj.core.util.Lists.newArrayList; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -173,6 +174,23 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { assertEquals(3L, userPosts.get(1).getPostId()); } + @Test + public void testUpdateUserLogin() { + // mock 数据 + AdminUserDO user = randomAdminUserDO(o -> o.setLoginDate(null)); + userMapper.insert(user); + // 准备参数 + Long id = user.getId(); + String loginIp = randomString(); + + // 调用 + userService.updateUserLogin(id, loginIp); + // 断言 + AdminUserDO dbUser = userMapper.selectById(id); + assertEquals(loginIp, dbUser.getLoginIp()); + assertNotNull(dbUser.getLoginDate()); + } + @Test public void testUpdateUserProfile_success() { // mock 数据 @@ -286,6 +304,34 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { verify(permissionService, times(1)).processUserDeleted(eq(userId)); } + @Test + public void testGetUserByUsername() { + // mock 数据 + AdminUserDO dbUser = randomAdminUserDO(); + userMapper.insert(dbUser); + // 准备参数 + String username = dbUser.getUsername(); + + // 调用 + AdminUserDO user = userService.getUserByUsername(username); + // 断言 + assertPojoEquals(dbUser, user); + } + + @Test + public void testGetUserByMobile() { + // mock 数据 + AdminUserDO dbUser = randomAdminUserDO(); + userMapper.insert(dbUser); + // 准备参数 + String mobile = dbUser.getMobile(); + + // 调用 + AdminUserDO user = userService.getUserByMobile(mobile); + // 断言 + assertPojoEquals(dbUser, user); + } + @Test public void testGetUserPage() { // mock 数据 @@ -295,7 +341,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { reqVO.setUsername("tu"); reqVO.setMobile("1560"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2020, 12, 1),buildTime(2020, 12, 24)})); + reqVO.setCreateTime(buildBetweenTime(2020, 12, 1, 2020, 12, 24)); reqVO.setDeptId(1L); // 其中,1L 是 2L 的父部门 // mock 方法 List deptList = newArrayList(randomPojo(DeptDO.class, o -> o.setId(2L))); @@ -310,7 +356,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { } @Test - public void testGetUsers() { + public void testGetUserList_export() { // mock 数据 AdminUserDO dbUser = initGetUserPageData(); // 准备参数 @@ -318,14 +364,14 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { reqVO.setUsername("tu"); reqVO.setMobile("1560"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2020, 12, 1),buildTime(2020, 12, 24)})); + reqVO.setCreateTime(buildBetweenTime(2020, 12, 1, 2020, 12, 24)); reqVO.setDeptId(1L); // 其中,1L 是 2L 的父部门 // mock 方法 List deptList = newArrayList(randomPojo(DeptDO.class, o -> o.setId(2L))); when(deptService.getDeptListByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList); // 调用 - List list = userService.getUsers(reqVO); + List list = userService.getUserList(reqVO); // 断言 assertEquals(1, list.size()); assertPojoEquals(dbUser, list.get(0)); @@ -345,23 +391,54 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { }); userMapper.insert(dbUser); // 测试 username 不匹配 - userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setUsername("dou"))); + userMapper.insert(cloneIgnoreId(dbUser, o -> o.setUsername("dou"))); // 测试 mobile 不匹配 - userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setMobile("18818260888"))); + userMapper.insert(cloneIgnoreId(dbUser, o -> o.setMobile("18818260888"))); // 测试 status 不匹配 - userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + userMapper.insert(cloneIgnoreId(dbUser, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); // 测试 createTime 不匹配 - userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setCreateTime(buildTime(2020, 11, 11)))); + userMapper.insert(cloneIgnoreId(dbUser, o -> o.setCreateTime(buildTime(2020, 11, 11)))); // 测试 dept 不匹配 - userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setDeptId(0L))); + userMapper.insert(cloneIgnoreId(dbUser, o -> o.setDeptId(0L))); return dbUser; } + @Test + public void testGetUser() { + // mock 数据 + AdminUserDO dbUser = randomAdminUserDO(); + userMapper.insert(dbUser); + // 准备参数 + Long userId = dbUser.getId(); + + // 调用 + AdminUserDO user = userService.getUser(userId); + // 断言 + assertPojoEquals(dbUser, user); + } + + @Test + public void testGetUserListByDeptIds() { + // mock 数据 + AdminUserDO dbUser = randomAdminUserDO(o -> o.setDeptId(1L)); + userMapper.insert(dbUser); + // 测试 deptId 不匹配 + userMapper.insert(cloneIgnoreId(dbUser, o -> o.setDeptId(2L))); + // 准备参数 + Collection deptIds = singleton(1L); + + // 调用 + List list = userService.getUserListByDeptIds(deptIds); + // 断言 + assertEquals(1, list.size()); + assertEquals(dbUser, list.get(0)); + } + /** * 情况一,校验不通过,导致插入失败 */ @Test - public void testImportUsers_01() { + public void testImportUserList_01() { // 准备参数 UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> { }); @@ -369,7 +446,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { doThrow(new ServiceException(DEPT_NOT_FOUND)).when(deptService).validateDeptList(any()); // 调用 - UserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true); + UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true); // 断言 assertEquals(0, respVO.getCreateUsernames().size()); assertEquals(0, respVO.getUpdateUsernames().size()); @@ -381,7 +458,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { * 情况二,不存在,进行插入 */ @Test - public void testImportUsers_02() { + public void testImportUserList_02() { // 准备参数 UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> { o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 @@ -397,7 +474,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { when(passwordEncoder.encode(eq("yudaoyuanma"))).thenReturn("java"); // 调用 - UserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true); + UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true); // 断言 assertEquals(1, respVO.getCreateUsernames().size()); AdminUserDO user = userMapper.selectByUsername(respVO.getCreateUsernames().get(0)); @@ -411,7 +488,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { * 情况三,存在,但是不强制更新 */ @Test - public void testImportUsers_03() { + public void testImportUserList_03() { // mock 数据 AdminUserDO dbUser = randomAdminUserDO(); userMapper.insert(dbUser); @@ -429,7 +506,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { when(deptService.getDept(eq(dept.getId()))).thenReturn(dept); // 调用 - UserImportRespVO respVO = userService.importUsers(newArrayList(importUser), false); + UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), false); // 断言 assertEquals(0, respVO.getCreateUsernames().size()); assertEquals(0, respVO.getUpdateUsernames().size()); @@ -441,7 +518,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { * 情况四,存在,强制更新 */ @Test - public void testImportUsers_04() { + public void testImportUserList_04() { // mock 数据 AdminUserDO dbUser = randomAdminUserDO(); userMapper.insert(dbUser); @@ -459,7 +536,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { when(deptService.getDept(eq(dept.getId()))).thenReturn(dept); // 调用 - UserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true); + UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true); // 断言 assertEquals(0, respVO.getCreateUsernames().size()); assertEquals(1, respVO.getUpdateUsernames().size()); @@ -469,24 +546,24 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { } @Test - public void testCheckUserExists_notExists() { - assertServiceException(() -> userService.checkUserExists(randomLongId()), USER_NOT_EXISTS); + public void testValidateUserExists_notExists() { + assertServiceException(() -> userService.validateUserExists(randomLongId()), USER_NOT_EXISTS); } @Test - public void testCheckUsernameUnique_usernameExistsForCreate() { + public void testValidateUsernameUnique_usernameExistsForCreate() { // 准备参数 String username = randomString(); // mock 数据 userMapper.insert(randomAdminUserDO(o -> o.setUsername(username))); // 调用,校验异常 - assertServiceException(() -> userService.checkUsernameUnique(null, username), + assertServiceException(() -> userService.validateUsernameUnique(null, username), USER_USERNAME_EXISTS); } @Test - public void testCheckUsernameUnique_usernameExistsForUpdate() { + public void testValidateUsernameUnique_usernameExistsForUpdate() { // 准备参数 Long id = randomLongId(); String username = randomString(); @@ -494,24 +571,24 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { userMapper.insert(randomAdminUserDO(o -> o.setUsername(username))); // 调用,校验异常 - assertServiceException(() -> userService.checkUsernameUnique(id, username), + assertServiceException(() -> userService.validateUsernameUnique(id, username), USER_USERNAME_EXISTS); } @Test - public void testCheckEmailUnique_emailExistsForCreate() { + public void testValidateEmailUnique_emailExistsForCreate() { // 准备参数 String email = randomString(); // mock 数据 userMapper.insert(randomAdminUserDO(o -> o.setEmail(email))); // 调用,校验异常 - assertServiceException(() -> userService.checkEmailUnique(null, email), + assertServiceException(() -> userService.validateEmailUnique(null, email), USER_EMAIL_EXISTS); } @Test - public void testCheckEmailUnique_emailExistsForUpdate() { + public void testValidateEmailUnique_emailExistsForUpdate() { // 准备参数 Long id = randomLongId(); String email = randomString(); @@ -519,24 +596,24 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { userMapper.insert(randomAdminUserDO(o -> o.setEmail(email))); // 调用,校验异常 - assertServiceException(() -> userService.checkEmailUnique(id, email), + assertServiceException(() -> userService.validateEmailUnique(id, email), USER_EMAIL_EXISTS); } @Test - public void testCheckMobileUnique_mobileExistsForCreate() { + public void testValidateMobileUnique_mobileExistsForCreate() { // 准备参数 String mobile = randomString(); // mock 数据 userMapper.insert(randomAdminUserDO(o -> o.setMobile(mobile))); // 调用,校验异常 - assertServiceException(() -> userService.checkMobileUnique(null, mobile), + assertServiceException(() -> userService.validateMobileUnique(null, mobile), USER_MOBILE_EXISTS); } @Test - public void testCheckMobileUnique_mobileExistsForUpdate() { + public void testValidateMobileUnique_mobileExistsForUpdate() { // 准备参数 Long id = randomLongId(); String mobile = randomString(); @@ -544,18 +621,18 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { userMapper.insert(randomAdminUserDO(o -> o.setMobile(mobile))); // 调用,校验异常 - assertServiceException(() -> userService.checkMobileUnique(id, mobile), + assertServiceException(() -> userService.validateMobileUnique(id, mobile), USER_MOBILE_EXISTS); } @Test - public void testCheckOldPassword_notExists() { - assertServiceException(() -> userService.checkOldPassword(randomLongId(), randomString()), + public void testValidateOldPassword_notExists() { + assertServiceException(() -> userService.validateOldPassword(randomLongId(), randomString()), USER_NOT_EXISTS); } @Test - public void testCheckOldPassword_passwordFailed() { + public void testValidateOldPassword_passwordFailed() { // mock 数据 AdminUserDO user = randomAdminUserDO(); userMapper.insert(user); @@ -564,14 +641,14 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { String oldPassword = user.getPassword(); // 调用,校验异常 - assertServiceException(() -> userService.checkOldPassword(id, oldPassword), + assertServiceException(() -> userService.validateOldPassword(id, oldPassword), USER_PASSWORD_FAILED); // 校验调用 verify(passwordEncoder, times(1)).matches(eq(oldPassword), eq(user.getPassword())); } @Test - public void testUsersByPostIds() { + public void testUserListByPostIds() { // 准备参数 Collection postIds = asSet(10L, 20L); // mock user1 数据 @@ -585,12 +662,114 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest { userPostMapper.insert(new UserPostDO().setUserId(user2.getId()).setPostId(100L)); // 调用 - List result = userService.getUsersByPostIds(postIds); + List result = userService.getUserListByPostIds(postIds); // 断言 assertEquals(1, result.size()); assertEquals(user1, result.get(0)); } + @Test + public void testGetUserList() { + // mock 数据 + AdminUserDO user = randomAdminUserDO(); + userMapper.insert(user); + // 测试 id 不匹配 + userMapper.insert(randomAdminUserDO()); + // 准备参数 + Collection ids = singleton(user.getId()); + + // 调用 + List result = userService.getUserList(ids); + // 断言 + assertEquals(1, result.size()); + assertEquals(user, result.get(0)); + } + + @Test + public void testGetUserMap() { + // mock 数据 + AdminUserDO user = randomAdminUserDO(); + userMapper.insert(user); + // 测试 id 不匹配 + userMapper.insert(randomAdminUserDO()); + // 准备参数 + Collection ids = singleton(user.getId()); + + // 调用 + Map result = userService.getUserMap(ids); + // 断言 + assertEquals(1, result.size()); + assertEquals(user, result.get(user.getId())); + } + + @Test + public void testGetUserListByNickname() { + // mock 数据 + AdminUserDO user = randomAdminUserDO(o -> o.setNickname("芋头")); + userMapper.insert(user); + // 测试 nickname 不匹配 + userMapper.insert(randomAdminUserDO(o -> o.setNickname("源码"))); + // 准备参数 + String nickname = "芋"; + + // 调用 + List result = userService.getUserListByNickname(nickname); + // 断言 + assertEquals(1, result.size()); + assertEquals(user, result.get(0)); + } + + @Test + public void testGetUserListByStatus() { + // mock 数据 + AdminUserDO user = randomAdminUserDO(o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())); + userMapper.insert(user); + // 测试 status 不匹配 + userMapper.insert(randomAdminUserDO(o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()))); + // 准备参数 + Integer status = CommonStatusEnum.DISABLE.getStatus(); + + // 调用 + List result = userService.getUserListByStatus(status); + // 断言 + assertEquals(1, result.size()); + assertEquals(user, result.get(0)); + } + + @Test + public void testValidateUserList_success() { + // mock 数据 + AdminUserDO userDO = randomAdminUserDO().setStatus(CommonStatusEnum.ENABLE.getStatus()); + userMapper.insert(userDO); + // 准备参数 + List ids = singletonList(userDO.getId()); + + // 调用,无需断言 + userService.validateUserList(ids); + } + + @Test + public void testValidateUserList_notFound() { + // 准备参数 + List ids = singletonList(randomLongId()); + + // 调用, 并断言异常 + assertServiceException(() -> userService.validateUserList(ids), USER_NOT_EXISTS); + } + + @Test + public void testValidateUserList_notEnable() { + // mock 数据 + AdminUserDO userDO = randomAdminUserDO().setStatus(CommonStatusEnum.DISABLE.getStatus()); + userMapper.insert(userDO); + // 准备参数 + List ids = singletonList(userDO.getId()); + + // 调用, 并断言异常 + assertServiceException(() -> userService.validateUserList(ids), USER_IS_DISABLE, + userDO.getNickname()); + } + // ========== 随机对象 ========== @SafeVarargs From 62dc3296d65e2b4f03b95da40cbab10ef0ca9095 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 3 Feb 2023 23:39:47 +0800 Subject: [PATCH 44/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20mail=20=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/mail/MailSendServiceImpl.java | 23 +-- .../mail/MailAccountServiceImplTest.java | 53 +++++- .../service/mail/MailLogServiceImplTest.java | 14 ++ .../service/mail/MailSendServiceImplTest.java | 171 ++++++++++++++++-- .../mail/MailTemplateServiceImplTest.java | 85 ++++++++- .../service/sms/SmsSendServiceImplTest.java | 2 +- 6 files changed, 317 insertions(+), 31 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java index d7b17d877..72da3cf89 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImpl.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.system.service.mail; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.mail.MailAccount; import cn.hutool.extra.mail.MailUtil; -import cn.iocoder.yudao.framework.common.core.KeyValue; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.module.system.convert.mail.MailAccountConvert; @@ -20,15 +19,13 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; /** - * 邮箱模版 服务实现类 + * 邮箱发送 Service 实现类 * * @author wangjingyi * @since 2022-03-21 @@ -82,13 +79,13 @@ public class MailSendServiceImpl implements MailSendService { public Long sendSingleMail(String mail, Long userId, Integer userType, String templateCode, Map templateParams) { // 校验邮箱模版是否合法 - MailTemplateDO template = checkMailTemplateValid(templateCode); + MailTemplateDO template = validateMailTemplate(templateCode); // 校验邮箱账号是否合法 - MailAccountDO account = checkMailAccountValid(template.getAccountId()); + MailAccountDO account = validateMailAccount(template.getAccountId()); // 校验邮箱是否存在 - mail = checkMail(mail); - checkTemplateParams(template, templateParams); + mail = validateMail(mail); + validateTemplateParams(template, templateParams); // 创建发送日志。如果模板被禁用,则不发送短信,只记录日志 Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus()); @@ -106,7 +103,7 @@ public class MailSendServiceImpl implements MailSendService { @Override public void doSendMail(MailSendMessage message) { // 1. 创建发送账号 - MailAccountDO account = checkMailAccountValid(message.getAccountId()); + MailAccountDO account = validateMailAccount(message.getAccountId()); MailAccount mailAccount = MailAccountConvert.INSTANCE.convert(account, message.getNickname()); // 2. 发送邮件 try { @@ -121,7 +118,7 @@ public class MailSendServiceImpl implements MailSendService { } @VisibleForTesting - public MailTemplateDO checkMailTemplateValid(String templateCode) { + MailTemplateDO validateMailTemplate(String templateCode) { // 获得邮件模板。考虑到效率,从缓存中获取 MailTemplateDO template = mailTemplateService.getMailTemplateByCodeFromCache(templateCode); // 邮件模板不存在 @@ -132,7 +129,7 @@ public class MailSendServiceImpl implements MailSendService { } @VisibleForTesting - public MailAccountDO checkMailAccountValid(Long accountId) { + MailAccountDO validateMailAccount(Long accountId) { // 获得邮箱账号。考虑到效率,从缓存中获取 MailAccountDO account = mailAccountService.getMailAccountFromCache(accountId); // 邮箱账号不存在 @@ -143,7 +140,7 @@ public class MailSendServiceImpl implements MailSendService { } @VisibleForTesting - public String checkMail(String mail) { + String validateMail(String mail) { if (StrUtil.isEmpty(mail)) { throw exception(MAIL_SEND_MAIL_NOT_EXISTS); } @@ -157,7 +154,7 @@ public class MailSendServiceImpl implements MailSendService { * @param templateParams 参数列表 */ @VisibleForTesting - public void checkTemplateParams(MailTemplateDO template, Map templateParams) { + void validateTemplateParams(MailTemplateDO template, Map templateParams) { template.getParams().forEach(key -> { Object value = templateParams.get(key); if (value == null) { diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailAccountServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailAccountServiceImplTest.java index ffca4b1b6..a0e41f75c 100755 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailAccountServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailAccountServiceImplTest.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccou import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountUpdateReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; -import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; import cn.iocoder.yudao.module.system.dal.mysql.mail.MailAccountMapper; import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer; import org.junit.jupiter.api.Test; @@ -14,7 +13,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; - +import java.util.List; import java.util.Map; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; @@ -23,7 +22,9 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServic import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_ACCOUNT_NOT_EXISTS; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** * {@link MailAccountServiceImpl} 的单元测试类 @@ -109,6 +110,8 @@ public class MailAccountServiceImplTest extends BaseDbUnitTest { mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据 // 准备参数 Long id = dbMailAccount.getId(); + // mock 方法(无关联模版) + when(mailTemplateService.countByAccountId(eq(id))).thenReturn(0L); // 调用 mailAccountService.deleteMailAccount(id); @@ -117,6 +120,21 @@ public class MailAccountServiceImplTest extends BaseDbUnitTest { verify(mailProducer).sendMailAccountRefreshMessage(); } + @Test + public void testGetMailAccountFromCache() { + // mock 数据 + MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class); + mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据 + mailAccountService.initLocalCache(); + // 准备参数 + Long id = dbMailAccount.getId(); + + // 调用 + MailAccountDO mailAccount = mailAccountService.getMailAccountFromCache(id); + // 断言 + assertPojoEquals(dbMailAccount, mailAccount); + } + @Test public void testDeleteMailAccount_notExists() { // 准备参数 @@ -151,4 +169,35 @@ public class MailAccountServiceImplTest extends BaseDbUnitTest { assertPojoEquals(dbMailAccount, pageResult.getList().get(0)); } + @Test + public void testGetMailAccount() { + // mock 数据 + MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class); + mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbMailAccount.getId(); + + // 调用 + MailAccountDO mailAccount = mailAccountService.getMailAccount(id); + // 断言 + assertPojoEquals(dbMailAccount, mailAccount); + } + + @Test + public void testGetMailAccountList() { + // mock 数据 + MailAccountDO dbMailAccount01 = randomPojo(MailAccountDO.class); + mailAccountMapper.insert(dbMailAccount01); + MailAccountDO dbMailAccount02 = randomPojo(MailAccountDO.class); + mailAccountMapper.insert(dbMailAccount02); + // 准备参数 + + // 调用 + List list = mailAccountService.getMailAccountList(); + // 断言 + assertEquals(2, list.size()); + assertPojoEquals(dbMailAccount01, list.get(0)); + assertPojoEquals(dbMailAccount02, list.get(1)); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImplTest.java index ccf4ba737..53acd0ef0 100755 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailLogServiceImplTest.java @@ -116,6 +116,20 @@ public class MailLogServiceImplTest extends BaseDbUnitTest { assertEquals("NullPointerException: 测试异常", dbLog.getSendException()); } + @Test + public void testGetMailLog() { + // mock 数据 + MailLogDO dbMailLog = randomPojo(MailLogDO.class, o -> o.setTemplateParams(randomTemplateParams())); + mailLogMapper.insert(dbMailLog); + // 准备参数 + Long id = dbMailLog.getId(); + + // 调用 + MailLogDO mailLog = mailLogService.getMailLog(id); + // 断言 + assertPojoEquals(dbMailLog, mailLog); + } + @Test public void testGetMailLogPage() { // mock 数据 diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java index e1be7e8d6..911e91c89 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailSendServiceImplTest.java @@ -6,14 +6,20 @@ import cn.hutool.extra.mail.MailUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.framework.test.core.util.RandomUtils; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; +import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage; import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer; +import cn.iocoder.yudao.module.system.service.member.MemberService; +import cn.iocoder.yudao.module.system.service.user.AdminUserService; import org.assertj.core.util.Lists; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.MockedStatic; import java.util.HashMap; import java.util.Map; @@ -23,6 +29,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServic import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @@ -31,6 +38,10 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest { @InjectMocks private MailSendServiceImpl mailSendService; + @Mock + private AdminUserService adminUserService; + @Mock + private MemberService memberService; @Mock private MailAccountService mailAccountService; @Mock @@ -55,6 +66,82 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest { System.out.println("发送结果:" + messageId); } + @Test + public void testSendSingleMailToAdmin() { + // 准备参数 + Long userId = randomLongId(); + String templateCode = RandomUtils.randomString(); + Map templateParams = MapUtil.builder().put("code", "1234") + .put("op", "login").build(); + // mock adminUserService 的方法 + AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setMobile("15601691300")); + when(adminUserService.getUser(eq(userId))).thenReturn(user); + + // mock MailTemplateService 的方法 + MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> { + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setContent("验证码为{code}, 操作为{op}"); + o.setParams(Lists.newArrayList("code", "op")); + }); + when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); + String content = RandomUtils.randomString(); + when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams))) + .thenReturn(content); + // mock MailAccountService 的方法 + MailAccountDO account = randomPojo(MailAccountDO.class); + when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); + // mock MailLogService 的方法 + Long mailLogId = randomLongId(); + when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.ADMIN.getValue()), eq(user.getEmail()), + eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId); + + // 调用 + Long resultMailLogId = mailSendService.sendSingleMailToAdmin(null, userId, templateCode, templateParams); + // 断言 + assertEquals(mailLogId, resultMailLogId); + // 断言调用 + verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(user.getEmail()), + eq(account.getId()), eq(template.getNickname()), eq(template.getTitle()), eq(content)); + } + + @Test + public void testSendSingleMailToMember() { + // 准备参数 + Long userId = randomLongId(); + String templateCode = RandomUtils.randomString(); + Map templateParams = MapUtil.builder().put("code", "1234") + .put("op", "login").build(); + // mock memberService 的方法 + String mail = randomEmail(); + when(memberService.getMemberUserEmail(eq(userId))).thenReturn(mail); + + // mock MailTemplateService 的方法 + MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> { + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setContent("验证码为{code}, 操作为{op}"); + o.setParams(Lists.newArrayList("code", "op")); + }); + when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); + String content = RandomUtils.randomString(); + when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams))) + .thenReturn(content); + // mock MailAccountService 的方法 + MailAccountDO account = randomPojo(MailAccountDO.class); + when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account); + // mock MailLogService 的方法 + Long mailLogId = randomLongId(); + when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.MEMBER.getValue()), eq(mail), + eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId); + + // 调用 + Long resultMailLogId = mailSendService.sendSingleMailToMember(null, userId, templateCode, templateParams); + // 断言 + assertEquals(mailLogId, resultMailLogId); + // 断言调用 + verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(mail), + eq(account.getId()), eq(template.getNickname()), eq(template.getTitle()), eq(content)); + } + /** * 发送成功,当短信模板开启时 */ @@ -64,7 +151,7 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest { String mail = randomEmail(); Long userId = randomLongId(); Integer userType = randomEle(UserTypeEnum.values()).getValue(); - String templateCode = randomString(); + String templateCode = RandomUtils.randomString(); Map templateParams = MapUtil.builder().put("code", "1234") .put("op", "login").build(); // mock MailTemplateService 的方法 @@ -74,7 +161,7 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest { o.setParams(Lists.newArrayList("code", "op")); }); when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); - String content = randomString(); + String content = RandomUtils.randomString(); when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams))) .thenReturn(content); // mock MailAccountService 的方法 @@ -103,7 +190,7 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest { String mail = randomEmail(); Long userId = randomLongId(); Integer userType = randomEle(UserTypeEnum.values()).getValue(); - String templateCode = randomString(); + String templateCode = RandomUtils.randomString(); Map templateParams = MapUtil.builder().put("code", "1234") .put("op", "login").build(); // mock MailTemplateService 的方法 @@ -113,7 +200,7 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest { o.setParams(Lists.newArrayList("code", "op")); }); when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); - String content = randomString(); + String content = RandomUtils.randomString(); when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams))) .thenReturn(content); // mock MailAccountService 的方法 @@ -134,18 +221,18 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest { } @Test - public void testCheckMailTemplateValid_notExists() { + public void testValidateMailTemplateValid_notExists() { // 准备参数 - String templateCode = randomString(); + String templateCode = RandomUtils.randomString(); // mock 方法 // 调用,并断言异常 - assertServiceException(() -> mailSendService.checkMailTemplateValid(templateCode), + assertServiceException(() -> mailSendService.validateMailTemplate(templateCode), MAIL_TEMPLATE_NOT_EXISTS); } @Test - public void testCheckTemplateParams_paramMiss() { + public void testValidateTemplateParams_paramMiss() { // 准备参数 MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> o.setParams(Lists.newArrayList("code"))); @@ -153,18 +240,80 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest { // mock 方法 // 调用,并断言异常 - assertServiceException(() -> mailSendService.checkTemplateParams(template, templateParams), + assertServiceException(() -> mailSendService.validateTemplateParams(template, templateParams), MAIL_SEND_TEMPLATE_PARAM_MISS, "code"); } @Test - public void testCheckMail_notExists() { + public void testValidateMail_notExists() { // 准备参数 // mock 方法 // 调用,并断言异常 - assertServiceException(() -> mailSendService.checkMail(null), + assertServiceException(() -> mailSendService.validateMail(null), MAIL_SEND_MAIL_NOT_EXISTS); } + @Test + public void testDoSendMail_success() { + try (MockedStatic mailUtilMock = mockStatic(MailUtil.class)) { + // 准备参数 + MailSendMessage message = randomPojo(MailSendMessage.class, o -> o.setNickname("芋艿")); + // mock 方法(获得邮箱账号) + MailAccountDO account = randomPojo(MailAccountDO.class, o -> o.setMail("7685@qq.com")); + when(mailAccountService.getMailAccountFromCache(eq(message.getAccountId()))) + .thenReturn(account); + + // mock 方法(发送邮件) + String messageId = randomString(); + mailUtilMock.when(() -> MailUtil.send(argThat(mailAccount -> { + assertEquals("芋艿 <7685@qq.com>", mailAccount.getFrom()); + assertTrue(mailAccount.isAuth()); + assertEquals(account.getUsername(), mailAccount.getUser()); + assertEquals(account.getPassword(), mailAccount.getPass()); + assertEquals(account.getHost(), mailAccount.getHost()); + assertEquals(account.getPort(), mailAccount.getPort()); + assertEquals(account.getSslEnable(), mailAccount.isSslEnable()); + return true; + }), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true))) + .thenReturn(messageId); + + // 调用 + mailSendService.doSendMail(message); + // 断言 + verify(mailLogService).updateMailSendResult(eq(message.getLogId()), eq(messageId), isNull()); + } + } + + @Test + public void testDoSendMail_exception() { + try (MockedStatic mailUtilMock = mockStatic(MailUtil.class)) { + // 准备参数 + MailSendMessage message = randomPojo(MailSendMessage.class, o -> o.setNickname("芋艿")); + // mock 方法(获得邮箱账号) + MailAccountDO account = randomPojo(MailAccountDO.class, o -> o.setMail("7685@qq.com")); + when(mailAccountService.getMailAccountFromCache(eq(message.getAccountId()))) + .thenReturn(account); + + // mock 方法(发送邮件) + Exception e = new NullPointerException("啦啦啦"); + mailUtilMock.when(() -> MailUtil.send(argThat(mailAccount -> { + assertEquals("芋艿 <7685@qq.com>", mailAccount.getFrom()); + assertTrue(mailAccount.isAuth()); + assertEquals(account.getUsername(), mailAccount.getUser()); + assertEquals(account.getPassword(), mailAccount.getPass()); + assertEquals(account.getHost(), mailAccount.getHost()); + assertEquals(account.getPort(), mailAccount.getPort()); + assertEquals(account.getSslEnable(), mailAccount.isSslEnable()); + return true; + }), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true))) + .thenThrow(e); + + // 调用 + mailSendService.doSendMail(message); + // 断言 + verify(mailLogService).updateMailSendResult(eq(message.getLogId()), isNull(), same(e)); + } + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java index ab005822b..017dbe0ae 100755 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplateCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplatePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplateUpdateReqVO; -import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; import cn.iocoder.yudao.module.system.dal.mysql.mail.MailTemplateMapper; import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer; @@ -15,7 +14,8 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; - +import java.util.HashMap; +import java.util.List; import java.util.Map; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; @@ -27,6 +27,7 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_TEMPLATE_NOT_EXISTS; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.verify; /** * {@link MailTemplateServiceImpl} 的单元测试类 @@ -72,6 +73,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { // 校验记录的属性是否正确 MailTemplateDO mailTemplate = mailTemplateMapper.selectById(mailTemplateId); assertPojoEquals(reqVO, mailTemplate); + verify(mailProducer).sendMailTemplateRefreshMessage(); } @Test @@ -89,6 +91,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { // 校验是否更新正确 MailTemplateDO mailTemplate = mailTemplateMapper.selectById(reqVO.getId()); // 获取最新的 assertPojoEquals(reqVO, mailTemplate); + verify(mailProducer).sendMailTemplateRefreshMessage(); } @Test @@ -110,8 +113,9 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { // 调用 mailTemplateService.deleteMailTemplate(id); - // 校验数据不存在了 - assertNull(mailTemplateMapper.selectById(id)); + // 校验数据不存在了 + assertNull(mailTemplateMapper.selectById(id)); + verify(mailProducer).sendMailTemplateRefreshMessage(); } @Test @@ -160,4 +164,77 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { assertPojoEquals(dbMailTemplate, pageResult.getList().get(0)); } + @Test + public void testGetMailTemplateList() { + // mock 数据 + MailTemplateDO dbMailTemplate01 = randomPojo(MailTemplateDO.class); + mailTemplateMapper.insert(dbMailTemplate01); + MailTemplateDO dbMailTemplate02 = randomPojo(MailTemplateDO.class); + mailTemplateMapper.insert(dbMailTemplate02); + + // 调用 + List list = mailTemplateService.getMailTemplateList(); + // 断言 + assertEquals(2, list.size()); + assertEquals(dbMailTemplate01, list.get(0)); + assertEquals(dbMailTemplate02, list.get(1)); + } + + @Test + public void testGetTemplate() { + // mock 数据 + MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class); + mailTemplateMapper.insert(dbMailTemplate); + // 准备参数 + Long id = dbMailTemplate.getId(); + + // 调用 + MailTemplateDO mailTemplate = mailTemplateService.getMailTemplate(id); + // 断言 + assertPojoEquals(dbMailTemplate, mailTemplate); + } + + @Test + public void testGetMailTemplateByCodeFromCache() { + // mock 数据 + MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class); + mailTemplateMapper.insert(dbMailTemplate); + mailTemplateService.initLocalCache(); + // 准备参数 + String code = dbMailTemplate.getCode(); + + // 调用 + MailTemplateDO mailTemplate = mailTemplateService.getMailTemplateByCodeFromCache(code); + // 断言 + assertPojoEquals(dbMailTemplate, mailTemplate); + } + + @Test + public void testFormatMailTemplateContent() { + // 准备参数 + Map params = new HashMap<>(); + params.put("name", "小红"); + params.put("what", "饭"); + + // 调用,并断言 + assertEquals("小红,你好,饭吃了吗?", + mailTemplateService.formatMailTemplateContent("{name},你好,{what}吃了吗?", params)); + } + + @Test + public void testCountByAccountId() { + // mock 数据 + MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class); + mailTemplateMapper.insert(dbMailTemplate); + // 测试 accountId 不匹配 + mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setAccountId(2L))); + // 准备参数 + Long accountId = dbMailTemplate.getAccountId(); + + // 调用 + long count = mailTemplateService.countByAccountId(accountId); + // 断言 + assertEquals(1, count); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImplTest.java index 868ae7865..0f7d0f9b7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsSendServiceImplTest.java @@ -101,7 +101,7 @@ public class SmsSendServiceImplTest extends BaseMockitoUnitTest { String templateCode = randomString(); Map templateParams = MapUtil.builder().put("code", "1234") .put("op", "login").build(); - // mock adminUserService 的方法 + // mock memberService 的方法 String mobile = "15601691300"; when(memberService.getMemberUserMobile(eq(userId))).thenReturn(mobile); From 2ba4dec0da5ec18d8bd1302863f422ef54550d3b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 00:02:37 +0800 Subject: [PATCH 45/59] =?UTF-8?q?=E5=AE=8C=E5=96=84=20notify=20=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/notify/NotifySendServiceImpl.java | 8 +-- .../mail/MailTemplateServiceImplTest.java | 2 +- .../notify/NotifyMessageServiceImplTest.java | 14 ++++ .../notify/NotifySendServiceImplTest.java | 65 +++++++++++++++++-- .../notify/NotifyTemplateServiceImplTest.java | 42 ++++++++++++ 5 files changed, 121 insertions(+), 10 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notify/NotifySendServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notify/NotifySendServiceImpl.java index 39e685fd5..f71c5fe5c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notify/NotifySendServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notify/NotifySendServiceImpl.java @@ -44,13 +44,13 @@ public class NotifySendServiceImpl implements NotifySendService { @Override public Long sendSingleNotify(Long userId, Integer userType, String templateCode, Map templateParams) { // 校验模版 - NotifyTemplateDO template = checkNotifyTemplateValid(templateCode); + NotifyTemplateDO template = validateNotifyTemplate(templateCode); if (Objects.equals(template.getStatus(), CommonStatusEnum.DISABLE.getStatus())) { log.info("[sendSingleNotify][模版({})已经关闭,无法给用户({}/{})发送]", templateCode, userId, userType); return null; } // 校验参数 - checkTemplateParams(template, templateParams); + validateTemplateParams(template, templateParams); // 发送站内信 String content = notifyTemplateService.formatNotifyTemplateContent(template.getContent(), templateParams); @@ -58,7 +58,7 @@ public class NotifySendServiceImpl implements NotifySendService { } @VisibleForTesting - public NotifyTemplateDO checkNotifyTemplateValid(String templateCode) { + public NotifyTemplateDO validateNotifyTemplate(String templateCode) { // 获得站内信模板。考虑到效率,从缓存中获取 NotifyTemplateDO template = notifyTemplateService.getNotifyTemplateByCodeFromCache(templateCode); // 站内信模板不存在 @@ -75,7 +75,7 @@ public class NotifySendServiceImpl implements NotifySendService { * @param templateParams 参数列表 */ @VisibleForTesting - public void checkTemplateParams(NotifyTemplateDO template, Map templateParams) { + public void validateTemplateParams(NotifyTemplateDO template, Map templateParams) { template.getParams().forEach(key -> { Object value = templateParams.get(key); if (value == null) { diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java index 017dbe0ae..83f23e92e 100755 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailTemplateServiceImplTest.java @@ -181,7 +181,7 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest { } @Test - public void testGetTemplate() { + public void testGetMailTemplate() { // mock 数据 MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class); mailTemplateMapper.insert(dbMailTemplate); diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifyMessageServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifyMessageServiceImplTest.java index 1087918cc..9e2158da1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifyMessageServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifyMessageServiceImplTest.java @@ -108,6 +108,20 @@ public class NotifyMessageServiceImplTest extends BaseDbUnitTest { assertPojoEquals(dbNotifyMessage, pageResult.getList().get(0)); } + @Test + public void testGetNotifyMessage() { + // mock 数据 + NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, + o -> o.setTemplateParams(randomTemplateParams())); + notifyMessageMapper.insert(dbNotifyMessage); + // 准备参数 + Long id = dbNotifyMessage.getId(); + + // 调用 + NotifyMessageDO notifyMessage = notifyMessageService.getNotifyMessage(id); + assertPojoEquals(dbNotifyMessage, notifyMessage); + } + @Test public void testGetMyNotifyMessagePage() { // mock 数据 diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifySendServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifySendServiceImplTest.java index e3ee32853..7c5078330 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifySendServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifySendServiceImplTest.java @@ -4,8 +4,6 @@ import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; -import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO; -import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO; import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO; import org.assertj.core.util.Lists; import org.junit.jupiter.api.Test; @@ -18,7 +16,8 @@ import java.util.Map; import static cn.hutool.core.util.RandomUtil.randomEle; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTICE_NOT_FOUND; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTIFY_SEND_TEMPLATE_PARAM_MISS; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.mockito.ArgumentMatchers.eq; @@ -34,6 +33,62 @@ class NotifySendServiceImplTest extends BaseMockitoUnitTest { @Mock private NotifyMessageService notifyMessageService; + @Test + public void testSendSingleNotifyToAdmin() { + // 准备参数 + Long userId = randomLongId(); + String templateCode = randomString(); + Map templateParams = MapUtil.builder().put("code", "1234") + .put("op", "login").build(); + // mock NotifyTemplateService 的方法 + NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class, o -> { + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setContent("验证码为{code}, 操作为{op}"); + o.setParams(Lists.newArrayList("code", "op")); + }); + when(notifyTemplateService.getNotifyTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); + String content = randomString(); + when(notifyTemplateService.formatNotifyTemplateContent(eq(template.getContent()), eq(templateParams))) + .thenReturn(content); + // mock NotifyMessageService 的方法 + Long messageId = randomLongId(); + when(notifyMessageService.createNotifyMessage(eq(userId), eq(UserTypeEnum.ADMIN.getValue()), + eq(template), eq(content), eq(templateParams))).thenReturn(messageId); + + // 调用 + Long resultMessageId = notifySendService.sendSingleNotifyToAdmin(userId, templateCode, templateParams); + // 断言 + assertEquals(messageId, resultMessageId); + } + + @Test + public void testSendSingleNotifyToMember() { + // 准备参数 + Long userId = randomLongId(); + String templateCode = randomString(); + Map templateParams = MapUtil.builder().put("code", "1234") + .put("op", "login").build(); + // mock NotifyTemplateService 的方法 + NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class, o -> { + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setContent("验证码为{code}, 操作为{op}"); + o.setParams(Lists.newArrayList("code", "op")); + }); + when(notifyTemplateService.getNotifyTemplateByCodeFromCache(eq(templateCode))).thenReturn(template); + String content = randomString(); + when(notifyTemplateService.formatNotifyTemplateContent(eq(template.getContent()), eq(templateParams))) + .thenReturn(content); + // mock NotifyMessageService 的方法 + Long messageId = randomLongId(); + when(notifyMessageService.createNotifyMessage(eq(userId), eq(UserTypeEnum.MEMBER.getValue()), + eq(template), eq(content), eq(templateParams))).thenReturn(messageId); + + // 调用 + Long resultMessageId = notifySendService.sendSingleNotifyToMember(userId, templateCode, templateParams); + // 断言 + assertEquals(messageId, resultMessageId); + } + /** * 发送成功,当短信模板开启时 */ @@ -100,7 +155,7 @@ class NotifySendServiceImplTest extends BaseMockitoUnitTest { // mock 方法 // 调用,并断言异常 - assertServiceException(() -> notifySendService.checkNotifyTemplateValid(templateCode), + assertServiceException(() -> notifySendService.validateNotifyTemplate(templateCode), NOTICE_NOT_FOUND); } @@ -113,7 +168,7 @@ class NotifySendServiceImplTest extends BaseMockitoUnitTest { // mock 方法 // 调用,并断言异常 - assertServiceException(() -> notifySendService.checkTemplateParams(template, templateParams), + assertServiceException(() -> notifySendService.validateTemplateParams(template, templateParams), NOTIFY_SEND_TEMPLATE_PARAM_MISS, "code"); } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifyTemplateServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifyTemplateServiceImplTest.java index 5a6f5a508..28f6f9a38 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifyTemplateServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/notify/NotifyTemplateServiceImplTest.java @@ -14,6 +14,8 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; @@ -143,4 +145,44 @@ public class NotifyTemplateServiceImplTest extends BaseDbUnitTest { assertPojoEquals(dbNotifyTemplate, pageResult.getList().get(0)); } + @Test + public void testGetNotifyTemplate() { + // mock 数据 + NotifyTemplateDO dbNotifyTemplate = randomPojo(NotifyTemplateDO.class); + notifyTemplateMapper.insert(dbNotifyTemplate); + // 准备参数 + Long id = dbNotifyTemplate.getId(); + + // 调用 + NotifyTemplateDO notifyTemplate = notifyTemplateService.getNotifyTemplate(id); + // 断言 + assertPojoEquals(dbNotifyTemplate, notifyTemplate); + } + + @Test + public void testGetNotifyTemplateByCodeFromCache() { + // mock 数据 + NotifyTemplateDO dbNotifyTemplate = randomPojo(NotifyTemplateDO.class); + notifyTemplateMapper.insert(dbNotifyTemplate); + notifyTemplateService.initLocalCache(); + // 准备参数 + String code = dbNotifyTemplate.getCode(); + + // 调用 + NotifyTemplateDO notifyTemplate = notifyTemplateService.getNotifyTemplateByCodeFromCache(code); + // 断言 + assertPojoEquals(dbNotifyTemplate, notifyTemplate); + } + + @Test + public void testFormatNotifyTemplateContent() { + // 准备参数 + Map params = new HashMap<>(); + params.put("name", "小红"); + params.put("what", "饭"); + + // 调用,并断言 + assertEquals("小红,你好,饭吃了吗?", + notifyTemplateService.formatNotifyTemplateContent("{name},你好,{what}吃了吗?", params)); + } } From 245e557309b2416013f149416ead333f66383e3c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 00:10:12 +0800 Subject: [PATCH 46/59] =?UTF-8?q?system=EF=BC=9A=E5=B0=86=20check=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E7=BB=9F=E4=B8=80=E6=88=90=20valida?= =?UTF-8?q?te=20=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notify/NotifyTemplateServiceImpl.java | 6 ++--- .../service/sms/SmsTemplateServiceImpl.java | 18 +++++++------- .../sms/SmsTemplateServiceImplTest.java | 24 +++++++++---------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notify/NotifyTemplateServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notify/NotifyTemplateServiceImpl.java index 5ee8b4bbc..5b63ac720 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notify/NotifyTemplateServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/notify/NotifyTemplateServiceImpl.java @@ -76,7 +76,7 @@ public class NotifyTemplateServiceImpl implements NotifyTemplateService { @Override public Long createNotifyTemplate(NotifyTemplateCreateReqVO createReqVO) { // 校验站内信编码是否重复 - checkNotifyTemplateCodeDuplicate(null, createReqVO.getCode()); + validateNotifyTemplateCodeDuplicate(null, createReqVO.getCode()); // 插入 NotifyTemplateDO notifyTemplate = NotifyTemplateConvert.INSTANCE.convert(createReqVO); @@ -93,7 +93,7 @@ public class NotifyTemplateServiceImpl implements NotifyTemplateService { // 校验存在 validateNotifyTemplateExists(updateReqVO.getId()); // 校验站内信编码是否重复 - checkNotifyTemplateCodeDuplicate(updateReqVO.getId(), updateReqVO.getCode()); + validateNotifyTemplateCodeDuplicate(updateReqVO.getId(), updateReqVO.getCode()); // 更新 NotifyTemplateDO updateObj = NotifyTemplateConvert.INSTANCE.convert(updateReqVO); @@ -136,7 +136,7 @@ public class NotifyTemplateServiceImpl implements NotifyTemplateService { } @VisibleForTesting - public void checkNotifyTemplateCodeDuplicate(Long id, String code) { + public void validateNotifyTemplateCodeDuplicate(Long id, String code) { NotifyTemplateDO template = notifyTemplateMapper.selectByCode(code); if (template == null) { return; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java index 25fe0031f..20c4ec3f3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImpl.java @@ -105,11 +105,11 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { @Override public Long createSmsTemplate(SmsTemplateCreateReqVO createReqVO) { // 校验短信渠道 - SmsChannelDO channelDO = checkSmsChannel(createReqVO.getChannelId()); + SmsChannelDO channelDO = validateSmsChannel(createReqVO.getChannelId()); // 校验短信编码是否重复 - checkSmsTemplateCodeDuplicate(null, createReqVO.getCode()); + validateSmsTemplateCodeDuplicate(null, createReqVO.getCode()); // 校验短信模板 - checkApiTemplate(createReqVO.getChannelId(), createReqVO.getApiTemplateId()); + validateApiTemplate(createReqVO.getChannelId(), createReqVO.getApiTemplateId()); // 插入 SmsTemplateDO template = SmsTemplateConvert.INSTANCE.convert(createReqVO); @@ -127,11 +127,11 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { // 校验存在 validateSmsTemplateExists(updateReqVO.getId()); // 校验短信渠道 - SmsChannelDO channelDO = checkSmsChannel(updateReqVO.getChannelId()); + SmsChannelDO channelDO = validateSmsChannel(updateReqVO.getChannelId()); // 校验短信编码是否重复 - checkSmsTemplateCodeDuplicate(updateReqVO.getId(), updateReqVO.getCode()); + validateSmsTemplateCodeDuplicate(updateReqVO.getId(), updateReqVO.getCode()); // 校验短信模板 - checkApiTemplate(updateReqVO.getChannelId(), updateReqVO.getApiTemplateId()); + validateApiTemplate(updateReqVO.getChannelId(), updateReqVO.getApiTemplateId()); // 更新 SmsTemplateDO updateObj = SmsTemplateConvert.INSTANCE.convert(updateReqVO); @@ -184,7 +184,7 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { } @VisibleForTesting - public SmsChannelDO checkSmsChannel(Long channelId) { + public SmsChannelDO validateSmsChannel(Long channelId) { SmsChannelDO channelDO = smsChannelService.getSmsChannel(channelId); if (channelDO == null) { throw exception(SMS_CHANNEL_NOT_EXISTS); @@ -196,7 +196,7 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { } @VisibleForTesting - public void checkSmsTemplateCodeDuplicate(Long id, String code) { + public void validateSmsTemplateCodeDuplicate(Long id, String code) { SmsTemplateDO template = smsTemplateMapper.selectByCode(code); if (template == null) { return; @@ -217,7 +217,7 @@ public class SmsTemplateServiceImpl implements SmsTemplateService { * @param apiTemplateId API 模板编号 */ @VisibleForTesting - public void checkApiTemplate(Long channelId, String apiTemplateId) { + public void validateApiTemplate(Long channelId, String apiTemplateId) { // 获得短信模板 SmsClient smsClient = smsClientFactory.getSmsClient(channelId); Assert.notNull(smsClient, String.format("短信客户端(%d) 不存在", channelId)); diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java index f0c4df40a..3b9b577a2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sms/SmsTemplateServiceImplTest.java @@ -279,7 +279,7 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { } @Test - public void testCheckSmsChannel_success() { + public void testValidateSmsChannel_success() { // 准备参数 Long channelId = randomLongId(); // mock 方法 @@ -290,23 +290,23 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { when(smsChannelService.getSmsChannel(eq(channelId))).thenReturn(channelDO); // 调用 - SmsChannelDO returnChannelDO = smsTemplateService.checkSmsChannel(channelId); + SmsChannelDO returnChannelDO = smsTemplateService.validateSmsChannel(channelId); // 断言 assertPojoEquals(returnChannelDO, channelDO); } @Test - public void testCheckSmsChannel_notExists() { + public void testValidateSmsChannel_notExists() { // 准备参数 Long channelId = randomLongId(); // 调用,校验异常 - assertServiceException(() -> smsTemplateService.checkSmsChannel(channelId), + assertServiceException(() -> smsTemplateService.validateSmsChannel(channelId), SMS_CHANNEL_NOT_EXISTS); } @Test - public void testCheckSmsChannel_disable() { + public void testValidateSmsChannel_disable() { // 准备参数 Long channelId = randomLongId(); // mock 方法 @@ -317,30 +317,30 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { when(smsChannelService.getSmsChannel(eq(channelId))).thenReturn(channelDO); // 调用,校验异常 - assertServiceException(() -> smsTemplateService.checkSmsChannel(channelId), + assertServiceException(() -> smsTemplateService.validateSmsChannel(channelId), SMS_CHANNEL_DISABLE); } @Test - public void testCheckDictDataValueUnique_success() { + public void testValidateDictDataValueUnique_success() { // 调用,成功 - smsTemplateService.checkSmsTemplateCodeDuplicate(randomLongId(), randomString()); + smsTemplateService.validateSmsTemplateCodeDuplicate(randomLongId(), randomString()); } @Test - public void testCheckSmsTemplateCodeDuplicate_valueDuplicateForCreate() { + public void testValidateSmsTemplateCodeDuplicate_valueDuplicateForCreate() { // 准备参数 String code = randomString(); // mock 数据 smsTemplateMapper.insert(randomSmsTemplateDO(o -> o.setCode(code))); // 调用,校验异常 - assertServiceException(() -> smsTemplateService.checkSmsTemplateCodeDuplicate(null, code), + assertServiceException(() -> smsTemplateService.validateSmsTemplateCodeDuplicate(null, code), SMS_TEMPLATE_CODE_DUPLICATE, code); } @Test - public void testCheckDictDataValueUnique_valueDuplicateForUpdate() { + public void testValidateDictDataValueUnique_valueDuplicateForUpdate() { // 准备参数 Long id = randomLongId(); String code = randomString(); @@ -348,7 +348,7 @@ public class SmsTemplateServiceImplTest extends BaseDbUnitTest { smsTemplateMapper.insert(randomSmsTemplateDO(o -> o.setCode(code))); // 调用,校验异常 - assertServiceException(() -> smsTemplateService.checkSmsTemplateCodeDuplicate(id, code), + assertServiceException(() -> smsTemplateService.validateSmsTemplateCodeDuplicate(id, code), SMS_TEMPLATE_CODE_DUPLICATE, code); } From 837345ed95d5f93018acde8ff64b1458e57b4f4c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 00:15:20 +0800 Subject: [PATCH 47/59] =?UTF-8?q?system=EF=BC=9A=E5=B0=86=20api=20?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E6=B3=95=E5=90=8D=E7=9A=84=E8=B4=9F=E6=95=B0?= =?UTF-8?q?=E9=83=BD=E6=8D=A2=E6=88=90=20List?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java | 2 +- .../tenant/core/service/TenantFrameworkServiceImpl.java | 4 ++-- .../yudao/module/system/api/errorcode/ErrorCodeApi.java | 2 +- .../cn/iocoder/yudao/module/system/api/tenant/TenantApi.java | 4 ++-- .../yudao/module/system/api/errorcode/ErrorCodeApiImpl.java | 2 +- .../iocoder/yudao/module/system/api/tenant/TenantApiImpl.java | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java index a7f6c2835..d670c1829 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/core/generator/ErrorCodeAutoGeneratorImpl.java @@ -49,7 +49,7 @@ public class ErrorCodeAutoGeneratorImpl implements ErrorCodeAutoGenerator { log.info("[execute][解析到错误码数量为 ({}) 个]", autoGenerateDTOs.size()); // 第二步,写入到 system 服务 - errorCodeApi.autoGenerateErrorCodes(autoGenerateDTOs); + errorCodeApi.autoGenerateErrorCodeList(autoGenerateDTOs); log.info("[execute][写入到 system 组件完成]"); } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkServiceImpl.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkServiceImpl.java index 75d065e1e..f2b7b27a8 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkServiceImpl.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/service/TenantFrameworkServiceImpl.java @@ -32,7 +32,7 @@ public class TenantFrameworkServiceImpl implements TenantFrameworkService { @Override public List load(Object key) { - return tenantApi.getTenantIds(); + return tenantApi.getTenantIdList(); } }); @@ -47,7 +47,7 @@ public class TenantFrameworkServiceImpl implements TenantFrameworkService { @Override public ServiceException load(Long id) { try { - tenantApi.validTenant(id); + tenantApi.validateTenant(id); return SERVICE_EXCEPTION_NULL; } catch (ServiceException ex) { return ex; diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/ErrorCodeApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/ErrorCodeApi.java index b41728d40..6f6bc24c7 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/ErrorCodeApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/ErrorCodeApi.java @@ -19,7 +19,7 @@ public interface ErrorCodeApi { * * @param autoGenerateDTOs 错误码信息 */ - void autoGenerateErrorCodes(@Valid List autoGenerateDTOs); + void autoGenerateErrorCodeList(@Valid List autoGenerateDTOs); /** * 增量获得错误码数组 diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApi.java index 3f255d55a..1fad83ed6 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApi.java @@ -14,13 +14,13 @@ public interface TenantApi { * * @return 租户编号数组 */ - List getTenantIds(); + List getTenantIdList(); /** * 校验租户是否合法 * * @param id 租户编号 */ - void validTenant(Long id); + void validateTenant(Long id); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/ErrorCodeApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/ErrorCodeApiImpl.java index b68c63215..c9c5f7029 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/ErrorCodeApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/errorcode/ErrorCodeApiImpl.java @@ -21,7 +21,7 @@ public class ErrorCodeApiImpl implements ErrorCodeApi { private ErrorCodeService errorCodeService; @Override - public void autoGenerateErrorCodes(List autoGenerateDTOs) { + public void autoGenerateErrorCodeList(List autoGenerateDTOs) { errorCodeService.autoGenerateErrorCodes(autoGenerateDTOs); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java index 6ea4c795e..4ecc9f9b2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java @@ -18,12 +18,12 @@ public class TenantApiImpl implements TenantApi { private TenantService tenantService; @Override - public List getTenantIds() { + public List getTenantIdList() { return tenantService.getTenantIds(); } @Override - public void validTenant(Long id) { + public void validateTenant(Long id) { tenantService.validTenant(id); } From 67e1879a8fb305d6a26ee2b73147a2ffb2b8f743 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 00:26:48 +0800 Subject: [PATCH 48/59] =?UTF-8?q?system=EF=BC=9A=E5=B0=86=20biz=20?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E6=B3=95=E5=90=8D=E7=9A=84=E8=B4=9F=E6=95=B0?= =?UTF-8?q?=E9=83=BD=E6=8D=A2=E6=88=90=20List?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iocoder/yudao/module/system/api/tenant/TenantApiImpl.java | 2 +- .../module/system/controller/admin/auth/AuthController.java | 2 +- .../module/system/controller/admin/dept/DeptController.java | 4 ++-- .../module/system/controller/admin/dept/PostController.java | 2 +- .../system/controller/admin/dict/DictDataController.java | 2 +- .../system/controller/admin/dict/DictTypeController.java | 2 +- .../admin/sensitiveword/SensitiveWordController.java | 4 ++-- .../system/service/sensitiveword/SensitiveWordService.java | 2 +- .../service/sensitiveword/SensitiveWordServiceImpl.java | 2 +- .../yudao/module/system/service/tenant/TenantService.java | 2 +- .../yudao/module/system/service/tenant/TenantServiceImpl.java | 2 +- .../service/sensitiveword/SensitiveWordServiceImplTest.java | 2 +- .../module/system/service/tenant/TenantServiceImplTest.java | 4 ++-- 13 files changed, 16 insertions(+), 16 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java index 4ecc9f9b2..25ea260c5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/tenant/TenantApiImpl.java @@ -19,7 +19,7 @@ public class TenantApiImpl implements TenantApi { @Override public List getTenantIdList() { - return tenantService.getTenantIds(); + return tenantService.getTenantIdList(); } @Override diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java index c28360326..f55d992bf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java @@ -108,7 +108,7 @@ public class AuthController { @GetMapping("/list-menus") @ApiOperation("获得登录用户的菜单列表") - public CommonResult> getMenus() { + public CommonResult> getMenuList() { // 获得角色列表 Set roleIds = permissionService.getUserRoleIdsFromCache(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus())); // 获得用户拥有的菜单列表 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java index f60415cee..cff8a9c46 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java @@ -57,7 +57,7 @@ public class DeptController { @GetMapping("/list") @ApiOperation("获取部门列表") @PreAuthorize("@ss.hasPermission('system:dept:query')") - public CommonResult> listDepts(DeptListReqVO reqVO) { + public CommonResult> getDeptList(DeptListReqVO reqVO) { List list = deptService.getDeptList(reqVO); list.sort(Comparator.comparing(DeptDO::getSort)); return success(DeptConvert.INSTANCE.convertList(list)); @@ -65,7 +65,7 @@ public class DeptController { @GetMapping("/list-all-simple") @ApiOperation(value = "获取部门精简信息列表", notes = "只包含被开启的部门,主要用于前端的下拉选项") - public CommonResult> getSimpleDepts() { + public CommonResult> getSimpleDeptList() { // 获得部门列表,只要开启状态的 DeptListReqVO reqVO = new DeptListReqVO(); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java index 52fa8edb2..0fc8af8aa 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java @@ -70,7 +70,7 @@ public class PostController { @GetMapping("/list-all-simple") @ApiOperation(value = "获取岗位精简信息列表", notes = "只包含被开启的岗位,主要用于前端的下拉选项") - public CommonResult> getSimplePosts() { + public CommonResult> getSimplePostList() { // 获得岗位列表,只要开启状态的 List list = postService.getPostList(null, Collections.singleton(CommonStatusEnum.ENABLE.getStatus())); // 排序后,返回给前端 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java index 4b14be80e..3679e2d00 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java @@ -61,7 +61,7 @@ public class DictDataController { @GetMapping("/list-all-simple") @ApiOperation(value = "获得全部字典数据列表", notes = "一般用于管理后台缓存字典数据在本地") // 无需添加权限认证,因为前端全局都需要 - public CommonResult> getSimpleDictDatas() { + public CommonResult> getSimpleDictDataList() { List list = dictDataService.getDictDataList(); return success(DictDataConvert.INSTANCE.convertList(list)); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java index e7c9b8894..e1606b267 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java @@ -76,7 +76,7 @@ public class DictTypeController { @GetMapping("/list-all-simple") @ApiOperation(value = "获得全部字典类型列表", notes = "包括开启 + 禁用的字典类型,主要用于前端的下拉选项") // 无需添加权限认证,因为前端全局都需要 - public CommonResult> listSimpleDictTypes() { + public CommonResult> getSimpleDictTypeList() { List list = dictTypeService.getDictTypeList(); return success(DictTypeConvert.INSTANCE.convertList(list)); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java index e9536ad9a..c40e5f6b8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sensitiveword/SensitiveWordController.java @@ -90,8 +90,8 @@ public class SensitiveWordController { @GetMapping("/get-tags") @ApiOperation("获取所有敏感词的标签数组") @PreAuthorize("@ss.hasPermission('system:sensitive-word:query')") - public CommonResult> getSensitiveWordTags() throws IOException { - return success(sensitiveWordService.getSensitiveWordTags()); + public CommonResult> getSensitiveWordTagSet() { + return success(sensitiveWordService.getSensitiveWordTagSet()); } @GetMapping("/validate-text") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java index 29cd55e6e..a852ec9cf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordService.java @@ -81,7 +81,7 @@ public interface SensitiveWordService { * * @return 标签数组 */ - Set getSensitiveWordTags(); + Set getSensitiveWordTagSet(); /** * 获得文本所包含的不合法的敏感词数组 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java index 868ef6f6f..b82807855 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java @@ -182,7 +182,7 @@ public class SensitiveWordServiceImpl implements SensitiveWordService { } @Override - public Set getSensitiveWordTags() { + public Set getSensitiveWordTagSet() { return sensitiveWordTagsCache; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantService.java index d9d55e9f4..3dacfefe7 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantService.java @@ -120,7 +120,7 @@ public interface TenantService { * * @return 租户编号数组 */ - List getTenantIds(); + List getTenantIdList(); /** * 校验租户是否合法 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java index 3045e7573..3a70d31b9 100755 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java @@ -75,7 +75,7 @@ public class TenantServiceImpl implements TenantService { private PermissionService permissionService; @Override - public List getTenantIds() { + public List getTenantIdList() { List tenants = tenantMapper.selectList(); return CollectionUtils.convertList(tenants, TenantDO::getId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java index 40a080b6a..141236987 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java @@ -60,7 +60,7 @@ public class SensitiveWordServiceImplTest extends BaseDbUnitTest { // 调用 sensitiveWordService.initLocalCache(); // 断言 sensitiveWordTagsCache 缓存 - assertEquals(SetUtils.asSet("论坛", "蔬菜"), sensitiveWordService.getSensitiveWordTags()); + assertEquals(SetUtils.asSet("论坛", "蔬菜"), sensitiveWordService.getSensitiveWordTagSet()); // 断言 tagSensitiveWordTries 缓存 assertNotNull(sensitiveWordService.getDefaultSensitiveWordTrie()); assertEquals(2, sensitiveWordService.getTagSensitiveWordTries().size()); diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java index 9e33f87fa..f181f177c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java @@ -81,13 +81,13 @@ public class TenantServiceImplTest extends BaseDbUnitTest { } @Test - public void testGetTenantIds() { + public void testGetTenantIdList() { // mock 数据 TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L)); tenantMapper.insert(tenant); // 调用,并断言业务异常 - List result = tenantService.getTenantIds(); + List result = tenantService.getTenantIdList(); assertEquals(Collections.singletonList(1L), result); } From 10f7352ef845f97678ac956ca5a2add67733cbe9 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 00:33:55 +0800 Subject: [PATCH 49/59] =?UTF-8?q?system=EF=BC=9A=E7=AE=80=E5=8C=96=20mappe?= =?UTF-8?q?r=20=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/system/dal/mysql/dept/UserPostMapper.java | 6 ++---- .../system/dal/mysql/social/SocialUserBindMapper.java | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java index 9d74a7beb..addc67d43 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java @@ -13,8 +13,7 @@ import java.util.List; public interface UserPostMapper extends BaseMapperX { default List selectListByUserId(Long userId) { - return selectList(new LambdaQueryWrapperX() - .eq(UserPostDO::getUserId, userId)); + return selectList(UserPostDO::getUserId, userId); } default void deleteByUserIdAndPostId(Long userId, Collection postIds) { @@ -24,8 +23,7 @@ public interface UserPostMapper extends BaseMapperX { } default List selectListByPostIds(Collection postIds) { - return selectList(new LambdaQueryWrapperX() - .in(UserPostDO::getPostId, postIds)); + return selectList(UserPostDO::getPostId, postIds); } default void deleteByUserId(Long userId) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserBindMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserBindMapper.java index 88d0c9227..28619ca51 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserBindMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialUserBindMapper.java @@ -24,9 +24,8 @@ public interface SocialUserBindMapper extends BaseMapperX { } default SocialUserBindDO selectByUserTypeAndSocialUserId(Integer userType, Long socialUserId) { - return selectOne(new LambdaQueryWrapperX() - .eq(SocialUserBindDO::getUserType, userType) - .eq(SocialUserBindDO::getSocialUserId, socialUserId)); + return selectOne(SocialUserBindDO::getUserType, userType, + SocialUserBindDO::getSocialUserId, socialUserId); } default List selectListByUserIdAndUserType(Long userId, Integer userType) { From b5b23b3d7ca2d19179130ba309b41e2ebc7f8db1 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 00:57:09 +0800 Subject: [PATCH 50/59] =?UTF-8?q?infra=EF=BC=9A=E5=AE=8C=E5=96=84=20config?= =?UTF-8?q?=20=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/config/ConfigController.java | 10 +-- .../service/config/ConfigServiceImpl.java | 28 ++++----- .../service/config/ConfigServiceTest.java | 62 ++++++++++++------- .../db/DataSourceConfigServiceImplTest.java | 1 - .../admin/user/UserProfileController.java | 4 +- .../service/permission/MenuServiceImpl.java | 18 +++--- .../service/tenant/TenantServiceImplTest.java | 6 +- 7 files changed, 71 insertions(+), 58 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java index 493b5faa6..885294ccb 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.infra.controller.admin.config; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; @@ -8,8 +7,8 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.infra.controller.admin.config.vo.*; import cn.iocoder.yudao.module.infra.convert.config.ConfigConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO; -import cn.iocoder.yudao.module.infra.service.config.ConfigService; import cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants; +import cn.iocoder.yudao.module.infra.service.config.ConfigService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; @@ -23,6 +22,7 @@ import javax.validation.Valid; import java.io.IOException; import java.util.List; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; @@ -76,7 +76,7 @@ public class ConfigController { return null; } if (!config.getVisible()) { - throw ServiceExceptionUtil.exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_VISIBLE); + throw exception(ErrorCodeConstants.CONFIG_GET_VALUE_ERROR_IF_VISIBLE); } return success(config.getValue()); } @@ -93,8 +93,8 @@ public class ConfigController { @ApiOperation("导出参数配置") @PreAuthorize("@ss.hasPermission('infra:config:export')") @OperateLog(type = EXPORT) - public void exportSysConfig(@Valid ConfigExportReqVO reqVO, - HttpServletResponse response) throws IOException { + public void exportConfig(@Valid ConfigExportReqVO reqVO, + HttpServletResponse response) throws IOException { List list = configService.getConfigList(reqVO); // 拼接数据 List datas = ConfigConvert.INSTANCE.convertList(list); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImpl.java index 5c354c989..51c912be7 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImpl.java @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigUpdateReqV import cn.iocoder.yudao.module.infra.convert.config.ConfigConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO; import cn.iocoder.yudao.module.infra.dal.mysql.config.ConfigMapper; -import cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; @@ -20,6 +19,7 @@ import javax.annotation.Resource; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*; /** * 参数配置 Service 实现类 @@ -35,7 +35,7 @@ public class ConfigServiceImpl implements ConfigService { @Override public Long createConfig(ConfigCreateReqVO reqVO) { // 校验正确性 - checkCreateOrUpdate(null, reqVO.getKey()); + validateConfigForCreateOrUpdate(null, reqVO.getKey()); // 插入参数配置 ConfigDO config = ConfigConvert.INSTANCE.convert(reqVO); config.setType(ConfigTypeEnum.CUSTOM.getType()); @@ -46,19 +46,19 @@ public class ConfigServiceImpl implements ConfigService { @Override public void updateConfig(ConfigUpdateReqVO reqVO) { // 校验正确性 - checkCreateOrUpdate(reqVO.getId(), null); // 不允许更新 key + validateConfigForCreateOrUpdate(reqVO.getId(), null); // 不允许更新 key // 更新参数配置 ConfigDO updateObj = ConfigConvert.INSTANCE.convert(reqVO); - configMapper.updateById(updateObj);; + configMapper.updateById(updateObj); } @Override public void deleteConfig(Long id) { // 校验配置存在 - ConfigDO config = checkConfigExists(id); + ConfigDO config = validateConfigExists(id); // 内置配置,不允许删除 if (ConfigTypeEnum.SYSTEM.getType().equals(config.getType())) { - throw exception(ErrorCodeConstants.CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE); + throw exception(CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE); } // 删除 configMapper.deleteById(id); @@ -84,39 +84,39 @@ public class ConfigServiceImpl implements ConfigService { return configMapper.selectList(reqVO); } - private void checkCreateOrUpdate(Long id, String key) { + private void validateConfigForCreateOrUpdate(Long id, String key) { // 校验自己存在 - checkConfigExists(id); + validateConfigExists(id); // 校验参数配置 key 的唯一性 if (StrUtil.isNotEmpty(key)) { - checkConfigKeyUnique(id, key); + validateConfigKeyUnique(id, key); } } @VisibleForTesting - public ConfigDO checkConfigExists(Long id) { + public ConfigDO validateConfigExists(Long id) { if (id == null) { return null; } ConfigDO config = configMapper.selectById(id); if (config == null) { - throw exception(ErrorCodeConstants.CONFIG_NOT_EXISTS); + throw exception(CONFIG_NOT_EXISTS); } return config; } @VisibleForTesting - public void checkConfigKeyUnique(Long id, String key) { + public void validateConfigKeyUnique(Long id, String key) { ConfigDO config = configMapper.selectByKey(key); if (config == null) { return; } // 如果 id 为空,说明不用比较是否为相同 id 的参数配置 if (id == null) { - throw exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE); + throw exception(CONFIG_KEY_DUPLICATE); } if (!config.getId().equals(id)) { - throw exception(ErrorCodeConstants.CONFIG_KEY_DUPLICATE); + throw exception(CONFIG_KEY_DUPLICATE); } } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceTest.java index 5f29e79ec..00ebae9f9 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceTest.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.infra.service.config; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.framework.test.core.util.RandomUtils; import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigCreateReqVO; @@ -12,17 +11,17 @@ import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigUpdateReqV import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO; import cn.iocoder.yudao.module.infra.dal.mysql.config.ConfigMapper; import cn.iocoder.yudao.module.infra.enums.config.ConfigTypeEnum; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.List; import java.util.function.Consumer; import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; @@ -50,7 +49,7 @@ public class ConfigServiceTest extends BaseDbUnitTest { // 校验记录的属性是否正确 ConfigDO config = configMapper.selectById(configId); assertPojoEquals(reqVO, config); - Assertions.assertEquals(ConfigTypeEnum.CUSTOM.getType(), config.getType()); + assertEquals(ConfigTypeEnum.CUSTOM.getType(), config.getType()); } @Test @@ -101,40 +100,40 @@ public class ConfigServiceTest extends BaseDbUnitTest { } @Test - public void testCheckConfigExists_success() { + public void testValidateConfigExists_success() { // mock 数据 ConfigDO dbConfigDO = randomConfigDO(); configMapper.insert(dbConfigDO);// @Sql: 先插入出一条存在的数据 // 调用成功 - configService.checkConfigExists(dbConfigDO.getId()); + configService.validateConfigExists(dbConfigDO.getId()); } @Test - public void testCheckConfigExist_notExists() { - assertServiceException(() -> configService.checkConfigExists(randomLongId()), CONFIG_NOT_EXISTS); + public void testValidateConfigExist_notExists() { + assertServiceException(() -> configService.validateConfigExists(randomLongId()), CONFIG_NOT_EXISTS); } @Test - public void testCheckConfigKeyUnique_success() { + public void testValidateConfigKeyUnique_success() { // 调用,成功 - configService.checkConfigKeyUnique(randomLongId(), randomString()); + configService.validateConfigKeyUnique(randomLongId(), randomString()); } @Test - public void testCheckConfigKeyUnique_keyDuplicateForCreate() { + public void testValidateConfigKeyUnique_keyDuplicateForCreate() { // 准备参数 String key = randomString(); // mock 数据 configMapper.insert(randomConfigDO(o -> o.setConfigKey(key))); // 调用,校验异常 - assertServiceException(() -> configService.checkConfigKeyUnique(null, key), + assertServiceException(() -> configService.validateConfigKeyUnique(null, key), CONFIG_KEY_DUPLICATE); } @Test - public void testCheckConfigKeyUnique_keyDuplicateForUpdate() { + public void testValidateConfigKeyUnique_keyDuplicateForUpdate() { // 准备参数 Long id = randomLongId(); String key = randomString(); @@ -142,7 +141,7 @@ public class ConfigServiceTest extends BaseDbUnitTest { configMapper.insert(randomConfigDO(o -> o.setConfigKey(key))); // 调用,校验异常 - assertServiceException(() -> configService.checkConfigKeyUnique(id, key), + assertServiceException(() -> configService.validateConfigKeyUnique(id, key), CONFIG_KEY_DUPLICATE); } @@ -157,19 +156,19 @@ public class ConfigServiceTest extends BaseDbUnitTest { }); configMapper.insert(dbConfig); // 测试 name 不匹配 - configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setName("土豆"))); + configMapper.insert(cloneIgnoreId(dbConfig, o -> o.setName("土豆"))); // 测试 key 不匹配 - configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setConfigKey("tudou"))); + configMapper.insert(cloneIgnoreId(dbConfig, o -> o.setConfigKey("tudou"))); // 测试 type 不匹配 - configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setType(ConfigTypeEnum.CUSTOM.getType()))); + configMapper.insert(cloneIgnoreId(dbConfig, o -> o.setType(ConfigTypeEnum.CUSTOM.getType()))); // 测试 createTime 不匹配 - configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setCreateTime(buildTime(2021, 1, 1)))); + configMapper.insert(cloneIgnoreId(dbConfig, o -> o.setCreateTime(buildTime(2021, 1, 1)))); // 准备参数 ConfigPageReqVO reqVO = new ConfigPageReqVO(); reqVO.setName("艿"); reqVO.setKey("nai"); reqVO.setType(ConfigTypeEnum.SYSTEM.getType()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 1, 15),buildTime(2021, 2, 15)})); + reqVO.setCreateTime(buildBetweenTime(2021, 1, 15, 2021, 2, 15)); // 调用 PageResult pageResult = configService.getConfigPage(reqVO); @@ -190,19 +189,19 @@ public class ConfigServiceTest extends BaseDbUnitTest { }); configMapper.insert(dbConfig); // 测试 name 不匹配 - configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setName("土豆"))); + configMapper.insert(cloneIgnoreId(dbConfig, o -> o.setName("土豆"))); // 测试 key 不匹配 - configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setConfigKey("tudou"))); + configMapper.insert(cloneIgnoreId(dbConfig, o -> o.setConfigKey("tudou"))); // 测试 type 不匹配 - configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setType(ConfigTypeEnum.CUSTOM.getType()))); + configMapper.insert(cloneIgnoreId(dbConfig, o -> o.setType(ConfigTypeEnum.CUSTOM.getType()))); // 测试 createTime 不匹配 - configMapper.insert(ObjectUtils.cloneIgnoreId(dbConfig, o -> o.setCreateTime(buildTime(2021, 1, 1)))); + configMapper.insert(cloneIgnoreId(dbConfig, o -> o.setCreateTime(buildTime(2021, 1, 1)))); // 准备参数 ConfigExportReqVO reqVO = new ConfigExportReqVO(); reqVO.setName("艿"); reqVO.setKey("nai"); reqVO.setType(ConfigTypeEnum.SYSTEM.getType()); - reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 1, 15),buildTime(2021, 2, 15)})); + reqVO.setCreateTime(buildBetweenTime(2021, 1, 15, 2021, 2, 15)); // 调用 List list = configService.getConfigList(reqVO); @@ -211,6 +210,21 @@ public class ConfigServiceTest extends BaseDbUnitTest { assertPojoEquals(dbConfig, list.get(0)); } + @Test + public void testGetConfig() { + // mock 数据 + ConfigDO dbConfig = randomConfigDO(); + configMapper.insert(dbConfig);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbConfig.getId(); + + // 调用 + ConfigDO config = configService.getConfig(id); + // 断言 + assertNotNull(config); + assertPojoEquals(dbConfig, config); + } + @Test public void testGetConfigByKey() { // mock 数据 diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImplTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImplTest.java index e1c997f7b..583a53cba 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImplTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImplTest.java @@ -89,7 +89,6 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest { o.setId(dbDataSourceConfig.getId()); // 设置更新的 ID }); // mock 方法 -// when(stringEncryptor.encrypt(eq(reqVO.getPassword()))).thenReturn("123456"); databaseUtilsMock.when(() -> JdbcUtils.isConnectionOK(eq(reqVO.getUrl()), eq(reqVO.getUsername()), eq(reqVO.getPassword()))).thenReturn(true); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java index ce6954694..e3e8bc8b3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserProfileController.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.system.controller.admin.user; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileRespVO; @@ -31,6 +30,7 @@ import javax.annotation.Resource; import javax.validation.Valid; import java.util.List; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_IS_EMPTY; @@ -99,7 +99,7 @@ public class UserProfileController { @ApiOperation("上传用户个人头像") public CommonResult updateUserAvatar(@RequestParam("avatarFile") MultipartFile file) throws Exception { if (file.isEmpty()) { - throw ServiceExceptionUtil.exception(FILE_IS_EMPTY); + throw exception(FILE_IS_EMPTY); } String avatar = userService.updateUserAvatar(getLoginUserId(), file.getInputStream()); return success(avatar); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java index 62e796784..27d6a3567 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.system.service.permission; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; @@ -31,6 +30,7 @@ import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; @@ -118,7 +118,7 @@ public class MenuServiceImpl implements MenuService { public void updateMenu(MenuUpdateReqVO reqVO) { // 校验更新的菜单是否存在 if (menuMapper.selectById(reqVO.getId()) == null) { - throw ServiceExceptionUtil.exception(MENU_NOT_EXISTS); + throw exception(MENU_NOT_EXISTS); } // 校验父菜单存在 validateParentMenu(reqVO.getParentId(), reqVO.getId()); @@ -138,11 +138,11 @@ public class MenuServiceImpl implements MenuService { public void deleteMenu(Long menuId) { // 校验是否还有子菜单 if (menuMapper.selectCountByParentId(menuId) > 0) { - throw ServiceExceptionUtil.exception(MENU_EXISTS_CHILDREN); + throw exception(MENU_EXISTS_CHILDREN); } // 校验删除的菜单是否存在 if (menuMapper.selectById(menuId) == null) { - throw ServiceExceptionUtil.exception(MENU_NOT_EXISTS); + throw exception(MENU_NOT_EXISTS); } // 标记删除 menuMapper.deleteById(menuId); @@ -229,17 +229,17 @@ public class MenuServiceImpl implements MenuService { } // 不能设置自己为父菜单 if (parentId.equals(childId)) { - throw ServiceExceptionUtil.exception(MENU_PARENT_ERROR); + throw exception(MENU_PARENT_ERROR); } MenuDO menu = menuMapper.selectById(parentId); // 父菜单不存在 if (menu == null) { - throw ServiceExceptionUtil.exception(MENU_PARENT_NOT_EXISTS); + throw exception(MENU_PARENT_NOT_EXISTS); } // 父菜单必须是目录或者菜单类型 if (!MenuTypeEnum.DIR.getType().equals(menu.getType()) && !MenuTypeEnum.MENU.getType().equals(menu.getType())) { - throw ServiceExceptionUtil.exception(MENU_PARENT_NOT_DIR_OR_MENU); + throw exception(MENU_PARENT_NOT_DIR_OR_MENU); } } @@ -260,10 +260,10 @@ public class MenuServiceImpl implements MenuService { } // 如果 id 为空,说明不用比较是否为相同 id 的菜单 if (id == null) { - throw ServiceExceptionUtil.exception(MENU_NAME_DUPLICATE); + throw exception(MENU_NAME_DUPLICATE); } if (!menu.getId().equals(id)) { - throw ServiceExceptionUtil.exception(MENU_NAME_DUPLICATE); + throw exception(MENU_NAME_DUPLICATE); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java index f181f177c..38357b280 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java @@ -34,6 +34,7 @@ import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; @@ -310,7 +311,7 @@ public class TenantServiceImplTest extends BaseDbUnitTest { reqVO.setContactName("艿"); reqVO.setContactMobile("1560"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime(new LocalDateTime[]{buildTime(2020, 12, 1),buildTime(2020, 12, 24)}); + reqVO.setCreateTime(buildBetweenTime(2020, 12, 1, 2020, 12, 24)); // 调用 PageResult pageResult = tenantService.getTenantPage(reqVO); @@ -347,7 +348,7 @@ public class TenantServiceImplTest extends BaseDbUnitTest { reqVO.setContactName("艿"); reqVO.setContactMobile("1560"); reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setCreateTime(new LocalDateTime[]{buildTime(2020, 12, 1),buildTime(2020, 12, 24)}); + reqVO.setCreateTime(buildBetweenTime(2020, 12, 1, 2020, 12, 24)); // 调用 List list = tenantService.getTenantList(reqVO); @@ -356,7 +357,6 @@ public class TenantServiceImplTest extends BaseDbUnitTest { assertPojoEquals(dbTenant, list.get(0)); } - @Test public void testGetTenantByName() { // mock 数据 From cc1fa54ea52f051e3f1b2b05f3b9633ea9a6bfe0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 01:14:59 +0800 Subject: [PATCH 51/59] =?UTF-8?q?infra=EF=BC=9A=E5=AE=8C=E5=96=84=20dataSo?= =?UTF-8?q?urce=20=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../db/DataSourceConfigServiceImpl.java | 6 +- .../db/DataSourceConfigServiceImplTest.java | 64 ++++++++++++++++++- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImpl.java index f2fd0a408..e4365c205 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImpl.java @@ -37,7 +37,7 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService { @Override public Long createDataSourceConfig(DataSourceConfigCreateReqVO createReqVO) { DataSourceConfigDO dataSourceConfig = DataSourceConfigConvert.INSTANCE.convert(createReqVO); - checkConnectionOK(dataSourceConfig); + validateConnectionOK(dataSourceConfig); // 插入 dataSourceConfigMapper.insert(dataSourceConfig); @@ -50,7 +50,7 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService { // 校验存在 validateDataSourceConfigExists(updateReqVO.getId()); DataSourceConfigDO updateObj = DataSourceConfigConvert.INSTANCE.convert(updateReqVO); - checkConnectionOK(updateObj); + validateConnectionOK(updateObj); // 更新 dataSourceConfigMapper.updateById(updateObj); @@ -88,7 +88,7 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService { return result; } - private void checkConnectionOK(DataSourceConfigDO config) { + private void validateConnectionOK(DataSourceConfigDO config) { boolean success = JdbcUtils.isConnectionOK(config.getUrl(), config.getUsername(), config.getPassword()); if (!success) { throw exception(DATA_SOURCE_CONFIG_NOT_OK); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImplTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImplTest.java index 583a53cba..b5ef46c46 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImplTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImplTest.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.infra.service.db; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.crypto.symmetric.AES; import cn.iocoder.yudao.framework.mybatis.core.type.EncryptTypeHandler; @@ -9,6 +10,7 @@ import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigCrea import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigUpdateReqVO; import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO; import cn.iocoder.yudao.module.infra.dal.mysql.db.DataSourceConfigMapper; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -18,14 +20,14 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; +import java.util.List; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.DATA_SOURCE_CONFIG_NOT_EXISTS; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mockStatic; @@ -57,6 +59,11 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest { ReflectUtil.setFieldValue(EncryptTypeHandler.class, "aes", aes); when(aes.encryptBase64(anyString())).then((Answer) invocation -> invocation.getArgument(0)); when(aes.decryptStr(anyString())).then((Answer) invocation -> invocation.getArgument(0)); + + // mock DynamicDataSourceProperties + when(dynamicDataSourceProperties.getPrimary()).thenReturn("primary"); + when(dynamicDataSourceProperties.getDatasource()).thenReturn(MapUtil.of("primary", + new DataSourceProperty().setUrl("http://localhost:3306").setUsername("yunai").setPassword("tudou"))); } @Test @@ -141,7 +148,58 @@ public class DataSourceConfigServiceImplTest extends BaseDbUnitTest { // 调用 DataSourceConfigDO result = dataSourceConfigMapper.selectOne(DataSourceConfigDO::getPassword, EncryptTypeHandler.encrypt(dbDataSourceConfig.getPassword())); - System.out.println(result); + assertPojoEquals(dbDataSourceConfig, result); + } + + @Test + public void testGetDataSourceConfig_master() { + // 准备参数 + Long id = 0L; + // mock 方法 + + // 调用 + DataSourceConfigDO dataSourceConfig = dataSourceConfigService.getDataSourceConfig(id); + // 断言 + assertEquals(id, dataSourceConfig.getId()); + assertEquals("primary", dataSourceConfig.getName()); + assertEquals("http://localhost:3306", dataSourceConfig.getUrl()); + assertEquals("yunai", dataSourceConfig.getUsername()); + assertEquals("tudou", dataSourceConfig.getPassword()); + } + + @Test + public void testGetDataSourceConfig_normal() { + // mock 数据 + DataSourceConfigDO dbDataSourceConfig = randomPojo(DataSourceConfigDO.class); + dataSourceConfigMapper.insert(dbDataSourceConfig);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbDataSourceConfig.getId(); + + // 调用 + DataSourceConfigDO dataSourceConfig = dataSourceConfigService.getDataSourceConfig(id); + // 断言 + assertPojoEquals(dbDataSourceConfig, dataSourceConfig); + } + + @Test + public void testGetDataSourceConfigList() { + // mock 数据 + DataSourceConfigDO dbDataSourceConfig = randomPojo(DataSourceConfigDO.class); + dataSourceConfigMapper.insert(dbDataSourceConfig);// @Sql: 先插入出一条存在的数据 + // 准备参数 + + // 调用 + List dataSourceConfigList = dataSourceConfigService.getDataSourceConfigList(); + // 断言 + assertEquals(2, dataSourceConfigList.size()); + // master + assertEquals(0L, dataSourceConfigList.get(0).getId()); + assertEquals("primary", dataSourceConfigList.get(0).getName()); + assertEquals("http://localhost:3306", dataSourceConfigList.get(0).getUrl()); + assertEquals("yunai", dataSourceConfigList.get(0).getUsername()); + assertEquals("tudou", dataSourceConfigList.get(0).getPassword()); + // normal + assertPojoEquals(dbDataSourceConfig, dataSourceConfigList.get(1)); } } From 3070392ecd5548632d774287b19ba9df1d6b3b8c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 07:50:36 +0800 Subject: [PATCH 52/59] =?UTF-8?q?infra=EF=BC=9A=E5=AE=8C=E5=96=84=20file?= =?UTF-8?q?=20=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/service/file/FileConfigService.java | 10 -------- .../service/file/FileConfigServiceImpl.java | 14 +++-------- .../infra/service/file/FileServiceImpl.java | 2 +- .../infra/service/job/JobServiceImpl.java | 8 +++--- ...ceTest.java => ConfigServiceImplTest.java} | 2 +- .../file/FileConfigServiceImplTest.java | 25 +++++++++++++++++++ ...viceTest.java => FileServiceImplTest.java} | 2 +- 7 files changed, 36 insertions(+), 27 deletions(-) rename yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/{ConfigServiceTest.java => ConfigServiceImplTest.java} (99%) rename yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/{FileServiceTest.java => FileServiceImplTest.java} (98%) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java index b3fc6bad2..43ab5bc68 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java @@ -8,8 +8,6 @@ import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigU import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO; import javax.validation.Valid; -import java.util.Collection; -import java.util.List; /** * 文件配置 Service 接口 @@ -60,14 +58,6 @@ public interface FileConfigService { */ FileConfigDO getFileConfig(Long id); - /** - * 获得文件配置列表 - * - * @param ids 编号 - * @return 文件配置列表 - */ - List getFileConfigList(Collection ids); - /** * 获得文件配置分页 * diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java index 590ff8116..6236df6ff 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java @@ -27,7 +27,6 @@ import org.springframework.validation.annotation.Validated; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.validation.Validator; -import java.util.Collection; import java.util.List; import java.util.Map; @@ -95,7 +94,7 @@ public class FileConfigServiceImpl implements FileConfigService { @Override public void updateFileConfig(FileConfigUpdateReqVO updateReqVO) { // 校验存在 - FileConfigDO config = this.validateFileConfigExists(updateReqVO.getId()); + FileConfigDO config = validateFileConfigExists(updateReqVO.getId()); // 更新 FileConfigDO updateObj = FileConfigConvert.INSTANCE.convert(updateReqVO) .setConfig(parseClientConfig(config.getStorage(), updateReqVO.getConfig())); @@ -108,7 +107,7 @@ public class FileConfigServiceImpl implements FileConfigService { @Transactional(rollbackFor = Exception.class) public void updateFileConfigMaster(Long id) { // 校验存在 - this.validateFileConfigExists(id); + validateFileConfigExists(id); // 更新其它为非 master fileConfigMapper.updateBatch(new FileConfigDO().setMaster(false)); // 更新 @@ -138,7 +137,7 @@ public class FileConfigServiceImpl implements FileConfigService { @Override public void deleteFileConfig(Long id) { // 校验存在 - FileConfigDO config = this.validateFileConfigExists(id); + FileConfigDO config = validateFileConfigExists(id); if (Boolean.TRUE.equals(config.getMaster())) { throw exception(FILE_CONFIG_DELETE_FAIL_MASTER); } @@ -161,11 +160,6 @@ public class FileConfigServiceImpl implements FileConfigService { return fileConfigMapper.selectById(id); } - @Override - public List getFileConfigList(Collection ids) { - return fileConfigMapper.selectBatchIds(ids); - } - @Override public PageResult getFileConfigPage(FileConfigPageReqVO pageReqVO) { return fileConfigMapper.selectPage(pageReqVO); @@ -174,7 +168,7 @@ public class FileConfigServiceImpl implements FileConfigService { @Override public String testFileConfig(Long id) throws Exception { // 校验存在 - this.validateFileConfigExists(id); + validateFileConfigExists(id); // 上传文件 byte[] content = ResourceUtil.readBytes("file/erweima.jpg"); return fileClientFactory.getFileClient(id).upload(content, IdUtil.fastSimpleUUID() + ".jpg", "image/jpeg"); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java index 2226e7bae..0732765d8 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java @@ -69,7 +69,7 @@ public class FileServiceImpl implements FileService { @Override public void deleteFile(Long id) throws Exception { // 校验存在 - FileDO file = this.validateFileExists(id); + FileDO file = validateFileExists(id); // 从文件存储器中删除 FileClient client = fileConfigService.getFileClient(file.getConfigId()); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java index e0a245750..498d816b8 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java @@ -69,7 +69,7 @@ public class JobServiceImpl implements JobService { public void updateJob(JobUpdateReqVO updateReqVO) throws SchedulerException { validateCronExpression(updateReqVO.getCronExpression()); // 校验存在 - JobDO job = this.validateJobExists(updateReqVO.getId()); + JobDO job = validateJobExists(updateReqVO.getId()); // 只有开启状态,才可以修改.原因是,如果出暂停状态,修改 Quartz Job 时,会导致任务又开始执行 if (!job.getStatus().equals(JobStatusEnum.NORMAL.getStatus())) { throw exception(JOB_UPDATE_ONLY_NORMAL_STATUS); @@ -92,7 +92,7 @@ public class JobServiceImpl implements JobService { throw exception(JOB_CHANGE_STATUS_INVALID); } // 校验存在 - JobDO job = this.validateJobExists(id); + JobDO job = validateJobExists(id); // 校验是否已经为当前状态 if (job.getStatus().equals(status)) { throw exception(JOB_CHANGE_STATUS_EQUALS); @@ -112,7 +112,7 @@ public class JobServiceImpl implements JobService { @Override public void triggerJob(Long id) throws SchedulerException { // 校验存在 - JobDO job = this.validateJobExists(id); + JobDO job = validateJobExists(id); // 触发 Quartz 中的 Job schedulerManager.triggerJob(job.getId(), job.getHandlerName(), job.getHandlerParam()); @@ -122,7 +122,7 @@ public class JobServiceImpl implements JobService { @Transactional(rollbackFor = Exception.class) public void deleteJob(Long id) throws SchedulerException { // 校验存在 - JobDO job = this.validateJobExists(id); + JobDO job = validateJobExists(id); // 更新 jobMapper.deleteById(id); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImplTest.java similarity index 99% rename from yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceTest.java rename to yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImplTest.java index 00ebae9f9..428b20522 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImplTest.java @@ -29,7 +29,7 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*; import static org.junit.jupiter.api.Assertions.*; @Import(ConfigServiceImpl.class) -public class ConfigServiceTest extends BaseDbUnitTest { +public class ConfigServiceImplTest extends BaseDbUnitTest { @Resource private ConfigServiceImpl configService; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java index 61c9827f6..656955194 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.file.core.client.FileClient; import cn.iocoder.yudao.framework.file.core.client.FileClientConfig; import cn.iocoder.yudao.framework.file.core.client.FileClientFactory; +import cn.iocoder.yudao.framework.file.core.client.local.LocalFileClient; import cn.iocoder.yudao.framework.file.core.client.local.LocalFileClientConfig; import cn.iocoder.yudao.framework.file.core.enums.FileStorageEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; @@ -242,6 +243,30 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest { assertEquals("https://www.iocoder.cn", fileConfigService.testFileConfig(id)); } + @Test + public void testGetFileConfig() { + // mock 数据 + FileConfigDO dbFileConfig = randomFileConfigDO().setMaster(false); + fileConfigMapper.insert(dbFileConfig);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbFileConfig.getId(); + + // 调用,并断言 + assertPojoEquals(dbFileConfig, fileConfigService.getFileConfig(id)); + } + + @Test + public void testGetFileClient() { + // 准备参数 + Long id = randomLongId(); + // mock 获得 Client + FileClient fileClient = new LocalFileClient(id, new LocalFileClientConfig()); + when(fileClientFactory.getFileClient(eq(id))).thenReturn(fileClient); + + // 调用,并断言 + assertSame(fileClient, fileConfigService.getFileClient(id)); + } + private FileConfigDO randomFileConfigDO() { return randomPojo(FileConfigDO.class).setStorage(randomEle(FileStorageEnum.values()).getStorage()) .setConfig(new EmptyFileClientConfig()); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImplTest.java similarity index 98% rename from yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java rename to yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImplTest.java index 90bde8f4e..57cc4c476 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImplTest.java @@ -26,7 +26,7 @@ import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.*; @Import({FileServiceImpl.class}) -public class FileServiceTest extends BaseDbUnitTest { +public class FileServiceImplTest extends BaseDbUnitTest { @Resource private FileService fileService; From ebf441ef13f35a57b0964c7d54b89b7737026922 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 08:42:29 +0800 Subject: [PATCH 53/59] =?UTF-8?q?infra=EF=BC=9A=E5=AE=8C=E5=96=84=20job=20?= =?UTF-8?q?=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ceTest.java => JobLogServiceImplTest.java} | 128 +++++++++------ ...rviceTest.java => JobServiceImplTest.java} | 148 +++++++++--------- 2 files changed, 156 insertions(+), 120 deletions(-) rename yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/{JobLogServiceTest.java => JobLogServiceImplTest.java} (52%) rename yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/{JobServiceTest.java => JobServiceImplTest.java} (60%) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobLogServiceTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobLogServiceImplTest.java similarity index 52% rename from yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobLogServiceTest.java rename to yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobLogServiceImplTest.java index 665e9c509..efba0c0cf 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobLogServiceTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobLogServiceImplTest.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.infra.service.job; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExportReqVO; import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogPageReqVO; @@ -12,18 +11,20 @@ import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.util.ArrayList; +import java.time.LocalDateTime; +import java.util.Collection; import java.util.List; -import static cn.hutool.core.util.RandomUtil.randomEle; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static java.util.Collections.singleton; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @Import(JobLogServiceImpl.class) -public class JobLogServiceTest extends BaseDbUnitTest { +public class JobLogServiceImplTest extends BaseDbUnitTest { @Resource private JobLogServiceImpl jobLogService; @@ -31,66 +32,103 @@ public class JobLogServiceTest extends BaseDbUnitTest { private JobLogMapper jobLogMapper; @Test - public void testCreateJobLog_success() { + public void testCreateJobLog() { // 准备参数 - JobLogDO reqVO = randomPojo(JobLogDO.class, o -> { - o.setExecuteIndex(1); - }); + JobLogDO reqVO = randomPojo(JobLogDO.class, o -> o.setExecuteIndex(1)); + // 调用 - Long jobLogId = jobLogService.createJobLog(reqVO.getJobId(), reqVO.getBeginTime(), reqVO.getHandlerName(), reqVO.getHandlerParam(), reqVO.getExecuteIndex()); + Long id = jobLogService.createJobLog(reqVO.getJobId(), reqVO.getBeginTime(), + reqVO.getHandlerName(), reqVO.getHandlerParam(), reqVO.getExecuteIndex()); // 断言 - assertNotNull(jobLogId); + assertNotNull(id); // 校验记录的属性是否正确 - JobLogDO job = jobLogMapper.selectById(jobLogId); + JobLogDO job = jobLogMapper.selectById(id); assertEquals(JobLogStatusEnum.RUNNING.getStatus(), job.getStatus()); } @Test public void testUpdateJobLogResultAsync_success() { - // 准备参数 - JobLogDO reqVO = randomPojo(JobLogDO.class, o -> { + // mock 数据 + JobLogDO log = randomPojo(JobLogDO.class, o -> { o.setExecuteIndex(1); + o.setStatus(JobLogStatusEnum.RUNNING.getStatus()); }); - JobLogDO log = JobLogDO.builder().jobId(reqVO.getJobId()).handlerName(reqVO.getHandlerName()).handlerParam(reqVO.getHandlerParam()).executeIndex(reqVO.getExecuteIndex()) - .beginTime(reqVO.getBeginTime()).status(JobLogStatusEnum.RUNNING.getStatus()).build(); jobLogMapper.insert(log); - // 调用 - jobLogService.updateJobLogResultAsync(log.getId(), reqVO.getBeginTime(), reqVO.getDuration(), true,reqVO.getResult()); - // 校验记录的属性是否正确 - JobLogDO job = jobLogMapper.selectById(log.getId()); - assertEquals(JobLogStatusEnum.SUCCESS.getStatus(), job.getStatus()); + // 准备参数 + Long logId = log.getId(); + LocalDateTime endTime = randomLocalDateTime(); + Integer duration = randomInteger(); + boolean success = true; + String result = randomString(); // 调用 - jobLogService.updateJobLogResultAsync(log.getId(), reqVO.getBeginTime(), reqVO.getDuration(), false,reqVO.getResult()); + jobLogService.updateJobLogResultAsync(logId, endTime, duration, success, result); // 校验记录的属性是否正确 - JobLogDO job2 = jobLogMapper.selectById(log.getId()); - assertEquals(JobLogStatusEnum.FAILURE.getStatus(), job2.getStatus()); + JobLogDO dbLog = jobLogMapper.selectById(log.getId()); + assertEquals(endTime, dbLog.getEndTime()); + assertEquals(duration, dbLog.getDuration()); + assertEquals(JobLogStatusEnum.SUCCESS.getStatus(), dbLog.getStatus()); + assertEquals(result, dbLog.getResult()); } @Test - public void testGetJobLogListByIds_success() { + public void testUpdateJobLogResultAsync_failure() { // mock 数据 - JobLogDO dbJobLog = randomPojo(JobLogDO.class, o -> { + JobLogDO log = randomPojo(JobLogDO.class, o -> { o.setExecuteIndex(1); - o.setStatus(randomEle(JobLogStatusEnum.values()).getStatus()); // 保证 status 的范围 + o.setStatus(JobLogStatusEnum.RUNNING.getStatus()); }); - JobLogDO cloneJobLog = ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString())); + jobLogMapper.insert(log); + // 准备参数 + Long logId = log.getId(); + LocalDateTime endTime = randomLocalDateTime(); + Integer duration = randomInteger(); + boolean success = false; + String result = randomString(); + + // 调用 + jobLogService.updateJobLogResultAsync(logId, endTime, duration, success, result); + // 校验记录的属性是否正确 + JobLogDO dbLog = jobLogMapper.selectById(log.getId()); + assertEquals(endTime, dbLog.getEndTime()); + assertEquals(duration, dbLog.getDuration()); + assertEquals(JobLogStatusEnum.FAILURE.getStatus(), dbLog.getStatus()); + assertEquals(result, dbLog.getResult()); + } + + @Test + public void testGetJobLog() { + // mock 数据 + JobLogDO dbJobLog = randomPojo(JobLogDO.class, o -> o.setExecuteIndex(1)); + jobLogMapper.insert(dbJobLog); + // 准备参数 + Long id = dbJobLog.getId(); + + // 调用 + JobLogDO jobLog = jobLogService.getJobLog(id); + // 断言 + assertPojoEquals(dbJobLog, jobLog); + } + + @Test + public void testGetJobLogList() { + // mock 数据 + JobLogDO dbJobLog = randomPojo(JobLogDO.class, o -> o.setExecuteIndex(1)); jobLogMapper.insert(dbJobLog); // 测试 handlerName 不匹配 - jobLogMapper.insert(cloneJobLog); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> {})); // 准备参数 - ArrayList ids = new ArrayList<>(); - ids.add(dbJobLog.getId()); - ids.add(cloneJobLog.getId()); + Collection ids = singleton(dbJobLog.getId()); + // 调用 List list = jobLogService.getJobLogList(ids); // 断言 - assertEquals(2, list.size()); + assertEquals(1, list.size()); assertPojoEquals(dbJobLog, list.get(0)); } @Test - public void testGetJobPage_success() { + public void testGetJobPage() { // mock 数据 JobLogDO dbJobLog = randomPojo(JobLogDO.class, o -> { o.setExecuteIndex(1); @@ -101,15 +139,15 @@ public class JobLogServiceTest extends BaseDbUnitTest { }); jobLogMapper.insert(dbJobLog); // 测试 jobId 不匹配 - jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setJobId(randomLongId()))); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> o.setJobId(randomLongId()))); // 测试 handlerName 不匹配 - jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString()))); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString()))); // 测试 beginTime 不匹配 - jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7)))); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7)))); // 测试 endTime 不匹配 - jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9)))); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9)))); // 测试 status 不匹配 - jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setStatus(JobLogStatusEnum.FAILURE.getStatus()))); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> o.setStatus(JobLogStatusEnum.FAILURE.getStatus()))); // 准备参数 JobLogPageReqVO reqVo = new JobLogPageReqVO(); reqVo.setJobId(dbJobLog.getJobId()); @@ -117,6 +155,7 @@ public class JobLogServiceTest extends BaseDbUnitTest { reqVo.setBeginTime(dbJobLog.getBeginTime()); reqVo.setEndTime(dbJobLog.getEndTime()); reqVo.setStatus(JobLogStatusEnum.SUCCESS.getStatus()); + // 调用 PageResult pageResult = jobLogService.getJobLogPage(reqVo); // 断言 @@ -126,7 +165,7 @@ public class JobLogServiceTest extends BaseDbUnitTest { } @Test - public void testGetJobListForExport_success() { + public void testGetJobList_export() { // mock 数据 JobLogDO dbJobLog = randomPojo(JobLogDO.class, o -> { o.setExecuteIndex(1); @@ -137,15 +176,15 @@ public class JobLogServiceTest extends BaseDbUnitTest { }); jobLogMapper.insert(dbJobLog); // 测试 jobId 不匹配 - jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setJobId(randomLongId()))); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> o.setJobId(randomLongId()))); // 测试 handlerName 不匹配 - jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString()))); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> o.setHandlerName(randomString()))); // 测试 beginTime 不匹配 - jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7)))); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> o.setBeginTime(buildTime(2021, 1, 7)))); // 测试 endTime 不匹配 - jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9)))); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> o.setEndTime(buildTime(2021, 1, 9)))); // 测试 status 不匹配 - jobLogMapper.insert(ObjectUtils.cloneIgnoreId(dbJobLog, o -> o.setStatus(JobLogStatusEnum.FAILURE.getStatus()))); + jobLogMapper.insert(cloneIgnoreId(dbJobLog, o -> o.setStatus(JobLogStatusEnum.FAILURE.getStatus()))); // 准备参数 JobLogExportReqVO reqVo = new JobLogExportReqVO(); reqVo.setJobId(dbJobLog.getJobId()); @@ -153,6 +192,7 @@ public class JobLogServiceTest extends BaseDbUnitTest { reqVo.setBeginTime(dbJobLog.getBeginTime()); reqVo.setEndTime(dbJobLog.getEndTime()); reqVo.setStatus(JobLogStatusEnum.SUCCESS.getStatus()); + // 调用 List list = jobLogService.getJobLogList(reqVo); // 断言 diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImplTest.java similarity index 60% rename from yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceTest.java rename to yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImplTest.java index 1cfcae998..f10c40365 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImplTest.java @@ -1,14 +1,12 @@ package cn.iocoder.yudao.module.infra.service.job; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.quartz.core.scheduler.SchedulerManager; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobCreateReqVO; import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobExportReqVO; import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobPageReqVO; import cn.iocoder.yudao.module.infra.controller.admin.job.vo.job.JobUpdateReqVO; -import cn.iocoder.yudao.module.infra.convert.job.JobConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO; import cn.iocoder.yudao.module.infra.dal.mysql.job.JobMapper; import cn.iocoder.yudao.module.infra.enums.job.JobStatusEnum; @@ -18,22 +16,23 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.util.ArrayList; +import java.util.Collection; import java.util.List; import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*; +import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @Import(JobServiceImpl.class) -public class JobServiceTest extends BaseDbUnitTest { +public class JobServiceImplTest extends BaseDbUnitTest { @Resource private JobServiceImpl jobService; @@ -46,6 +45,7 @@ public class JobServiceTest extends BaseDbUnitTest { public void testCreateJob_cronExpressionValid() { // 准备参数。Cron 表达式为 String 类型,默认随机字符串。 JobCreateReqVO reqVO = randomPojo(JobCreateReqVO.class); + // 调用,并断言异常 assertServiceException(() -> jobService.createJob(reqVO), JOB_CRON_EXPRESSION_VALID); } @@ -54,6 +54,7 @@ public class JobServiceTest extends BaseDbUnitTest { public void testCreateJob_jobHandlerExists() throws SchedulerException { // 准备参数 指定 Cron 表达式 JobCreateReqVO reqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); + // 调用 jobService.createJob(reqVO); // 调用,并断言异常 @@ -64,6 +65,7 @@ public class JobServiceTest extends BaseDbUnitTest { public void testCreateJob_success() throws SchedulerException { // 准备参数 指定 Cron 表达式 JobCreateReqVO reqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); + // 调用 Long jobId = jobService.createJob(reqVO); // 断言 @@ -73,14 +75,15 @@ public class JobServiceTest extends BaseDbUnitTest { assertPojoEquals(reqVO, job); assertEquals(JobStatusEnum.NORMAL.getStatus(), job.getStatus()); // 校验调用 - verify(schedulerManager, times(1)).addJob(eq(job.getId()), eq(job.getHandlerName()), eq(job.getHandlerParam()), eq(job.getCronExpression()), - eq(reqVO.getRetryCount()), eq(reqVO.getRetryInterval())); + verify(schedulerManager).addJob(eq(job.getId()), eq(job.getHandlerName()), eq(job.getHandlerParam()), + eq(job.getCronExpression()), eq(reqVO.getRetryCount()), eq(reqVO.getRetryInterval())); } @Test public void testUpdateJob_jobNotExists(){ // 准备参数 JobUpdateReqVO reqVO = randomPojo(JobUpdateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); + // 调用,并断言异常 assertServiceException(() -> jobService.updateJob(reqVO), JOB_NOT_EXISTS); } @@ -88,150 +91,136 @@ public class JobServiceTest extends BaseDbUnitTest { @Test public void testUpdateJob_onlyNormalStatus(){ // mock 数据 - JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); - JobDO job = JobConvert.INSTANCE.convert(createReqVO); - job.setStatus(JobStatusEnum.INIT.getStatus()); - fillJobMonitorTimeoutEmpty(job); + JobDO job = randomPojo(JobDO.class, o -> o.setStatus(JobStatusEnum.INIT.getStatus())); jobMapper.insert(job); // 准备参数 JobUpdateReqVO updateReqVO = randomPojo(JobUpdateReqVO.class, o -> { o.setId(job.getId()); - o.setName(createReqVO.getName()); - o.setCronExpression(createReqVO.getCronExpression()); + o.setCronExpression("0 0/1 * * * ? *"); }); + // 调用,并断言异常 - assertServiceException(() -> jobService.updateJob(updateReqVO), JOB_UPDATE_ONLY_NORMAL_STATUS); + assertServiceException(() -> jobService.updateJob(updateReqVO), + JOB_UPDATE_ONLY_NORMAL_STATUS); } @Test public void testUpdateJob_success() throws SchedulerException { // mock 数据 - JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); - JobDO job = JobConvert.INSTANCE.convert(createReqVO); - job.setStatus(JobStatusEnum.NORMAL.getStatus()); - fillJobMonitorTimeoutEmpty(job); + JobDO job = randomPojo(JobDO.class, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus())); jobMapper.insert(job); // 准备参数 JobUpdateReqVO updateReqVO = randomPojo(JobUpdateReqVO.class, o -> { o.setId(job.getId()); - o.setName(createReqVO.getName()); - o.setCronExpression(createReqVO.getCronExpression()); + o.setCronExpression("0 0/1 * * * ? *"); }); + // 调用 jobService.updateJob(updateReqVO); // 校验记录的属性是否正确 JobDO updateJob = jobMapper.selectById(updateReqVO.getId()); assertPojoEquals(updateReqVO, updateJob); // 校验调用 - verify(schedulerManager, times(1)).updateJob(eq(job.getHandlerName()), eq(updateReqVO.getHandlerParam()), eq(updateReqVO.getCronExpression()), - eq(updateReqVO.getRetryCount()), eq(updateReqVO.getRetryInterval())); + verify(schedulerManager).updateJob(eq(job.getHandlerName()), eq(updateReqVO.getHandlerParam()), + eq(updateReqVO.getCronExpression()), eq(updateReqVO.getRetryCount()), eq(updateReqVO.getRetryInterval())); } @Test public void testUpdateJobStatus_changeStatusInvalid() { // 调用,并断言异常 - assertServiceException(() -> jobService.updateJobStatus(1L, JobStatusEnum.INIT.getStatus()), JOB_CHANGE_STATUS_INVALID); + assertServiceException(() -> jobService.updateJobStatus(1L, JobStatusEnum.INIT.getStatus()), + JOB_CHANGE_STATUS_INVALID); } @Test public void testUpdateJobStatus_changeStatusEquals() { // mock 数据 - JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); - JobDO job = JobConvert.INSTANCE.convert(createReqVO); - job.setStatus(JobStatusEnum.NORMAL.getStatus()); - fillJobMonitorTimeoutEmpty(job); + JobDO job = randomPojo(JobDO.class, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus())); jobMapper.insert(job); + // 调用,并断言异常 - assertServiceException(() -> jobService.updateJobStatus(job.getId(), job.getStatus()), JOB_CHANGE_STATUS_EQUALS); + assertServiceException(() -> jobService.updateJobStatus(job.getId(), job.getStatus()), + JOB_CHANGE_STATUS_EQUALS); } @Test - public void testUpdateJobStatus_NormalToStop_success() throws SchedulerException { + public void testUpdateJobStatus_stopSuccess() throws SchedulerException { // mock 数据 - JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); - JobDO job = JobConvert.INSTANCE.convert(createReqVO); - job.setStatus(JobStatusEnum.NORMAL.getStatus()); - fillJobMonitorTimeoutEmpty(job); + JobDO job = randomPojo(JobDO.class, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus())); jobMapper.insert(job); + // 调用 jobService.updateJobStatus(job.getId(), JobStatusEnum.STOP.getStatus()); // 校验记录的属性是否正确 - JobDO updateJob = jobMapper.selectById(job.getId()); - assertEquals(JobStatusEnum.STOP.getStatus(), updateJob.getStatus()); + JobDO dbJob = jobMapper.selectById(job.getId()); + assertEquals(JobStatusEnum.STOP.getStatus(), dbJob.getStatus()); // 校验调用 - verify(schedulerManager, times(1)).pauseJob(eq(job.getHandlerName())); + verify(schedulerManager).pauseJob(eq(job.getHandlerName())); } @Test - public void testUpdateJobStatus_StopToNormal_success() throws SchedulerException { + public void testUpdateJobStatus_normalSuccess() throws SchedulerException { // mock 数据 - JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); - JobDO job = JobConvert.INSTANCE.convert(createReqVO); - job.setStatus(JobStatusEnum.STOP.getStatus()); - fillJobMonitorTimeoutEmpty(job); + JobDO job = randomPojo(JobDO.class, o -> o.setStatus(JobStatusEnum.STOP.getStatus())); jobMapper.insert(job); + // 调用 jobService.updateJobStatus(job.getId(), JobStatusEnum.NORMAL.getStatus()); // 校验记录的属性是否正确 - JobDO updateJob = jobMapper.selectById(job.getId()); - assertEquals(JobStatusEnum.NORMAL.getStatus(), updateJob.getStatus()); + JobDO dbJob = jobMapper.selectById(job.getId()); + assertEquals(JobStatusEnum.NORMAL.getStatus(), dbJob.getStatus()); // 校验调用 - verify(schedulerManager, times(1)).resumeJob(eq(job.getHandlerName())); + verify(schedulerManager).resumeJob(eq(job.getHandlerName())); } @Test public void testTriggerJob_success() throws SchedulerException { // mock 数据 - JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); - JobDO job = JobConvert.INSTANCE.convert(createReqVO); - job.setStatus(JobStatusEnum.NORMAL.getStatus()); - fillJobMonitorTimeoutEmpty(job); + JobDO job = randomPojo(JobDO.class); jobMapper.insert(job); + // 调用 jobService.triggerJob(job.getId()); // 校验调用 - verify(schedulerManager, times(1)).triggerJob(eq(job.getId()), eq(job.getHandlerName()), eq(job.getHandlerParam())); + verify(schedulerManager).triggerJob(eq(job.getId()), + eq(job.getHandlerName()), eq(job.getHandlerParam())); } @Test public void testDeleteJob_success() throws SchedulerException { // mock 数据 - JobCreateReqVO createReqVO = randomPojo(JobCreateReqVO.class, o -> o.setCronExpression("0 0/1 * * * ? *")); - JobDO job = JobConvert.INSTANCE.convert(createReqVO); - job.setStatus(JobStatusEnum.NORMAL.getStatus()); - fillJobMonitorTimeoutEmpty(job); + JobDO job = randomPojo(JobDO.class); jobMapper.insert(job); - // 调用 UPDATE inf_job SET deleted=1 WHERE id=? AND deleted=0 + + // 调用 jobService.deleteJob(job.getId()); - // 校验数据不存在了 WHERE id=? AND deleted=0 查询为空正常 + // 校验不存在 assertNull(jobMapper.selectById(job.getId())); // 校验调用 - verify(schedulerManager, times(1)).deleteJob(eq(job.getHandlerName())); + verify(schedulerManager).deleteJob(eq(job.getHandlerName())); } @Test - public void testGetJobListByIds_success() { + public void testGetJobList() { // mock 数据 JobDO dbJob = randomPojo(JobDO.class, o -> { o.setStatus(randomEle(JobStatusEnum.values()).getStatus()); // 保证 status 的范围 }); - JobDO cloneJob = ObjectUtils.cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString())); jobMapper.insert(dbJob); - // 测试 handlerName 不匹配 - jobMapper.insert(cloneJob); + // 测试 id 不匹配 + jobMapper.insert(cloneIgnoreId(dbJob, o -> {})); + // 准备参数 - ArrayList ids = new ArrayList<>(); - ids.add(dbJob.getId()); - ids.add(cloneJob.getId()); + Collection ids = singletonList(dbJob.getId()); // 调用 List list = jobService.getJobList(ids); // 断言 - assertEquals(2, list.size()); + assertEquals(1, list.size()); assertPojoEquals(dbJob, list.get(0)); } @Test - public void testGetJobPage_success() { + public void testGetJobPage() { // mock 数据 JobDO dbJob = randomPojo(JobDO.class, o -> { o.setName("定时任务测试"); @@ -240,16 +229,17 @@ public class JobServiceTest extends BaseDbUnitTest { }); jobMapper.insert(dbJob); // 测试 name 不匹配 - jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setName("土豆"))); + jobMapper.insert(cloneIgnoreId(dbJob, o -> o.setName("土豆"))); // 测试 status 不匹配 - jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus()))); + jobMapper.insert(cloneIgnoreId(dbJob, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus()))); // 测试 handlerName 不匹配 - jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString()))); + jobMapper.insert(cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString()))); // 准备参数 JobPageReqVO reqVo = new JobPageReqVO(); reqVo.setName("定时"); reqVo.setStatus(JobStatusEnum.INIT.getStatus()); reqVo.setHandlerName("单元"); + // 调用 PageResult pageResult = jobService.getJobPage(reqVo); // 断言 @@ -259,7 +249,7 @@ public class JobServiceTest extends BaseDbUnitTest { } @Test - public void testGetJobListForExport_success() { + public void testGetJobList_export() { // mock 数据 JobDO dbJob = randomPojo(JobDO.class, o -> { o.setName("定时任务测试"); @@ -268,16 +258,17 @@ public class JobServiceTest extends BaseDbUnitTest { }); jobMapper.insert(dbJob); // 测试 name 不匹配 - jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setName("土豆"))); + jobMapper.insert(cloneIgnoreId(dbJob, o -> o.setName("土豆"))); // 测试 status 不匹配 - jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus()))); + jobMapper.insert(cloneIgnoreId(dbJob, o -> o.setStatus(JobStatusEnum.NORMAL.getStatus()))); // 测试 handlerName 不匹配 - jobMapper.insert(ObjectUtils.cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString()))); + jobMapper.insert(cloneIgnoreId(dbJob, o -> o.setHandlerName(randomString()))); // 准备参数 JobExportReqVO reqVo = new JobExportReqVO(); reqVo.setName("定时"); reqVo.setStatus(JobStatusEnum.INIT.getStatus()); reqVo.setHandlerName("单元"); + // 调用 List list = jobService.getJobList(reqVo); // 断言 @@ -285,10 +276,15 @@ public class JobServiceTest extends BaseDbUnitTest { assertPojoEquals(dbJob, list.get(0)); } - private static void fillJobMonitorTimeoutEmpty(JobDO job) { - if (job.getMonitorTimeout() == null) { - job.setMonitorTimeout(0); - } + @Test + public void testGetJob() { + // mock 数据 + JobDO dbJob = randomPojo(JobDO.class); + jobMapper.insert(dbJob); + // 调用 + JobDO job = jobService.getJob(dbJob.getId()); + // 断言 + assertPojoEquals(dbJob, job); } } From ec913adb207b88fde0d0bc95f5db5386d4314038 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 09:10:09 +0800 Subject: [PATCH 54/59] =?UTF-8?q?infra=EF=BC=9A=E5=AE=8C=E5=96=84=20logger?= =?UTF-8?q?=20=E7=9A=84=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../logger/ApiErrorLogServiceImpl.java | 14 +- .../service/test/TestDemoServiceImpl.java | 4 +- .../codegen/java/service/serviceImpl.vm | 4 +- .../codegen/java/test/serviceTest.vm | 2 +- .../logger/ApiAccessLogServiceImplTest.java | 179 +++++-------- .../logger/ApiErrorLogServiceImplTest.java | 253 +++++++++--------- 6 files changed, 208 insertions(+), 248 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java index c1b129322..c0f9252af 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.infra.service.logger; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO; import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExportReqVO; @@ -8,7 +7,6 @@ import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiE import cn.iocoder.yudao.module.infra.convert.logger.ApiErrorLogConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO; import cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper; -import cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants; import cn.iocoder.yudao.module.infra.enums.logger.ApiErrorLogProcessStatusEnum; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -17,6 +15,10 @@ import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.List; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.API_ERROR_LOG_NOT_FOUND; +import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.API_ERROR_LOG_PROCESSED; + /** * API 错误日志 Service 实现类 * @@ -31,8 +33,8 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService { @Override public void createApiErrorLog(ApiErrorLogCreateReqDTO createDTO) { - ApiErrorLogDO apiErrorLog = ApiErrorLogConvert.INSTANCE.convert(createDTO); - apiErrorLog.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); + ApiErrorLogDO apiErrorLog = ApiErrorLogConvert.INSTANCE.convert(createDTO) + .setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); apiErrorLogMapper.insert(apiErrorLog); } @@ -50,10 +52,10 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService { public void updateApiErrorLogProcess(Long id, Integer processStatus, Long processUserId) { ApiErrorLogDO errorLog = apiErrorLogMapper.selectById(id); if (errorLog == null) { - throw ServiceExceptionUtil.exception(ErrorCodeConstants.API_ERROR_LOG_NOT_FOUND); + throw exception(API_ERROR_LOG_NOT_FOUND); } if (!ApiErrorLogProcessStatusEnum.INIT.getStatus().equals(errorLog.getProcessStatus())) { - throw ServiceExceptionUtil.exception(ErrorCodeConstants.API_ERROR_LOG_PROCESSED); + throw exception(API_ERROR_LOG_PROCESSED); } // 标记处理 apiErrorLogMapper.updateById(ApiErrorLogDO.builder().id(id).processStatus(processStatus) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/test/TestDemoServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/test/TestDemoServiceImpl.java index 731a29ccc..70f2ebc5d 100755 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/test/TestDemoServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/test/TestDemoServiceImpl.java @@ -45,7 +45,7 @@ public class TestDemoServiceImpl implements TestDemoService { @CacheEvict(value = "test", key = "#updateReqVO.id") public void updateTestDemo(TestDemoUpdateReqVO updateReqVO) { // 校验存在 - this.validateTestDemoExists(updateReqVO.getId()); + validateTestDemoExists(updateReqVO.getId()); // 更新 TestDemoDO updateObj = TestDemoConvert.INSTANCE.convert(updateReqVO); testDemoMapper.updateById(updateObj); @@ -55,7 +55,7 @@ public class TestDemoServiceImpl implements TestDemoService { @CacheEvict(value = "test", key = "#id") public void deleteTestDemo(Long id) { // 校验存在 - this.validateTestDemoExists(id); + validateTestDemoExists(id); // 删除 testDemoMapper.deleteById(id); } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm index 85dfa0aab..a732039ce 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm @@ -39,7 +39,7 @@ public class ${table.className}ServiceImpl implements ${table.className}Service @Override public void update${simpleClassName}(${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) { // 校验存在 - this.validate${simpleClassName}Exists(updateReqVO.getId()); + validate${simpleClassName}Exists(updateReqVO.getId()); // 更新 ${table.className}DO updateObj = ${table.className}Convert.INSTANCE.convert(updateReqVO); ${classNameVar}Mapper.updateById(updateObj); @@ -48,7 +48,7 @@ public class ${table.className}ServiceImpl implements ${table.className}Service @Override public void delete${simpleClassName}(${primaryColumn.javaType} id) { // 校验存在 - this.validate${simpleClassName}Exists(id); + validate${simpleClassName}Exists(id); // 删除 ${classNameVar}Mapper.deleteById(id); } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/test/serviceTest.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/test/serviceTest.vm index e97fbb275..67a44e989 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/test/serviceTest.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/test/serviceTest.vm @@ -52,7 +52,7 @@ import static org.mockito.Mockito.*; #if (${column.listOperation}) #set ($JavaField = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})##首字母大写 #if (${column.listOperationCondition} == "BETWEEN")## BETWEEN 的情况 - reqVO.set${JavaField}((new LocalDateTime[]{})); + reqVO.set${JavaField}(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); #else reqVO.set$JavaField(null); #end diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImplTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImplTest.java index b650fb603..8ff2dd9bf 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImplTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImplTest.java @@ -1,12 +1,9 @@ package cn.iocoder.yudao.module.infra.service.logger; -import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.framework.test.core.util.RandomUtils; import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO; import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogExportReqVO; import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO; @@ -16,149 +13,121 @@ import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.List; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; @Import(ApiAccessLogServiceImpl.class) public class ApiAccessLogServiceImplTest extends BaseDbUnitTest { @Resource - private ApiAccessLogService apiAccessLogService; + private ApiAccessLogServiceImpl apiAccessLogService; @Resource private ApiAccessLogMapper apiAccessLogMapper; @Test public void testGetApiAccessLogPage() { - // 构造测试数据 - long userId = 2233L; - int userType = UserTypeEnum.ADMIN.getValue(); - String applicationName = "yudao-test"; - String requestUrl = "foo"; - LocalDateTime beginTime = buildTime(2021, 3, 13); - int duration = 1000; - int resultCode = GlobalErrorCodeConstants.SUCCESS.getCode(); - - ApiAccessLogDO infApiAccessLogDO = RandomUtils.randomPojo(ApiAccessLogDO.class, dto -> { - dto.setUserId(userId); - dto.setUserType(userType); - dto.setApplicationName(applicationName); - dto.setRequestUrl(requestUrl); - dto.setBeginTime(beginTime); - dto.setDuration(duration); - dto.setResultCode(resultCode); + ApiAccessLogDO apiAccessLogDO = randomPojo(ApiAccessLogDO.class, o -> { + o.setUserId(2233L); + o.setUserType(UserTypeEnum.ADMIN.getValue()); + o.setApplicationName("yudao-test"); + o.setRequestUrl("foo"); + o.setBeginTime(buildTime(2021, 3, 13)); + o.setDuration(1000); + o.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode()); }); - apiAccessLogMapper.insert(infApiAccessLogDO); - - // 下面几个都是不匹配的数据 - // userId 不同的 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setUserId(3344L))); - // userType - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); - // applicationName 不同的 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setApplicationName("test"))); - // requestUrl 不同的 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar"))); - // 构造一个早期时间 2021-02-06 00:00:00 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6)))); - // duration 不同的 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setDuration(100))); - // resultCode 不同的 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setResultCode(2))); - - // 构造调用参数 + apiAccessLogMapper.insert(apiAccessLogDO); + // 测试 userId 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setUserId(3344L))); + // 测试 userType 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setUserType(UserTypeEnum.MEMBER.getValue()))); + // 测试 applicationName 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setApplicationName("test"))); + // 测试 requestUrl 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setRequestUrl("bar"))); + // 测试 beginTime 不匹配:构造一个早期时间 2021-02-06 00:00:00 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setBeginTime(buildTime(2021, 2, 6)))); + // 测试 duration 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setDuration(100))); + // 测试 resultCode 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setResultCode(2))); + // 准备参数 ApiAccessLogPageReqVO reqVO = new ApiAccessLogPageReqVO(); - reqVO.setUserId(userId); - reqVO.setUserType(userType); - reqVO.setApplicationName(applicationName); - reqVO.setRequestUrl(requestUrl); - reqVO.setBeginTime((new LocalDateTime[]{buildTime(2021, 3, 12),buildTime(2021, 3, 14)})); - reqVO.setDuration(duration); - reqVO.setResultCode(resultCode); + reqVO.setUserId(2233L); + reqVO.setUserType(UserTypeEnum.ADMIN.getValue()); + reqVO.setApplicationName("yudao-test"); + reqVO.setRequestUrl("foo"); + reqVO.setBeginTime(buildBetweenTime(2021, 3, 13, 2021, 3, 13)); + reqVO.setDuration(1000); + reqVO.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode()); - // 调用service方法 + // 调用 PageResult pageResult = apiAccessLogService.getApiAccessLogPage(reqVO); - // 断言,只查到了一条符合条件的 assertEquals(1, pageResult.getTotal()); assertEquals(1, pageResult.getList().size()); - assertPojoEquals(infApiAccessLogDO, pageResult.getList().get(0)); + assertPojoEquals(apiAccessLogDO, pageResult.getList().get(0)); } @Test public void testGetApiAccessLogList() { - // 构造测试数据 - long userId = 2233L; - int userType = UserTypeEnum.ADMIN.getValue(); - String applicationName = "yudao-test"; - String requestUrl = "foo"; - LocalDateTime beginTime = buildTime(2021, 3, 13); - int duration = 1000; - int resultCode = GlobalErrorCodeConstants.SUCCESS.getCode(); - - ApiAccessLogDO infApiAccessLogDO = RandomUtils.randomPojo(ApiAccessLogDO.class, dto -> { - dto.setUserId(userId); - dto.setUserType(userType); - dto.setApplicationName(applicationName); - dto.setRequestUrl(requestUrl); - dto.setBeginTime(beginTime); - dto.setDuration(duration); - dto.setResultCode(resultCode); + ApiAccessLogDO apiAccessLogDO = randomPojo(ApiAccessLogDO.class, o -> { + o.setUserId(2233L); + o.setUserType(UserTypeEnum.ADMIN.getValue()); + o.setApplicationName("yudao-test"); + o.setRequestUrl("foo"); + o.setBeginTime(buildTime(2021, 3, 13)); + o.setDuration(1000); + o.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode()); }); - apiAccessLogMapper.insert(infApiAccessLogDO); - - // 下面几个都是不匹配的数据 - // userId 不同的 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setUserId(3344L))); - // userType - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); - // applicationName 不同的 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setApplicationName("test"))); - // requestUrl 不同的 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar"))); - // 构造一个早期时间 2021-02-06 00:00:00 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6)))); - // duration 不同的 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setDuration(100))); - // resultCode 不同的 - apiAccessLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiAccessLogDO, logDO -> logDO.setResultCode(2))); - - // 构造调用参数 + apiAccessLogMapper.insert(apiAccessLogDO); + // 测试 userId 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setUserId(3344L))); + // 测试 userType 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setUserType(UserTypeEnum.MEMBER.getValue()))); + // 测试 applicationName 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setApplicationName("test"))); + // 测试 requestUrl 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setRequestUrl("bar"))); + // 测试 beginTime 不匹配:构造一个早期时间 2021-02-06 00:00:00 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setBeginTime(buildTime(2021, 2, 6)))); + // 测试 duration 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setDuration(100))); + // 测试 resultCode 不匹配 + apiAccessLogMapper.insert(cloneIgnoreId(apiAccessLogDO, o -> o.setResultCode(2))); + // 准备参数 ApiAccessLogExportReqVO reqVO = new ApiAccessLogExportReqVO(); - reqVO.setUserId(userId); - reqVO.setUserType(userType); - reqVO.setApplicationName(applicationName); - reqVO.setRequestUrl(requestUrl); - reqVO.setBeginTime((new LocalDateTime[]{buildTime(2021, 3, 12),buildTime(2021, 3, 14)})); - reqVO.setDuration(duration); - reqVO.setResultCode(resultCode); + reqVO.setUserId(2233L); + reqVO.setUserType(UserTypeEnum.ADMIN.getValue()); + reqVO.setApplicationName("yudao-test"); + reqVO.setRequestUrl("foo"); + reqVO.setBeginTime(buildBetweenTime(2021, 3, 13, 2021, 3, 13)); + reqVO.setDuration(1000); + reqVO.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode()); - // 调用service方法 + // 调用 List list = apiAccessLogService.getApiAccessLogList(reqVO); - // 断言,只查到了一条符合条件的 assertEquals(1, list.size()); - assertPojoEquals(infApiAccessLogDO, list.get(0)); + assertPojoEquals(apiAccessLogDO, list.get(0)); } @Test - public void testCreateApiAccessLogAsync() { + public void testCreateApiAccessLog() { // 准备参数 - ApiAccessLogCreateReqDTO createDTO = RandomUtils.randomPojo(ApiAccessLogCreateReqDTO.class, - dto -> dto.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue())); + ApiAccessLogCreateReqDTO createDTO = randomPojo(ApiAccessLogCreateReqDTO.class); // 调用 apiAccessLogService.createApiAccessLog(createDTO); // 断言 - ApiAccessLogDO infApiAccessLogDO = apiAccessLogMapper.selectOne(null); - assertNotNull(infApiAccessLogDO); - assertPojoEquals(createDTO, infApiAccessLogDO); + ApiAccessLogDO apiAccessLogDO = apiAccessLogMapper.selectOne(null); + assertPojoEquals(createDTO, apiAccessLogDO); } - } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImplTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImplTest.java index 4e35ba7ea..86e55f5d1 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImplTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImplTest.java @@ -1,28 +1,28 @@ package cn.iocoder.yudao.module.infra.service.logger; -import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.framework.test.core.util.RandomUtils; import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO; import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogExportReqVO; import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO; import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO; import cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper; import cn.iocoder.yudao.module.infra.enums.logger.ApiErrorLogProcessStatusEnum; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.List; +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.API_ERROR_LOG_NOT_FOUND; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.API_ERROR_LOG_PROCESSED; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -35,161 +35,150 @@ public class ApiErrorLogServiceImplTest extends BaseDbUnitTest { private ApiErrorLogServiceImpl apiErrorLogService; @Resource - private ApiErrorLogMapper infApiErrorLogMapper; + private ApiErrorLogMapper apiErrorLogMapper; @Test public void testGetApiErrorLogPage() { - // 构造测试数据 - long userId = 2233L; - int userType = UserTypeEnum.ADMIN.getValue(); - String applicationName = "yudao-test"; - String requestUrl = "foo"; - LocalDateTime beginTime = buildTime(2021, 3, 13); - int progressStatus = ApiErrorLogProcessStatusEnum.INIT.getStatus(); - - ApiErrorLogDO infApiErrorLogDO = RandomUtils.randomPojo(ApiErrorLogDO.class, logDO -> { - logDO.setUserId(userId); - logDO.setUserType(userType); - logDO.setApplicationName(applicationName); - logDO.setRequestUrl(requestUrl); - logDO.setExceptionTime(beginTime); - logDO.setProcessStatus(progressStatus); + // mock 数据 + ApiErrorLogDO apiErrorLogDO = randomPojo(ApiErrorLogDO.class, o -> { + o.setUserId(2233L); + o.setUserType(UserTypeEnum.ADMIN.getValue()); + o.setApplicationName("yudao-test"); + o.setRequestUrl("foo"); + o.setExceptionTime(buildTime(2021, 3, 13)); + o.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); }); - infApiErrorLogMapper.insert(infApiErrorLogDO); - - // 下面几个都是不匹配的数据 - // userId 不同的 - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setUserId(3344L))); - // userType - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); - // applicationName 不同的 - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setApplicationName("test"))); - // requestUrl 不同的 - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar"))); - // 构造一个早期时间 2021-02-06 00:00:00 - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6)))); - // progressStatus 不同的 - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setProcessStatus(ApiErrorLogProcessStatusEnum.DONE.getStatus()))); - - // 构造调用参数 + apiErrorLogMapper.insert(apiErrorLogDO); + // 测试 userId 不匹配 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setUserId(3344L))); + // 测试 userType 不匹配 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); + // 测试 applicationName 不匹配 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setApplicationName("test"))); + // 测试 requestUrl 不匹配 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setRequestUrl("bar"))); + // 测试 exceptionTime 不匹配:构造一个早期时间 2021-02-06 00:00:00 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6)))); + // 测试 progressStatus 不匹配 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setProcessStatus(ApiErrorLogProcessStatusEnum.DONE.getStatus()))); + // 准备参数 ApiErrorLogPageReqVO reqVO = new ApiErrorLogPageReqVO(); - reqVO.setUserId(userId); - reqVO.setUserType(userType); - reqVO.setApplicationName(applicationName); - reqVO.setRequestUrl(requestUrl); - reqVO.setExceptionTime((new LocalDateTime[]{buildTime(2021, 3, 12),buildTime(2021, 3, 14)})); - reqVO.setProcessStatus(progressStatus); + reqVO.setUserId(2233L); + reqVO.setUserType(UserTypeEnum.ADMIN.getValue()); + reqVO.setApplicationName("yudao-test"); + reqVO.setRequestUrl("foo"); + reqVO.setExceptionTime(buildBetweenTime(2021, 3, 1, 2021, 3, 31)); + reqVO.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); - // 调用service方法 + // 调用 PageResult pageResult = apiErrorLogService.getApiErrorLogPage(reqVO); - // 断言,只查到了一条符合条件的 assertEquals(1, pageResult.getTotal()); assertEquals(1, pageResult.getList().size()); - assertPojoEquals(infApiErrorLogDO, pageResult.getList().get(0)); + assertPojoEquals(apiErrorLogDO, pageResult.getList().get(0)); } @Test public void testGetApiErrorLogList() { - // 构造测试数据 - long userId = 2233L; - int userType = UserTypeEnum.ADMIN.getValue(); - String applicationName = "yudao-test"; - String requestUrl = "foo"; - LocalDateTime beginTime = buildTime(2021, 3, 13); - int progressStatus = ApiErrorLogProcessStatusEnum.INIT.getStatus(); - - ApiErrorLogDO infApiErrorLogDO = RandomUtils.randomPojo(ApiErrorLogDO.class, logDO -> { - logDO.setUserId(userId); - logDO.setUserType(userType); - logDO.setApplicationName(applicationName); - logDO.setRequestUrl(requestUrl); - logDO.setExceptionTime(beginTime); - logDO.setProcessStatus(progressStatus); + // mock 数据 + ApiErrorLogDO apiErrorLogDO = randomPojo(ApiErrorLogDO.class, o -> { + o.setUserId(2233L); + o.setUserType(UserTypeEnum.ADMIN.getValue()); + o.setApplicationName("yudao-test"); + o.setRequestUrl("foo"); + o.setExceptionTime(buildTime(2021, 3, 13)); + o.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); }); - infApiErrorLogMapper.insert(infApiErrorLogDO); - - // 下面几个都是不匹配的数据 - // userId 不同的 - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setUserId(3344L))); - // userType - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); - // applicationName 不同的 - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setApplicationName("test"))); - // requestUrl 不同的 - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar"))); - // 构造一个早期时间 2021-02-06 00:00:00 - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6)))); - // progressStatus 不同的 - infApiErrorLogMapper.insert(ObjectUtils.cloneIgnoreId(infApiErrorLogDO, logDO -> logDO.setProcessStatus(ApiErrorLogProcessStatusEnum.DONE.getStatus()))); - - // 构造调用参数 + apiErrorLogMapper.insert(apiErrorLogDO); + // 测试 userId 不匹配 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, o -> o.setUserId(3344L))); + // 测试 userType 不匹配 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); + // 测试 applicationName 不匹配 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setApplicationName("test"))); + // 测试 requestUrl 不匹配 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setRequestUrl("bar"))); + // 测试 exceptionTime 不匹配:构造一个早期时间 2021-02-06 00:00:00 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6)))); + // 测试 progressStatus 不匹配 + apiErrorLogMapper.insert(cloneIgnoreId(apiErrorLogDO, logDO -> logDO.setProcessStatus(ApiErrorLogProcessStatusEnum.DONE.getStatus()))); + // 准备参数 ApiErrorLogExportReqVO reqVO = new ApiErrorLogExportReqVO(); - reqVO.setUserId(userId); - reqVO.setUserType(userType); - reqVO.setApplicationName(applicationName); - reqVO.setRequestUrl(requestUrl); - reqVO.setExceptionTime((new LocalDateTime[]{buildTime(2021, 3, 12),buildTime(2021, 3, 14)})); - reqVO.setProcessStatus(progressStatus); + reqVO.setUserId(2233L); + reqVO.setUserType(UserTypeEnum.ADMIN.getValue()); + reqVO.setApplicationName("yudao-test"); + reqVO.setRequestUrl("foo"); + reqVO.setExceptionTime(buildBetweenTime(2021, 3, 1, 2021, 3, 31)); + reqVO.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); - // 调用service方法 + // 调用 List list = apiErrorLogService.getApiErrorLogList(reqVO); - // 断言,只查到了一条符合条件的 assertEquals(1, list.size()); - assertPojoEquals(infApiErrorLogDO, list.get(0)); - } - - - // TODO 芋艿:单元测试,可以拆小一点 - @Test - public void testUpdateApiErrorLogProcess() { - // 先构造两条数据,第一条用于抛出异常,第二条用于正常的执行update操作 - Long processUserId = 2233L; - - ApiErrorLogDO first = RandomUtils.randomPojo(ApiErrorLogDO.class, logDO -> { - logDO.setProcessUserId(processUserId); - logDO.setUserType(UserTypeEnum.ADMIN.getValue()); - logDO.setProcessStatus(ApiErrorLogProcessStatusEnum.DONE.getStatus()); - }); - infApiErrorLogMapper.insert(first); - - ApiErrorLogDO second = RandomUtils.randomPojo(ApiErrorLogDO.class, logDO -> { - logDO.setProcessUserId(1122L); - logDO.setUserType(UserTypeEnum.ADMIN.getValue()); - logDO.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); - }); - infApiErrorLogMapper.insert(second); - - Long firstId = first.getId(); - Long secondId = second.getId(); - - // 执行正常的 update 操作 - apiErrorLogService.updateApiErrorLogProcess(secondId, ApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId); - ApiErrorLogDO secondSelect = infApiErrorLogMapper.selectOne("id", secondId); - - // id 为 0 查询不到,应该抛出异常 API_ERROR_LOG_NOT_FOUND - assertServiceException(() -> apiErrorLogService.updateApiErrorLogProcess(0L, ApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId), API_ERROR_LOG_NOT_FOUND); - // id 为 first 的 progressStatus 为 DONE ,应该抛出 API_ERROR_LOG_PROCESSED - assertServiceException(() -> apiErrorLogService.updateApiErrorLogProcess(firstId, ApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId), API_ERROR_LOG_PROCESSED); - // 验证 progressStatus 是否修改成功 - Assertions.assertEquals(ApiErrorLogProcessStatusEnum.DONE.getStatus(), secondSelect.getProcessStatus()); - // 验证 progressUserId 是否修改成功 - Assertions.assertEquals(processUserId, secondSelect.getProcessUserId()); + assertPojoEquals(apiErrorLogDO, list.get(0)); } @Test - public void testCreateApiErrorLogAsync() { + public void testCreateApiErrorLog() { // 准备参数 - ApiErrorLogCreateReqDTO createDTO = RandomUtils.randomPojo(ApiErrorLogCreateReqDTO.class, - dto -> dto.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue())); + ApiErrorLogCreateReqDTO createDTO = randomPojo(ApiErrorLogCreateReqDTO.class); // 调用 apiErrorLogService.createApiErrorLog(createDTO); // 断言 - ApiErrorLogDO infApiErrorLogDO = infApiErrorLogMapper.selectOne(null); - assertNotNull(infApiErrorLogDO); - assertPojoEquals(createDTO, infApiErrorLogDO); + ApiErrorLogDO apiErrorLogDO = apiErrorLogMapper.selectOne(null); + assertPojoEquals(createDTO, apiErrorLogDO); + assertEquals(ApiErrorLogProcessStatusEnum.INIT.getStatus(), apiErrorLogDO.getProcessStatus()); + } + + @Test + public void testUpdateApiErrorLogProcess_success() { + // 准备参数 + ApiErrorLogDO apiErrorLogDO = randomPojo(ApiErrorLogDO.class, + o -> o.setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus())); + apiErrorLogMapper.insert(apiErrorLogDO); + // 准备参数 + Long id = apiErrorLogDO.getId(); + Integer processStatus = randomEle(ApiErrorLogProcessStatusEnum.values()).getStatus(); + Long processUserId = randomLongId(); + + // 调用 + apiErrorLogService.updateApiErrorLogProcess(id, processStatus, processUserId); + // 断言 + ApiErrorLogDO dbApiErrorLogDO = apiErrorLogMapper.selectById(apiErrorLogDO.getId()); + assertEquals(processStatus, dbApiErrorLogDO.getProcessStatus()); + assertEquals(processUserId, dbApiErrorLogDO.getProcessUserId()); + assertNotNull(dbApiErrorLogDO.getProcessTime()); + } + + @Test + public void testUpdateApiErrorLogProcess_processed() { + // 准备参数 + ApiErrorLogDO apiErrorLogDO = randomPojo(ApiErrorLogDO.class, + o -> o.setProcessStatus(ApiErrorLogProcessStatusEnum.DONE.getStatus())); + apiErrorLogMapper.insert(apiErrorLogDO); + // 准备参数 + Long id = apiErrorLogDO.getId(); + Integer processStatus = randomEle(ApiErrorLogProcessStatusEnum.values()).getStatus(); + Long processUserId = randomLongId(); + + // 调用,并断言异常 + assertServiceException(() -> + apiErrorLogService.updateApiErrorLogProcess(id, processStatus, processUserId), + API_ERROR_LOG_PROCESSED); + } + + @Test + public void testUpdateApiErrorLogProcess_notFound() { + // 准备参数 + Long id = randomLongId(); + Integer processStatus = randomEle(ApiErrorLogProcessStatusEnum.values()).getStatus(); + Long processUserId = randomLongId(); + + // 调用,并断言异常 + assertServiceException(() -> + apiErrorLogService.updateApiErrorLogProcess(id, processStatus, processUserId), + API_ERROR_LOG_NOT_FOUND); } } From 0ff786d0eadc86f03e0a661901c23b62fd9713f7 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 09:15:46 +0800 Subject: [PATCH 55/59] =?UTF-8?q?infra=EF=BC=9A=E6=A0=87=E5=87=86=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 --- .../infra/dal/mysql/job/JobLogMapper.java | 30 +++++++++---------- .../service/codegen/CodegenServiceImpl.java | 6 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/job/JobLogMapper.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/job/JobLogMapper.java index fe196df35..c467498bf 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/job/JobLogMapper.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/job/JobLogMapper.java @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.infra.dal.mysql.job; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogExportReqVO; import cn.iocoder.yudao.module.infra.controller.admin.job.vo.log.JobLogPageReqVO; import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobLogDO; @@ -19,24 +19,24 @@ import java.util.List; public interface JobLogMapper extends BaseMapperX { default PageResult selectPage(JobLogPageReqVO reqVO) { - return selectPage(reqVO, new QueryWrapperX() - .eqIfPresent("job_id", reqVO.getJobId()) - .likeIfPresent("handler_name", reqVO.getHandlerName()) - .geIfPresent("begin_time", reqVO.getBeginTime()) - .leIfPresent("end_time", reqVO.getEndTime()) - .eqIfPresent("status", reqVO.getStatus()) - .orderByDesc("id") // ID 倒序 + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(JobLogDO::getJobId, reqVO.getJobId()) + .likeIfPresent(JobLogDO::getHandlerName, reqVO.getHandlerName()) + .geIfPresent(JobLogDO::getBeginTime, reqVO.getBeginTime()) + .leIfPresent(JobLogDO::getEndTime, reqVO.getEndTime()) + .eqIfPresent(JobLogDO::getStatus, reqVO.getStatus()) + .orderByDesc(JobLogDO::getId) // ID 倒序 ); } default List selectList(JobLogExportReqVO reqVO) { - return selectList(new QueryWrapperX() - .eqIfPresent("job_id", reqVO.getJobId()) - .likeIfPresent("handler_name", reqVO.getHandlerName()) - .geIfPresent("begin_time", reqVO.getBeginTime()) - .leIfPresent("end_time", reqVO.getEndTime()) - .eqIfPresent("status", reqVO.getStatus()) - .orderByDesc("id") // ID 倒序 + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(JobLogDO::getJobId, reqVO.getJobId()) + .likeIfPresent(JobLogDO::getHandlerName, reqVO.getHandlerName()) + .geIfPresent(JobLogDO::getBeginTime, reqVO.getBeginTime()) + .leIfPresent(JobLogDO::getEndTime, reqVO.getEndTime()) + .eqIfPresent(JobLogDO::getStatus, reqVO.getStatus()) + .orderByDesc(JobLogDO::getId) // ID 倒序 ); } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java index 3b693eb50..e3a352b8b 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java @@ -76,7 +76,7 @@ public class CodegenServiceImpl implements CodegenService { private Long createCodegen0(Long userId, Long dataSourceConfigId, TableInfo tableInfo) { // 校验导入的表和字段非空 - checkTableInfo(tableInfo); + validateTableInfo(tableInfo); // 校验是否已经存在 if (codegenTableMapper.selectByTableNameAndDataSourceConfigId(tableInfo.getName(), dataSourceConfigId) != null) { @@ -100,7 +100,7 @@ public class CodegenServiceImpl implements CodegenService { return table.getId(); } - private void checkTableInfo(TableInfo tableInfo) { + private void validateTableInfo(TableInfo tableInfo) { if (tableInfo == null) { throw exception(CODEGEN_IMPORT_TABLE_NULL); } @@ -149,7 +149,7 @@ public class CodegenServiceImpl implements CodegenService { private void syncCodegen0(Long tableId, TableInfo tableInfo) { // 校验导入的表和字段非空 - checkTableInfo(tableInfo); + validateTableInfo(tableInfo); List tableFields = tableInfo.getFields(); // 构建 CodegenColumnDO 数组,只同步新增的字段 From ba4e90b5298c81977a462f360763ddeb88d76a37 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 09:57:18 +0800 Subject: [PATCH 56/59] =?UTF-8?q?infra=EF=BC=9A=E5=AE=8C=E5=96=84=20Databa?= =?UTF-8?q?seTableServiceImpl=20=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dataobject/codegen/CodegenColumnDO.java | 17 +++- .../dataobject/codegen/CodegenTableDO.java | 5 ++ .../service/db/DatabaseTableServiceImpl.java | 2 +- .../db/DatabaseTableServiceImplTest.java | 89 +++++++++++++++++++ .../src/test/resources/sql/create_tables.sql | 4 +- 5 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImplTest.java diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenColumnDO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenColumnDO.java index f1990f3fc..368162214 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenColumnDO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenColumnDO.java @@ -39,27 +39,38 @@ public class CodegenColumnDO extends BaseDO { /** * 字段名 + * + * 关联 {@link TableField#getName()} */ private String columnName; /** * 数据库字段类型 + * * 关联 {@link TableField.MetaInfo#getJdbcType()} */ private String dataType; /** * 字段描述 + * + * 关联 {@link TableField#getComment()} */ private String columnComment; /** * 是否允许为空 + * + * 关联 {@link TableField.MetaInfo#isNullable()} */ private Boolean nullable; /** * 是否主键 + * + * 关联 {@link TableField#isKeyFlag()} */ private Boolean primaryKey; /** * 是否自增 + * + * 关联 {@link TableField#isKeyIdentityFlag()} */ private Boolean autoIncrement; /** @@ -71,12 +82,16 @@ public class CodegenColumnDO extends BaseDO { /** * Java 属性类型 - *

+ * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + /** + * 库存 + */ + private Integer stock; + /** + * 预警预存 + */ + private Integer warnStock; + /** + * 商品重量,单位:kg 千克 + */ + private Double weight; + /** + * 商品体积,单位:m^3 平米 + */ + private Double volume; + + /** + * 商品属性 + */ + @Data + public static class Property { + + /** + * 属性编号 + */ + private Long propertyId; + /** + * 属性值编号 + */ + private Long valueId; + + } + + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuUpdateStockReqDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuUpdateStockReqDTO.java new file mode 100644 index 000000000..345c17cbd --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuUpdateStockReqDTO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.product.api.sku.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 商品 SKU 更新库存 Request DTO + * + * @author LeeYan9 + * @since 2022-08-26 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ProductSkuUpdateStockReqDTO { + + /** + * 商品 SKU + */ + @NotNull(message = "商品 SKU 不能为空") + private List items; + + @Data + public static class Item { + + /** + * 商品 SKU 编号 + */ + @NotNull(message = "商品 SKU 编号不能为空") + private Long id; + + /** + * 库存变化数量 + * + * 正数:增加库存 + * 负数:扣减库存 + */ + @NotNull(message = "库存变化数量不能为空") + private Integer incrCount; + + } + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java new file mode 100644 index 000000000..8ba0fba7d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.product.api.spu; + +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; + +import java.util.Collection; +import java.util.List; + +/** + * 商品 SPU API 接口 + * + * @author LeeYan9 + * @since 2022-08-26 + */ +public interface ProductSpuApi { + + /** + * 批量查询 SPU 数组 + * + * @param ids SPU 编号列表 + * @return SPU 数组 + */ + List getSpuList(Collection ids); + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java new file mode 100644 index 000000000..45d42f41b --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java @@ -0,0 +1,127 @@ +package cn.iocoder.yudao.module.product.api.spu.dto; + +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import lombok.Data; + +import java.util.List; + +// TODO @LeeYan9: ProductSpuRespDTO +/** + * 商品 SPU 信息 Response DTO + * + * @author LeeYan9 + * @since 2022-08-26 + */ +@Data +public class ProductSpuRespDTO { + + /** + * 商品 SPU 编号,自增 + */ + private Long id; + + // ========== 基本信息 ========= + + /** + * 商品名称 + */ + private String name; + /** + * 商品编码 + */ + private String code; + /** + * 促销语 + */ + private String sellPoint; + /** + * 商品详情 + */ + private String description; + /** + * 商品分类编号 + */ + private Long categoryId; + /** + * 商品品牌编号 + */ + private Long brandId; + /** + * 商品图片的数组 + *

+ * 1. 第一张图片将作为商品主图,支持同时上传多张图; + * 2. 建议使用尺寸 800x800 像素以上、大小不超过 1M 的正方形图片; + * 3. 至少 1 张,最多上传 10 张 + */ + private List picUrls; + /** + * 商品视频 + */ + private String videoUrl; + + /** + * 排序字段 + */ + private Integer sort; + /** + * 商品状态 + *

+ * 枚举 {@link ProductSpuStatusEnum} + */ + private Integer status; + + // ========== SKU 相关字段 ========= + + /** + * 规格类型 + *

+ * 枚举 {@link ProductSpuSpecTypeEnum} + */ + private Integer specType; + /** + * 最小价格,单位使用:分 + *

+ * 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最小值 + */ + private Integer minPrice; + /** + * 最大价格,单位使用:分 + *

+ * 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最大值 + */ + private Integer maxPrice; + /** + * 市场价,单位使用:分 + *

+ * 基于其对应的 {@link ProductSkuRespDTO#getMarketPrice()} 最大值 + */ + private Integer marketPrice; + /** + * 总库存 + *

+ * 基于其对应的 {@link ProductSkuRespDTO#getStock()} 求和 + */ + private Integer totalStock; + /** + * 是否展示库存 + */ + private Boolean showStock; + + // ========== 统计相关字段 ========= + + /** + * 商品销量 + */ + private Integer salesCount; + /** + * 虚拟销量 + */ + private Integer virtualSalesCount; + /** + * 商品点击量 + */ + private Integer clickCount; + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java new file mode 100644 index 000000000..4adad0afc --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.product.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * Product 错误码枚举类 + * + * product 系统,使用 1-008-000-000 段 + */ +public interface ErrorCodeConstants { + + // ========== 商品分类相关 1008001000 ============ + ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在"); + ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在"); + ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类"); + ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除"); + ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用"); + + // ========== 商品品牌相关编号 1008002000 ========== + ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在"); + ErrorCode BRAND_DISABLED = new ErrorCode(1008002001, "品牌不存在"); + ErrorCode BRAND_NAME_EXISTS = new ErrorCode(1008002002, "品牌名称已存在"); + + // ========== 商品属性项 1008003000 ========== + ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "属性项不存在"); + ErrorCode PROPERTY_EXISTS = new ErrorCode(1008003001, "属性项的名称已存在"); + ErrorCode PROPERTY_DELETE_FAIL_VALUE_EXISTS = new ErrorCode(1008003002, "属性项下存在属性值,无法删除"); + + // ========== 商品属性值 1008004000 ========== + ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "属性值不存在"); + ErrorCode PROPERTY_VALUE_EXISTS = new ErrorCode(1008004001, "属性值的名称已存在"); + + // ========== 商品 SPU 1008005000 ========== + ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在"); + ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第三级的商品分类下"); + ErrorCode SPU_NOT_ENABLE = new ErrorCode(1008005002, "商品 SPU 不处于上架状态"); + + // ========== 商品 SKU 1008006000 ========== + ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在"); + ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1008006001, "商品 SKU 的属性组合存在重复"); + ErrorCode SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1008006002, "一个 SPU 下的每个 SKU,其属性项必须一致"); + ErrorCode SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU,必须不重复"); + ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足"); + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentAuditStatusEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentAuditStatusEnum.java new file mode 100644 index 000000000..276839daf --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentAuditStatusEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.product.enums.comment; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 商品评论的审批状态枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum ProductCommentAuditStatusEnum implements IntArrayValuable { + + NONE(1, "待审核"), + APPROVE(2, "审批通过"), + REJECT(2, "审批不通过"),; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductCommentAuditStatusEnum::getStatus).toArray(); + + /** + * 审批状态 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java new file mode 100644 index 000000000..da322ff24 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.product.enums.delivery; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 配送方式枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum DeliveryTypeEnum implements IntArrayValuable { + + // TODO 芋艿:英文单词,需要再想下; + EXPRESS(1, "快递发货"), + USER(2, "用户自提"),; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeliveryTypeEnum::getMode).toArray(); + + /** + * 配送方式 + */ + private final Integer mode; + /** + * 状态名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java new file mode 100644 index 000000000..c5e55e8e4 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.product.enums.group; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 商品分组的样式枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum ProductGroupStyleEnum implements IntArrayValuable { + + ONE(1, "每列一个"), + TWO(2, "每列两个"), + THREE(2, "每列三个"),; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductGroupStyleEnum::getStyle).toArray(); + + /** + * 列表样式 + */ + private final Integer style; + /** + * 状态名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java new file mode 100644 index 000000000..fbc227b53 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.product.enums.spu; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 商品 SPU 规格类型 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum ProductSpuSpecTypeEnum implements IntArrayValuable { + + RECYCLE(1, "统一规格"), + DISABLE(2, "多规格"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuSpecTypeEnum::getType).toArray(); + + /** + * 规格类型 + */ + private final Integer type; + /** + * 规格名称 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java new file mode 100644 index 000000000..2223cf23d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.product.enums.spu; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 商品 SPU 状态 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum ProductSpuStatusEnum implements IntArrayValuable { + + RECYCLE(-1, "回收站"), + DISABLE(0, "下架"), + ENABLE(1, "上架"),; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuStatusEnum::getStatus).toArray(); + + /** + * 状态 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + + /** + * 判断是否处于【上架】状态 + * + * @param status 状态 + * @return 是否处于【上架】状态 + */ + public static boolean isEnable(Integer status) { + return ENABLE.getStatus().equals(status); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/pom.xml b/yudao-module-mall/yudao-module-product-biz/pom.xml new file mode 100644 index 000000000..e89ed105e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/pom.xml @@ -0,0 +1,62 @@ + + + + cn.iocoder.boot + yudao-module-mall + ${revision} + + 4.0.0 + yudao-module-product-biz + jar + + ${project.artifactId} + + product 模块,主要实现商品相关功能 + 例如:品牌、商品分类、spu、sku等功能。 + + + + + cn.iocoder.boot + yudao-module-product-api + ${revision} + + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-operatelog + + + + + cn.iocoder.boot + yudao-spring-boot-starter-web + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + + cn.iocoder.boot + yudao-spring-boot-starter-test + + + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + + + diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java new file mode 100644 index 000000000..162453c3c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.product.api; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java new file mode 100644 index 000000000..9aab9e560 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.product.api.property; + +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; +import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +/** + * 商品属性值 API 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class ProductPropertyValueApiImpl implements ProductPropertyValueApi { + + @Resource + private ProductPropertyValueService productPropertyValueService; + + @Override + public List getPropertyValueDetailList(Collection ids) { + return ProductPropertyValueConvert.INSTANCE.convertList02( + productPropertyValueService.getPropertyValueDetailList(ids)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java new file mode 100644 index 000000000..89913c70e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.product.api.sku; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * TODO LeeYan9: 类注释; + * @author LeeYan9 + * @since 2022-09-06 + */ +@Service +@Validated +public class ProductSkuApiImpl implements ProductSkuApi { + + @Resource + private ProductSkuService productSkuService; + + @Override + public ProductSkuRespDTO getSku(Long id) { + // TODO TODO LeeYan9: 需要实现 + return null; + } + + @Override + public List getSkuList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } + List skus = productSkuService.getSkuList(ids); + return ProductSkuConvert.INSTANCE.convertList04(skus); + } + + @Override + public void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO) { + productSkuService.updateSkuStock(updateStockReqDTO); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java new file mode 100644 index 000000000..4d880e662 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.product.api.spu; + +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * TODO LeeYan9: 类注释; + * + * @author LeeYan9 + * @since 2022-09-06 + */ +@Service +@Validated +public class ProductSpuApiImpl implements ProductSpuApi { + + @Resource + private ProductSpuMapper productSpuMapper; + + @Override + public List getSpuList(Collection spuIds) { + // TODO TODO LeeYan9: AllEmpty? + if (CollectionUtils.isAnyEmpty(spuIds)) { + return Collections.emptyList(); + } + List productSpuDOList = productSpuMapper.selectBatchIds(spuIds); + return ProductSpuConvert.INSTANCE.convertList2(productSpuDOList); + } +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java new file mode 100644 index 000000000..0e6f7f3bc --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.product.controller.admin.brand; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*; +import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; +import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Comparator; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 商品品牌") +@RestController +@RequestMapping("/product/brand") +@Validated +public class ProductBrandController { + + @Resource + private ProductBrandService brandService; + + @PostMapping("/create") + @Operation(summary = "创建品牌") + @PreAuthorize("@ss.hasPermission('product:brand:create')") + public CommonResult createBrand(@Valid @RequestBody ProductBrandCreateReqVO createReqVO) { + return success(brandService.createBrand(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新品牌") + @PreAuthorize("@ss.hasPermission('product:brand:update')") + public CommonResult updateBrand(@Valid @RequestBody ProductBrandUpdateReqVO updateReqVO) { + brandService.updateBrand(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除品牌") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('product:brand:delete')") + public CommonResult deleteBrand(@RequestParam("id") Long id) { + brandService.deleteBrand(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得品牌") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('product:brand:query')") + public CommonResult getBrand(@RequestParam("id") Long id) { + ProductBrandDO brand = brandService.getBrand(id); + return success(ProductBrandConvert.INSTANCE.convert(brand)); + } + + @GetMapping("/page") + @Operation(summary = "获得品牌分页") + @PreAuthorize("@ss.hasPermission('product:brand:query')") + public CommonResult> getBrandPage(@Valid ProductBrandPageReqVO pageVO) { + PageResult pageResult = brandService.getBrandPage(pageVO); + return success(ProductBrandConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/list") + @Operation(summary = "获得品牌列表") + @PreAuthorize("@ss.hasPermission('product:brand:query')") + public CommonResult> getBrandList(@Valid ProductBrandListReqVO listVO) { + List list = brandService.getBrandList(listVO); + list.sort(Comparator.comparing(ProductBrandDO::getSort)); + return success(ProductBrandConvert.INSTANCE.convertList(list)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java new file mode 100644 index 000000000..e8561fe07 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.product.controller.admin.brand.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** +* 商品品牌 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class ProductBrandBaseVO { + + @Schema(description = "品牌名称", required = true, example = "芋道") + @NotNull(message = "品牌名称不能为空") + private String name; + + @Schema(description = "品牌图片", required = true) + @NotNull(message = "品牌图片不能为空") + private String picUrl; + + @Schema(description = "品牌排序", required = true, example = "1") + @NotNull(message = "品牌排序不能为空") + private Integer sort; + + @Schema(description = "品牌描述", example = "描述") + private String description; + + @Schema(description = "状态", required = true, example = "0") + @NotNull(message = "状态不能为空") + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java new file mode 100644 index 000000000..dc85a476b --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.product.controller.admin.brand.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 商品品牌创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductBrandCreateReqVO extends ProductBrandBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java new file mode 100644 index 000000000..63305810c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.product.controller.admin.brand.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 商品品牌分页 Request VO") +@Data +public class ProductBrandListReqVO { + + @Schema(description = "品牌名称", example = "芋道") + private String name; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java new file mode 100644 index 000000000..81d470b1b --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.product.controller.admin.brand.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 商品品牌分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductBrandPageReqVO extends PageParam { + + @Schema(description = "品牌名称", example = "芋道") + private String name; + + @Schema(description = "状态", example = "0") + private Integer status; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @Schema(description = "创建时间") + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java new file mode 100644 index 000000000..b68fbc5be --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.product.controller.admin.brand.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 品牌 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductBrandRespVO extends ProductBrandBaseVO { + + @Schema(description = "品牌编号", required = true, example = "1") + private Long id; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java new file mode 100644 index 000000000..c01c3c4b7 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.product.controller.admin.brand.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 商品品牌更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductBrandUpdateReqVO extends ProductBrandBaseVO { + + @Schema(description = "品牌编号", required = true, example = "1") + @NotNull(message = "品牌编号不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java new file mode 100644 index 000000000..dc3a57a38 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.product.controller.admin.category; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Comparator; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 商品分类") +@RestController +@RequestMapping("/product/category") +@Validated +public class ProductCategoryController { + + @Resource + private ProductCategoryService categoryService; + + @PostMapping("/create") + @Operation(summary = "创建商品分类") + @PreAuthorize("@ss.hasPermission('product:category:create')") + public CommonResult createCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) { + return success(categoryService.createCategory(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新商品分类") + @PreAuthorize("@ss.hasPermission('product:category:update')") + public CommonResult updateCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) { + categoryService.updateCategory(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除商品分类") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('product:category:delete')") + public CommonResult deleteCategory(@RequestParam("id") Long id) { + categoryService.deleteCategory(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得商品分类") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('product:category:query')") + public CommonResult getCategory(@RequestParam("id") Long id) { + ProductCategoryDO category = categoryService.getCategory(id); + return success(ProductCategoryConvert.INSTANCE.convert(category)); + } + + @GetMapping("/list") + @Operation(summary = "获得商品分类列表") + @PreAuthorize("@ss.hasPermission('product:category:query')") + public CommonResult> getCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) { + List list = categoryService.getEnableCategoryList(treeListReqVO); + list.sort(Comparator.comparing(ProductCategoryDO::getSort)); + return success(ProductCategoryConvert.INSTANCE.convertList(list)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java new file mode 100644 index 000000000..5182bdadd --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** +* 商品分类 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class ProductCategoryBaseVO { + + @Schema(description = "父分类编号", required = true, example = "1") + @NotNull(message = "父分类编号不能为空") + private Long parentId; + + @Schema(description = "分类名称", required = true, example = "办公文具") + @NotBlank(message = "分类名称不能为空") + private String name; + + @Schema(description = "分类图片", required = true) + @NotBlank(message = "分类图片不能为空") + private String picUrl; + + @Schema(description = "分类排序", required = true, example = "1") + private Integer sort; + + @Schema(description = "分类描述", required = true, example = "描述") + private String description; + + @Schema(description = "开启状态", required = true, example = "0") + @NotNull(message = "开启状态不能为空") + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java new file mode 100644 index 000000000..f9b559776 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 商品分类创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java new file mode 100644 index 000000000..9c9439d3e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 商品分类列表查询 Request VO") +@Data +public class ProductCategoryListReqVO { + + @Schema(description = "分类名称", example = "办公文具") + private String name; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java new file mode 100644 index 000000000..484e0e51e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 商品分类 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductCategoryRespVO extends ProductCategoryBaseVO { + + @Schema(description = "分类编号", required = true, example = "2") + private Long id; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java new file mode 100644 index 000000000..15f663761 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 商品分类更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO { + + @Schema(description = "分类编号", required = true, example = "2") + @NotNull(message = "分类编号不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java new file mode 100644 index 000000000..bd063e0ec --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java @@ -0,0 +1,99 @@ +package cn.iocoder.yudao.module.product.controller.admin.property; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*; +import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Collections; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +@Tag(name = "管理后台 - 商品属性项") +@RestController +@RequestMapping("/product/property") +@Validated +public class ProductPropertyController { + + @Resource + private ProductPropertyService productPropertyService; + @Resource + private ProductPropertyValueService productPropertyValueService; + + @PostMapping("/create") + @Operation(summary = "创建属性项") + @PreAuthorize("@ss.hasPermission('product:property:create')") + public CommonResult createProperty(@Valid @RequestBody ProductPropertyCreateReqVO createReqVO) { + return success(productPropertyService.createProperty(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新属性项") + @PreAuthorize("@ss.hasPermission('product:property:update')") + public CommonResult updateProperty(@Valid @RequestBody ProductPropertyUpdateReqVO updateReqVO) { + productPropertyService.updateProperty(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除属性项") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('product:property:delete')") + public CommonResult deleteProperty(@RequestParam("id") Long id) { + productPropertyService.deleteProperty(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得属性项") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('product:property:query')") + public CommonResult getProperty(@RequestParam("id") Long id) { + return success(ProductPropertyConvert.INSTANCE.convert(productPropertyService.getProperty(id))); + } + + @GetMapping("/list") + @Operation(summary = "获得属性项列表") + @PreAuthorize("@ss.hasPermission('product:property:query')") + public CommonResult> getPropertyList(@Valid ProductPropertyListReqVO listReqVO) { + return success(ProductPropertyConvert.INSTANCE.convertList(productPropertyService.getPropertyList(listReqVO))); + } + + @GetMapping("/page") + @Operation(summary = "获得属性项分页") + @PreAuthorize("@ss.hasPermission('product:property:query')") + public CommonResult> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) { + return success(ProductPropertyConvert.INSTANCE.convertPage(productPropertyService.getPropertyPage(pageVO))); + } + + @GetMapping("/get-value-list") + @Operation(summary = "获得属性项列表") + @PreAuthorize("@ss.hasPermission('product:property:query')") + public CommonResult> getPropertyAndValueList(@Valid ProductPropertyListReqVO listReqVO) { + // 查询属性项 + List keys = productPropertyService.getPropertyList(listReqVO); + if (CollUtil.isEmpty(keys)) { + return success(Collections.emptyList()); + } + // 查询属性值 + List values = productPropertyValueService.getPropertyValueListByPropertyId( + convertSet(keys, ProductPropertyDO::getId)); + return success(ProductPropertyConvert.INSTANCE.convertList(keys, values)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java new file mode 100644 index 000000000..92ce6bee0 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.product.controller.admin.property; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; +import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 商品属性值") +@RestController +@RequestMapping("/product/property/value") +@Validated +public class ProductPropertyValueController { + + @Resource + private ProductPropertyValueService productPropertyValueService; + + @PostMapping("/create") + @Operation(summary = "创建属性值") + @PreAuthorize("@ss.hasPermission('product:property:create')") + public CommonResult createProperty(@Valid @RequestBody ProductPropertyValueCreateReqVO createReqVO) { + return success(productPropertyValueService.createPropertyValue(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新属性值") + @PreAuthorize("@ss.hasPermission('product:property:update')") + public CommonResult updateProperty(@Valid @RequestBody ProductPropertyValueUpdateReqVO updateReqVO) { + productPropertyValueService.updatePropertyValue(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除属性值") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('product:property:delete')") + public CommonResult deleteProperty(@RequestParam("id") Long id) { + productPropertyValueService.deletePropertyValue(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得属性值") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('product:property:query')") + public CommonResult getProperty(@RequestParam("id") Long id) { + return success(ProductPropertyValueConvert.INSTANCE.convert(productPropertyValueService.getPropertyValue(id))); + } + + @GetMapping("/page") + @Operation(summary = "获得属性值分页") + @PreAuthorize("@ss.hasPermission('product:property:query')") + public CommonResult> getPropertyValuePage(@Valid ProductPropertyValuePageReqVO pageVO) { + return success(ProductPropertyValueConvert.INSTANCE.convertPage(productPropertyValueService.getPropertyValuePage(pageVO))); + } +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java new file mode 100644 index 000000000..4be1bad18 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "管理后台 - 商品属性项 + 属性值 Response VO") +@Data +public class ProductPropertyAndValueRespVO { + + @Schema(description = "属性项的编号", required = true, example = "1024") + private Long id; + + @Schema(description = "属性项的名称", required = true, example = "颜色") + private String name; + + /** + * 属性值的集合 + */ + private List values; + + @Schema(description = "管理后台 - 属性值的简单 Response VO") + @Data + public static class Value { + + @Schema(description = "属性值的编号", required = true, example = "2048") + private Long id; + + @Schema(description = "属性值的名称", required = true, example = "红色") + private String name; + + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java new file mode 100644 index 000000000..1f05af4b2 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 商品属性项 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class ProductPropertyBaseVO { + + @Schema(description = "名称", required = true, example = "颜色") + @NotBlank(message = "名称不能为空") + private String name; + + @Schema(description = "备注", example = "颜色") + private String remark; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java new file mode 100644 index 000000000..b854dd73c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 属性项创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductPropertyCreateReqVO extends ProductPropertyBaseVO { + + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java new file mode 100644 index 000000000..242caff84 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.ToString; + +@Schema(description = "管理后台 - 属性项 List Request VO") +@Data +@ToString(callSuper = true) +public class ProductPropertyListReqVO { + + @Schema(description = "名称", example = "颜色") + private String name; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java new file mode 100644 index 000000000..d729880f0 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 属性项 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductPropertyPageReqVO extends PageParam { + + @Schema(description = "名称", example = "颜色") + private String name; + + @Schema(description = "状态", required = true, example = "1") + private Integer status; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @Schema(description = "创建时间") + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java new file mode 100644 index 000000000..b33e615fc --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 属性项 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductPropertyRespVO extends ProductPropertyBaseVO { + + @Schema(description = "编号", required = true, example = "1024") + private Long id; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java new file mode 100644 index 000000000..33ba8f2c1 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 属性项更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductPropertyUpdateReqVO extends ProductPropertyBaseVO { + + @Schema(description = "主键", required = true, example = "1") + @NotNull(message = "主键不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java new file mode 100644 index 000000000..da3bf5068 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** +* 属性值 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class ProductPropertyValueBaseVO { + + @Schema(description = "属性项的编号", required = true, example = "1024") + @NotNull(message = "属性项的编号不能为空") + private Long propertyId; + + @Schema(description = "名称", required = true, example = "红色") + @NotEmpty(message = "名称名字不能为空") + private String name; + + @Schema(description = "备注", example = "颜色") + private String remark; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java new file mode 100644 index 000000000..d3fe4d0f1 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 商品属性值创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductPropertyValueCreateReqVO extends ProductPropertyValueBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java new file mode 100644 index 000000000..56801cc7d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 商品属性值的明细 Response VO") +@Data +public class ProductPropertyValueDetailRespVO { + + @Schema(description = "属性的编号", required = true, example = "1") + private Long propertyId; + + @Schema(description = "属性的名称", required = true, example = "颜色") + private String propertyName; + + @Schema(description = "属性值的编号", required = true, example = "1024") + private Long valueId; + + @Schema(description = "属性值的名称", required = true, example = "红色") + private String valueName; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java new file mode 100644 index 000000000..a6088deb9 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 商品属性值分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductPropertyValuePageReqVO extends PageParam { + + @Schema(description = "属性项的编号", example = "1024") + private String propertyId; + + @Schema(description = "名称", example = "红色") + private String name; + + @Schema(description = "状态", required = true, example = "1") + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java new file mode 100644 index 000000000..dac075b86 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 商品属性值 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductPropertyValueRespVO extends ProductPropertyValueBaseVO { + + @Schema(description = "编号", required = true, example = "10") + private Long id; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java new file mode 100644 index 000000000..474a980b8 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 商品属性值更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductPropertyValueUpdateReqVO extends ProductPropertyValueBaseVO { + + @Schema(description = "主键", required = true, example = "1024") + @NotNull(message = "主键不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java new file mode 100755 index 000000000..038642db1 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.product.controller.admin.sku; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO; +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +@Tag(name = "管理后台 - 商品 sku") +@RestController +@RequestMapping("/product/sku") +@Validated +public class ProductSkuController { + + @Resource + private ProductSkuService productSkuService; + @Resource + private ProductSpuService productSpuService; + + @GetMapping("/get-option-list") + @Operation(summary = "获得商品 SKU 选项的列表") +// @PreAuthorize("@ss.hasPermission('product:sku:query')") + public CommonResult> getSkuOptionList() { + // 获得 SKU 列表 + List skus = productSkuService.getSkuList(); + if (CollUtil.isEmpty(skus)) { + return success(Collections.emptyList()); + } + + // 获得对应的 SPU 映射 + Map spuMap = productSpuService.getSpuMap(convertSet(skus, ProductSkuDO::getSpuId)); + // 转换为返回结果 + List skuVOs = ProductSkuConvert.INSTANCE.convertList05(skus); + skuVOs.forEach(sku -> MapUtils.findAndThen(spuMap, sku.getSpuId(), + spu -> sku.setSpuId(spu.getId()).setSpuName(spu.getName()))); + return success(skuVOs); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java new file mode 100755 index 000000000..f28220046 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.product.controller.admin.sku.vo; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** +* 商品 SKU Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class ProductSkuBaseVO { + + @Schema(description = "商品 SKU 名字", required = true, example = "芋道") + @NotEmpty(message = "商品 SKU 名字不能为空") + private String name; + + @Schema(description = "销售价格,单位:分", required = true, example = "1024") + @NotNull(message = "销售价格,单位:分不能为空") + private Integer price; + + @Schema(description = "市场价", example = "1024") + private Integer marketPrice; + + @Schema(description = "成本价", example = "1024") + private Integer costPrice; + + @Schema(description = "条形码", example = "haha") + private String barCode; + + @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") + @NotNull(message = "图片地址不能为空") + private String picUrl; + + @Schema(description = "SKU 状态", required = true, example = "1") + @NotNull(message = "SKU 状态不能为空") + @InEnum(CommonStatusEnum.class) + private Integer status; + + @Schema(description = "库存", required = true, example = "1") + @NotNull(message = "库存不能为空") + private Integer stock; + + @Schema(description = "预警预存", example = "1") + private Integer warnStock; + + @Schema(description = "商品重量", example = "1") // 单位:kg 千克 + private Double weight; + + @Schema(description = "商品体积", example = "1024") // 单位:m^3 平米 + private Double volume; + + @Schema(description = "商品属性") + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class Property { + + @Schema(description = "属性编号", required = true, example = "1") + @NotNull(message = "属性编号不能为空") + private Long propertyId; + + @Schema(description = "属性值编号", required = true, example = "1024") + @NotNull(message = "属性值编号不能为空") + private Long valueId; + + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java new file mode 100755 index 000000000..496475f99 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.product.controller.admin.sku.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; + +@Schema(description = "管理后台 - 商品 SKU 创建/更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO { + + /** + * 属性数组 + */ + private List properties; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java new file mode 100644 index 000000000..861454795 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.product.controller.admin.sku.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 商品 SKU 选项 Response VO") // 用于前端 SELECT 选项 +@Data +public class ProductSkuOptionRespVO { + + @Schema(description = "主键", required = true, example = "1024") + private Long id; + + @Schema(description = "商品 SKU 名字", example = "红色") + private String name; + + @Schema(description = "销售价格", required = true, example = "100") + private String price; + + @Schema(description = "库存", required = true, example = "100") + private Integer stock; + + // ========== 商品 SPU 信息 ========== + + @Schema(description = "商品 SPU 编号", required = true, example = "1") + private Long spuId; + + @Schema(description = "商品 SPU 名字", required = true, example = "iPhone 11") + private String spuName; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java new file mode 100755 index 000000000..95e394ada --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.product.controller.admin.sku.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "管理后台 - 商品 SKU Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductSkuRespVO extends ProductSkuBaseVO { + + @Schema(description = "主键", required = true, example = "1024") + private Long id; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + /** + * 属性数组 + */ + private List properties; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http new file mode 100644 index 000000000..4ab7b4f71 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http @@ -0,0 +1,4 @@ +### 获得商品 SPU 明细 +GET {{baseUrl}}/product/spu/get-detail?id=4 +Authorization: Bearer {{token}} +tenant-id: {{adminTenentId}} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java new file mode 100755 index 000000000..85fa93f8e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -0,0 +1,101 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; +import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; + +@Tag(name = "管理后台 - 商品 SPU") +@RestController +@RequestMapping("/product/spu") +@Validated +public class ProductSpuController { + + @Resource + private ProductSpuService productSpuService; + @Resource + private ProductSkuService productSkuService; + @Resource + private ProductPropertyValueService productPropertyValueService; + + @PostMapping("/create") + @Operation(summary = "创建商品 SPU") + @PreAuthorize("@ss.hasPermission('product:spu:create')") + public CommonResult createProductSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) { + return success(productSpuService.createSpu(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新商品 SPU") + @PreAuthorize("@ss.hasPermission('product:spu:update')") + public CommonResult updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) { + productSpuService.updateSpu(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除商品 SPU") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('product:spu:delete')") + public CommonResult deleteSpu(@RequestParam("id") Long id) { + productSpuService.deleteSpu(id); + return success(true); + } + + @GetMapping("/get-detail") + @Operation(summary = "获得商品 SPU 明细") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('product:spu:query')") + public CommonResult getSpuDetail(@RequestParam("id") Long id) { + // 获得商品 SPU + ProductSpuDO spu = productSpuService.getSpu(id); + if (spu == null) { + throw exception(SPU_NOT_EXISTS); + } + + // 查询商品 SKU + List skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(), null); + // 查询商品属性 + List propertyValues = productPropertyValueService + .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); + // 拼接 + return success(ProductSpuConvert.INSTANCE.convert03(spu, skus, propertyValues)); + } + + @GetMapping("/get-simple-list") + @Operation(summary = "获得商品 SPU 精简列表") + @PreAuthorize("@ss.hasPermission('product:spu:query')") + public CommonResult> getSpuSimpleList() { + List list = productSpuService.getSpuList(); + return success(ProductSpuConvert.INSTANCE.convertList02(list)); + } + + @GetMapping("/page") + @Operation(summary = "获得商品 SPU 分页") + @PreAuthorize("@ss.hasPermission('product:spu:query')") + public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { + return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO))); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java new file mode 100755 index 000000000..3f0c94a74 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** +* 商品 SPU Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class ProductSpuBaseVO { + + @Schema(description = "商品名称", required = true, example = "芋道") + @NotEmpty(message = "商品名称不能为空") + private String name; + + @Schema(description = "商品编码", example = "yudaoyuanma") + private String code; + + @Schema(description = "促销语", example = "好吃!") + private String sellPoint; + + @Schema(description = "商品详情", required = true, example = "我是商品描述") + @NotNull(message = "商品详情不能为空") + private String description; + + @Schema(description = "商品分类编号", required = true, example = "1") + @NotNull(message = "商品分类编号不能为空") + private Long categoryId; + + @Schema(description = "商品品牌编号", example = "1") + private Long brandId; + + @Schema(description = "商品图片的数组", required = true) + @NotNull(message = "商品图片的数组不能为空") + private List picUrls; + + @Schema(description = "商品视频", required = true) + private String videoUrl; + + @Schema(description = "排序字段", required = true, example = "1") + private Integer sort; + + @Schema(description = "商品状态", required = true, example = "1") + @NotNull(message = "商品状态不能为空") + @InEnum(ProductSpuStatusEnum.class) + private Integer status; + + // ========== SKU 相关字段 ========= + + @Schema(description = "规格类型", required = true, example = "1") + @NotNull(message = "规格类型不能为空") + @InEnum(ProductSpuSpecTypeEnum.class) + private Integer specType; + + @Schema(description = "是否展示库存", required = true, example = "true") + @NotNull(message = "是否展示库存不能为空") + private Boolean showStock; + + @Schema(description = "市场价", example = "1024") + private Integer marketPrice; + + // ========== 统计相关字段 ========= + + @Schema(description = "虚拟销量", required = true, example = "1024") + @NotNull(message = "虚拟销量不能为空") + private Integer virtualSalesCount; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java new file mode 100755 index 000000000..c75ed4d2e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.Valid; +import java.util.List; + +@Schema(description = "管理后台 - 商品 SPU 创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductSpuCreateReqVO extends ProductSpuBaseVO { + + /** + * SKU 数组 + */ + @Valid + private List skus; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java new file mode 100644 index 000000000..58f9565c8 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; + +@Schema(description = "管理后台 - 商品 SPU 详细 Response VO") // 包括关联的 SKU 等信息 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductSpuDetailRespVO extends ProductSpuRespVO { + + // ========== SKU 相关字段 ========= + + /** + * SKU 数组 + */ + private List skus; + + @Schema(description = "管理后台 - 商品 SKU 详细 Response VO") + @Data + @EqualsAndHashCode(callSuper = true) + @ToString(callSuper = true) + public static class Sku extends ProductSkuBaseVO { + + /** + * 属性数组 + */ + private List properties; + + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java new file mode 100755 index 000000000..0bfefb8d4 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 商品 SPU 分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductSpuPageReqVO extends PageParam { + + @Schema(description = "商品名称", example = "yutou") + private String name; + + @Schema(description = "商品编码", example = "yudaoyuanma") + private String code; + + @Schema(description = "分类编号", example = "1") + private Long categoryId; + + @Schema(description = "商品品牌编号", example = "1") + private Long brandId; + + @Schema(description = "上下架状态", example = "1") + private Integer status; + + @Schema(description = "销量最小值", example = "1") + private Integer salesCountMin; + + @Schema(description = "销量最大值", example = "1024") + private Integer salesCountMax; + + @Schema(description = "市场价最小值", example = "1") + private Integer marketPriceMin; + + @Schema(description = "市场价最大值", example = "1024") + private Integer marketPriceMax; + + @Schema(description = "是否库存告警", example = "true") + private Boolean alarmStock; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java new file mode 100755 index 000000000..5f088b74b --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 商品 SPU Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductSpuRespVO extends ProductSpuBaseVO { + + @Schema(description = "主键", required = true, example = "1") + private Long id; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + // ========== SKU 相关字段 ========= + + @Schema(description = "库存", required = true, example = "true") + private Integer totalStock; + + @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") + private Integer minPrice; + + @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") + private Integer maxPrice; + + @Schema(description = "商品销量", example = "1024") + private Integer salesCount; + + // ========== 统计相关字段 ========= + + @Schema(description = "点击量", example = "1024") + private Integer clickCount; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java new file mode 100755 index 000000000..9cc7bf169 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 商品 SPU 精简 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductSpuSimpleRespVO extends ProductSpuBaseVO { + + @Schema(description = "主键", required = true, example = "1") + private Long id; + + @Schema(description = "商品名称", required = true, example = "芋道") + private String name; + + @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") + private Integer minPrice; + + @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") + private Integer maxPrice; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java new file mode 100755 index 000000000..6ea84fb9e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.product.controller.admin.spu.vo; + +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "管理后台 - 商品 SPU 更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductSpuUpdateReqVO extends ProductSpuBaseVO { + + @Schema(description = "商品编号", required = true, example = "1") + @NotNull(message = "商品编号不能为空") + private Long id; + + /** + * SKU 数组 + */ + @Valid + private List skus; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java new file mode 100644 index 000000000..e484498b8 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.product.controller.app.category; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRespVO; +import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.Comparator; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 APP - 商品分类") +@RestController +@RequestMapping("/product/category") +@Validated +public class AppCategoryController { + + @Resource + private ProductCategoryService categoryService; + + @GetMapping("/list") + @Operation(summary = "获得商品分类列表") + public CommonResult> getProductCategoryList() { + List list = categoryService.getEnableCategoryList(); + list.sort(Comparator.comparing(ProductCategoryDO::getSort)); + return success(ProductCategoryConvert.INSTANCE.convertList03(list)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java new file mode 100644 index 000000000..1dca05a3a --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.product.controller.app.category.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +@Schema(description = "用户 APP - 商品分类 Response VO") +public class AppCategoryRespVO { + + @Schema(description = "分类编号", required = true, example = "2") + private Long id; + + @Schema(description = "父分类编号", required = true, example = "1") + @NotNull(message = "父分类编号不能为空") + private Long parentId; + + @Schema(description = "分类名称", required = true, example = "办公文具") + @NotBlank(message = "分类名称不能为空") + private String name; + + @Schema(description = "分类图片", required = true) + @NotBlank(message = "分类图片不能为空") + private String picUrl; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java new file mode 100644 index 000000000..379e85180 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位符,无时间作用,避免 package 缩进 + */ +package cn.iocoder.yudao.module.product.controller.app.property; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java new file mode 100644 index 000000000..6538bea3c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位符,无时间作用,避免 package 缩进 + */ +package cn.iocoder.yudao.module.product.controller.app.property.vo.property; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java new file mode 100644 index 000000000..ac687e547 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.product.controller.app.property.vo.value; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "用户 App - 商品属性值的明细 Response VO") +@Data +public class AppProductPropertyValueDetailRespVO { + + @Schema(description = "属性的编号", required = true, example = "1") + private Long propertyId; + + @Schema(description = "属性的名称", required = true, example = "颜色") + private String propertyName; + + @Schema(description = "属性值的编号", required = true, example = "1024") + private Long valueId; + + @Schema(description = "属性值的名称", required = true, example = "红色") + private String valueName; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http new file mode 100644 index 000000000..04df7bfec --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http @@ -0,0 +1,8 @@ +### 获得订单交易的分页 TODO +GET {{appApi}}/product/spu/page?pageNo=1&pageSize=10 +Authorization: Bearer {{appToken}} +tenant-id: {{appTenentId}} + +### 获得商品 SPU 明细 +GET {{appApi}}/product/spu/get-detail?id=4 +tenant-id: {{appTenentId}} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java new file mode 100644 index 000000000..d9ab87c72 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -0,0 +1,79 @@ +package cn.iocoder.yudao.module.product.controller.app.spu; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; +import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; + +@Tag(name = "用户 APP - 商品 SPU") +@RestController +@RequestMapping("/product/spu") +@Validated +public class AppProductSpuController { + + @Resource + private ProductSpuService productSpuService; + @Resource + private ProductSkuService productSkuService; + @Resource + private ProductPropertyValueService productPropertyValueService; + + @GetMapping("/page") + @Operation(summary = "获得商品 SPU 分页") + public CommonResult> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { + PageResult pageResult = productSpuService.getSpuPage(pageVO, ProductSpuStatusEnum.ENABLE.getStatus()); + return success(ProductSpuConvert.INSTANCE.convertPage02(pageResult)); + } + + @GetMapping("/get-detail") + @Operation(summary = "获得商品 SPU 明细") + @Parameter(name = "id", description = "编号", required = true) + public CommonResult getSpuDetail(@RequestParam("id") Long id) { + // 获得商品 SPU + ProductSpuDO spu = productSpuService.getSpu(id); + if (spu == null) { + throw exception(SPU_NOT_EXISTS); + } + if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { + throw exception(SPU_NOT_ENABLE); + } + + // 查询商品 SKU + List skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(), + CommonStatusEnum.ENABLE.getStatus()); + // 查询商品属性 + List propertyValues = productPropertyValueService + .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus)); + // 拼接 + return success(ProductSpuConvert.INSTANCE.convert(spu, skus, propertyValues)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java new file mode 100644 index 000000000..cf5471cba --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java @@ -0,0 +1,91 @@ +package cn.iocoder.yudao.module.product.controller.app.spu.vo; + +import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "用户 App - 商品 SPU 明细 Response VO") +@Data +public class AppProductSpuDetailRespVO { + + @Schema(description = "商品 SPU 编号", required = true, example = "1") + private Long id; + + // ========== 基本信息 ========= + + @Schema(description = "商品名称", required = true, example = "芋道") + private String name; + + @Schema(description = "促销语", example = "好吃!") + private String sellPoint; + + @Schema(description = "商品详情", required = true, example = "我是商品描述") + private String description; + + @Schema(description = "商品分类编号", required = true, example = "1") + private Long categoryId; + + @Schema(description = "商品图片的数组", required = true) + private List picUrls; + + @Schema(description = "商品视频", required = true) + private String videoUrl; + + // ========== SKU 相关字段 ========= + + @Schema(description = "规格类型", required = true, example = "1") + private Integer specType; + + @Schema(description = "是否展示库存", required = true, example = "true") + private Boolean showStock; + + @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") + private Integer minPrice; + + @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") + private Integer maxPrice; + + /** + * SKU 数组 + */ + private List skus; + + // ========== 统计相关字段 ========= + + @Schema(description = "商品销量", required = true, example = "1024") + private Integer salesCount; + + @Schema(description = "用户 App - 商品 SPU 明细的 SKU 信息") + @Data + public static class Sku { + + @Schema(description = "商品 SKU 编号", example = "1") + private Long id; + + /** + * 商品属性数组 + */ + private List properties; + + @Schema(description = "销售价格,单位:分", required = true, example = "1024") + private Integer price; + + @Schema(description = "市场价", example = "1024") + private Integer marketPrice; + + @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png") + private String picUrl; + + @Schema(description = "库存", required = true, example = "1") + private Integer stock; + + @Schema(description = "商品重量", example = "1") // 单位:kg 千克 + private Double weight; + + @Schema(description = "商品体积", example = "1024") // 单位:m^3 平米 + private Double volume; + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java new file mode 100644 index 000000000..d826900a6 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.product.controller.app.spu.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "用户 App - 商品 SPU 分页项 Response VO") +@Data +public class AppProductSpuPageItemRespVO { + + @Schema(description = "商品 SPU 编号", required = true, example = "1") + private Long id; + + @Schema(description = "商品名称", required = true, example = "芋道") + @NotEmpty(message = "商品名称不能为空") + private String name; + + @Schema(description = "分类编号", required = true) + @NotNull(message = "分类编号不能为空") + private Long categoryId; + + @Schema(description = "商品图片的数组", required = true) + private List picUrls; + + @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024") + private Integer minPrice; + + @Schema(description = "最大价格,单位使用:分", required = true, example = "1024") + private Integer maxPrice; + + // ========== 统计相关字段 ========= + + @Schema(description = "商品销量", example = "1024") + private Integer salesCount; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java new file mode 100644 index 000000000..dcbd1e190 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.product.controller.app.spu.vo; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.AssertTrue; + +@Schema(description = "用户 App - 商品 SPU 分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AppProductSpuPageReqVO extends PageParam { + + public static final String SORT_FIELD_PRICE = "price"; + public static final String SORT_FIELD_SALES_COUNT = "salesCount"; + + @Schema(description = "分类编号", example = "1") + private Long categoryId; + + @Schema(description = "关键字", example = "好看") + private String keyword; + + @Schema(description = "排序字段", example = "price") // 参见 AppSpuPageReqVO.SORT_FIELD_XXX 常量 + private String sortField; + + @Schema(description = "排序方式", example = "true") + private Boolean sortAsc; + + @AssertTrue(message = "排序字段不合法") + @JsonIgnore + public boolean isSortFieldValid() { + if (StrUtil.isEmpty(sortField)) { + return true; + } + return StrUtil.equalsAny(sortField, SORT_FIELD_PRICE, SORT_FIELD_SALES_COUNT); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java new file mode 100644 index 000000000..a318e9128 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.product.convert.brand; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandRespVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 品牌 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface ProductBrandConvert { + + ProductBrandConvert INSTANCE = Mappers.getMapper(ProductBrandConvert.class); + + ProductBrandDO convert(ProductBrandCreateReqVO bean); + + ProductBrandDO convert(ProductBrandUpdateReqVO bean); + + ProductBrandRespVO convert(ProductBrandDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java new file mode 100644 index 000000000..ae01ca9d5 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.product.convert.category; + +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRespVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 商品分类 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface ProductCategoryConvert { + + ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class); + + ProductCategoryDO convert(ProductCategoryCreateReqVO bean); + + ProductCategoryDO convert(ProductCategoryUpdateReqVO bean); + + ProductCategoryRespVO convert(ProductCategoryDO bean); + + List convertList(List list); + + List convertList03(List list); +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java new file mode 100644 index 000000000..211bcc293 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.product.convert.property; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; +import java.util.Map; + +/** + * 属性项 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface ProductPropertyConvert { + + ProductPropertyConvert INSTANCE = Mappers.getMapper(ProductPropertyConvert.class); + + ProductPropertyDO convert(ProductPropertyCreateReqVO bean); + + ProductPropertyDO convert(ProductPropertyUpdateReqVO bean); + + ProductPropertyRespVO convert(ProductPropertyDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + default List convertList(List keys, List values) { + Map> valueMap = CollectionUtils.convertMultiMap(values, ProductPropertyValueDO::getPropertyId); + return CollectionUtils.convertList(keys, key -> { + ProductPropertyAndValueRespVO respVO = convert02(key); + respVO.setValues(convertList02(valueMap.get(key.getId()))); + return respVO; + }); + } + ProductPropertyAndValueRespVO convert02(ProductPropertyDO bean); + List convertList02(List list); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/propertyvalue/ProductPropertyValueConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/propertyvalue/ProductPropertyValueConvert.java new file mode 100644 index 000000000..d6167c174 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/propertyvalue/ProductPropertyValueConvert.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.product.convert.propertyvalue; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +/** + * 属性值 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface ProductPropertyValueConvert { + + ProductPropertyValueConvert INSTANCE = Mappers.getMapper(ProductPropertyValueConvert.class); + + ProductPropertyValueDO convert(ProductPropertyValueCreateReqVO bean); + + ProductPropertyValueDO convert(ProductPropertyValueUpdateReqVO bean); + + ProductPropertyValueRespVO convert(ProductPropertyValueDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + default List convertList(List values, List keys) { + Map keyMap = convertMap(keys, ProductPropertyDO::getId); + return CollectionUtils.convertList(values, value -> { + ProductPropertyValueDetailRespBO valueDetail = new ProductPropertyValueDetailRespBO() + .setValueId(value.getId()).setValueName(value.getName()); + // 设置属性项 + MapUtils.findAndThen(keyMap, value.getPropertyId(), + key -> valueDetail.setPropertyId(key.getId()).setPropertyName(key.getName())); + return valueDetail; + }); + } + + List convertList02(List list); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java new file mode 100755 index 000000000..f397dfc48 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java @@ -0,0 +1,93 @@ +package cn.iocoder.yudao.module.product.convert.sku; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.*; +import java.util.stream.Collectors; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +/** + * 商品 SKU Convert + * + * @author 芋道源码 + */ +@Mapper +public interface ProductSkuConvert { + + ProductSkuConvert INSTANCE = Mappers.getMapper(ProductSkuConvert.class); + + ProductSkuDO convert(ProductSkuCreateOrUpdateReqVO bean); + + ProductSkuRespVO convert(ProductSkuDO bean); + + List convertList(List list); + + List convertList06(List list); + + default List convertList06(List list, Long spuId, String spuName) { + List result = convertList06(list); + result.forEach(item -> item.setSpuId(spuId).setSpuName(spuName)); + return result; + } + + ProductSkuRespDTO convert02(ProductSkuDO bean); + + List convertList03(List list); + + List convertList04(List list); + + List convertList05(List skus); + + /** + * 获得 SPU 的库存变化 Map + * + * @param items SKU 库存变化 + * @param skus SKU 列表 + * @return SPU 的库存变化 Map + */ + default Map convertSpuStockMap(List items, + List skus) { + Map skuIdAndSpuIdMap = convertMap(skus, ProductSkuDO::getId, ProductSkuDO::getSpuId); // SKU 与 SKU 编号的 Map 关系 + Map spuIdAndStockMap = new HashMap<>(); // SPU 的库存变化 Map 关系 + items.forEach(item -> { + Long spuId = skuIdAndSpuIdMap.get(item.getId()); + if (spuId == null) { + return; + } + Integer stock = spuIdAndStockMap.getOrDefault(spuId, 0) + item.getIncrCount(); + spuIdAndStockMap.put(spuId, stock); + }); + return spuIdAndStockMap; + } + + default Collection convertPropertyValueIds(List list) { + if (CollUtil.isEmpty(list)) { + return new HashSet<>(); + } + return list.stream().filter(item -> item.getProperties() != null) + .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 + .map(ProductSkuDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 + .collect(Collectors.toSet()); + } + + default String buildPropertyKey(ProductSkuDO bean) { + if (CollUtil.isEmpty(bean.getProperties())) { + return StrUtil.EMPTY; + } + List properties = new ArrayList<>(bean.getProperties()); + properties.sort(Comparator.comparing(ProductSkuDO.Property::getValueId)); + return properties.stream().map(m -> String.valueOf(m.getValueId())).collect(Collectors.joining()); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java new file mode 100755 index 000000000..fcf6d6436 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -0,0 +1,108 @@ +package cn.iocoder.yudao.module.product.convert.spu; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; +import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static cn.hutool.core.util.ObjectUtil.defaultIfNull; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +/** + * 商品 SPU Convert + * + * @author 芋道源码 + */ +@Mapper +public interface ProductSpuConvert { + + ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class); + + ProductSpuDO convert(ProductSpuCreateReqVO bean); + + ProductSpuDO convert(ProductSpuUpdateReqVO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean); + + List convertList2(List list); + + List convertList02(List list); + + default AppProductSpuDetailRespVO convert(ProductSpuDO spu, List skus, + List propertyValues) { + AppProductSpuDetailRespVO spuVO = convert02(spu) + .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)); + spuVO.setSkus(convertList03(skus)); + // 处理商品属性 + Map propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); + for (int i = 0; i < skus.size(); i++) { + List properties = skus.get(i).getProperties(); + if (CollUtil.isEmpty(properties)) { + continue; + } + AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); + sku.setProperties(new ArrayList<>(properties.size())); + // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 + properties.forEach(property -> { + ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); + if (propertyValue == null) { + return; + } + sku.getProperties().add(convert03(propertyValue)); + }); + } + return spuVO; + } + AppProductSpuDetailRespVO convert02(ProductSpuDO spu); + List convertList03(List skus); + AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue); + + PageResult convertPage02(PageResult page); + + default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List skus, + List propertyValues) { + ProductSpuDetailRespVO spuVO = convert03(spu); + spuVO.setSkus(convertList04(skus)); + // 处理商品属性 + Map propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId); + for (int i = 0; i < skus.size(); i++) { + List properties = skus.get(i).getProperties(); + if (CollUtil.isEmpty(properties)) { + continue; + } + ProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i); + sku.setProperties(new ArrayList<>(properties.size())); + // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中 + properties.forEach(property -> { + ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId()); + if (propertyValue == null) { + return; + } + sku.getProperties().add(convert04(propertyValue)); + }); + } + return spuVO; + } + ProductSpuDetailRespVO convert03(ProductSpuDO spu); + List convertList04(List skus); + ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java new file mode 100644 index 000000000..9775f36a5 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.brand; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 商品品牌 DO + * + * @author 芋道源码 + */ +@TableName("product_brand") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductBrandDO extends BaseDO { + + /** + * 品牌编号 + */ + @TableId + private Long id; + /** + * 品牌名称 + */ + private String name; + /** + * 品牌图片 + */ + private String picUrl; + /** + * 品牌排序 + */ + private Integer sort; + /** + * 品牌描述 + */ + private String description; + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + + // TODO 芋艿:firstLetter 首字母 + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java new file mode 100644 index 000000000..93ec925a9 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.category; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 商品分类 DO + * + * 商品分类一共两类: + * 1)一级分类:{@link #parentId} 等于 0 + * 2)二级 + 三级分类:{@link #parentId} 不等于 0 + * + * @author 芋道源码 + */ +@TableName("product_category") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductCategoryDO extends BaseDO { + + /** + * 父分类编号 - 根分类 + */ + public static final Long PARENT_ID_NULL = 0L; + + /** + * 分类编号 + */ + @TableId + private Long id; + /** + * 父分类编号 + */ + private Long parentId; + /** + * 分类名称 + */ + private String name; + /** + * 分类图片 + * + * 一级分类:推荐 200 x 100 分辨率 + * 二级 + 三级分类:推荐 100 x 100 分辨率 + */ + private String picUrl; + /** + * 分类排序 + */ + private Integer sort; + /** + * 分类描述 + */ + private String description; + /** + * 开启状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java new file mode 100644 index 000000000..c14808f22 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java @@ -0,0 +1,129 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.comment; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.enums.comment.ProductCommentAuditStatusEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.*; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 商品评论 DO + * + * @author 芋道源码 + */ +@TableName("product_comment") +@KeySequence("product_comment_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductCommentDO extends BaseDO { + + /** + * 评论编号,主键自增 + */ + @TableId + private Long id; + /** + * 商品 SPU 编号 + * + * 关联 {@link ProductSpuDO#getId()} + */ + private Long spuId; + /** + * 交易订单编号 + * + * 关联 TradeOrderDO 的 id 编号 + */ + private Long orderId; + /** + * 交易订单项编号 + * + * 关联 TradeOrderItemDO 的 id 编号 + */ + private Long orderItemId; + /** + * 审核状态 + * + * 枚举 {@link ProductCommentAuditStatusEnum} + */ + private Integer auditStatus; + + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 编号 + */ + private Long userId; + /** + * 用户 IP + */ + private String userIp; + /** + * 是否匿名 + */ + private Boolean anonymous; + /** + * 评论内容 + */ + private String content; + /** + * 评论图片地址数组 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List picUrls; + /** + * 描述相符星级 + * + * 1-5 星 + */ + private Integer descriptionScore; + /** + * 商品评论星级 + * + * 1-5 星 + */ + private Integer productScore; + /** + * 服务评论星级 + * + * 1-5 星 + */ + private Integer serviceScore; + /** + * 物流评论星级 + * + * 1-5 星 + */ + private Integer expressComment; + + /** + * 商家是否回复 + */ + private Boolean replied; + /** + * 商家回复内容 + */ + private String replyContent; + /** + * 商家回复时间 + */ + private LocalDateTime replyTime; + + /** + * 有用的计数 + * + * 其他用户看到评论时,可点击「有用」按钮 + */ + private Integer usefulCount; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java new file mode 100644 index 000000000..70445dc01 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.delivery; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 配送模板 SPU DO + * + * @author 芋道源码 + */ +@TableName("delivery_template") +@KeySequence("delivery_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class DeliveryTemplateDO extends BaseDO { + + /** + * 编号,自增 + */ + @TableId + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java new file mode 100644 index 000000000..54d4b31ac --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.favorite; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 商品收藏 DO + * + * @author 芋道源码 + */ +@TableName("product_favorite") +@KeySequence("product_favorite_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductFavoriteDO extends BaseDO { + + /** + * 编号,主键自增 + */ + @TableId + private Long id; + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 编号 + */ + private Long userId; + /** + * 商品 SPU 编号 + * + * 关联 {@link ProductSpuDO#getId()} + */ + private Long spuId; + + // TODO 芋艿:type 1 收藏;2 点赞 + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java new file mode 100644 index 000000000..2e3b63e59 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.group; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 商品分组的绑定 DO + * + * @author 芋道源码 + */ +@TableName("product_group_bind") +@KeySequence("product_group_bind_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductGroupBindDO extends BaseDO { + + /** + * 编号,自增 + */ + @TableId + private Long id; + /** + * 商品分组编号 + * + * 关联 {@link ProductGroupDO#getId()} + */ + private Long groupId; + /** + * 商品 SPU 编号 + * + * 关联 {@link ProductSpuDO#getId()} + */ + private Long spuId; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java new file mode 100644 index 000000000..605e8c38a --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.group; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.product.enums.group.ProductGroupStyleEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 商品分组 DO + * + * @author 芋道源码 + */ +@TableName("product_group") +@KeySequence("product_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductGroupDO extends BaseDO { + + /** + * 商品分组编号,自增 + */ + @TableId + private Long id; + /** + * 分组名称 + */ + private String name; + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + /** + * 商品数量 + */ + private Integer count; + /** + * 排序 + */ + private Integer sort; + /** + * 风格,用于 APP 首页展示商品的样式 + * + * 枚举 {@link ProductGroupStyleEnum} + */ + private Integer style; + /** + * 是否默认 + * + * true - 系统默认,不允许删除 + * false - 自定义,允许删除 + */ + private Boolean defaulted; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java new file mode 100644 index 000000000..2976674c1 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.property; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 商品属性项 DO + * + * @author 芋道源码 + */ +@TableName("product_property") +@KeySequence("product_property_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductPropertyDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + /** + * 名称 + */ + private String name; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java new file mode 100644 index 000000000..d73fe06b2 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.property; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + + +/** + * 商品属性值 DO + * + * @author 芋道源码 + */ +@TableName("product_property_value") +@KeySequence("product_property_value_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductPropertyValueDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + /** + * 属性项的编号 + * + * 关联 {@link ProductPropertyDO#getId()} + */ + private Long propertyId; + /** + * 名称 + */ + private String name; + /** + * 备注 + * + */ + private String remark; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java new file mode 100644 index 000000000..3d5cf9101 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.search; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 商品热搜关键字 DO + * + * @author 芋道源码 + */ +@TableName("product_hot_search") +@KeySequence("product_hot_search_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductHotSearchDO extends BaseDO { + + /** + * 编号,主键自增 + */ + @TableId + private Long id; + /** + * 关键字 + */ + private String name; + /** + * 内容 + */ + private String content; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java new file mode 100644 index 000000000..1c702da91 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.shop; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +// TODO 芋艿:待设计 +/** + * 店铺 DO + * + * @author 芋道源码 + */ +@TableName("shop") +@KeySequence("shop_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ShopDO extends BaseDO { + + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java new file mode 100755 index 000000000..3836f20e5 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java @@ -0,0 +1,137 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.sku; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; +import lombok.*; + +import java.util.List; + +/** + * 商品 SKU DO + * + * @author 芋道源码 + */ +@TableName(value = "product_sku",autoResultMap = true) +@KeySequence("product_sku_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductSkuDO extends BaseDO { + + /** + * 商品 SKU 编号,自增 + */ + @TableId + private Long id; + /** + * SPU 编号 + *

+ * 关联 {@link ProductSpuDO#getId()} + */ + private Long spuId; + /** + * SPU 名字 + * + * 冗余 {@link ProductSkuDO#getSpuName()} + */ + private String spuName; + /** + * 属性数组,JSON 格式 + */ + @TableField(typeHandler = PropertyTypeHandler.class) + private List properties; + /** + * 销售价格,单位:分 + */ + private Integer price; + /** + * 市场价,单位:分 + */ + private Integer marketPrice; + /** + * 成本价,单位:分 + */ + private Integer costPrice; + /** + * SKU 的条形码 + */ + private String barCode; + /** + * 图片地址 + */ + private String picUrl; + /** + * SKU 状态 + *

+ * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + /** + * 库存 + */ + private Integer stock; + /** + * 预警预存 + */ + private Integer warnStock; + /** + * 商品重量,单位:kg 千克 + */ + private Double weight; + /** + * 商品体积,单位:m^3 平米 + */ + private Double volume; + + /** + * 商品属性 + */ + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class Property { + + /** + * 属性编号 + *

+ * 关联 {@link ProductPropertyDO#getId()} + */ + private Long propertyId; + /** + * 属性值编号 + *

+ * 关联 {@link ProductPropertyValueDO#getId()} + */ + private Long valueId; + + } + + // TODO @芋艿:可以找一些新的思路 + public static class PropertyTypeHandler extends AbstractJsonTypeHandler { + + @Override + protected Object parse(String json) { + return JsonUtils.parseArray(json, Property.class); + } + + @Override + protected String toJson(Object obj) { + return JsonUtils.toJsonString(obj); + } + + } + +} + diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java new file mode 100755 index 000000000..93c47d4af --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -0,0 +1,212 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.spu; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.*; + +import java.util.List; + +/** + * 商品 SPU DO + * + * @author 芋道源码 + */ +@TableName(value = "product_spu", autoResultMap = true) +@KeySequence("product_spu_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductSpuDO extends BaseDO { + + /** + * 商品 SPU 编号,自增 + */ + @TableId + private Long id; + + // ========== 基本信息 ========= + + /** + * 商品名称 + */ + private String name; + /** + * 商品编码 + */ + private String code; + /** + * 促销语 + */ + private String sellPoint; + /** + * 商品详情 + */ + private String description; + /** + * 商品分类编号 + * + * 关联 {@link ProductCategoryDO#getId()} + */ + private Long categoryId; + /** + * 商品品牌编号 + * + * 关联 {@link ProductBrandDO#getId()} + */ + private Long brandId; + /** + * 商品图片的数组 + * + * 1. 第一张图片将作为商品主图,支持同时上传多张图; + * 2. 建议使用尺寸 800x800 像素以上、大小不超过 1M 的正方形图片; + * 3. 至少 1 张,最多上传 10 张 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List picUrls; + /** + * 商品视频 + */ + private String videoUrl; + + /** + * 排序字段 + */ + private Integer sort; + /** + * 商品状态 + * + * 枚举 {@link ProductSpuStatusEnum} + */ + private Integer status; + + // ========== SKU 相关字段 ========= + + /** + * 规格类型 + * + * 枚举 {@link ProductSpuSpecTypeEnum} + */ + private Integer specType; + /** + * 最小价格,单位使用:分 + * + * 基于其对应的 {@link ProductSkuDO#getPrice()} 最小值 + */ + private Integer minPrice; + /** + * 最大价格,单位使用:分 + * + * 基于其对应的 {@link ProductSkuDO#getPrice()} 最大值 + */ + private Integer maxPrice; + /** + * 市场价,单位使用:分 + * + * 基于其对应的 {@link ProductSkuDO#getMarketPrice()} 最大值 + */ + private Integer marketPrice; + /** + * 总库存 + * + * 基于其对应的 {@link ProductSkuDO#getStock()} 求和 + */ + private Integer totalStock; + /** + * 是否展示库存 + */ + private Boolean showStock; + + // ========== 统计相关字段 ========= + + /** + * 商品销量 + */ + private Integer salesCount; + /** + * 虚拟销量 + */ + private Integer virtualSalesCount; + /** + * 商品点击量 + */ + private Integer clickCount; + + // ========== 物流相关字段 ========= + + // TODO 芋艿:稍后完善物流的字段 +// /** +// * 配送方式 +// * +// * 枚举 {@link DeliveryModeEnum} +// */ +// private Integer deliveryMode; +// /** +// * 配置模板编号 +// * +// * 关联 {@link DeliveryTemplateDO#getId()} +// */ +// private Long deliveryTemplateId; + + // TODO ========== 待定字段:yv ========= + // TODO vip_price 会员价格 + // TODO postage 邮费 + // TODO is_postage 是否包邮 + // TODO unit_name 单位 + // TODO is_new 商户是否代理 + // TODO give_integral 获得积分 + // TODO is_integral 是开启积分兑换 + // TODO integral 所需积分 + // TODO is_seckill 秒杀状态 + // TODO is_bargain 砍价状态 + // TODO code_path 产品二维码地址 + // TODO is_sub 是否分佣 + + // TODO ↓↓ 芋艿 ↓↓ 看起来走分组更合适? + // TODO is_hot 是否热卖 + // TODO is_benefit 是否优惠 + // TODO is_best 是否精品 + // TODO is_new 是否新品 + // TODO is_good 是否优品推荐 + + // TODO ========== 待定字段:cf ========= + // TODO source_link 淘宝京东1688类型 + // TODO activity 活动显示排序 0=默认 1=秒 2=砍价 3=拼团 + + // TODO ========== 待定字段:lf ========= + + // TODO free_shipping_type:运费类型:1-包邮;2-统一运费;3-运费模板 + // TODO free_shipping:统一运费金额 + // TODO free_shipping_template_id:运费模板 + // TODO is_commission:分销佣金:1-开启;0-不开启;first_ratio second_ratio three_ratio + // TODO is_share_bouns:区域股东分红:1-开启;0-不开启;region_ratio;shareholder_ratio + + // TODO is_new:新品推荐:1-是;0-否 + // TODO is_best:好物优选:1-是;0-否 + // TODO is_like:猜你喜欢:1-是;0-否 + + // TODO is_team:是否开启拼团[0=否, 1=是] + // TODO is_integral:积分抵扣:1-开启;0-不开启 + // TODO is_member:会员价:1-开启;0-不开启 + // TODO give_integral_type:赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分 + // TODO give_integral:赠送积分; + + // TODO poster:商品自定义海报 + + // TODO ========== 待定字段:laoji ========= + // TODO productType 1 - 普通商品 2 - 预售商品;可能和 type 合并不错 + // TODO productUnit 商品单位 + // TODO extJson 扩展信息;例如说,预售商品的信息 + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java new file mode 100644 index 000000000..a62df7dc8 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.product.dal.mysql.brand; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface ProductBrandMapper extends BaseMapperX { + + default PageResult selectPage(ProductBrandPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(ProductBrandDO::getName, reqVO.getName()) + .eqIfPresent(ProductBrandDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(ProductBrandDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(ProductBrandDO::getId)); + } + + + default List selectList(ProductBrandListReqVO reqVO) { + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(ProductBrandDO::getName, reqVO.getName())); + } + + default ProductBrandDO selectByName(String name) { + return selectOne(ProductBrandDO::getName, name); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java new file mode 100644 index 000000000..8130d5a46 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.product.dal.mysql.category; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 商品分类 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface ProductCategoryMapper extends BaseMapperX { + + default List selectList(ProductCategoryListReqVO listReqVO) { + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(ProductCategoryDO::getName, listReqVO.getName()) + .orderByDesc(ProductCategoryDO::getId)); + } + + default Long selectCountByParentId(Long parentId) { + return selectCount(ProductCategoryDO::getParentId, parentId); + } + + default List selectListByStatus(Integer status) { + return selectList(ProductCategoryDO::getStatus, status); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java new file mode 100644 index 000000000..26f8d5239 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.product.dal.mysql.property; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface ProductPropertyMapper extends BaseMapperX { + + default PageResult selectPage(ProductPropertyPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(ProductPropertyDO::getName, reqVO.getName()) + .betweenIfPresent(ProductPropertyDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(ProductPropertyDO::getId)); + } + + default ProductPropertyDO selectByName(String name) { + return selectOne(ProductPropertyDO::getName, name); + } + + default List selectList(ProductPropertyListReqVO listReqVO) { + return selectList(new LambdaQueryWrapperX() + .eqIfPresent(ProductPropertyDO::getName, listReqVO.getName())); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java new file mode 100644 index 000000000..402df51e7 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.product.dal.mysql.property; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +@Mapper +public interface ProductPropertyValueMapper extends BaseMapperX { + + default List selectListByPropertyId(Collection propertyIds) { + return selectList(new LambdaQueryWrapperX() + .inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds)); + } + + default ProductPropertyValueDO selectByName(Long propertyId, String name) { + return selectOne(new LambdaQueryWrapperX() + .eq(ProductPropertyValueDO::getPropertyId, propertyId) + .eq(ProductPropertyValueDO::getName, name)); + } + + default void deleteByPropertyId(Long propertyId) { + delete(new LambdaQueryWrapperX() + .eq(ProductPropertyValueDO::getPropertyId, propertyId)); + } + + default PageResult selectPage(ProductPropertyValuePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(ProductPropertyValueDO::getPropertyId, reqVO.getPropertyId()) + .likeIfPresent(ProductPropertyValueDO::getName, reqVO.getName()) + .orderByDesc(ProductPropertyValueDO::getId)); + } + + default Integer selectCountByPropertyId(Long propertyId) { + return selectCount(ProductPropertyValueDO::getPropertyId, propertyId).intValue(); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java new file mode 100755 index 000000000..56bc54499 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.product.dal.mysql.sku; + +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +/** + * 商品 SKU Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface ProductSkuMapper extends BaseMapperX { + + default List selectListBySpuId(Long spuId) { + return selectList(ProductSkuDO::getSpuId, spuId); + } + + default List selectListBySpuIdAndStatus(Long spuId, + Integer status) { + return selectList(new LambdaQueryWrapperX() + .eq(ProductSkuDO::getSpuId, spuId) + .eqIfPresent(ProductSkuDO::getStatus, status)); + } + + default List selectListBySpuId(Collection spuIds) { + return selectList(ProductSkuDO::getSpuId, spuIds); + } + + default void deleteBySpuId(Long spuId) { + delete(new LambdaQueryWrapperX().eq(ProductSkuDO::getSpuId, spuId)); + } + + /** + * 更新 SKU 库存(增加) + * + * @param id 编号 + * @param incrCount 增加库存(正数) + */ + default void updateStockIncr(Long id, Integer incrCount) { + Assert.isTrue(incrCount > 0); + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .setSql(" stock = stock + " + incrCount) + .eq(ProductSkuDO::getId, id); + update(null, lambdaUpdateWrapper); + } + + /** + * 更新 SKU 库存(减少) + * + * @param id 编号 + * @param incrCount 减少库存(负数) + * @return 更新条数 + */ + default int updateStockDecr(Long id, Integer incrCount) { + Assert.isTrue(incrCount < 0); + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() + .setSql(" stock = stock + " + incrCount) // 负数,所以使用 + 号 + .eq(ProductSkuDO::getId, id) + .ge(ProductSkuDO::getStock, -incrCount); // cas 逻辑 + return update(null, updateWrapper); + } + + default List selectListByAlarmStock(){ + return selectList(new QueryWrapper().apply("stock <= warn_stock")); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java new file mode 100755 index 000000000..57a3125d8 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.product.dal.mysql.spu; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Objects; +import java.util.Set; + +/** + * 商品spu Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface ProductSpuMapper extends BaseMapperX { + + default PageResult selectPage(ProductSpuPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) + .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) + .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) + .leIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMax()) + .geIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMin()) + .leIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMax()) + .geIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMin()) + .orderByDesc(ProductSpuDO::getSort)); + } + + default PageResult selectPage(ProductSpuPageReqVO reqVO, Set alarmStockSpuIds) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(ProductSpuDO::getName, reqVO.getName()) + .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) + .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) + .leIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMax()) + .geIfPresent(ProductSpuDO::getSalesCount, reqVO.getSalesCountMin()) + .leIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMax()) + .geIfPresent(ProductSpuDO::getMarketPrice, reqVO.getMarketPriceMin()) + .inIfPresent(ProductSpuDO::getId, alarmStockSpuIds) // 库存告警 + .eqIfPresent(ProductSpuDO::getStatus, reqVO.getStatus()) + .orderByDesc(ProductSpuDO::getSort)); + } + + default PageResult selectPage(AppProductSpuPageReqVO pageReqVO, Integer status) { + LambdaQueryWrapperX query = new LambdaQueryWrapperX() + .eqIfPresent(ProductSpuDO::getCategoryId, pageReqVO.getCategoryId()) + .eqIfPresent(ProductSpuDO::getStatus, status); + // 排序逻辑 + if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_PRICE)) { + query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getMaxPrice); + } else if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { + query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getSalesCount); + } + return selectPage(pageReqVO, query); + } + + /** + * 更新商品 SPU 库存 + * + * @param id 商品 SPU 编号 + * @param incrCount 增加的库存数量 + */ + default void updateStock(Long id, Integer incrCount) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() + .setSql(" total_stock = total_stock +" + incrCount) // 负数,所以使用 + 号 + .eq(ProductSpuDO::getId, id); + update(null, updateWrapper); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/package-info.java new file mode 100644 index 000000000..d2e1c934a --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/package-info.java @@ -0,0 +1,6 @@ +/** + * 属于 product 模块的 framework 封装 + * + * @author 芋道源码 + */ +package cn.iocoder.yudao.module.product.framework; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/web/config/ProductWebConfiguration.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/web/config/ProductWebConfiguration.java new file mode 100644 index 000000000..9d1bf7db9 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/web/config/ProductWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.product.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * product 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class ProductWebConfiguration { + + /** + * product 模块的 API 分组 + */ + @Bean + public GroupedOpenApi productGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("product"); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/web/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/web/package-info.java new file mode 100644 index 000000000..f4adb2d76 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * product 模块的 web 配置 + */ +package cn.iocoder.yudao.module.product.framework.web; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java new file mode 100644 index 000000000..01967857e --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java @@ -0,0 +1,8 @@ +/** + * trade 模块,主要实现交易相关功能 + * 例如:订单、退款、购物车等功能。 + * + * 1. Controller URL:以 /product/ 开头,避免和其它 Module 冲突 + * 2. DataObject 表名:以 product_ 开头,方便在数据库中区分 + */ +package cn.iocoder.yudao.module.product; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java new file mode 100644 index 000000000..a90ec8a87 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java @@ -0,0 +1,79 @@ +package cn.iocoder.yudao.module.product.service.brand; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*; +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; + +/** + * 商品品牌 Service 接口 + * + * @author 芋道源码 + */ +public interface ProductBrandService { + + /** + * 创建品牌 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createBrand(@Valid ProductBrandCreateReqVO createReqVO); + + /** + * 更新品牌 + * + * @param updateReqVO 更新信息 + */ + void updateBrand(@Valid ProductBrandUpdateReqVO updateReqVO); + + /** + * 删除品牌 + * + * @param id 编号 + */ + void deleteBrand(Long id); + + /** + * 获得品牌 + * + * @param id 编号 + * @return 品牌 + */ + ProductBrandDO getBrand(Long id); + + /** + * 获得品牌列表 + * + * @param ids 编号 + * @return 品牌列表 + */ + List getBrandList(Collection ids); + + /** + * 获得品牌列表 + * + * @param listReqVO 请求参数 + * @return 品牌列表 + */ + List getBrandList(ProductBrandListReqVO listReqVO); + + /** + * 验证选择的商品分类是否合法 + * + * @param id 分类编号 + */ + void validateProductBrand(Long id); + + /** + * 获得品牌分页 + * + * @param pageReqVO 分页查询 + * @return 品牌分页 + */ + PageResult getBrandPage(ProductBrandPageReqVO pageReqVO); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java new file mode 100644 index 000000000..c7a3e5198 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java @@ -0,0 +1,117 @@ +package cn.iocoder.yudao.module.product.service.brand; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO; +import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; +import cn.iocoder.yudao.module.product.dal.mysql.brand.ProductBrandMapper; +import com.google.common.annotations.VisibleForTesting; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; + +/** + * 品牌 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class ProductBrandServiceImpl implements ProductBrandService { + + @Resource + private ProductBrandMapper brandMapper; + + @Override + public Long createBrand(ProductBrandCreateReqVO createReqVO) { + // 校验 + validateBrandNameUnique(null, createReqVO.getName()); + + // 插入 + ProductBrandDO brand = ProductBrandConvert.INSTANCE.convert(createReqVO); + brandMapper.insert(brand); + // 返回 + return brand.getId(); + } + + @Override + public void updateBrand(ProductBrandUpdateReqVO updateReqVO) { + // 校验存在 + validateBrandExists(updateReqVO.getId()); + validateBrandNameUnique(updateReqVO.getId(), updateReqVO.getName()); + // 更新 + ProductBrandDO updateObj = ProductBrandConvert.INSTANCE.convert(updateReqVO); + brandMapper.updateById(updateObj); + } + + @Override + public void deleteBrand(Long id) { + // 校验存在 + validateBrandExists(id); + // 删除 + brandMapper.deleteById(id); + } + + private void validateBrandExists(Long id) { + if (brandMapper.selectById(id) == null) { + throw exception(BRAND_NOT_EXISTS); + } + } + + @VisibleForTesting + public void validateBrandNameUnique(Long id, String name) { + ProductBrandDO brand = brandMapper.selectByName(name); + if (brand == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的字典类型 + if (id == null) { + throw exception(BRAND_NAME_EXISTS); + } + if (!brand.getId().equals(id)) { + throw exception(BRAND_NAME_EXISTS); + } + } + + @Override + public ProductBrandDO getBrand(Long id) { + return brandMapper.selectById(id); + } + + @Override + public List getBrandList(Collection ids) { + return brandMapper.selectBatchIds(ids); + } + + @Override + public List getBrandList(ProductBrandListReqVO listReqVO) { + return brandMapper.selectList(listReqVO); + } + + @Override + public void validateProductBrand(Long id) { + ProductBrandDO brand = brandMapper.selectById(id); + if (brand == null) { + throw exception(BRAND_NOT_EXISTS); + } + if (brand.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) { + throw exception(BRAND_DISABLED); + } + } + + @Override + public PageResult getBrandPage(ProductBrandPageReqVO pageReqVO) { + return brandMapper.selectPage(pageReqVO); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java new file mode 100644 index 000000000..32a4c030d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.product.service.category; + +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; + +import javax.validation.Valid; +import java.util.List; + +/** + * 商品分类 Service 接口 + * + * @author 芋道源码 + */ +public interface ProductCategoryService { + + /** + * 创建商品分类 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createCategory(@Valid ProductCategoryCreateReqVO createReqVO); + + /** + * 更新商品分类 + * + * @param updateReqVO 更新信息 + */ + void updateCategory(@Valid ProductCategoryUpdateReqVO updateReqVO); + + /** + * 删除商品分类 + * + * @param id 编号 + */ + void deleteCategory(Long id); + + /** + * 获得商品分类 + * + * @param id 编号 + * @return 商品分类 + */ + ProductCategoryDO getCategory(Long id); + + /** + * 校验商品分类 + * + * @param id 分类编号 + */ + void validateCategory(Long id); + + /** + * 获得商品分类的层级 + * + * @param id 编号 + * @return 商品分类的层级 + */ + Integer getCategoryLevel(Long id); + + /** + * 获得商品分类列表 + * + * @param listReqVO 查询条件 + * @return 商品分类列表 + */ + List getEnableCategoryList(ProductCategoryListReqVO listReqVO); + + /** + * 获得开启状态的商品分类列表 + * + * @return 商品分类列表 + */ + List getEnableCategoryList(); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java new file mode 100644 index 000000000..f0d10b8b8 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -0,0 +1,138 @@ +package cn.iocoder.yudao.module.product.service.category; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; + +/** + * 商品分类 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class ProductCategoryServiceImpl implements ProductCategoryService { + + @Resource + private ProductCategoryMapper productCategoryMapper; + + @Override + public Long createCategory(ProductCategoryCreateReqVO createReqVO) { + // 校验父分类存在 + validateParentProductCategory(createReqVO.getParentId()); + + // 插入 + ProductCategoryDO category = ProductCategoryConvert.INSTANCE.convert(createReqVO); + productCategoryMapper.insert(category); + // 返回 + return category.getId(); + } + + @Override + public void updateCategory(ProductCategoryUpdateReqVO updateReqVO) { + // 校验分类是否存在 + validateProductCategoryExists(updateReqVO.getId()); + // 校验父分类存在 + validateParentProductCategory(updateReqVO.getParentId()); + + // 更新 + ProductCategoryDO updateObj = ProductCategoryConvert.INSTANCE.convert(updateReqVO); + productCategoryMapper.updateById(updateObj); + } + + @Override + public void deleteCategory(Long id) { + // 校验分类是否存在 + validateProductCategoryExists(id); + // 校验是否还有子分类 + if (productCategoryMapper.selectCountByParentId(id) > 0) { + throw exception(CATEGORY_EXISTS_CHILDREN); + } + // TODO 芋艿 补充只有不存在商品才可以删除 + // 删除 + productCategoryMapper.deleteById(id); + } + + private void validateParentProductCategory(Long id) { + // 如果是根分类,无需验证 + if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { + return; + } + // 父分类不存在 + ProductCategoryDO category = productCategoryMapper.selectById(id); + if (category == null) { + throw exception(CATEGORY_PARENT_NOT_EXISTS); + } + // 父分类不能是二级分类 + if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { + throw exception(CATEGORY_PARENT_NOT_FIRST_LEVEL); + } + } + + private void validateProductCategoryExists(Long id) { + ProductCategoryDO category = productCategoryMapper.selectById(id); + if (category == null) { + throw exception(CATEGORY_NOT_EXISTS); + } + } + + @Override + public ProductCategoryDO getCategory(Long id) { + return productCategoryMapper.selectById(id); + } + + @Override + public void validateCategory(Long id) { + ProductCategoryDO category = productCategoryMapper.selectById(id); + if (category == null) { + throw exception(CATEGORY_NOT_EXISTS); + } + if (Objects.equals(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { + throw exception(CATEGORY_DISABLED, category.getName()); + } + } + + @Override + public Integer getCategoryLevel(Long id) { + if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { + return 0; + } + int level = 1; + for (int i = 0; i < 100; i++) { + ProductCategoryDO category = productCategoryMapper.selectById(id); + // 如果没有父节点,break 结束 + if (category == null + || Objects.equals(category.getParentId(), ProductCategoryDO.PARENT_ID_NULL)) { + break; + } + // 继续递归父节点 + level++; + id = category.getParentId(); + } + return level; + } + + @Override + public List getEnableCategoryList(ProductCategoryListReqVO listReqVO) { + return productCategoryMapper.selectList(listReqVO); + } + + @Override + public List getEnableCategoryList() { + return productCategoryMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java new file mode 100644 index 000000000..564bc82a9 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.product.service.property; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; + +/** + * 商品属性项 Service 接口 + * + * @author 芋道源码 + */ +public interface ProductPropertyService { + + /** + * 创建属性项 + * 注意,如果已经存在该属性项,直接返回它的编号即可 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createProperty(@Valid ProductPropertyCreateReqVO createReqVO); + + /** + * 更新属性项 + * + * @param updateReqVO 更新信息 + */ + void updateProperty(@Valid ProductPropertyUpdateReqVO updateReqVO); + + /** + * 删除属性项 + * + * @param id 编号 + */ + void deleteProperty(Long id); + + /** + * 获得属性项列表 + * @param listReqVO 集合查询 + * @return 属性项集合 + */ + List getPropertyList(ProductPropertyListReqVO listReqVO); + + /** + * 获取属性名称分页 + * + * @param pageReqVO 分页条件 + * @return 属性项分页 + */ + PageResult getPropertyPage(ProductPropertyPageReqVO pageReqVO); + + /** + * 获得指定编号的属性项 + * + * @param id 编号 + * @return 属性项 + */ + ProductPropertyDO getProperty(Long id); + + /** + * 根据属性项的编号的集合,获得对应的属性项数组 + * + * @param ids 属性项的编号的集合 + * @return 属性项数组 + */ + List getPropertyList(Collection ids); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java new file mode 100644 index 000000000..328c343d6 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java @@ -0,0 +1,113 @@ +package cn.iocoder.yudao.module.product.service.property; + +import cn.hutool.core.util.ObjUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO; +import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyMapper; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; + +/** + * 商品属性项 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class ProductPropertyServiceImpl implements ProductPropertyService { + + @Resource + private ProductPropertyMapper productPropertyMapper; + + @Resource + @Lazy // 延迟加载,解决循环依赖问题 + private ProductPropertyValueService productPropertyValueService; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createProperty(ProductPropertyCreateReqVO createReqVO) { + // 如果已经添加过该属性项,直接返回 + ProductPropertyDO dbProperty = productPropertyMapper.selectByName(createReqVO.getName()); + if (dbProperty != null) { + return dbProperty.getId(); + } + + // 插入 + ProductPropertyDO property = ProductPropertyConvert.INSTANCE.convert(createReqVO); + productPropertyMapper.insert(property); + // 返回 + return property.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateProperty(ProductPropertyUpdateReqVO updateReqVO) { + validatePropertyExists(updateReqVO.getId()); + // 校验名字重复 + ProductPropertyDO productPropertyDO = productPropertyMapper.selectByName(updateReqVO.getName()); + if (productPropertyDO != null && + ObjUtil.notEqual(productPropertyDO.getId(), updateReqVO.getId())) { + throw exception(PROPERTY_EXISTS); + } + + // 更新 + ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO); + productPropertyMapper.updateById(updateObj); + } + + @Override + public void deleteProperty(Long id) { + // 校验存在 + validatePropertyExists(id); + // 校验其下是否有规格值 + if (productPropertyValueService.getPropertyValueCountByPropertyId(id) > 0) { + throw exception(PROPERTY_DELETE_FAIL_VALUE_EXISTS); + } + + // 删除 + productPropertyMapper.deleteById(id); + // 同步删除属性值 + productPropertyValueService.deletePropertyValueByPropertyId(id); + } + + private void validatePropertyExists(Long id) { + if (productPropertyMapper.selectById(id) == null) { + throw exception(PROPERTY_NOT_EXISTS); + } + } + + @Override + public List getPropertyList(ProductPropertyListReqVO listReqVO) { + return productPropertyMapper.selectList(listReqVO); + } + + @Override + public PageResult getPropertyPage(ProductPropertyPageReqVO pageReqVO) { + return productPropertyMapper.selectPage(pageReqVO); + } + + @Override + public ProductPropertyDO getProperty(Long id) { + return productPropertyMapper.selectById(id); + } + + @Override + public List getPropertyList(Collection ids) { + return productPropertyMapper.selectBatchIds(ids); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java new file mode 100644 index 000000000..553e2578d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java @@ -0,0 +1,90 @@ +package cn.iocoder.yudao.module.product.service.property; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; + +import java.util.Collection; +import java.util.List; + +/** + * 商品属性值 Service 接口 + * + * @author LuoWenFeng + */ +public interface ProductPropertyValueService { + + /** + * 创建属性值 + * 注意,如果已经存在该属性值,直接返回它的编号即可 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO); + + /** + * 更新属性值 + * + * @param updateReqVO 更新信息 + */ + void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO); + + /** + * 删除属性值 + * + * @param id 编号 + */ + void deletePropertyValue(Long id); + + /** + * 获得属性值 + * + * @param id 编号 + * @return 属性值 + */ + ProductPropertyValueDO getPropertyValue(Long id); + + /** + * 根据属性项编号数组,获得属性值列表 + * + * @param propertyIds 属性项目编号数组 + * @return 属性值列表 + */ + List getPropertyValueListByPropertyId(Collection propertyIds); + + /** + * 根据编号数组,获得属性值列表 + * + * @param ids 编号数组 + * @return 属性值明细列表 + */ + List getPropertyValueDetailList(Collection ids); + + /** + * 根据属性项编号,活的属性值数量 + * + * @param propertyId 属性项编号数 + * @return 属性值数量 + */ + Integer getPropertyValueCountByPropertyId(Long propertyId); + + /** + * 获取属性值的分页 + * + * @param pageReqVO 查询条件 + * @return 属性值的分页 + */ + PageResult getPropertyValuePage(ProductPropertyValuePageReqVO pageReqVO); + + /** + * 删除指定属性项编号下的属性值们 + * + * @param propertyId 属性项的编号 + */ + void deletePropertyValueByPropertyId(Long propertyId); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java new file mode 100644 index 000000000..e5bc6874b --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java @@ -0,0 +1,127 @@ +package cn.iocoder.yudao.module.product.service.property; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; +import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; +import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyValueMapper; +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_NOT_EXISTS; + +/** + * 商品属性值 Service 实现类 + * + * @author LuoWenFeng + */ +@Service +@Validated +public class ProductPropertyValueServiceImpl implements ProductPropertyValueService { + + @Resource + private ProductPropertyValueMapper productPropertyValueMapper; + + @Resource + @Lazy // 延迟加载,避免循环依赖 + private ProductPropertyService productPropertyService; + + @Override + public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) { + // 如果已经添加过该属性值,直接返回 + ProductPropertyValueDO dbValue = productPropertyValueMapper.selectByName( + createReqVO.getPropertyId(), createReqVO.getName()); + if (dbValue != null) { + return dbValue.getId(); + } + + // 新增 + ProductPropertyValueDO value = ProductPropertyValueConvert.INSTANCE.convert(createReqVO); + productPropertyValueMapper.insert(value); + return value.getId(); + } + + @Override + public void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO) { + validatePropertyValueExists(updateReqVO.getId()); + // 校验名字唯一 + ProductPropertyValueDO productPropertyValueDO = productPropertyValueMapper.selectByName + (updateReqVO.getPropertyId(), updateReqVO.getName()); + if (productPropertyValueDO != null && !productPropertyValueDO.getId().equals(updateReqVO.getId())) { + throw exception(PROPERTY_VALUE_EXISTS); + } + + // 更新 + ProductPropertyValueDO updateObj = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO); + productPropertyValueMapper.updateById(updateObj); + } + + @Override + public void deletePropertyValue(Long id) { + validatePropertyValueExists(id); + productPropertyValueMapper.deleteById(id); + } + + private void validatePropertyValueExists(Long id) { + if (productPropertyValueMapper.selectById(id) == null) { + throw exception(PROPERTY_VALUE_NOT_EXISTS); + } + } + + @Override + public ProductPropertyValueDO getPropertyValue(Long id) { + return productPropertyValueMapper.selectById(id); + } + + @Override + public List getPropertyValueListByPropertyId(Collection propertyIds) { + return productPropertyValueMapper.selectListByPropertyId(propertyIds); + } + + @Override + public List getPropertyValueDetailList(Collection ids) { + // 获得属性值列表 + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } + List values = productPropertyValueMapper.selectBatchIds(ids); + if (CollUtil.isEmpty(values)) { + return Collections.emptyList(); + } + // 获得属性项列表 + List keys = productPropertyService.getPropertyList( + convertSet(values, ProductPropertyValueDO::getPropertyId)); + // 组装明细 + return ProductPropertyValueConvert.INSTANCE.convertList(values, keys); + } + + @Override + public Integer getPropertyValueCountByPropertyId(Long propertyId) { + return productPropertyValueMapper.selectCountByPropertyId(propertyId); + } + + @Override + public PageResult getPropertyValuePage(ProductPropertyValuePageReqVO pageReqVO) { + return productPropertyValueMapper.selectPage(pageReqVO); + } + + @Override + public void deletePropertyValueByPropertyId(Long propertyId) { + productPropertyValueMapper.deleteByPropertyId(propertyId); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/bo/ProductPropertyValueDetailRespBO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/bo/ProductPropertyValueDetailRespBO.java new file mode 100644 index 000000000..6776731f9 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/bo/ProductPropertyValueDetailRespBO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.product.service.property.bo; + +import lombok.Data; + +/** + * 商品属性项的明细 Response BO + * + * @author 芋道源码 + */ +@Data +public class ProductPropertyValueDetailRespBO { + + /** + * 属性的编号 + */ + private Long propertyId; + + /** + * 属性的名称 + */ + private String propertyName; + + /** + * 属性值的编号 + */ + private Long valueId; + + /** + * 属性值的名称 + */ + private String valueName; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java new file mode 100755 index 000000000..621e12d9f --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java @@ -0,0 +1,122 @@ +package cn.iocoder.yudao.module.product.service.sku; + +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import org.springframework.lang.Nullable; + +import java.util.Collection; +import java.util.List; + +/** + * 商品 SKU Service 接口 + * + * @author 芋道源码 + */ +public interface ProductSkuService { + + /** + * 删除商品 SKU + * + * @param id 编号 + */ + void deleteSku(Long id); + + /** + * 获得商品 SKU 信息 + * + * @param id 编号 + * @return 商品 SKU 信息 + */ + ProductSkuDO getSku(Long id); + + /** + * 获得商品 SKU 列表 + * + * @return 商品sku列表 + */ + List getSkuList(); + + /** + * 获得商品 SKU 列表 + * + * @param ids 编号 + * @return 商品sku列表 + */ + List getSkuList(Collection ids); + + /** + * 对 sku 的组合的属性等进行合法性校验 + * + * @param list sku组合的集合 + */ + void validateSkuList(List list, Integer specType); + + /** + * 批量创建 SKU + * + * @param spuId 商品 SPU 编号 + * @param spuName 商品 SPU 名称 + * @param list SKU 对象集合 + */ + void createSkuList(Long spuId, String spuName, List list); + + /** + * 根据 SPU 编号,批量更新它的 SKU 信息 + * + * @param spuId SPU 编码 + * @param spuName 商品 SPU 名称 + * @param skus SKU 的集合 + */ + void updateSkuList(Long spuId, String spuName, List skus); + + /** + * 更新 SKU 库存(增量) + * + * 如果更新的库存不足,会抛出异常 + * + * @param updateStockReqDTO 更行请求 + */ + void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO); + + /** + * 获得商品 SKU 集合 + * + * @param spuId spu 编号 + * @return 商品sku 集合 + */ + List getSkuListBySpuId(Long spuId); + + /** + * 基于 SPU 编号和状态,获得商品 SKU 集合 + * + * @param spuId SPU 编号 + * @param status 状态 + * @return 商品 SKU 集合 + */ + List getSkuListBySpuIdAndStatus(Long spuId, + @Nullable Integer status); + + /** + * 获得 spu 对应的 SKU 集合 + * + * @param spuIds spu 编码集合 + * @return 商品 sku 集合 + */ + List getSkuListBySpuId(List spuIds); + + /** + * 通过 spuId 删除 sku 信息 + * + * @param spuId spu 编码 + */ + void deleteSkuBySpuId(Long spuId); + + /** + * 获得库存预警的 SKU 数组 + * + * @return SKU 数组 + */ + List getSkuListByAlarmStock(); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java new file mode 100755 index 000000000..1ab2523cc --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java @@ -0,0 +1,214 @@ +package cn.iocoder.yudao.module.product.service.sku; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper; +import cn.iocoder.yudao.module.product.enums.ErrorCodeConstants; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; + +/** + * 商品 SKU Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class ProductSkuServiceImpl implements ProductSkuService { + + @Resource + private ProductSkuMapper productSkuMapper; + + @Resource + @Lazy // 循环依赖,避免报错 + private ProductSpuService productSpuService; + @Resource + private ProductPropertyService productPropertyService; + @Resource + private ProductPropertyValueService productPropertyValueService; + + @Override + public void deleteSku(Long id) { + // 校验存在 + validateSkuExists(id); + // 删除 + productSkuMapper.deleteById(id); + } + + private void validateSkuExists(Long id) { + if (productSkuMapper.selectById(id) == null) { + throw exception(SKU_NOT_EXISTS); + } + } + + @Override + public ProductSkuDO getSku(Long id) { + return productSkuMapper.selectById(id); + } + + @Override + public List getSkuList() { + return productSkuMapper.selectList(); + } + + @Override + public List getSkuList(Collection ids) { + return productSkuMapper.selectBatchIds(ids); + } + + @Override + public void validateSkuList(List skus, Integer specType) { + // 非多规格,不需要校验 + if (ObjectUtil.notEqual(specType, ProductSpuSpecTypeEnum.DISABLE.getType())) { + return; + } + + // 1、校验属性项存在 + Set propertyIds = skus.stream().filter(p -> p.getProperties() != null) + .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 + .map(ProductSkuBaseVO.Property::getPropertyId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 + .collect(Collectors.toSet()); + List propertyList = productPropertyService.getPropertyList(propertyIds); + if (propertyList.size() != propertyIds.size()) { + throw exception(PROPERTY_NOT_EXISTS); + } + + // 2. 校验,一个 SKU 下,没有重复的属性。校验方式是,遍历每个 SKU ,看看是否有重复的属性 propertyId + Map propertyValueMap = convertMap(productPropertyValueService.getPropertyValueListByPropertyId(propertyIds), ProductPropertyValueDO::getId); + skus.forEach(sku -> { + Set skuPropertyIds = convertSet(sku.getProperties(), propertyItem -> propertyValueMap.get(propertyItem.getValueId()).getPropertyId()); + if (skuPropertyIds.size() != sku.getProperties().size()) { + throw exception(SKU_PROPERTIES_DUPLICATED); + } + }); + + // 3. 再校验,每个 Sku 的属性值的数量,是一致的。 + int attrValueIdsSize = skus.get(0).getProperties().size(); + for (int i = 1; i < skus.size(); i++) { + if (attrValueIdsSize != skus.get(i).getProperties().size()) { + throw exception(ErrorCodeConstants.SPU_ATTR_NUMBERS_MUST_BE_EQUALS); + } + } + + // 4. 最后校验,每个 Sku 之间不是重复的 + Set> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的. + for (ProductSkuCreateOrUpdateReqVO sku : skus) { + if (!skuAttrValues.add(convertSet(sku.getProperties(), ProductSkuBaseVO.Property::getValueId))) { // 添加失败,说明重复 + throw exception(ErrorCodeConstants.SPU_SKU_NOT_DUPLICATE); + } + } + } + + @Override + public void createSkuList(Long spuId, String spuName, List skuCreateReqList) { + productSkuMapper.insertBatch(ProductSkuConvert.INSTANCE.convertList06(skuCreateReqList, spuId, spuName)); + } + + @Override + public List getSkuListBySpuId(Long spuId) { + return productSkuMapper.selectListBySpuId(spuId); + } + + @Override + public List getSkuListBySpuIdAndStatus(Long spuId, Integer status) { + return productSkuMapper.selectListBySpuIdAndStatus(spuId, status); + } + + @Override + public List getSkuListBySpuId(List spuIds) { + return productSkuMapper.selectListBySpuId(spuIds); + } + + @Override + public void deleteSkuBySpuId(Long spuId) { + productSkuMapper.deleteBySpuId(spuId); + } + + @Override + public List getSkuListByAlarmStock() { + return productSkuMapper.selectListByAlarmStock(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateSkuList(Long spuId, String spuName, List skus) { + // 构建属性与 SKU 的映射关系; + Map existsSkuMap = convertMap(productSkuMapper.selectListBySpuId(spuId), + ProductSkuConvert.INSTANCE::buildPropertyKey, ProductSkuDO::getId); + + // 拆分三个集合,新插入的、需要更新的、需要删除的 + List insertSkus = new ArrayList<>(); + List updateSkus = new ArrayList<>(); + List allUpdateSkus = ProductSkuConvert.INSTANCE.convertList06(skus, null, spuName); + allUpdateSkus.forEach(sku -> { + String propertiesKey = ProductSkuConvert.INSTANCE.buildPropertyKey(sku); + // 1、找得到的,进行更新 + Long existsSkuId = existsSkuMap.remove(propertiesKey); + if (existsSkuId != null) { + sku.setId(existsSkuId); + updateSkus.add(sku); + return; + } + // 2、找不到,进行插入 + sku.setSpuId(spuId); + insertSkus.add(sku); + }); + + // 执行最终的批量操作 + if (CollUtil.isNotEmpty(insertSkus)) { + productSkuMapper.insertBatch(insertSkus); + } + if (CollUtil.isNotEmpty(updateSkus)) { + updateSkus.forEach(sku -> productSkuMapper.updateById(sku)); + } + if (CollUtil.isNotEmpty(existsSkuMap)) { + productSkuMapper.deleteBatchIds(existsSkuMap.values()); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO) { + // 更新 SKU 库存 + updateStockReqDTO.getItems().forEach(item -> { + if (item.getIncrCount() > 0) { + productSkuMapper.updateStockIncr(item.getId(), item.getIncrCount()); + } else if (item.getIncrCount() < 0) { + int updateStockIncr = productSkuMapper.updateStockDecr(item.getId(), item.getIncrCount()); + if (updateStockIncr == 0) { + throw exception(SKU_STOCK_NOT_ENOUGH); + } + } + }); + + // 更新 SPU 库存 + List skus = productSkuMapper.selectBatchIds( + convertSet(updateStockReqDTO.getItems(), ProductSkuUpdateStockReqDTO.Item::getId)); + Map spuStockIncrCounts = ProductSkuConvert.INSTANCE.convertSpuStockMap( + updateStockReqDTO.getItems(), skus); + productSpuService.updateSpuStock(spuStockIncrCounts); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java new file mode 100755 index 000000000..0ae7359eb --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -0,0 +1,101 @@ +package cn.iocoder.yudao.module.product.service.spu; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +/** + * 商品 SPU Service 接口 + * + * @author 芋道源码 + */ +public interface ProductSpuService { + + /** + * 创建商品 SPU + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createSpu(@Valid ProductSpuCreateReqVO createReqVO); + + /** + * 更新商品 SPU + * + * @param updateReqVO 更新信息 + */ + void updateSpu(@Valid ProductSpuUpdateReqVO updateReqVO); + + /** + * 删除商品 SPU + * + * @param id 编号 + */ + void deleteSpu(Long id); + + /** + * 获得商品 SPU + * + * @param id 编号 + * @return 商品 SPU + */ + ProductSpuDO getSpu(Long id); + + /** + * 获得商品 SPU 列表 + * + * @param ids 编号数组 + * @return 商品 SPU 列表 + */ + List getSpuList(Collection ids); + + /** + * 获得商品 SPU 映射 + * + * @param ids 编号数组 + * @return 商品 SPU 映射 + */ + default Map getSpuMap(Collection ids) { + return convertMap(getSpuList(ids), ProductSpuDO::getId); + } + + /** + * 获得所有商品 SPU 列表 + * + * @return 商品 SPU 列表 + */ + List getSpuList(); + + /** + * 获得商品 SPU 分页 + * + * @param pageReqVO 分页查询 + * @return 商品spu分页 + */ + PageResult getSpuPage(ProductSpuPageReqVO pageReqVO); + + /** + * 获得商品 SPU 分页 + * + * @param pageReqVO 分页查询 + * @param status 状态 + * @return 商品 SPU 分页 + */ + PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO, Integer status); + + /** + * 更新商品 SPU 库存(增量) + * + * @param stockIncrCounts SPU 编号与库存变化(增量)的映射 + */ + void updateSpuStock(Map stockIncrCounts); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java new file mode 100755 index 000000000..0dd9cdf55 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -0,0 +1,180 @@ +package cn.iocoder.yudao.module.product.service.spu; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; +import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; +import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR; + +/** + * 商品 SPU Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class ProductSpuServiceImpl implements ProductSpuService { + + @Resource + private ProductSpuMapper productSpuMapper; + + @Resource + @Lazy // 循环依赖,避免报错 + private ProductSkuService productSkuService; + @Resource + private ProductBrandService brandService; + @Resource + private ProductCategoryService categoryService; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createSpu(ProductSpuCreateReqVO createReqVO) { + // 校验分类 + validateCategory(createReqVO.getCategoryId()); + // 校验品牌 + brandService.validateProductBrand(createReqVO.getBrandId()); + // 校验SKU + List skuSaveReqList = createReqVO.getSkus(); + productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType()); + + // 插入 SPU + ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO); + initSpuFromSkus(spu, skuSaveReqList); + productSpuMapper.insert(spu); + // 插入 SKU + productSkuService.createSkuList(spu.getId(), spu.getName(), skuSaveReqList); + // 返回 + return spu.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateSpu(ProductSpuUpdateReqVO updateReqVO) { + // 校验 SPU 是否存在 + validateSpuExists(updateReqVO.getId()); + // 校验分类 + validateCategory(updateReqVO.getCategoryId()); + // 校验品牌 + brandService.validateProductBrand(updateReqVO.getBrandId()); + // 校验SKU + List skuSaveReqList = updateReqVO.getSkus(); + productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType()); + + // 更新 SPU + ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO); + initSpuFromSkus(updateObj, skuSaveReqList); + productSpuMapper.updateById(updateObj); + // 批量更新 SKU + productSkuService.updateSkuList(updateObj.getId(), updateObj.getName(), updateReqVO.getSkus()); + } + + /** + * 基于 SKU 的信息,初始化 SPU 的信息 + * 主要是计数相关的字段,例如说市场价、最大最小价、库存等等 + * + * @param spu 商品 SPU + * @param skus 商品 SKU 数组 + */ + private void initSpuFromSkus(ProductSpuDO spu, List skus) { + spu.setMarketPrice(getMaxValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); + spu.setMaxPrice(getMaxValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); + spu.setMinPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice)); + spu.setTotalStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); + } + + /** + * 校验商品分类是否合法 + * + * @param id 商品分类编号 + */ + private void validateCategory(Long id) { + categoryService.validateCategory(id); + // 校验层级 + if (categoryService.getCategoryLevel(id) != 3) { + throw exception(SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteSpu(Long id) { + // 校验存在 + validateSpuExists(id); + // 删除 SPU + productSpuMapper.deleteById(id); + // 删除关联的 SKU + productSkuService.deleteSkuBySpuId(id); + } + + private void validateSpuExists(Long id) { + if (productSpuMapper.selectById(id) == null) { + throw exception(SPU_NOT_EXISTS); + } + } + + @Override + public ProductSpuDO getSpu(Long id) { + return productSpuMapper.selectById(id); + } + + @Override + public List getSpuList(Collection ids) { + return productSpuMapper.selectBatchIds(ids); + } + + @Override + public List getSpuList() { + return productSpuMapper.selectList(); + } + + @Override + public PageResult getSpuPage(ProductSpuPageReqVO pageReqVO) { + // 库存告警的 SPU 编号的集合 + Set alarmStockSpuIds = null; + if (Boolean.TRUE.equals(pageReqVO.getAlarmStock())) { + alarmStockSpuIds = CollectionUtils.convertSet(productSkuService.getSkuListByAlarmStock(), ProductSkuDO::getSpuId); + if (CollUtil.isEmpty(alarmStockSpuIds)) { + return PageResult.empty(); + } + } + // 分页查询 + return productSpuMapper.selectPage(pageReqVO, alarmStockSpuIds); + } + + @Override + public PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO, Integer status) { + return productSpuMapper.selectPage(pageReqVO, status); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateSpuStock(Map stockIncrCounts) { + stockIncrCounts.forEach((id, incCount) -> productSpuMapper.updateStock(id, incCount)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImplTest.java new file mode 100644 index 000000000..1b5c68ba4 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImplTest.java @@ -0,0 +1,133 @@ +package cn.iocoder.yudao.module.product.service.brand; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; +import cn.iocoder.yudao.module.product.dal.mysql.brand.ProductBrandMapper; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.BRAND_NOT_EXISTS; +import static org.junit.jupiter.api.Assertions.*; + +/** +* {@link ProductBrandServiceImpl} 的单元测试类 +* +* @author 芋道源码 +*/ +@Import(ProductBrandServiceImpl.class) +public class ProductBrandServiceImplTest extends BaseDbUnitTest { + + @Resource + private ProductBrandServiceImpl brandService; + + @Resource + private ProductBrandMapper brandMapper; + + @Test + public void testCreateBrand_success() { + // 准备参数 + ProductBrandCreateReqVO reqVO = randomPojo(ProductBrandCreateReqVO.class); + + // 调用 + Long brandId = brandService.createBrand(reqVO); + // 断言 + assertNotNull(brandId); + // 校验记录的属性是否正确 + ProductBrandDO brand = brandMapper.selectById(brandId); + assertPojoEquals(reqVO, brand); + } + + @Test + public void testUpdateBrand_success() { + // mock 数据 + ProductBrandDO dbBrand = randomPojo(ProductBrandDO.class); + brandMapper.insert(dbBrand);// @Sql: 先插入出一条存在的数据 + // 准备参数 + ProductBrandUpdateReqVO reqVO = randomPojo(ProductBrandUpdateReqVO.class, o -> { + o.setId(dbBrand.getId()); // 设置更新的 ID + }); + + // 调用 + brandService.updateBrand(reqVO); + // 校验是否更新正确 + ProductBrandDO brand = brandMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, brand); + } + + @Test + public void testUpdateBrand_notExists() { + // 准备参数 + ProductBrandUpdateReqVO reqVO = randomPojo(ProductBrandUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> brandService.updateBrand(reqVO), BRAND_NOT_EXISTS); + } + + @Test + public void testDeleteBrand_success() { + // mock 数据 + ProductBrandDO dbBrand = randomPojo(ProductBrandDO.class); + brandMapper.insert(dbBrand);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbBrand.getId(); + + // 调用 + brandService.deleteBrand(id); + // 校验数据不存在了 + assertNull(brandMapper.selectById(id)); + } + + @Test + public void testDeleteBrand_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> brandService.deleteBrand(id), BRAND_NOT_EXISTS); + } + + @Test + public void testGetBrandPage() { + // mock 数据 + ProductBrandDO dbBrand = randomPojo(ProductBrandDO.class, o -> { // 等会查询到 + o.setName("芋道源码"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setCreateTime(buildTime(2022, 2, 1)); + }); + brandMapper.insert(dbBrand); + // 测试 name 不匹配 + brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setName("源码"))); + // 测试 status 不匹配 + brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + // 测试 createTime 不匹配 + brandMapper.insert(cloneIgnoreId(dbBrand, o -> o.setCreateTime(buildTime(2022, 3, 1)))); + // 准备参数 + ProductBrandPageReqVO reqVO = new ProductBrandPageReqVO(); + reqVO.setName("芋道"); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setCreateTime((new LocalDateTime[]{buildTime(2022, 1, 1), buildTime(2022, 2, 25)})); + + // 调用 + PageResult pageResult = brandService.getBrandPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbBrand, pageResult.getList().get(0)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java new file mode 100644 index 000000000..a2963d498 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java @@ -0,0 +1,145 @@ +package cn.iocoder.yudao.module.product.service.category; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS; +import static org.junit.jupiter.api.Assertions.*; + +/** + * {@link ProductCategoryServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(ProductCategoryServiceImpl.class) +public class ProductCategoryServiceImplTest extends BaseDbUnitTest { + + @Resource + private ProductCategoryServiceImpl productCategoryService; + + @Resource + private ProductCategoryMapper productCategoryMapper; + + @Test + public void testCreateCategory_success() { + // 准备参数 + ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class); + // mock 父类 + ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> o.setId(reqVO.getParentId())); + productCategoryMapper.insert(parentProductCategory); + + // 调用 + Long categoryId = productCategoryService.createCategory(reqVO); + // 断言 + assertNotNull(categoryId); + // 校验记录的属性是否正确 + ProductCategoryDO category = productCategoryMapper.selectById(categoryId); + assertPojoEquals(reqVO, category); + } + + @Test + public void testUpdateCategory_success() { + // mock 数据 + ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class); + productCategoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据 + // 准备参数 + ProductCategoryUpdateReqVO reqVO = randomPojo(ProductCategoryUpdateReqVO.class, o -> { + o.setId(dbCategory.getId()); // 设置更新的 ID + }); + // mock 父类 + ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> o.setId(reqVO.getParentId())); + productCategoryMapper.insert(parentProductCategory); + + // 调用 + productCategoryService.updateCategory(reqVO); + // 校验是否更新正确 + ProductCategoryDO category = productCategoryMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, category); + } + + @Test + public void testUpdateCategory_notExists() { + // 准备参数 + ProductCategoryUpdateReqVO reqVO = randomPojo(ProductCategoryUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> productCategoryService.updateCategory(reqVO), CATEGORY_NOT_EXISTS); + } + + @Test + public void testDeleteCategory_success() { + // mock 数据 + ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class); + productCategoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbCategory.getId(); + + // 调用 + productCategoryService.deleteCategory(id); + // 校验数据不存在了 + assertNull(productCategoryMapper.selectById(id)); + } + + @Test + public void testDeleteCategory_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> productCategoryService.deleteCategory(id), CATEGORY_NOT_EXISTS); + } + + @Test + public void testGetCategoryLevel() { + // mock 数据 + ProductCategoryDO category1 = randomPojo(ProductCategoryDO.class, + o -> o.setParentId(ProductCategoryDO.PARENT_ID_NULL)); + productCategoryMapper.insert(category1); + ProductCategoryDO category2 = randomPojo(ProductCategoryDO.class, + o -> o.setParentId(category1.getId())); + productCategoryMapper.insert(category2); + ProductCategoryDO category3 = randomPojo(ProductCategoryDO.class, + o -> o.setParentId(category2.getId())); + productCategoryMapper.insert(category3); + + // 调用,并断言 + assertEquals(productCategoryService.getCategoryLevel(category1.getId()), 1); + assertEquals(productCategoryService.getCategoryLevel(category2.getId()), 2); + assertEquals(productCategoryService.getCategoryLevel(category3.getId()), 3); + } + + @Test + public void testGetCategoryList() { + // mock 数据 + ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class, o -> { // 等会查询到 + o.setName("奥特曼"); + }); + productCategoryMapper.insert(dbCategory); + // 测试 name 不匹配 + productCategoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName("奥特块"))); + // 准备参数 + ProductCategoryListReqVO reqVO = new ProductCategoryListReqVO(); + reqVO.setName("特曼"); + + // 调用 + List list = productCategoryService.getEnableCategoryList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbCategory, list.get(0)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java new file mode 100644 index 000000000..ec088cfdd --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java @@ -0,0 +1,171 @@ +package cn.iocoder.yudao.module.product.service.sku; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.framework.test.core.util.AssertUtils; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.List; + +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; +import static java.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.verify; + +/** + * {@link ProductSkuServiceImpl} 的单元测试 + * + * @author 芋道源码 + */ +@Import(ProductSkuServiceImpl.class) +public class ProductSkuServiceTest extends BaseDbUnitTest { + + @Resource + private ProductSkuService productSkuService; + + @Resource + private ProductSkuMapper productSkuMapper; + + @MockBean + private ProductSpuService productSpuService; + @MockBean + private ProductPropertyService productPropertyService; + @MockBean + private ProductPropertyValueService productPropertyValueService; + + @Test + public void testUpdateSkuList() { + // mock 数据 + ProductSkuDO sku01 = randomPojo(ProductSkuDO.class, o -> { // 测试更新 + o.setSpuId(1L); + o.setProperties(singletonList(new ProductSkuDO.Property(10L, 20L))); + }); + productSkuMapper.insert(sku01); + ProductSkuDO sku02 = randomPojo(ProductSkuDO.class, o -> { // 测试删除 + o.setSpuId(1L); + o.setProperties(singletonList(new ProductSkuDO.Property(10L, 30L))); + }); + productSkuMapper.insert(sku02); + // 准备参数 + Long spuId = 1L; + String spuName = "测试商品"; + List skus = Arrays.asList( + randomPojo(ProductSkuCreateOrUpdateReqVO.class, o -> { // 测试更新 + o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property(10L, 20L))); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + }), + randomPojo(ProductSkuCreateOrUpdateReqVO.class, o -> { // 测试新增 + o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property(10L, 40L))); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + }) + ); + + // 调用 + productSkuService.updateSkuList(spuId, spuName, skus); + // 断言 + List dbSkus = productSkuMapper.selectListBySpuId(spuId); + assertEquals(dbSkus.size(), 2); + // 断言更新的 + assertEquals(dbSkus.get(0).getId(), sku01.getId()); + assertPojoEquals(dbSkus.get(0), skus.get(0), "properties"); + assertEquals(skus.get(0).getProperties().size(), 1); + assertPojoEquals(dbSkus.get(0).getProperties().get(0), skus.get(0).getProperties().get(0)); + // 断言新增的 + assertNotEquals(dbSkus.get(1).getId(), sku02.getId()); + assertPojoEquals(dbSkus.get(1), skus.get(1), "properties"); + assertEquals(skus.get(1).getProperties().size(), 1); + assertPojoEquals(dbSkus.get(1).getProperties().get(0), skus.get(1).getProperties().get(0)); + } + + @Test + public void testUpdateSkuStock_incrSuccess() { + // 准备参数 + ProductSkuUpdateStockReqDTO updateStockReqDTO = new ProductSkuUpdateStockReqDTO() + .setItems(singletonList(new ProductSkuUpdateStockReqDTO.Item().setId(1L).setIncrCount(10))); + // mock 数据 + productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> o.setId(1L).setSpuId(10L).setStock(20))); + + // 调用 + productSkuService.updateSkuStock(updateStockReqDTO); + // 断言 + ProductSkuDO sku = productSkuMapper.selectById(1L); + assertEquals(sku.getStock(), 30); + verify(productSpuService).updateSpuStock(argThat(spuStockIncrCounts -> { + assertEquals(spuStockIncrCounts.size(), 1); + assertEquals(spuStockIncrCounts.get(10L), 10); + return true; + })); + } + + @Test + public void testUpdateSkuStock_decrSuccess() { + // 准备参数 + ProductSkuUpdateStockReqDTO updateStockReqDTO = new ProductSkuUpdateStockReqDTO() + .setItems(singletonList(new ProductSkuUpdateStockReqDTO.Item().setId(1L).setIncrCount(-10))); + // mock 数据 + productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> o.setId(1L).setSpuId(10L).setStock(20))); + + // 调用 + productSkuService.updateSkuStock(updateStockReqDTO); + // 断言 + ProductSkuDO sku = productSkuMapper.selectById(1L); + assertEquals(sku.getStock(), 10); + verify(productSpuService).updateSpuStock(argThat(spuStockIncrCounts -> { + assertEquals(spuStockIncrCounts.size(), 1); + assertEquals(spuStockIncrCounts.get(10L), -10); + return true; + })); + } + + @Test + public void testUpdateSkuStock_decrFail() { + // 准备参数 + ProductSkuUpdateStockReqDTO updateStockReqDTO = new ProductSkuUpdateStockReqDTO() + .setItems(singletonList(new ProductSkuUpdateStockReqDTO.Item().setId(1L).setIncrCount(-30))); + // mock 数据 + productSkuMapper.insert(randomPojo(ProductSkuDO.class, o -> o.setId(1L).setSpuId(10L).setStock(20))); + + // 调用并断言 + AssertUtils.assertServiceException(() -> productSkuService.updateSkuStock(updateStockReqDTO), + SKU_STOCK_NOT_ENOUGH); + } + + @Test + public void testDeleteSku_success() { + // mock 数据 + ProductSkuDO dbSku = randomPojo(ProductSkuDO.class); + productSkuMapper.insert(dbSku);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbSku.getId(); + + // 调用 + productSkuService.deleteSku(id); + // 校验数据不存在了 + assertNull(productSkuMapper.selectById(id)); + } + + @Test + public void testDeleteSku_notExists() { + // 准备参数 + Long id = 1L; + + // 调用, 并断言异常 + assertServiceException(() -> productSkuService.deleteSku(id), SKU_NOT_EXISTS); + } +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java new file mode 100755 index 000000000..1e029570c --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -0,0 +1,359 @@ +package cn.iocoder.yudao.module.product.service.spu; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO; +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO; +import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import cn.iocoder.yudao.module.product.service.brand.ProductBrandServiceImpl; +import cn.iocoder.yudao.module.product.service.category.ProductCategoryServiceImpl; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; +import cn.iocoder.yudao.module.product.service.sku.ProductSkuServiceImpl; +import com.google.common.collect.Lists; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static org.junit.jupiter.api.Assertions.assertEquals; + +// TODO @芋艿:review 下单元测试 + +/** + * {@link ProductSpuServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(ProductSpuServiceImpl.class) +@Disabled // TODO 芋艿:临时去掉 +public class ProductSpuServiceImplTest extends BaseDbUnitTest { + + @Resource + private ProductSpuServiceImpl productSpuService; + + @Resource + private ProductSpuMapper productSpuMapper; + + @MockBean + private ProductSkuServiceImpl productSkuService; + @MockBean + private ProductCategoryServiceImpl categoryService; + @MockBean + private ProductBrandServiceImpl brandService; + @MockBean + private ProductPropertyService productPropertyService; + @MockBean + private ProductPropertyValueService productPropertyValueService; + + public String generateNo() { + return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999); + } + + public Long generateId() { + return RandomUtil.randomLong(100000, 999999); + } + + @Test + public void testCreateSpu_success() { + // 准备参数 + ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class, o -> { + o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()); + o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); + }); + + // 校验SKU + List skuCreateReqList = createReqVO.getSkus(); + + Long spu = productSpuService.createSpu(createReqVO); + ProductSpuDO productSpuDO = productSpuMapper.selectById(spu); + + createReqVO.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); +// createReqVO.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); +// createReqVO.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); +// createReqVO.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); + + assertPojoEquals(createReqVO, productSpuDO); + + } + + @Test + public void testUpdateSpu_success() { + // 准备参数 + ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); + productSpuMapper.insert(createReqVO); + // 准备参数 + ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { + o.setId(createReqVO.getId()); // 设置更新的 ID + o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()); + o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()); + }); + // 调用 + productSpuService.updateSpu(reqVO); + + List skuCreateReqList = reqVO.getSkus(); + reqVO.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice)); +// reqVO.setMaxPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); +// reqVO.setMinPrice(CollectionUtils.getMinValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getPrice)); +// reqVO.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum)); + + // 校验是否更新正确 + ProductSpuDO spu = productSpuMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, spu); + } + + @Test + public void testValidateSpuExists_exception() { + ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> { + o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()); + o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()); + }); + // 调用 + Assertions.assertThrows(ServiceException.class, () -> productSpuService.updateSpu(reqVO)); + } + + @Test + void deleteSpu() { + // 准备参数 + ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); + productSpuMapper.insert(createReqVO); + + // 调用 + productSpuService.deleteSpu(createReqVO.getId()); + + Assertions.assertNull(productSpuMapper.selectById(createReqVO.getId())); + } + + @Test + void getSpu() { + // 准备参数 + ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class); + productSpuMapper.insert(createReqVO); + + ProductSpuDO spu = productSpuService.getSpu(createReqVO.getId()); + assertPojoEquals(createReqVO, spu); + } + + @Test + void getSpuList() { + // 准备参数 + ArrayList createReqVO = Lists.newArrayList(randomPojo(ProductSpuDO.class), randomPojo(ProductSpuDO.class)); + productSpuMapper.insertBatch(createReqVO); + + // 调用 + List spuList = productSpuService.getSpuList(createReqVO.stream().map(ProductSpuDO::getId).collect(Collectors.toList())); + Assertions.assertIterableEquals(createReqVO, spuList); + } + + @Test + void getSpuPage_alarmStock_empty() { + // 调用 + ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); + productSpuPageReqVO.setAlarmStock(true); + + PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); + + PageResult result = PageResult.empty(); + Assertions.assertIterableEquals(result.getList(), spuPage.getList()); + assertEquals(spuPage.getTotal(), result.getTotal()); + } + + @Test + void getSpuPage_alarmStock() { + // mock 数据 + Long brandId = generateId(); + Long categoryId = generateId(); + String code = generateNo(); + + // 准备参数 + ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o->{ + o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); + o.setTotalStock(500); + o.setMinPrice(1); + o.setMaxPrice(50); + o.setMarketPrice(25); + o.setSpecType(ProductSpuSpecTypeEnum.RECYCLE.getType()); + o.setBrandId(brandId); + o.setCategoryId(categoryId); + o.setClickCount(100); + o.setCode(code); + o.setDescription("测试商品"); + o.setPicUrls(new ArrayList<>()); + o.setName("测试"); + o.setSalesCount(100); + o.setSellPoint("超级加倍"); + o.setShowStock(true); + o.setVideoUrl(""); + }); + productSpuMapper.insert(createReqVO); + + Set alarmStockSpuIds = SetUtils.asSet(createReqVO.getId()); + + List productSpuDOS = Arrays.asList(randomPojo(ProductSkuDO.class, o -> { + o.setSpuId(createReqVO.getId()); + }), randomPojo(ProductSkuDO.class, o -> { + o.setSpuId(createReqVO.getId()); + })); + + Mockito.when(productSkuService.getSkuListByAlarmStock()).thenReturn(productSpuDOS); + + // 调用 + ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); + productSpuPageReqVO.setAlarmStock(true); + PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); + + PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, alarmStockSpuIds)); + Assertions.assertIterableEquals(result.getList(), spuPage.getList()); + assertEquals(spuPage.getTotal(), result.getTotal()); + } + + @Test + void getSpuPage() { + // mock 数据 + Long brandId = generateId(); + Long categoryId = generateId(); + + // 准备参数 + ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o->{ + o.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); + o.setTotalStock(1); + o.setMinPrice(1); + o.setMaxPrice(1); + o.setMarketPrice(1); + o.setSpecType(ProductSpuSpecTypeEnum.RECYCLE.getType()); + o.setBrandId(brandId); + o.setCategoryId(categoryId); + o.setClickCount(1); + o.setCode(generateNo()); + o.setDescription("测试商品"); + o.setPicUrls(new ArrayList<>()); + o.setName("测试"); + o.setSalesCount(1); + o.setSellPoint("卖点"); + o.setShowStock(true); + }); + + // 准备参数 + productSpuMapper.insert(createReqVO); + // 测试 status 不匹配 + productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setStatus(ProductSpuStatusEnum.DISABLE.getStatus()))); + productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setStatus(ProductSpuStatusEnum.RECYCLE.getStatus()))); + // 测试 SpecType 不匹配 + productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType()))); + // 测试 BrandId 不匹配 + productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setBrandId(generateId()))); + // 测试 CategoryId 不匹配 + productSpuMapper.insert(cloneIgnoreId(createReqVO, o -> o.setCategoryId(generateId()))); + + // 调用 + ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO(); + productSpuPageReqVO.setAlarmStock(false); + productSpuPageReqVO.setBrandId(brandId); + productSpuPageReqVO.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); + productSpuPageReqVO.setCategoryId(categoryId); + + PageResult spuPage = productSpuService.getSpuPage(productSpuPageReqVO); + + PageResult result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, (Set) null)); + assertEquals(result, spuPage); + } + + @Test + void testGetSpuPage() { +// 准备参数 + ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o -> { + o.setCategoryId(2L); + }); + productSpuMapper.insert(createReqVO); + + // 调用 + AppProductSpuPageReqVO appSpuPageReqVO = new AppProductSpuPageReqVO(); + appSpuPageReqVO.setCategoryId(2L); + +// PageResult spuPage = productSpuService.getSpuPage(appSpuPageReqVO); +// +// PageResult result = productSpuMapper.selectPage( +// ProductSpuConvert.INSTANCE.convert(appSpuPageReqVO)); +// +// List collect = result.getList() +// .stream() +// .map(ProductSpuConvert.INSTANCE::convertAppResp) +// .collect(Collectors.toList()); +// +// Assertions.assertIterableEquals(collect, spuPage.getList()); +// assertEquals(spuPage.getTotal(), result.getTotal()); + } + + + /** + * 生成笛卡尔积 + * + * @param data 数据 + * @return 笛卡尔积 + */ + public static List> cartesianProduct(List> data) { + List> res = null; // 结果集(当前为第N个List,则该处存放的就为前N-1个List的笛卡尔积集合) + for (List list : data) { // 遍历数据 + List> temp = new ArrayList<>(); // 临时结果集,存放本次循环后生成的笛卡尔积集合 + if (res == null) { // 结果集为null表示第一次循环既list为第一个List + for (T t : list) { // 便利第一个List + // 利用stream生成List,第一个List的笛卡尔积集合约等于自己本身(需要创建一个List并把对象添加到当中),存放到临时结果集 + temp.add(Stream.of(t).collect(Collectors.toList())); + } + res = temp; // 将临时结果集赋值给结果集 + continue; // 跳过本次循环 + } + // 不为第一个List,计算前面的集合(笛卡尔积)和当前List的笛卡尔积集合 + for (T t : list) { // 便利 + for (List rl : res) { // 便利前面的笛卡尔积集合 + // 利用stream生成List + temp.add(Stream.concat(rl.stream(), Stream.of(t)).collect(Collectors.toList())); + } + } + res = temp; // 将临时结果集赋值给结果集 + } + // 返回结果 + return res; + } + + @Test + public void testUpdateSpuStock() { + // 准备参数 + Map stockIncrCounts = MapUtil.builder(1L, 10).put(2L, -20).build(); + // mock 方法(数据) + productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> o.setId(1L).setTotalStock(20))); + productSpuMapper.insert(randomPojo(ProductSpuDO.class, o -> o.setId(2L).setTotalStock(30))); + + // 调用 + productSpuService.updateSpuStock(stockIncrCounts); + // 断言 + assertEquals(productSpuService.getSpu(1L).getTotalStock(), 30); + assertEquals(productSpuService.getSpu(2L).getTotalStock(), 10); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml new file mode 100644 index 000000000..31e5ae5c9 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml @@ -0,0 +1,50 @@ +spring: + main: + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner + +--- #################### 数据库相关配置 #################### + +spring: + # 数据源配置项 + datasource: + name: ruoyi-vue-pro + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + driver-class-name: org.h2.Driver + username: sa + password: + druid: + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 + initial-size: 1 # 单元测试,配置为 1,提升启动速度 + sql: + init: + schema-locations: classpath:/sql/create_tables.sql + + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 + redis: + host: 127.0.0.1 # 地址 + port: 16379 # 端口(单元测试,使用 16379 端口) + database: 0 # 数据库索引 + +mybatis-plus: + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 + type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject + +--- #################### 定时任务相关配置 #################### + +--- #################### 配置中心相关配置 #################### + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项(单元测试,禁用 Lock4j) + +# Resilience4j 配置项 + +--- #################### 监控相关配置 #################### + +--- #################### 芋道相关配置 #################### + +# 芋道配置项,设置当前项目所有自定义的配置 +yudao: + info: + base-package: cn.iocoder.yudao diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml b/yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml new file mode 100644 index 000000000..daf756bff --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml @@ -0,0 +1,4 @@ + + + + diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql index 2a45ce1bd..48079766a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/clean.sql @@ -1,7 +1,4 @@ DELETE FROM "product_sku"; DELETE FROM "product_spu"; +DELETE FROM "product_brand"; DELETE FROM "product_category"; - - - - diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql index 6b0ffc7c7..8f53ba72f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql @@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS `product_sku` ( PRIMARY KEY (`id`) ) COMMENT '商品sku'; + CREATE TABLE IF NOT EXISTS `product_spu` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', @@ -66,3 +67,18 @@ CREATE TABLE IF NOT EXISTS `product_category` ( `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', PRIMARY KEY (`id`) ) COMMENT '商品分类'; + +CREATE TABLE IF NOT EXISTS `product_brand` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '品牌编号', + `name` varchar(128) NOT NULL COMMENT '品牌名称', + `pic_url` varchar DEFAULT NULL COMMENT '品牌图片', + `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', + `description` varchar(256) NOT NULL DEFAULT '0' COMMENT '品牌描述', + `status` bit(1) DEFAULT NULL COMMENT '状态', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar DEFAULT NULL COMMENT '创建人', + `updater` varchar DEFAULT NULL COMMENT '更新人', + `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', + PRIMARY KEY (`id`) +) COMMENT '商品品牌'; diff --git a/yudao-module-mall/yudao-module-promotion-api/pom.xml b/yudao-module-mall/yudao-module-promotion-api/pom.xml new file mode 100644 index 000000000..510b17bee --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/pom.xml @@ -0,0 +1,33 @@ + + + + cn.iocoder.boot + yudao-module-mall + ${revision} + + 4.0.0 + yudao-module-promotion-api + jar + + ${project.artifactId} + + market 模块 API,暴露给其它模块调用 + + + + + cn.iocoder.boot + yudao-common + + + + + org.springframework.boot + spring-boot-starter-validation + true + + + + diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java new file mode 100644 index 000000000..f99ff815f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.api.coupon; + +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; + +import javax.validation.Valid; + +/** + * 优惠劵 API 接口 + * + * @author 芋道源码 + */ +public interface CouponApi { + + /** + * 使用优惠劵 + * + * @param useReqDTO 使用请求 + */ + void useCoupon(@Valid CouponUseReqDTO useReqDTO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponUseReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponUseReqDTO.java new file mode 100644 index 000000000..9323ab553 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponUseReqDTO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.promotion.api.coupon.dto; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 优惠劵使用 Request DTO + * + * @author 芋道源码 + */ +@Data +public class CouponUseReqDTO { + + /** + * 优惠劵编号 + */ + @NotNull(message = "优惠劵编号不能为空") + private Long id; + + /** + * 用户编号 + */ + @NotNull(message = "用户编号不能为空") + private Long userId; + + /** + * 订单编号 + */ + @NotNull(message = "订单编号不能为空") + private Long orderId; + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java new file mode 100644 index 000000000..08e1020a6 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位 + */ +package cn.iocoder.yudao.module.promotion.api; diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java new file mode 100644 index 000000000..b36c938bc --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.api.price; + +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; + +/** + * 价格 API 接口 + * + * @author 芋道源码 + */ +public interface PriceApi { + + /** + * 计算商品的价格 + * + * @param calculateReqDTO 价格请求 + * @return 价格相应 + */ + PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/CouponMeetRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/CouponMeetRespDTO.java new file mode 100644 index 000000000..310959e2c --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/CouponMeetRespDTO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.promotion.api.price.dto; + +import lombok.Data; + +/** + * 优惠劵的匹配信息 Response DTO + * + * why 放在 price 包下?主要获取的时候,需要涉及到较多的价格计算逻辑,放在 price 可以更好的复用逻辑 + * + * @author 芋道源码 + */ +@Data +public class CouponMeetRespDTO { + + /** + * 优惠劵编号 + */ + private Long id; + + // ========== 非优惠劵的基本信息字段 ========== + /** + * 是否匹配 + */ + private Boolean meet; + /** + * 不匹配的提示,即 {@link #meet} = true 才有值 + * + * 例如说: + * 1. 所结算商品没有符合条件的商品 + * 2. 差 XXX 元可用优惠劵 + * 3. 优惠劵未到使用时间 + */ + private String meetTip; + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java new file mode 100644 index 000000000..01f0ac220 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.promotion.api.price.dto; + +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 价格计算 Request DTO + * + * @author 芋道源码 + */ +@Data +public class PriceCalculateReqDTO { + + /** + * 用户编号 + * + * 对应 MemberUserDO 的 id 编号 + */ + private Long userId; + + /** + * 优惠劵编号 + */ + private Long couponId; + + /** + * 商品 SKU 数组 + */ + @NotNull(message = "商品数组不能为空") + private List items; + + /** + * 商品 SKU + */ + @Data + public static class Item { + + /** + * SKU 编号 + */ + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + /** + * SKU 数量 + */ + @NotNull(message = "商品 SKU 数量不能为空") + @Min(value = 0L, message = "商品 SKU 数量必须大于等于 0") // 可传递 0 数量,用于购物车未选中的情况 + private Integer count; + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java new file mode 100644 index 000000000..cda6d99d6 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java @@ -0,0 +1,257 @@ +package cn.iocoder.yudao.module.promotion.api.price.dto; + +import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import lombok.Data; + +import java.util.List; + +/** + * 价格计算 Response DTO + * + * 整体设计,参考 taobao 的技术文档: + * 1. 订单管理 + * 2. 常用订单金额说明 + * + * 举个例子:订单图 + * 输入: + * 1. 订单实付: trade.payment = 198.00;订单邮费:5 元; + * 2. 商品级优惠 圣诞价: 省 29.00 元 和 圣诞价:省 150.00 元; 订单级优惠,圣诞 2:省 5.00 元; + * 分摊: + * 1. 商品 1:原价 108 元,优惠 29 元,子订单实付 79 元,分摊主订单优惠 1.99 元; + * 2. 商品 2:原价 269 元,优惠 150 元,子订单实付 119 元,分摊主订单优惠 3.01 元; + * + * @author 芋道源码 + */ +@Data +public class PriceCalculateRespDTO { + + /** + * 订单 + */ + private Order order; + + /** + * 营销活动数组 + * + * 只对应 {@link Order#items} 商品匹配的活动 + */ + private List promotions; + + /** + * 订单 + */ + @Data + public static class Order { + + /** + * 商品原价(总),单位:分 + * + * 基于 {@link OrderItem#getOriginalPrice()} 求和 + * + * 对应 taobao 的 trade.total_fee 字段 + */ + private Integer originalPrice; + /** + * 订单原价(总),单位:分 + * + * 基于 {@link OrderItem#getPayPrice()} 求和 + * 和 {@link #originalPrice} 的差异:去除商品级优惠 + */ + private Integer orderPrice; + /** + * 订单优惠(总),单位:分 + * + * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。 + * + * 对应 taobao 的 order.discount_fee 字段 + */ + private Integer discountPrice; + /** + * 优惠劵减免金额(总),单位:分 + * + * 对应 taobao 的 trade.coupon_fee 字段 + */ + private Integer couponPrice; + /** + * 积分减免金额(总),单位:分 + * + * 对应 taobao 的 trade.point_fee 字段 + */ + private Integer pointPrice; + /** + * 运费金额,单位:分 + */ + private Integer deliveryPrice; + /** + * 最终购买金额(总),单位:分 + * + * = {@link OrderItem#getPayPrice()} 求和 + * - {@link #couponPrice} + * - {@link #pointPrice} + * + {@link #deliveryPrice} + * - {@link #discountPrice} + */ + private Integer payPrice; + /** + * 商品 SKU 数组 + */ + private List items; + + // ========== 营销基本信息 ========== + /** + * 优惠劵编号 + */ + private Long couponId; + + } + + /** + * 订单商品 SKU + */ + @Data + public static class OrderItem { + + /** + * SPU 编号 + */ + private Long spuId; + /** + * SKU 编号 + */ + private Long skuId; + /** + * 购买数量 + */ + private Integer count; + + /** + * 商品原价(总),单位:分 + * + * = {@link #originalUnitPrice} * {@link #getCount()} + */ + private Integer originalPrice; + /** + * 商品原价(单),单位:分 + * + * 对应 ProductSkuDO 的 price 字段 + * 对应 taobao 的 order.price 字段 + */ + private Integer originalUnitPrice; + /** + * 商品优惠(总),单位:分 + * + * 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元 + * + * 对应 taobao 的 order.discount_fee 字段 + */ + private Integer discountPrice; + /** + * 子订单实付金额,不算主订单分摊金额,单位:分 + * + * = {@link #originalPrice} + * - {@link #discountPrice} + * + * 对应 taobao 的 order.payment 字段 + */ + private Integer payPrice; + + /** + * 子订单分摊金额(总),单位:分 + * 需要分摊 {@link Order#discountPrice}、{@link Order#couponPrice}、{@link Order#pointPrice} + * + * 对应 taobao 的 order.part_mjz_discount 字段 + * 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。 + */ + private Integer orderPartPrice; + /** + * 分摊后子订单实付金额(总),单位:分 + * + * = {@link #payPrice} + * - {@link #orderPartPrice} + * + * 对应 taobao 的 divide_order_fee 字段 + */ + private Integer orderDividePrice; + + } + + /** + * 营销明细 + */ + @Data + public static class Promotion { + + /** + * 营销编号 + * + * 例如说:营销活动的编号、优惠劵的编号 + */ + private Long id; + /** + * 营销名字 + */ + private String name; + /** + * 营销类型 + * + * 枚举 {@link PromotionTypeEnum} + */ + private Integer type; + /** + * 营销级别 + * + * 枚举 {@link PromotionLevelEnum} + */ + private Integer level; + /** + * 计算时的原价(总),单位:分 + */ + private Integer originalPrice; + /** + * 计算时的优惠(总),单位:分 + */ + private Integer discountPrice; + /** + * 匹配的商品 SKU 数组 + */ + private List items; + + // ========== 匹配情况 ========== + + /** + * 是否满足优惠条件 + */ + private Boolean meet; + /** + * 满足条件的提示 + * + * 如果 {@link #meet} = true 满足,则提示“圣诞价:省 150.00 元” + * 如果 {@link #meet} = false 不满足,则提示“购满 85 元,可减 40 元” + */ + private String meetTip; + + } + + /** + * 营销匹配的商品 SKU + */ + @Data + public static class PromotionItem { + + /** + * 商品 SKU 编号 + */ + private Long skuId; + /** + * 计算时的原价(总),单位:分 + */ + private Integer originalPrice; + /** + * 计算时的优惠(总),单位:分 + */ + private Integer discountPrice; + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java new file mode 100644 index 000000000..47ce28b4b --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java @@ -0,0 +1,60 @@ +package cn.iocoder.yudao.module.promotion.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * promotion 错误码枚举类 + * + * market 系统,使用 1-003-000-000 段 + */ +public interface ErrorCodeConstants { + + // ========== 促销活动相关 1003001000 ============ + ErrorCode DISCOUNT_ACTIVITY_NOT_EXISTS = new ErrorCode(1003001000, "限时折扣活动不存在"); + ErrorCode DISCOUNT_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003006001, "存在商品参加了其它限时折扣活动"); + ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "限时折扣活动已关闭,不能修改"); + ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "限时折扣活动未关闭,不能删除"); + ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "限时折扣活动已关闭,不能重复关闭"); + ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "限时折扣活动已结束,不能关闭"); + + // ========== Banner 相关 1003002000 ============ + ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1003002000, "Banner 不存在"); + + // ========== Coupon 相关 1003003000 ============ + ErrorCode COUPON_NO_MATCH_SPU = new ErrorCode(1003003000, "优惠劵没有可使用的商品!"); + ErrorCode COUPON_NO_MATCH_MIN_PRICE = new ErrorCode(1003003000, "所结算的商品中未满足使用的金额"); + + // ========== 优惠劵模板 1003004000 ========== + ErrorCode COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1003004000, "优惠劵模板不存在"); + ErrorCode COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL = new ErrorCode(1003004001, "发放数量不能小于已领取数量({})"); + + // ========== 优惠劵模板 1003005000 ========== + ErrorCode COUPON_NOT_EXISTS = new ErrorCode(1003005000, "优惠券不存在"); + ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1003005001, "回收优惠劵失败,优惠劵已被使用"); + ErrorCode COUPON_STATUS_NOT_UNUSED = new ErrorCode(1006003003, "优惠劵不处于待使用状态"); + ErrorCode COUPON_VALID_TIME_NOT_NOW = new ErrorCode(1006003004, "优惠券不在使用时间范围内"); + + // ========== 满减送活动 1003006000 ========== + ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1003006000, "满减送活动不存在"); + ErrorCode REWARD_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003006001, "存在商品参加了其它满减送活动"); + ErrorCode REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003006002, "满减送活动已关闭,不能修改"); + ErrorCode REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1003006003, "满减送活动未关闭,不能删除"); + ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003006004, "满减送活动已关闭,不能重复关闭"); + ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003006004, "满减送活动已结束,不能关闭"); + + // ========== Price 相关 1003007000 ============ + ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1003007000, "支付价格计算异常,原因:价格小于等于 0"); + + // ========== 秒杀活动 1003008000 ========== + ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1003008000, "秒杀活动不存在"); + ErrorCode SECKILL_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1003008002, "存在商品参加了其它秒杀活动"); + ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1003008003, "秒杀活动已关闭,不能修改"); + ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1003008004, "秒杀活动未关闭或未结束,不能删除"); + ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1003008005, "秒杀活动已关闭,不能重复关闭"); + ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1003008006, "秒杀活动已结束,不能关闭"); + + // ========== 秒杀时段 1003009000 ========== + ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1003009000, "秒杀时段不存在"); + ErrorCode SECKILL_TIME_CONFLICTS = new ErrorCode(1003009001, "秒杀时段冲突"); + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java new file mode 100644 index 000000000..db79f871b --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 促销活动的状态枚举 + * + * @author 芋道源码 + */ +@AllArgsConstructor +@Getter +public enum PromotionActivityStatusEnum implements IntArrayValuable { + + WAIT(10, "未开始"), + RUN(20, "进行中"), + END(30, "已结束"), + CLOSE(40, "已关闭"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionActivityStatusEnum::getStatus).toArray(); + + /** + * 状态值 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java new file mode 100644 index 000000000..05e62e399 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 营销的条件类型枚举 + * + * @author 芋道源码 + */ +@AllArgsConstructor +@Getter +public enum PromotionConditionTypeEnum implements IntArrayValuable { + + PRICE(10, "满 N 元"), + COUNT(20, "满 N 件"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionConditionTypeEnum::getType).toArray(); + + /** + * 类型值 + */ + private final Integer type; + /** + * 类型名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionDiscountTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionDiscountTypeEnum.java new file mode 100644 index 000000000..7da6b4b08 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionDiscountTypeEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 优惠类型枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PromotionDiscountTypeEnum implements IntArrayValuable { + + PRICE(1, "满减"), // 具体金额 + PERCENT(2, "折扣"), // 百分比 + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionDiscountTypeEnum::getType).toArray(); + + /** + * 优惠类型 + */ + private final Integer type; + /** + * 名字 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java new file mode 100644 index 000000000..ed0564a70 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 营销的级别枚举 + * + * 参考有赞:营销级别 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PromotionLevelEnum implements IntArrayValuable { + + ORDER(1, "订单级"), // 多个商品,进行组合后优惠。例如说:满减送、打包一口价、第二件半价 + SKU(2, "商品级"), // 单个商品,直接优惠。例如说:限时折扣、会员折扣 + COUPON(3, "优惠劵"), // 多个商品,进行组合后优惠。例如说:优惠劵 + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionLevelEnum::getLevel).toArray(); + + /** + * 级别值 + */ + private final Integer level; + /** + * 类型名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java new file mode 100644 index 000000000..0a7a4994d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 营销的商品范围枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PromotionProductScopeEnum implements IntArrayValuable { + + ALL(1, "全部商品参与"), + SPU(2, "指定商品参与"), + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionProductScopeEnum::getScope).toArray(); + + /** + * 范围值 + */ + private final Integer scope; + /** + * 范围名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java new file mode 100644 index 000000000..eea48f7dc --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 营销类型枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PromotionTypeEnum implements IntArrayValuable { + + DISCOUNT_ACTIVITY(1, "限时折扣"), + REWARD_ACTIVITY(2, "满减送"), + + MEMBER(3, "会员折扣"), + COUPON(4, "优惠劵") + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray(); + + /** + * 类型值 + */ + private final Integer type; + /** + * 类型名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponStatusEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponStatusEnum.java new file mode 100644 index 000000000..320345d85 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponStatusEnum.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.promotion.enums.coupon; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 优惠劵状态枚举 + * + * @author 芋道源码 + */ +@AllArgsConstructor +@Getter +public enum CouponStatusEnum implements IntArrayValuable { + + UNUSED(1, "未使用"), + USED(2, "已使用"), + EXPIRE(3, "已过期"), + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponStatusEnum::getStatus).toArray(); + + /** + * 值 + */ + private final Integer status; + /** + * 名字 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTakeTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTakeTypeEnum.java new file mode 100644 index 000000000..ce7974142 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTakeTypeEnum.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.promotion.enums.coupon; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 优惠劵领取方式 + * + * @author 芋道源码 + */ +@AllArgsConstructor +@Getter +public enum CouponTakeTypeEnum implements IntArrayValuable { + + BY_USER(1, "直接领取"), // 用户可在首页、每日领劵直接领取 + BY_ADMIN(2, "指定发放"), // 后台指定会员赠送优惠劵 + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponTakeTypeEnum::getValue).toArray(); + + /** + * 值 + */ + private final Integer value; + /** + * 名字 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTemplateValidityTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTemplateValidityTypeEnum.java new file mode 100644 index 000000000..391515de3 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTemplateValidityTypeEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.promotion.enums.coupon; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 优惠劵模板的有限期类型的枚举 + * + * @author 芋道源码 + */ +@AllArgsConstructor +@Getter +public enum CouponTemplateValidityTypeEnum implements IntArrayValuable { + + DATE(1, "固定日期"), + TERM(2, "领取之后"), + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponTemplateValidityTypeEnum::getType).toArray(); + + /** + * 值 + */ + private final Integer type; + /** + * 名字 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/pom.xml b/yudao-module-mall/yudao-module-promotion-biz/pom.xml new file mode 100644 index 000000000..266cb1511 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/pom.xml @@ -0,0 +1,77 @@ + + + + cn.iocoder.boot + yudao-module-mall + ${revision} + + 4.0.0 + jar + yudao-module-promotion-biz + + ${project.artifactId} + + + market模块,主要实现营销相关功能 + 例如:营销活动、banner广告、优惠券、优惠码等功能。 + + + + + cn.iocoder.boot + yudao-module-promotion-api + ${revision} + + + cn.iocoder.boot + yudao-module-product-api + ${revision} + + + cn.iocoder.boot + yudao-module-member-api + ${revision} + + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-operatelog + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-weixin + + + + + cn.iocoder.boot + yudao-spring-boot-starter-web + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + + cn.iocoder.boot + yudao-spring-boot-starter-test + + + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + + + diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java new file mode 100644 index 000000000..349eba1ff --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.promotion.api.coupon; + + +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; +import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 优惠劵 API 实现类 + * + * @author 芋道源码 + */ +@Service +public class CouponApiImpl implements CouponApi { + + @Resource + private CouponService couponService; + + @Override + public void useCoupon(CouponUseReqDTO useReqDTO) { + couponService.useCoupon(useReqDTO.getId(), useReqDTO.getUserId(), + useReqDTO.getOrderId()); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java new file mode 100644 index 000000000..4e3ce77a8 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.promotion.api.discount; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java new file mode 100644 index 000000000..3c415f1c4 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.promotion.api.price; + +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.service.price.PriceService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 价格 API 实现类 + * + * @author 芋道源码 + */ +@Service +public class PriceApiImpl implements PriceApi { + + @Resource + private PriceService priceService; + + @Override + public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { + return priceService.calculatePrice(calculateReqDTO); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java new file mode 100644 index 000000000..0bf2b2c33 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; +import cn.iocoder.yudao.module.promotion.service.banner.BannerService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - Banner 管理") +@RestController +@RequestMapping("/market/banner") +@Validated +public class BannerController { + + @Resource + private BannerService bannerService; + + @PostMapping("/create") + @Operation(summary = "创建 Banner") + @PreAuthorize("@ss.hasPermission('market:banner:create')") + public CommonResult createBanner(@Valid @RequestBody BannerCreateReqVO createReqVO) { + return success(bannerService.createBanner(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新 Banner") + @PreAuthorize("@ss.hasPermission('market:banner:update')") + public CommonResult updateBanner(@Valid @RequestBody BannerUpdateReqVO updateReqVO) { + bannerService.updateBanner(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除 Banner") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('market:banner:delete')") + public CommonResult deleteBanner(@RequestParam("id") Long id) { + bannerService.deleteBanner(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得 Banner") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('market:banner:query')") + public CommonResult getBanner(@RequestParam("id") Long id) { + BannerDO banner = bannerService.getBanner(id); + return success(BannerConvert.INSTANCE.convert(banner)); + } + + @GetMapping("/page") + @Operation(summary = "获得 Banner 分页") + @PreAuthorize("@ss.hasPermission('market:banner:query')") + public CommonResult> getBannerPage(@Valid BannerPageReqVO pageVO) { + PageResult pageResult = bannerService.getBannerPage(pageVO); + return success(BannerConvert.INSTANCE.convertPage(pageResult)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java new file mode 100644 index 000000000..6c72155f4 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * Banner Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + * @author xia + */ +@Data +public class BannerBaseVO { + + @Schema(description = "标题", required = true) + @NotNull(message = "标题不能为空") + private String title; + + @Schema(description = "跳转链接", required = true) + @NotNull(message = "跳转链接不能为空") + private String url; + + @Schema(description = "图片地址", required = true) + @NotNull(message = "图片地址不能为空") + private String picUrl; + + @Schema(description = "排序", required = true) + @NotNull(message = "排序不能为空") + private Integer sort; + + @Schema(description = "状态", required = true) + @NotNull(message = "状态不能为空") + @InEnum(CommonStatusEnum.class) + private Integer status; + + @Schema(description = "备注") + private String memo; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java new file mode 100644 index 000000000..180cdfe87 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +/** + * @author xia + */ +@Schema(description = "管理后台 - Banner 创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BannerCreateReqVO extends BannerBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java new file mode 100644 index 000000000..b97008ccd --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * @author xia + */ +@Schema(description = "管理后台 - Banner 分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BannerPageReqVO extends PageParam { + + @Schema(description = "标题") + private String title; + + + @Schema(description = "状态") + @InEnum(CommonStatusEnum.class) + private Integer status; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @Schema(description = "创建时间") + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java new file mode 100644 index 000000000..fb0010669 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +/** + * @author xia + */ +@Schema(description = "管理后台 - Banner Response VO") +@Data +@ToString(callSuper = true) +public class BannerRespVO extends BannerBaseVO { + + @Schema(description = "banner编号", required = true) + @NotNull(message = "banner编号不能为空") + private Long id; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java new file mode 100644 index 000000000..033b6054d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +/** + * @author xia + */ +@Schema(description = "管理后台 - Banner更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BannerUpdateReqVO extends BannerBaseVO { + + @Schema(description = "banner 编号", required = true) + @NotNull(message = "banner 编号不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java new file mode 100755 index 000000000..e7780ca2a --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java @@ -0,0 +1,75 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; +import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Map; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +@Tag(name = "管理后台 - 优惠劵") +@RestController +@RequestMapping("/promotion/coupon") +@Validated +public class CouponController { + + @Resource + private CouponService couponService; + @Resource + private MemberUserApi memberUserApi; + +// @GetMapping("/get") +// @Operation(summary = "获得优惠劵") +// @Parameter(name = "id", description = "编号", required = true, example = "1024") +// @PreAuthorize("@ss.hasPermission('promotion:coupon:query')") +// public CommonResult getCoupon(@RequestParam("id") Long id) { +// CouponDO coupon = couponService.getCoupon(id); +// return success(CouponConvert.INSTANCE.convert(coupon)); +// } + + @DeleteMapping("/delete") + @Operation(summary = "回收优惠劵") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:coupon:delete')") + public CommonResult deleteCoupon(@RequestParam("id") Long id) { + couponService.deleteCoupon(id); + return success(true); + } + + @GetMapping("/page") + @Operation(summary = "获得优惠劵分页") + @PreAuthorize("@ss.hasPermission('promotion:coupon:query')") + public CommonResult> getCouponPage(@Valid CouponPageReqVO pageVO) { + PageResult pageResult = couponService.getCouponPage(pageVO); + PageResult pageResulVO = CouponConvert.INSTANCE.convertPage(pageResult); + if (CollUtil.isEmpty(pageResulVO.getList())) { + return success(pageResulVO); + } + // 读取用户信息,进行拼接 + Set userIds = convertSet(pageResult.getList(), CouponDO::getUserId); + Map userMap = memberUserApi.getUserMap(userIds); + pageResulVO.getList().forEach(itemRespVO -> MapUtils.findAndThen(userMap, itemRespVO.getUserId(), + userRespDTO -> itemRespVO.setNickname(userRespDTO.getNickname()))); + return success(pageResulVO); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java new file mode 100755 index 000000000..1b1ae505c --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java @@ -0,0 +1,79 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.*; +import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; +import cn.iocoder.yudao.module.promotion.service.coupon.CouponTemplateService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 优惠劵模板") +@RestController +@RequestMapping("/promotion/coupon-template") +@Validated +public class CouponTemplateController { + + @Resource + private CouponTemplateService couponTemplateService; + + @PostMapping("/create") + @Operation(summary = "创建优惠劵模板") + @PreAuthorize("@ss.hasPermission('promotion:coupon-template:create')") + public CommonResult createCouponTemplate(@Valid @RequestBody CouponTemplateCreateReqVO createReqVO) { + return success(couponTemplateService.createCouponTemplate(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新优惠劵模板") + @PreAuthorize("@ss.hasPermission('promotion:coupon-template:update')") + public CommonResult updateCouponTemplate(@Valid @RequestBody CouponTemplateUpdateReqVO updateReqVO) { + couponTemplateService.updateCouponTemplate(updateReqVO); + return success(true); + } + + @PutMapping("/update-status") + @Operation(summary = "更新优惠劵模板状态") + @PreAuthorize("@ss.hasPermission('promotion:coupon-template:update')") + public CommonResult updateCouponTemplateStatus(@Valid @RequestBody CouponTemplateUpdateStatusReqVO reqVO) { + couponTemplateService.updateCouponTemplateStatus(reqVO.getId(), reqVO.getStatus()); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除优惠劵模板") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:coupon-template:delete')") + public CommonResult deleteCouponTemplate(@RequestParam("id") Long id) { + couponTemplateService.deleteCouponTemplate(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得优惠劵模板") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('promotion:coupon-template:query')") + public CommonResult getCouponTemplate(@RequestParam("id") Long id) { + CouponTemplateDO couponTemplate = couponTemplateService.getCouponTemplate(id); + return success(CouponTemplateConvert.INSTANCE.convert(couponTemplate)); + } + + @GetMapping("/page") + @Operation(summary = "获得优惠劵模板分页") + @PreAuthorize("@ss.hasPermission('promotion:coupon-template:query')") + public CommonResult> getCouponTemplatePage(@Valid CouponTemplatePageReqVO pageVO) { + PageResult pageResult = couponTemplateService.getCouponTemplatePage(pageVO); + return success(CouponTemplateConvert.INSTANCE.convertPage(pageResult)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java new file mode 100755 index 000000000..2609c0a2c --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java @@ -0,0 +1,103 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; + +/** +* 优惠劵 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class CouponBaseVO { + + // ========== 基本信息 BEGIN ========== + @Schema(description = "优惠劵模板编号", required = true, example = "1024") + @NotNull(message = "优惠劵模板编号不能为空") + private Integer templateId; + + @Schema(description = "优惠劵名", required = true, example = "春节送送送") + @NotNull(message = "优惠劵名不能为空") + private String name; + + @Schema(description = "优惠码状态", required = true, example = "1") + private Integer status; + + // ========== 基本信息 END ========== + + // ========== 领取情况 BEGIN ========== + @Schema(description = "用户编号", required = true, example = "1") + @NotNull(message = "用户编号不能为空") + private Long userId; + + @Schema(description = "领取方式", required = true, example = "1") + @NotNull(message = "领取方式不能为空") + private Integer takeType; + // ========== 领取情况 END ========== + + // ========== 使用规则 BEGIN ========== + @Schema(description = "是否设置满多少金额可用", required = true, example = "100") // 单位:分;0 - 不限制 + @NotNull(message = "是否设置满多少金额可用不能为空") + private Integer usePrice; + + @Schema(description = "固定日期 - 生效开始时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime validStartTime; + + @Schema(description = "固定日期 - 生效结束时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime validEndTime; + + @Schema(description = "商品范围", required = true, example = "1") + @NotNull(message = "商品范围不能为空") + @InEnum(PromotionProductScopeEnum.class) + private Integer productScope; + + @Schema(description = "商品 SPU 编号的数组", example = "1,3") + private List productSpuIds; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + @Schema(description = "优惠类型", required = true, example = "1") + @NotNull(message = "优惠类型不能为空") + @InEnum(PromotionDiscountTypeEnum.class) + private Integer discountType; + + @Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80 + private Integer discountPercent; + + @Schema(description = "优惠金额", example = "10") + @Min(value = 0, message = "优惠金额需要大于等于 0") + private Integer discountPrice; + + @Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用 + private Integer discountLimitPrice; + // ========== 使用效果 END ========== + + // ========== 使用情况 BEGIN ========== + + @Schema(description = "使用订单号", example = "4096") + private Long useOrderId; + + @Schema(description = "使用时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime useTime; + + // ========== 使用情况 END ========== + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java new file mode 100755 index 000000000..118736ef6 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 优惠劵分页的每一项 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CouponPageItemRespVO extends CouponRespVO { + + @Schema(description = "用户昵称", example = "老芋艿") + private String nickname; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java new file mode 100755 index 000000000..11d61a518 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 优惠劵分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CouponPageReqVO extends PageParam { + + @Schema(description = "优惠劵模板编号", example = "2048") + private Long templateId; + + @Schema(description = "优惠码状态", example = "1") + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + @Schema(description = "用户昵称", example = "芋艿") + private String nickname; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java new file mode 100755 index 000000000..68f0bc44e --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 优惠劵 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CouponRespVO extends CouponBaseVO { + + @Schema(description = "优惠劵编号", required = true, example = "1024") + private Long id; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java new file mode 100755 index 000000000..d63d447cc --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java @@ -0,0 +1,154 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; + +/** +* 优惠劵模板 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class CouponTemplateBaseVO { + + @Schema(description = "优惠劵名", required = true, example = "春节送送送") + @NotNull(message = "优惠劵名不能为空") + private String name; + + @Schema(description = "发行总量", required = true, example = "1024") // -1 - 则表示不限制发放数量 + @NotNull(message = "发行总量不能为空") + private Integer totalCount; + + @Schema(description = "每人限领个数", required = true, example = "66") // -1 - 则表示不限制 + @NotNull(message = "每人限领个数不能为空") + private Integer takeLimitCount; + + @Schema(description = "领取方式", required = true, example = "1") + @NotNull(message = "领取方式不能为空") + private Integer takeType; + + @Schema(description = "是否设置满多少金额可用", required = true, example = "100") // 单位:分;0 - 不限制 + @NotNull(message = "是否设置满多少金额可用不能为空") + private Integer usePrice; + + @Schema(description = "商品范围", required = true, example = "1") + @NotNull(message = "商品范围不能为空") + @InEnum(PromotionProductScopeEnum.class) + private Integer productScope; + + @Schema(description = "商品 SPU 编号的数组", example = "1,3") + private List productSpuIds; + + @Schema(description = "生效日期类型", required = true, example = "1") + @NotNull(message = "生效日期类型不能为空") + @InEnum(CouponTemplateValidityTypeEnum.class) + private Integer validityType; + + @Schema(description = "固定日期 - 生效开始时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime validStartTime; + + @Schema(description = "固定日期 - 生效结束时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime validEndTime; + + @Schema(description = "领取日期 - 开始天数") + @Min(value = 0L, message = "开始天数必须大于 0") + private Integer fixedStartTerm; + + @Schema(description = "领取日期 - 结束天数") + @Min(value = 1L, message = "开始天数必须大于 1") + private Integer fixedEndTerm; + + @Schema(description = "优惠类型", required = true, example = "1") + @NotNull(message = "优惠类型不能为空") + @InEnum(PromotionDiscountTypeEnum.class) + private Integer discountType; + + @Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80 + private Integer discountPercent; + + @Schema(description = "优惠金额", example = "10") + @Min(value = 0, message = "优惠金额需要大于等于 0") + private Integer discountPrice; + + @Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用 + private Integer discountLimitPrice; + + @AssertTrue(message = "商品 SPU 编号的数组不能为空") + @JsonIgnore + public boolean isProductSpuIdsValid() { + return Objects.equals(productScope, PromotionProductScopeEnum.ALL.getScope()) // 全部范围时,可以为空 + || CollUtil.isNotEmpty(productSpuIds); + } + + @AssertTrue(message = "生效开始时间不能为空") + @JsonIgnore + public boolean isValidStartTimeValid() { + return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.DATE.getType()) + || validStartTime != null; + } + + @AssertTrue(message = "生效结束时间不能为空") + @JsonIgnore + public boolean isValidEndTimeValid() { + return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.DATE.getType()) + || validEndTime != null; + } + + @AssertTrue(message = "开始天数不能为空") + @JsonIgnore + public boolean isFixedStartTermValid() { + return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.TERM.getType()) + || fixedStartTerm != null; + } + + @AssertTrue(message = "结束天数不能为空") + @JsonIgnore + public boolean isFixedEndTermValid() { + return ObjectUtil.notEqual(validityType, CouponTemplateValidityTypeEnum.TERM.getType()) + || fixedEndTerm != null; + } + + @AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99") + @JsonIgnore + public boolean isDiscountPercentValid() { + return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType()) + || (discountPercent != null && discountPercent >= 1 && discountPercent<= 99); + } + + @AssertTrue(message = "优惠金额不能为空") + @JsonIgnore + public boolean isDiscountPriceValid() { + return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType()) + || discountPrice != null; + } + + @AssertTrue(message = "折扣上限不能为空") + @JsonIgnore + public boolean isDiscountLimitPriceValid() { + return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType()) + || discountLimitPrice != null; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java new file mode 100755 index 000000000..d9c5c326d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 优惠劵模板创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CouponTemplateCreateReqVO extends CouponTemplateBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java new file mode 100755 index 000000000..e78d0140f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 优惠劵模板分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CouponTemplatePageReqVO extends PageParam { + + @Schema(description = "优惠劵名", example = "你好") + private String name; + + @Schema(description = "状态", example = "1") + private Integer status; + + @Schema(description = "优惠类型", example = "1") + private Integer discountType; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java new file mode 100755 index 000000000..b90407b43 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 优惠劵模板 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CouponTemplateRespVO extends CouponTemplateBaseVO { + + @Schema(description = "模板编号", required = true, example = "1024") + private Long id; + + @Schema(description = "状态", required = true, example = "1") + @InEnum(CommonStatusEnum.class) + private Integer status; + + @Schema(description = "领取优惠券的数量", required = true, example = "1024") + private Integer takeCount; + + @Schema(description = "使用优惠券的次数", required = true, example = "2048") + private Integer useCount; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java new file mode 100755 index 000000000..922e4f057 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 优惠劵模板更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CouponTemplateUpdateReqVO extends CouponTemplateBaseVO { + + @Schema(description = "模板编号", required = true, example = "1024") + @NotNull(message = "模板编号不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java new file mode 100644 index 000000000..630f91fea --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 优惠劵模板更新状态 Request VO") +@Data +public class CouponTemplateUpdateStatusReqVO { + + @Schema(description = "优惠劵模板编号", required = true, example = "1024") + @NotNull(message = "优惠劵模板编号不能为空") + private Long id; + + @Schema(description = "状态", required = true, example = "1") + @NotNull(message = "状态不能为空") + @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java new file mode 100755 index 000000000..b3b1810fc --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java @@ -0,0 +1,87 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.discount; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*; +import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; +import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 限时折扣活动") +@RestController +@RequestMapping("/promotion/discount-activity") +@Validated +public class DiscountActivityController { + + @Resource + private DiscountActivityService discountActivityService; + + @PostMapping("/create") + @Operation(summary = "创建限时折扣活动") + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:create')") + public CommonResult createDiscountActivity(@Valid @RequestBody DiscountActivityCreateReqVO createReqVO) { + return success(discountActivityService.createDiscountActivity(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新限时折扣活动") + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:update')") + public CommonResult updateDiscountActivity(@Valid @RequestBody DiscountActivityUpdateReqVO updateReqVO) { + discountActivityService.updateDiscountActivity(updateReqVO); + return success(true); + } + + @PutMapping("/close") + @Operation(summary = "关闭限时折扣活动") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:close')") + public CommonResult closeRewardActivity(@RequestParam("id") Long id) { + discountActivityService.closeRewardActivity(id); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除限时折扣活动") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:delete')") + public CommonResult deleteDiscountActivity(@RequestParam("id") Long id) { + discountActivityService.deleteDiscountActivity(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得限时折扣活动") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')") + public CommonResult getDiscountActivity(@RequestParam("id") Long id) { + DiscountActivityDO discountActivity = discountActivityService.getDiscountActivity(id); + if (discountActivity == null) { + return success(null); + } + // 拼接结果 + List discountProducts = discountActivityService.getDiscountProductsByActivityId(id); + return success(DiscountActivityConvert.INSTANCE.convert(discountActivity, discountProducts)); + } + + @GetMapping("/page") + @Operation(summary = "获得限时折扣活动分页") + @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')") + public CommonResult> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) { + PageResult pageResult = discountActivityService.getDiscountActivityPage(pageVO); + return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java new file mode 100755 index 000000000..1f0d6e066 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java @@ -0,0 +1,81 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** +* 限时折扣活动 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class DiscountActivityBaseVO { + + @Schema(description = "活动标题", required = true, example = "一个标题") + @NotNull(message = "活动标题不能为空") + private String name; + + @Schema(description = "开始时间", required = true) + @NotNull(message = "开始时间不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime startTime; + + @Schema(description = "结束时间", required = true) + @NotNull(message = "结束时间不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime endTime; + + @Schema(description = "备注", example = "我是备注") + private String remark; + + @Schema(description = "商品") + @Data + public static class Product { + + @Schema(description = "商品 SPU 编号", required = true, example = "1") + @NotNull(message = "商品 SPU 编号不能为空") + private Long spuId; + + @Schema(description = "商品 SKU 编号", required = true, example = "1") + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + @Schema(description = "优惠类型", required = true, example = "1") + @NotNull(message = "优惠类型不能为空") + @InEnum(PromotionDiscountTypeEnum.class) + private Integer discountType; + + @Schema(description = "折扣百分比", example = "80") // 例如说,80% 为 80 + private Integer discountPercent; + + @Schema(description = "优惠金额", example = "10") + @Min(value = 0, message = "优惠金额需要大于等于 0") + private Integer discountPrice; + + @AssertTrue(message = "折扣百分比需要大于等于 1,小于等于 99") + @JsonIgnore + public boolean isDiscountPercentValid() { + return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PERCENT.getType()) + || (discountPercent != null && discountPercent >= 1 && discountPercent<= 99); + } + + @AssertTrue(message = "优惠金额不能为空") + @JsonIgnore + public boolean isDiscountPriceValid() { + return ObjectUtil.notEqual(discountType, PromotionDiscountTypeEnum.PRICE.getType()) + || discountPrice != null; + } + + } +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java new file mode 100755 index 000000000..4da80a1b9 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +@Schema(description = "管理后台 - 限时折扣活动创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DiscountActivityCreateReqVO extends DiscountActivityBaseVO { + + /** + * 商品列表 + */ + @NotEmpty(message = "商品列表不能为空") + @Valid + private List products; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java new file mode 100755 index 000000000..85a989c05 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; + +@Schema(description = "管理后台 - 限时折扣活动的详细 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DiscountActivityDetailRespVO extends DiscountActivityRespVO { + + /** + * 商品列表 + */ + private List products; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java new file mode 100755 index 000000000..4463555ea --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 限时折扣活动分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DiscountActivityPageReqVO extends PageParam { + + @Schema(description = "活动标题", example = "一个标题") + private String name; + + @Schema(description = "活动状态", example = "1") + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java new file mode 100755 index 000000000..b552c56ed --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 限时折扣活动 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DiscountActivityRespVO extends DiscountActivityBaseVO { + + @Schema(description = "活动编号", required = true, example = "1024") + private Long id; + + @Schema(description = "活动状态", required = true, example = "1") + @NotNull(message = "活动状态不能为空") + private Integer status; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java new file mode 100755 index 000000000..f9bf48c06 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "管理后台 - 限时折扣活动更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class DiscountActivityUpdateReqVO extends DiscountActivityBaseVO { + + @Schema(description = "活动编号", required = true, example = "1024") + @NotNull(message = "活动编号不能为空") + private Long id; + + /** + * 商品列表 + */ + @NotEmpty(message = "商品列表不能为空") + @Valid + private List products; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java new file mode 100755 index 000000000..7827fd114 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java @@ -0,0 +1,83 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.reward; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; +import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 满减送活动") +@RestController +@RequestMapping("/promotion/reward-activity") +@Validated +public class RewardActivityController { + + @Resource + private RewardActivityService rewardActivityService; + + @PostMapping("/create") + @Operation(summary = "创建满减送活动") + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:create')") + public CommonResult createRewardActivity(@Valid @RequestBody RewardActivityCreateReqVO createReqVO) { + return success(rewardActivityService.createRewardActivity(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新满减送活动") + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:update')") + public CommonResult updateRewardActivity(@Valid @RequestBody RewardActivityUpdateReqVO updateReqVO) { + rewardActivityService.updateRewardActivity(updateReqVO); + return success(true); + } + + @PutMapping("/close") + @Operation(summary = "关闭满减送活动") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:close')") + public CommonResult closeRewardActivity(@RequestParam("id") Long id) { + rewardActivityService.closeRewardActivity(id); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除满减送活动") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:delete')") + public CommonResult deleteRewardActivity(@RequestParam("id") Long id) { + rewardActivityService.deleteRewardActivity(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得满减送活动") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:query')") + public CommonResult getRewardActivity(@RequestParam("id") Long id) { + RewardActivityDO rewardActivity = rewardActivityService.getRewardActivity(id); + return success(RewardActivityConvert.INSTANCE.convert(rewardActivity)); + } + + @GetMapping("/page") + @Operation(summary = "获得满减送活动分页") + @PreAuthorize("@ss.hasPermission('promotion:reward-activity:query')") + public CommonResult> getRewardActivityPage(@Valid RewardActivityPageReqVO pageVO) { + PageResult pageResult = rewardActivityService.getRewardActivityPage(pageVO); + return success(RewardActivityConvert.INSTANCE.convertPage(pageResult)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java new file mode 100755 index 000000000..2cd7c7240 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java @@ -0,0 +1,98 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.Valid; +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.Future; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** +* 满减送活动 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class RewardActivityBaseVO { + + @Schema(description = "活动标题", required = true, example = "满啦满啦") + @NotNull(message = "活动标题不能为空") + private String name; + + @Schema(description = "开始时间", required = true) + @NotNull(message = "开始时间不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime startTime; + + @Schema(description = "结束时间", required = true) + @NotNull(message = "结束时间不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @Future(message = "结束时间必须大于当前时间") + private LocalDateTime endTime; + + @Schema(description = "备注", example = "biubiubiu") + private String remark; + + @Schema(description = "条件类型", required = true, example = "1") + @NotNull(message = "条件类型不能为空") + @InEnum(value = PromotionConditionTypeEnum.class, message = "条件类型必须是 {value}") + private Integer conditionType; + + @Schema(description = "商品范围", required = true, example = "1") + @NotNull(message = "商品范围不能为空") + @InEnum(value = PromotionConditionTypeEnum.class, message = "商品范围必须是 {value}") + private Integer productScope; + + @Schema(description = "商品 SPU 编号的数组", example = "1,2,3") + private List productSpuIds; + + /** + * 优惠规则的数组 + */ + @Valid // 校验下子对象 + private List rules; + + @Schema(description = "优惠规则") + @Data + public static class Rule { + + @Schema(description = "优惠门槛", required = true, example = "100") // 1. 满 N 元,单位:分; 2. 满 N 件 + @Min(value = 1L, message = "优惠门槛必须大于等于 1") + private Integer limit; + + @Schema(description = "优惠价格", required = true, example = "100") + @Min(value = 1L, message = "优惠价格必须大于等于 1") + private Integer discountPrice; + + @Schema(description = "是否包邮", required = true, example = "true") + private Boolean freeDelivery; + + @Schema(description = "赠送的积分", required = true, example = "100") + @Min(value = 1L, message = "赠送的积分必须大于等于 1") + private Integer point; + + @Schema(description = "赠送的优惠劵编号的数组", example = "1,2,3") + private List couponIds; + + @Schema(description = "赠送的优惠卷数量的数组", example = "1,2,3") + private List couponCounts; + + @AssertTrue(message = "优惠劵和数量必须一一对应") + @JsonIgnore + public boolean isCouponCountsValid() { + return CollUtil.size(couponCounts) == CollUtil.size(couponCounts); + } + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java new file mode 100755 index 000000000..0710e46a4 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 满减送活动创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class RewardActivityCreateReqVO extends RewardActivityBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java new file mode 100755 index 000000000..7052c9c66 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 满减送活动分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class RewardActivityPageReqVO extends PageParam { + + @Schema(description = "活动标题", example = "满啦满啦") + private String name; + + @Schema(description = "活动状态", example = "1") + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java new file mode 100755 index 000000000..8ad93cb59 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 满减送活动 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class RewardActivityRespVO extends RewardActivityBaseVO { + + @Schema(description = "活动编号", required = true, example = "1024") + private Integer id; + + @Schema(description = "活动状态", required = true, example = "1") + private Integer status; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java new file mode 100755 index 000000000..66d9c02ba --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 满减送活动更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class RewardActivityUpdateReqVO extends RewardActivityBaseVO { + + @Schema(description = "活动编号", required = true, example = "1024") + @NotNull(message = "活动编号不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java new file mode 100644 index 000000000..ba750b296 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java @@ -0,0 +1,96 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.*; +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; +import cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity.SeckillActivityService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 秒杀活动") +@RestController +@RequestMapping("/promotion/seckill-activity") +@Validated +public class SeckillActivityController { + + @Resource + private SeckillActivityService seckillActivityService; + + @PostMapping("/create") + @Operation(summary = "创建秒杀活动") + @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:create')") + public CommonResult createSeckillActivity(@Valid @RequestBody SeckillActivityCreateReqVO createReqVO) { + return success(seckillActivityService.createSeckillActivity(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新秒杀活动") + @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:update')") + public CommonResult updateSeckillActivity(@Valid @RequestBody SeckillActivityUpdateReqVO updateReqVO) { + seckillActivityService.updateSeckillActivity(updateReqVO); + return success(true); + } + + @PutMapping("/close") + @Operation(summary = "关闭秒杀活动") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:close')") + public CommonResult closeSeckillActivity(@RequestParam("id") Long id) { + seckillActivityService.closeSeckillActivity(id); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除秒杀活动") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:delete')") + public CommonResult deleteSeckillActivity(@RequestParam("id") Long id) { + seckillActivityService.deleteSeckillActivity(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得秒杀活动") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')") + public CommonResult getSeckillActivity(@RequestParam("id") Long id) { + SeckillActivityDO seckillActivity = seckillActivityService.getSeckillActivity(id); + if (seckillActivity == null) { + return success(null); + } + List seckillProducts = seckillActivityService.getSeckillProductListByActivityId(id); + return success(SeckillActivityConvert.INSTANCE.convert(seckillActivity,seckillProducts)); + } + + @GetMapping("/list") + @Operation(summary = "获得秒杀活动列表") + @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") + @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')") + public CommonResult> getSeckillActivityList(@RequestParam("ids") Collection ids) { + List list = seckillActivityService.getSeckillActivityList(ids); + return success(SeckillActivityConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @Operation(summary = "获得秒杀活动分页") + @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')") + public CommonResult> getSeckillActivityPage(@Valid SeckillActivityPageReqVO pageVO) { + PageResult pageResult = seckillActivityService.getSeckillActivityPage(pageVO); + return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java new file mode 100644 index 000000000..992f34ab9 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime.SeckillTimeConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; +import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 秒杀时段") +@RestController +@RequestMapping("/promotion/seckill-time") +@Validated +public class SeckillTimeController { + + @Resource + private SeckillTimeService seckillTimeService; + + @PostMapping("/create") + @Operation(summary = "创建秒杀时段") + @PreAuthorize("@ss.hasPermission('promotion:seckill-time:create')") + public CommonResult createSeckillTime(@Valid @RequestBody SeckillTimeCreateReqVO createReqVO) { + return success(seckillTimeService.createSeckillTime(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新秒杀时段") + @PreAuthorize("@ss.hasPermission('promotion:seckill-time:update')") + public CommonResult updateSeckillTime(@Valid @RequestBody SeckillTimeUpdateReqVO updateReqVO) { + seckillTimeService.updateSeckillTime(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除秒杀时段") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('promotion:seckill-time:delete')") + public CommonResult deleteSeckillTime(@RequestParam("id") Long id) { + seckillTimeService.deleteSeckillTime(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得秒杀时段") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')") + public CommonResult getSeckillTime(@RequestParam("id") Long id) { + SeckillTimeDO seckillTime = seckillTimeService.getSeckillTime(id); + return success(SeckillTimeConvert.INSTANCE.convert(seckillTime)); + } + + @GetMapping("/list") + @Operation(summary = "获得所有秒杀时段列表") + @PreAuthorize("@ss.hasPermission('promotion:seckill-time:query')") + public CommonResult> getSeckillTimeList() { + List list = seckillTimeService.getSeckillTimeList(); + return success(SeckillTimeConvert.INSTANCE.convertList(list)); + } +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java new file mode 100644 index 000000000..1fa803f71 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; + +/** + * 秒杀活动 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class SeckillActivityBaseVO { + + @Schema(description = "秒杀活动名称", required = true, example = "晚九点限时秒杀") + @NotNull(message = "秒杀活动名称不能为空") + private String name; + + @Schema(description = "活动开始时间", required = true) + @NotNull(message = "活动开始时间不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime startTime; + + @Schema(description = "活动结束时间", required = true) + @NotNull(message = "活动结束时间不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime endTime; + + + @Schema(description = "商品") + @Data + public static class Product { + + @Schema(description = "商品 SPU 编号", required = true, example = "1") + @NotNull(message = "商品 SPU 编号不能为空") + private Long spuId; + + @Schema(description = "商品 SKU 编号", required = true, example = "1") + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + @Schema(description = "秒杀金额", required = true, example = "12.00") + @NotNull(message = "秒杀金额不能为空") + private Integer seckillPrice; + + @Schema(description = "秒杀库存", example = "80") + @Min(value = 0, message = "秒杀库存需要大于等于 0") + private Integer stock; + + @Schema(description = "每人限购", example = "10") // 如果为 0 则不限购 + @Min(value = 0, message = "每人限购需要大于等于 0") + private Integer limitBuyCount; + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java new file mode 100644 index 000000000..37adfc7e4 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "管理后台 - 秒杀活动创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillActivityCreateReqVO extends SeckillActivityBaseVO { + + @Schema(description = "备注", example = "限时秒杀活动") + private String remark; + + @Schema(description = "排序", required = true, example = "1") + @NotNull(message = "排序不能为空") + private Integer sort; + + @Schema(description = "秒杀时段id", required = true, example = "1,3") + @NotEmpty(message = "参与场次不能为空") + private List timeIds; + + /** + * 商品列表 + */ + @NotEmpty(message = "商品列表不能为空") + @Valid + private List products; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityDetailRespVO.java new file mode 100644 index 000000000..14b32c324 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityDetailRespVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; + +@Schema(description = "管理后台 - 秒杀活动的详细 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillActivityDetailRespVO extends SeckillActivityRespVO { + + /** + * 商品列表 + */ + private List products; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityPageReqVO.java new file mode 100644 index 000000000..f0299377d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityPageReqVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; + +@Schema(description = "管理后台 - 秒杀活动分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillActivityPageReqVO extends PageParam { + + @Schema(description = "秒杀活动名称", example = "晚九点限时秒杀") + private String name; + + @Schema(description = "活动状态", example = "进行中") + private Integer status; + + @Schema(description = "秒杀时段id", example = "1") + private Long timeId; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java new file mode 100644 index 000000000..e898a0d4f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "管理后台 - 秒杀活动 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillActivityRespVO extends SeckillActivityBaseVO { + + @Schema(description = "秒杀活动id", required = true, example = "1") + private Long id; + + @Schema(description = "付款订单数", required = true, example = "1") + private Integer orderCount; + + @Schema(description = "付款人数", required = true, example = "1") + private Integer userCount; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + + @Schema(description = "秒杀时段id", required = true, example = "1,3") + private List timeIds; + + @Schema(description = "排序", required = true, example = "1") + private Integer sort; + + @Schema(description = "备注", example = "限时秒杀活动") + private String remark; + + @Schema(description = "活动状态", example = "进行中") + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java new file mode 100644 index 000000000..3787d619c --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "管理后台 - 秒杀活动更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillActivityUpdateReqVO extends SeckillActivityBaseVO { + + @Schema(description = "秒杀活动编号", required = true, example = "224") + @NotNull(message = "秒杀活动编号不能为空") + private Long id; + + @Schema(description = "备注", example = "限时秒杀活动") + private String remark; + + @Schema(description = "排序", required = true, example = "1") + @NotNull(message = "排序不能为空") + private Integer sort; + + @Schema(description = "秒杀时段id", required = true, example = "1,3") + @NotEmpty(message = "秒杀时段id不能为空") + private List timeIds; + + /** + * 商品列表 + */ + @NotEmpty(message = "商品列表不能为空") + @Valid + private List products; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java new file mode 100644 index 000000000..c15854da6 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.time.LocalTime; + +/** + * 秒杀时段 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class SeckillTimeBaseVO { + + @Schema(description = "秒杀时段名称", required = true, example = "上午场") + @NotNull(message = "秒杀时段名称不能为空") + private String name; + + @Schema(description = "开始时间点", required = true, example = "16:30:40") + @NotNull(message = "开始时间点不能为空") + private LocalTime startTime; + + @Schema(description = "结束时间点", required = true, example = "16:30:40") + @NotNull(message = "结束时间点不能为空") + private LocalTime endTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java new file mode 100644 index 000000000..4d3ccd092 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 秒杀时段创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillTimeCreateReqVO extends SeckillTimeBaseVO { + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java new file mode 100644 index 000000000..36853a0e0 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalTime; + +@Schema(description = "管理后台 - 秒杀时段分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillTimePageReqVO extends PageParam { + + @Schema(description = "秒杀时段名称", example = "上午场") + private String name; + + @Schema(description = "开始时间点", example = "16:30:40") + @DateTimeFormat(pattern = "HH:mm:ss") + private LocalTime startTime; + + @Schema(description = "结束时间点", example = "16:30:40") + @DateTimeFormat(pattern = "HH:mm:ss") + private LocalTime endTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java new file mode 100644 index 000000000..8e8c41406 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 秒杀时段 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillTimeRespVO extends SeckillTimeBaseVO { + + @Schema(description = "编号", required = true, example = "1") + private Long id; + + @Schema(description = "秒杀活动数量", required = true, example = "1") + private Integer seckillActivityCount; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java new file mode 100644 index 000000000..3ef8db3e3 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 秒杀时段更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillTimeUpdateReqVO extends SeckillTimeBaseVO { + + @Schema(description = "编号", required = true, example = "1") + @NotNull(message = "编号不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java new file mode 100644 index 000000000..cafddecf5 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.promotion.controller.app; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "用户 App - 营销") +@RestController +@RequestMapping("/market/test") +@Validated +public class AppMarketTestController { + + @GetMapping("/get") + @Operation(summary = "获取 market 信息") + public CommonResult get() { + return success("true"); + } +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java new file mode 100644 index 000000000..4bc094598 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.promotion.controller.app.banner; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO; +import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; +import cn.iocoder.yudao.module.promotion.service.banner.BannerService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * @author: XIA + */ +@RestController +@RequestMapping("/market/banner") +@Tag(name = "用户APP- 首页Banner") +@Validated +public class AppBannerController { + + @Resource + private BannerService bannerService; + + // TODO @xia:新建一个 AppBannerRespVO,只返回必要的字段。status 要过滤下。然后 sort 下结果 + @GetMapping("/list") + @Operation(summary = "获得banner列表") + @PreAuthorize("@ss.hasPermission('market:banner:query')") + public CommonResult> getBannerList() { + List list = bannerService.getBannerList(); + return success(BannerConvert.INSTANCE.convertList(list)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java new file mode 100644 index 000000000..3e2afeb49 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.promotion.convert.banner; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface BannerConvert { + + BannerConvert INSTANCE = Mappers.getMapper(BannerConvert.class); + + List convertList(List list); + + PageResult convertPage(PageResult pageResult); + + BannerRespVO convert(BannerDO banner); + + BannerDO convert(BannerCreateReqVO createReqVO); + + BannerDO convert(BannerUpdateReqVO updateReqVO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java new file mode 100755 index 000000000..281318f7d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.convert.coupon; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 优惠劵 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface CouponConvert { + + CouponConvert INSTANCE = Mappers.getMapper(CouponConvert.class); + + PageResult convertPage(PageResult page); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java new file mode 100755 index 000000000..22d78f46f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.promotion.convert.coupon; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 优惠劵模板 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface CouponTemplateConvert { + + CouponTemplateConvert INSTANCE = Mappers.getMapper(CouponTemplateConvert.class); + + CouponTemplateDO convert(CouponTemplateCreateReqVO bean); + + CouponTemplateDO convert(CouponTemplateUpdateReqVO bean); + + CouponTemplateRespVO convert(CouponTemplateDO bean); + + PageResult convertPage(PageResult page); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java new file mode 100755 index 000000000..07d2e03ab --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java @@ -0,0 +1,102 @@ +package cn.iocoder.yudao.module.promotion.convert.discount; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; +import java.util.Map; + +/** + * 限时折扣活动 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface DiscountActivityConvert { + + DiscountActivityConvert INSTANCE = Mappers.getMapper(DiscountActivityConvert.class); + + DiscountActivityDO convert(DiscountActivityCreateReqVO bean); + + DiscountActivityDO convert(DiscountActivityUpdateReqVO bean); + + DiscountActivityRespVO convert(DiscountActivityDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + DiscountProductDetailBO convert(DiscountProductDO product); + + default List convertList(List products, Map activityMap) { + return CollectionUtils.convertList(products, product -> { + DiscountProductDetailBO detail = convert(product); + MapUtils.findAndThen(activityMap, product.getActivityId(), activity -> { + detail.setActivityName(activity.getName()); + }); + return detail; + }); + } + + DiscountProductDO convert(DiscountActivityBaseVO.Product bean); + + DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List products); + + // =========== 比较是否相等 ========== + /** + * 比较两个限时折扣商品是否相等 + * + * @param productDO 数据库中的商品 + * @param productVO 前端传入的商品 + * @return 是否匹配 + */ + @SuppressWarnings("DuplicatedCode") + default boolean isEquals(DiscountProductDO productDO, DiscountActivityBaseVO.Product productVO) { + if (ObjectUtil.notEqual(productDO.getSpuId(), productVO.getSpuId()) + || ObjectUtil.notEqual(productDO.getSkuId(), productVO.getSkuId()) + || ObjectUtil.notEqual(productDO.getDiscountType(), productVO.getDiscountType())) { + return false; + } + if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PRICE.getType())) { + return ObjectUtil.equal(productDO.getDiscountPrice(), productVO.getDiscountPrice()); + } + if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PERCENT.getType())) { + return ObjectUtil.equal(productDO.getDiscountPercent(), productVO.getDiscountPercent()); + } + return true; + } + + /** + * 比较两个限时折扣商品是否相等 + * 注意,比较时忽略 id 编号 + * + * @param productDO 商品 1 + * @param productVO 商品 2 + * @return 是否匹配 + */ + @SuppressWarnings("DuplicatedCode") + default boolean isEquals(DiscountProductDO productDO, DiscountProductDO productVO) { + if (ObjectUtil.notEqual(productDO.getSpuId(), productVO.getSpuId()) + || ObjectUtil.notEqual(productDO.getSkuId(), productVO.getSkuId()) + || ObjectUtil.notEqual(productDO.getDiscountType(), productVO.getDiscountType())) { + return false; + } + if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PRICE.getType())) { + return ObjectUtil.equal(productDO.getDiscountPrice(), productVO.getDiscountPrice()); + } + if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PERCENT.getType())) { + return ObjectUtil.equal(productDO.getDiscountPercent(), productVO.getDiscountPercent()); + } + return true; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java new file mode 100644 index 000000000..8e4b24666 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.promotion.convert.price; + +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Mapper +public interface PriceConvert { + + PriceConvert INSTANCE = Mappers.getMapper(PriceConvert.class); + + default PriceCalculateRespDTO convert(PriceCalculateReqDTO calculateReqDTO, List skuList) { + // 创建 PriceCalculateRespDTO 对象 + PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); + // 创建它的 Order 属性 + PriceCalculateRespDTO.Order order = new PriceCalculateRespDTO.Order().setOriginalPrice(0).setDiscountPrice(0) + .setCouponPrice(0).setPointPrice(0).setDeliveryPrice(0).setPayPrice(0) + .setItems(new ArrayList<>()).setCouponId(calculateReqDTO.getCouponId()); + priceCalculate.setOrder(order).setPromotions(new ArrayList<>()); + // 创建它的 OrderItem 属性 + Map skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), + PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); + skuList.forEach(sku -> { + Integer count = skuIdCountMap.get(sku.getId()); + PriceCalculateRespDTO.OrderItem orderItem = new PriceCalculateRespDTO.OrderItem() + .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setCount(count) + .setOriginalUnitPrice(sku.getPrice()).setOriginalPrice(sku.getPrice() * count) + .setDiscountPrice(0).setOrderPartPrice(0); + orderItem.setPayPrice(orderItem.getOriginalPrice()).setOrderDividePrice(orderItem.getOriginalPrice()); + priceCalculate.getOrder().getItems().add(orderItem); + // 补充价格信息到 Order 中 + order.setOriginalPrice(order.getOriginalPrice() + orderItem.getOriginalPrice()) + .setOrderPrice(order.getOriginalPrice()).setPayPrice(order.getOriginalPrice()); + }); + return priceCalculate; + } + + CouponMeetRespDTO convert(CouponDO coupon); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/reward/RewardActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/reward/RewardActivityConvert.java new file mode 100755 index 000000000..5343656ed --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/reward/RewardActivityConvert.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.promotion.convert.reward; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 满减送活动 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface RewardActivityConvert { + + RewardActivityConvert INSTANCE = Mappers.getMapper(RewardActivityConvert.class); + + RewardActivityDO convert(RewardActivityCreateReqVO bean); + + RewardActivityDO convert(RewardActivityUpdateReqVO bean); + + RewardActivityRespVO convert(RewardActivityDO bean); + + PageResult convertPage(PageResult page); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java new file mode 100644 index 000000000..1a00fdeb6 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java @@ -0,0 +1,83 @@ +package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.*; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 秒杀活动 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface SeckillActivityConvert { + + SeckillActivityConvert INSTANCE = Mappers.getMapper(SeckillActivityConvert.class); + + SeckillProductDO convert(SeckillActivityBaseVO.Product product); + + + SeckillActivityDO convert(SeckillActivityCreateReqVO bean); + + default String map(Long[] value) { + return value.toString(); + } + + SeckillActivityDO convert(SeckillActivityUpdateReqVO bean); + + SeckillActivityRespVO convert(SeckillActivityDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + @Mappings({@Mapping(target = "products", source = "seckillProducts")}) + SeckillActivityDetailRespVO convert(SeckillActivityDO seckillActivity, List seckillProducts); + + + /** + * 比较两个秒杀商品对象是否相等 + * + * @param productDO 数据库中的商品 + * @param productVO 前端传入的商品 + * @return 是否匹配 + */ + default boolean isEquals(SeckillProductDO productDO, SeckillActivityBaseVO.Product productVO) { + return ObjectUtil.equals(productDO.getSpuId(), productVO.getSpuId()) + && ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId()) + && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice()) + && ObjectUtil.equals(productDO.getStock(), productVO.getStock()) + && ObjectUtil.equals(productDO.getLimitBuyCount(), productVO.getLimitBuyCount()); + } + + /** + * 比较两个秒杀商品对象是否相等 + * + * @param productDO 商品1 + * @param productVO 商品2 + * @return 是否匹配 + */ + default boolean isEquals(SeckillProductDO productDO, SeckillProductDO productVO) { + return ObjectUtil.equals(productDO.getSpuId(), productVO.getSpuId()) + && ObjectUtil.equals(productDO.getSkuId(), productVO.getSkuId()) + && ObjectUtil.equals(productDO.getSeckillPrice(), productVO.getSeckillPrice()) + && ObjectUtil.equals(productDO.getStock(), productVO.getStock()) + && ObjectUtil.equals(productDO.getLimitBuyCount(), productVO.getLimitBuyCount()); + + } + + default List convertList(List products, SeckillActivityDO seckillActivity) { + return CollectionUtils.convertList(products, product -> convert(product) + .setActivityId(seckillActivity.getId()).setTimeIds(seckillActivity.getTimeIds())); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java new file mode 100644 index 000000000..4cea7a91c --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; + +/** + * 秒杀时段 Convert + * + * @author 芋道源码 + */ +@Mapper +public interface SeckillTimeConvert { + + SeckillTimeConvert INSTANCE = Mappers.getMapper(SeckillTimeConvert.class); + + SeckillTimeDO convert(SeckillTimeCreateReqVO bean); + + SeckillTimeDO convert(SeckillTimeUpdateReqVO bean); + + SeckillTimeRespVO convert(SeckillTimeDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java new file mode 100644 index 000000000..585462b95 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.banner; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * banner DO + * + * @author xia + */ +@TableName("market_banner") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BannerDO extends BaseDO { + + /** + * 编号 + */ + private Long id; + /** + * 标题 + */ + private String title; + /** + * 跳转链接 + */ + private String url; + /** + * 图片链接 + */ + private String picUrl; + /** + * 排序 + */ + private Integer sort; + + /** + * 状态 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum} + */ + private Integer status; + /** + * 备注 + */ + private String memo; + + // TODO 芋艿 点击次数。&& 其他数据相关 + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java new file mode 100644 index 000000000..7971392d4 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java @@ -0,0 +1,139 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 优惠劵 DO + * + * @author 芋道源码 + */ +@TableName(value = "promotion_coupon", autoResultMap = true) +@KeySequence("promotion_coupon_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +public class CouponDO extends BaseDO { + + // ========== 基本信息 BEGIN ========== + /** + * 优惠劵编号 + */ + private Long id; + /** + * 优惠劵模板编号 + * + * 关联 {@link CouponTemplateDO#getId()} + */ + private Integer templateId; + /** + * 优惠劵名 + * + * 冗余 {@link CouponTemplateDO#getName()} + */ + private String name; + /** + * 优惠码状态 + * + * 枚举 {@link CouponStatusEnum} + */ + private Integer status; + + // ========== 基本信息 END ========== + + // ========== 领取情况 BEGIN ========== + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 字段 + */ + private Long userId; + /** + * 领取类型 + * + * 枚举 {@link CouponTakeTypeEnum} + */ + private Integer takeType; + // ========== 领取情况 END ========== + + // ========== 使用规则 BEGIN ========== + /** + * 是否设置满多少金额可用,单位:分 + * + * 冗余 {@link CouponTemplateDO#getUsePrice()} + */ + private Integer usePrice; + /** + * 生效开始时间 + */ + private LocalDateTime validStartTime; + /** + * 生效结束时间 + */ + private LocalDateTime validEndTime; + /** + * 商品范围 + * + * 枚举 {@link PromotionProductScopeEnum} + */ + private Integer productScope; + /** + * 商品 SPU 编号的数组 + * + * 冗余 {@link CouponTemplateDO#getProductSpuIds()} + */ + @TableField(typeHandler = LongListTypeHandler.class) + private List productSpuIds; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + /** + * 折扣类型 + * + * 冗余 {@link CouponTemplateDO#getDiscountType()} + */ + private Integer discountType; + /** + * 折扣百分比 + * + * 冗余 {@link CouponTemplateDO#getDiscountPercent()} + */ + private Integer discountPercent; + /** + * 优惠金额,单位:分 + * + * 冗余 {@link CouponTemplateDO#getDiscountPrice()} + */ + private Integer discountPrice; + /** + * 折扣上限,仅在 {@link #discountType} 等于 {@link PromotionDiscountTypeEnum#PERCENT} 时生效 + * + * 冗余 {@link CouponTemplateDO#getDiscountLimitPrice()} + */ + private Integer discountLimitPrice; + // ========== 使用效果 END ========== + + // ========== 使用情况 BEGIN ========== + /** + * 使用订单号 + */ + private Long useOrderId; + /** + * 使用时间 + */ + private LocalDateTime useTime; + + // ========== 使用情况 END ========== + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java new file mode 100644 index 000000000..93f9ace35 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java @@ -0,0 +1,162 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 优惠劵模板 DO + * + * 当用户领取时,会生成 {@link CouponDO} 优惠劵 + * + * @author 芋道源码 + */ +@TableName(value = "promotion_coupon_template", autoResultMap = true) +@KeySequence("promotion_coupon_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +public class CouponTemplateDO extends BaseDO { + + // ========== 基本信息 BEGIN ========== + /** + * 模板编号,自增唯一 + */ + @TableId + private Long id; + /** + * 优惠劵名 + */ + private String name; + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + + // ========== 基本信息 END ========== + + // ========== 领取规则 BEGIN ========== + /** + * 发放数量 + * + * -1 - 则表示不限制发放数量 + */ + private Integer totalCount; + /** + * 每人限领个数 + * + * -1 - 则表示不限制 + */ + private Integer takeLimitCount; + /** + * 领取方式 + * + * 枚举 {@link CouponTakeTypeEnum} + */ + private Integer takeType; + // ========== 领取规则 END ========== + + // ========== 使用规则 BEGIN ========== + /** + * 是否设置满多少金额可用,单位:分 + * + * 0 - 不限制 + * 大于 0 - 多少金额可用 + */ + private Integer usePrice; + /** + * 商品范围 + * + * 枚举 {@link PromotionProductScopeEnum} + */ + private Integer productScope; + /** + * 商品 SPU 编号的数组 + */ + @TableField(typeHandler = LongListTypeHandler.class) + private List productSpuIds; + /** + * 生效日期类型 + * + * 枚举 {@link CouponTemplateValidityTypeEnum} + */ + private Integer validityType; + /** + * 固定日期 - 生效开始时间 + * + * 当 {@link #validityType} 为 {@link CouponTemplateValidityTypeEnum#DATE} + */ + private LocalDateTime validStartTime; + /** + * 固定日期 - 生效结束时间 + * + * 当 {@link #validityType} 为 {@link CouponTemplateValidityTypeEnum#DATE} + */ + private LocalDateTime validEndTime; + /** + * 领取日期 - 开始天数 + * + * 当 {@link #validityType} 为 {@link CouponTemplateValidityTypeEnum#TERM} + */ + private Integer fixedStartTerm; + /** + * 领取日期 - 结束天数 + * + * 当 {@link #validityType} 为 {@link CouponTemplateValidityTypeEnum#TERM} + */ + private Integer fixedEndTerm; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + /** + * 折扣类型 + * + * 枚举 {@link PromotionDiscountTypeEnum} + */ + private Integer discountType; + /** + * 折扣百分比 + * + * 例如,80% 为 80 + */ + private Integer discountPercent; + /** + * 优惠金额,单位:分 + * + * 当 {@link #discountType} 为 {@link PromotionDiscountTypeEnum#PRICE} 生效 + */ + private Integer discountPrice; + /** + * 折扣上限,仅在 {@link #discountType} 等于 {@link PromotionDiscountTypeEnum#PERCENT} 时生效 + * + * 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。 + */ + private Integer discountLimitPrice; + // ========== 使用效果 END ========== + + // ========== 统计信息 BEGIN ========== + /** + * 领取优惠券的数量 + */ + private Integer takeCount; + /** + * 使用优惠券的次数 + */ + private Integer useCount; + // ========== 统计信息 END ========== + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java new file mode 100644 index 000000000..91071f309 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.discount; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/** + * 限时折扣活动 DO + * + * 一个活动下,可以有 {@link DiscountProductDO} 商品; + * 一个商品,在指定时间段内,只能属于一个活动; + * + * @author 芋道源码 + */ +@TableName(value = "promotion_discount_activity", autoResultMap = true) +@KeySequence("promotion_discount_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +public class DiscountActivityDO extends BaseDO { + + /** + * 活动编号,主键自增 + */ + @TableId + private Long id; + /** + * 活动标题 + */ + private String name; + /** + * 状态 + * + * 枚举 {@link PromotionActivityStatusEnum} + */ + private Integer status; + /** + * 开始时间 + */ + private LocalDateTime startTime; + /** + * 结束时间 + */ + private LocalDateTime endTime; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java new file mode 100644 index 000000000..55c924e4f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.discount; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 限时折扣商品 DO + * + * @author 芋道源码 + */ +@TableName(value = "promotion_discount_product", autoResultMap = true) +@KeySequence("promotion_discount_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +public class DiscountProductDO extends BaseDO { + + /** + * 编号,主键自增 + */ + @TableId + private Long id; + /** + * 限时折扣活动的编号 + * + * 关联 {@link DiscountActivityDO#getId()} + */ + private Long activityId; + /** + * 商品 SPU 编号 + * + * 关联 ProductSpuDO 的 id 编号 + */ + private Long spuId; + /** + * 商品 SKU 编号 + * + * 关联 ProductSkuDO 的 id 编号 + */ + private Long skuId; + + /** + * 折扣类型 + * + * 枚举 {@link PromotionDiscountTypeEnum} + */ + private Integer discountType; + /** + * 折扣百分比 + * + * 例如,80% 为 80 + */ + private Integer discountPercent; + /** + * 优惠金额,单位:分 + * + * 当 {@link #discountType} 为 {@link PromotionDiscountTypeEnum#PRICE} 生效 + */ + private Integer discountPrice; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java new file mode 100644 index 000000000..e825881d1 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java @@ -0,0 +1,133 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.reward; + +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 满减送活动 DO + * + * @author 芋道源码 + */ +@TableName(value = "promotion_reward_activity", autoResultMap = true) +@KeySequence("promotion_reward_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +public class RewardActivityDO extends BaseDO { + + /** + * 活动编号,主键自增 + */ + @TableId + private Long id; + /** + * 活动标题 + */ + private String name; + /** + * 状态 + * + * 枚举 {@link PromotionActivityStatusEnum} + */ + private Integer status; + /** + * 开始时间 + */ + private LocalDateTime startTime; + /** + * 结束时间 + */ + private LocalDateTime endTime; + /** + * 备注 + */ + private String remark; + /** + * 条件类型 + * + * 枚举 {@link PromotionConditionTypeEnum} + */ + private Integer conditionType; + /** + * 商品范围 + * + * 枚举 {@link PromotionProductScopeEnum} + */ + private Integer productScope; + /** + * 商品 SPU 编号的数组 + */ + @TableField(typeHandler = LongListTypeHandler.class) + private List productSpuIds; + /** + * 优惠规则的数组 + */ + @TableField(typeHandler = RuleTypeHandler.class) + private List rules; + + /** + * 优惠规则 + */ + @Data + public static class Rule implements Serializable { + + /** + * 优惠门槛 + * + * 1. 满 N 元,单位:分 + * 2. 满 N 件 + */ + private Integer limit; + /** + * 优惠价格,单位:分 + */ + private Integer discountPrice; + /** + * 是否包邮 + */ + private Boolean freeDelivery; + /** + * 赠送的积分 + */ + private Integer point; + /** + * 赠送的优惠劵编号的数组 + */ + private List couponIds; + /** + * 赠送的优惠卷数量的数组 + */ + private List couponCounts; + + } + + // TODO @芋艿:可以找一些新的思路 + public static class RuleTypeHandler extends AbstractJsonTypeHandler> { + + @Override + protected List parse(String json) { + return JsonUtils.parseArray(json, Rule.class); + } + + @Override + protected String toJson(List obj) { + return JsonUtils.toJsonString(obj); + } + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java new file mode 100644 index 000000000..1d3b6da27 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 秒杀活动 DO + * + * @author halfninety + */ +@TableName(value = "promotion_seckill_activity", autoResultMap = true) +@KeySequence("promotion_seckill_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillActivityDO extends BaseDO { + + /** + * 秒杀活动编号 + */ + @TableId + private Long id; + /** + * 秒杀活动名称 + */ + private String name; + /** + * 活动状态 + *

+ * 枚举 {@link PromotionActivityStatusEnum 对应的类} + */ + private Integer status; + /** + * 备注 + */ + private String remark; + /** + * 活动开始时间 + */ + private LocalDateTime startTime; + /** + * 活动结束时间 + */ + private LocalDateTime endTime; + /** + * 排序 + */ + private Integer sort; + /** + * 秒杀时段 id + */ + @TableField(typeHandler = LongListTypeHandler.class) + private List timeIds; + /** + * 付款订单数 + */ + private Integer orderCount; + /** + * 付款人数 + */ + private Integer userCount; + /** + * 订单实付金额,单位:分 + */ + private Long totalPrice; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java new file mode 100644 index 000000000..3783d6dda --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; + +/** + * 秒杀参与商品 + * + * @author halfninety + * @TableName promotion_seckill_product + */ +@TableName(value = "promotion_seckill_product", autoResultMap = true) +@KeySequence("promotion_seckill_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillProductDO extends BaseDO { + /** + * 秒杀参与商品编号 + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 秒杀活动id + */ + private Long activityId; + + /** + * 秒杀时段id + */ + @TableField(typeHandler = LongListTypeHandler.class) + private List timeIds; + + /** + * 商品id + */ + private Long spuId; + + /** + * 商品sku_id + */ + private Long skuId; + + /** + * 秒杀金额 + */ + private Integer seckillPrice; + + /** + * 秒杀库存 + */ + private Integer stock; + + /** + * 每人限购 + */ + private Integer limitBuyCount; +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java new file mode 100644 index 000000000..df338c0e6 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalTime; + +/** + * 秒杀时段 DO + * + * @author 芋道源码 + */ +@TableName("promotion_seckill_time") +@KeySequence("promotion_seckill_time_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SeckillTimeDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 秒杀时段名称 + */ + private String name; + /** + * 开始时间点 + */ + private LocalTime startTime; + /** + * 结束时间点 + */ + private LocalTime endTime; + /** + * 秒杀活动数量 + */ + private Integer seckillActivityCount; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java new file mode 100644 index 000000000..d98375365 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.banner; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * Banner Mapper + * + * @author xia + */ +@Mapper +public interface BannerMapper extends BaseMapperX { + + default PageResult selectPage(BannerPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(BannerDO::getTitle, reqVO.getTitle()) + .eqIfPresent(BannerDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(BannerDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(BannerDO::getSort)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java new file mode 100755 index 000000000..e5ae5f79d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.coupon; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +/** + * 优惠劵 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface CouponMapper extends BaseMapperX { + + default PageResult selectPage(CouponPageReqVO reqVO, Collection userIds) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(CouponDO::getTemplateId, reqVO.getTemplateId()) + .eqIfPresent(CouponDO::getStatus, reqVO.getStatus()) + .inIfPresent(CouponDO::getUserId, userIds) + .betweenIfPresent(CouponDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(CouponDO::getId)); + } + + default List selectListByUserIdAndStatus(Long userId, Integer status) { + return selectList(new LambdaQueryWrapperX() + .eq(CouponDO::getUserId, userId).eq(CouponDO::getStatus, status)); + } + + default CouponDO selectByIdAndUserId(Long id, Long userId) { + return selectOne(new LambdaQueryWrapperX() + .eq(CouponDO::getId, id).eq(CouponDO::getUserId, userId)); + } + + default int delete(Long id, Collection whereStatuses) { + return update(null, new LambdaUpdateWrapper() + .eq(CouponDO::getId, id).in(CouponDO::getStatus, whereStatuses) + .set(CouponDO::getDeleted, 1)); + } + + default int updateByIdAndStatus(Long id, Integer status, CouponDO updateObj) { + return update(updateObj, new LambdaUpdateWrapper() + .eq(CouponDO::getId, id).eq(CouponDO::getStatus, status)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java new file mode 100755 index 000000000..7cea814af --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.coupon; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 优惠劵模板 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface CouponTemplateMapper extends BaseMapperX { + + default PageResult selectPage(CouponTemplatePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(CouponTemplateDO::getName, reqVO.getName()) + .eqIfPresent(CouponTemplateDO::getStatus, reqVO.getStatus()) + .eqIfPresent(CouponTemplateDO::getDiscountType, reqVO.getDiscountType()) + .betweenIfPresent(CouponTemplateDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(CouponTemplateDO::getId)); + } + + void updateTakeCount(@Param("id") Long id, @Param("incrCount") Integer incrCount); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountActivityMapper.java new file mode 100755 index 000000000..534ce627a --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountActivityMapper.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.discount; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * 限时折扣活动 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface DiscountActivityMapper extends BaseMapperX { + + default PageResult selectPage(DiscountActivityPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(DiscountActivityDO::getName, reqVO.getName()) + .eqIfPresent(DiscountActivityDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(DiscountActivityDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(DiscountActivityDO::getId)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java new file mode 100755 index 000000000..646b60707 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.discount; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +/** + * 限时折扣商城 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface DiscountProductMapper extends BaseMapperX { + + default List selectListBySkuId(Collection skuIds) { + return selectList(DiscountProductDO::getSkuId, skuIds); + } + + default List selectListByActivityId(Long activityId) { + return selectList(DiscountProductDO::getActivityId, activityId); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java new file mode 100755 index 000000000..2ee879823 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.reward; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +/** + * 满减送活动 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface RewardActivityMapper extends BaseMapperX { + + default PageResult selectPage(RewardActivityPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(RewardActivityDO::getName, reqVO.getName()) + .eqIfPresent(RewardActivityDO::getStatus, reqVO.getStatus()) + .orderByDesc(RewardActivityDO::getId)); + } + + default List selectListByStatus(Collection statuses) { + return selectList(RewardActivityDO::getStatus, statuses); + } + + default List selectListByProductScopeAndStatus(Integer productScope, Integer status) { + return selectList(new LambdaQueryWrapperX() + .eq(RewardActivityDO::getProductScope, productScope) + .eq(RewardActivityDO::getStatus, status)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java new file mode 100644 index 000000000..c01676c2a --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 秒杀活动 Mapper + * + * @author halfninety + */ +@Mapper +public interface SeckillActivityMapper extends BaseMapperX { + default PageResult selectPage(SeckillActivityPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(SeckillActivityDO::getName, reqVO.getName()) + .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime()) + .apply(ObjectUtil.isNotNull(reqVO.getTimeId()),"FIND_IN_SET(" + reqVO.getTimeId() + ",time_ids) > 0") + .orderByDesc(SeckillActivityDO::getId)); + } +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java new file mode 100644 index 000000000..a590de1a5 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; +import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +/** + * 秒杀活动商品 Mapper + * + * @author halfninety + */ +@Mapper +public interface SeckillProductMapper extends BaseMapperX { + + default List selectListByActivityId(Long id) { + return selectList(SeckillProductDO::getActivityId, id); + } + + default List selectListBySkuIds(Collection skuIds) { + return selectList(SeckillProductDO::getSkuId, skuIds); + } + + default void updateTimeIdsByActivityId(Long id, List timeIds) { + new LambdaUpdateChainWrapper<>(this) + .set(SeckillProductDO::getTimeIds, CollUtil.join(timeIds, ",")) + .eq(SeckillProductDO::getActivityId, id) + .update(); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java new file mode 100644 index 000000000..c34484e8c --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.time.LocalTime; +import java.util.Collection; +import java.util.List; + +/** + * 秒杀时段 Mapper + * + * @author halfninety + */ +@Mapper +public interface SeckillTimeMapper extends BaseMapperX { + + default List selectListByTime(LocalTime time) { + return selectList(SeckillTimeDO::getStartTime, SeckillTimeDO::getEndTime, time); + } + + default List selectListByTime(LocalTime startTime, LocalTime endTime) { + return selectList(new LambdaQueryWrapper() + .ge(SeckillTimeDO::getStartTime, startTime) + .le(SeckillTimeDO::getEndTime, endTime)); + } + + default void updateActivityCount(Collection ids, String type, Integer count) { + new LambdaUpdateChainWrapper<>(this) + .in(SeckillTimeDO::getId, ids) + .setSql("`seckill_activity_count` = `seckill_activity_count` " + type + count) + .update(); + } +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/package-info.java new file mode 100644 index 000000000..b2131910d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/package-info.java @@ -0,0 +1,6 @@ +/** + * 属于 promotion 模块的 framework 封装 + * + * @author 芋道源码 + */ +package cn.iocoder.yudao.module.promotion.framework; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/web/config/PromotionWebConfiguration.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/web/config/PromotionWebConfiguration.java new file mode 100644 index 000000000..37945474d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/web/config/PromotionWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.promotion.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * promotion 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class PromotionWebConfiguration { + + /** + * promotion 模块的 API 分组 + */ + @Bean + public GroupedOpenApi promotionGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("promotion"); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/web/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/web/package-info.java new file mode 100644 index 000000000..8359130d4 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * promotion 模块的 web 配置 + */ +package cn.iocoder.yudao.module.promotion.framework.web; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java new file mode 100644 index 000000000..c022c6276 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java @@ -0,0 +1,8 @@ +/** + * promotion 模块,我们放营销业务。 + * 例如说:营销活动、banner、优惠券等等 + * + * 1. Controller URL:以 /promotion/ 开头,避免和其它 Module 冲突 + * 2. DataObject 表名:以 promotion_ 开头,方便在数据库中区分 + */ +package cn.iocoder.yudao.module.promotion; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java new file mode 100644 index 000000000..d541211be --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.promotion.service.banner; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; + +import javax.validation.Valid; +import java.util.List; + +/** + * 首页 Banner Service 接口 + * + * @author xia + */ +public interface BannerService { + + /** + * 创建 Banner + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createBanner(@Valid BannerCreateReqVO createReqVO); + + /** + * 更新 Banner + * + * @param updateReqVO 更新信息 + */ + void updateBanner(@Valid BannerUpdateReqVO updateReqVO); + + /** + * 删除 Banner + * + * @param id 编号 + */ + void deleteBanner(Long id); + + /** + * 获得 Banner + * + * @param id 编号 + * @return Banner + */ + BannerDO getBanner(Long id); + + /** + * 获得所有 Banner列表 + * @return Banner列表 + */ + List getBannerList(); + + /** + * 获得 Banner 分页 + * + * @param pageReqVO 分页查询 + * @return Banner分页 + */ + PageResult getBannerPage(BannerPageReqVO pageReqVO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java new file mode 100644 index 000000000..013ae8992 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.promotion.service.banner; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.banner.BannerMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.BANNER_NOT_EXISTS; + +/** + * 首页 banner 实现类 + * + * @author xia + */ +@Service +@Validated +public class BannerServiceImpl implements BannerService { + + @Resource + private BannerMapper bannerMapper; + + @Override + public Long createBanner(BannerCreateReqVO createReqVO) { + // 插入 + BannerDO banner = BannerConvert.INSTANCE.convert(createReqVO); + bannerMapper.insert(banner); + // 返回 + return banner.getId(); + } + + @Override + public void updateBanner(BannerUpdateReqVO updateReqVO) { + // 校验存在 + this.validateBannerExists(updateReqVO.getId()); + // 更新 + BannerDO updateObj = BannerConvert.INSTANCE.convert(updateReqVO); + bannerMapper.updateById(updateObj); + } + + @Override + public void deleteBanner(Long id) { + // 校验存在 + this.validateBannerExists(id); + // 删除 + bannerMapper.deleteById(id); + } + + private void validateBannerExists(Long id) { + if (bannerMapper.selectById(id) == null) { + throw exception(BANNER_NOT_EXISTS); + } + } + + @Override + public BannerDO getBanner(Long id) { + return bannerMapper.selectById(id); + } + + @Override + public List getBannerList() { + return bannerMapper.selectList(); + } + + @Override + public PageResult getBannerPage(BannerPageReqVO pageReqVO) { + return bannerMapper.selectPage(pageReqVO); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java new file mode 100644 index 000000000..96b5b5d63 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.promotion.service.coupon; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; + +import java.util.List; + +/** + * 优惠劵 Service 接口 + * + * @author 芋道源码 + */ +public interface CouponService { + + /** + * 校验优惠劵,包括状态、有限期 + * + * 1. 如果校验通过,则返回优惠劵信息 + * 2. 如果校验不通过,则直接抛出业务异常 + * + * @param id 优惠劵编号 + * @param userId 用户编号 + * @return 优惠劵信息 + */ + CouponDO validCoupon(Long id, Long userId); + + /** + * 校验优惠劵,包括状态、有限期 + * + * @see #validCoupon(Long, Long) 逻辑相同,只是入参不同 + * + * @param coupon 优惠劵 + */ + void validCoupon(CouponDO coupon); + + /** + * 获得优惠劵分页 + * + * @param pageReqVO 分页查询 + * @return 优惠劵分页 + */ + PageResult getCouponPage(CouponPageReqVO pageReqVO); + + /** + * 使用优惠劵 + * + * @param id 优惠劵编号 + * @param userId 用户编号 + * @param orderId 订单编号 + */ + void useCoupon(Long id, Long userId, Long orderId); + + /** + * 回收优惠劵 + * + * @param id 优惠劵编号 + */ + void deleteCoupon(Long id); + + /** + * 获得用户的优惠劵列表 + * + * @param userId 用户编号 + * @param status 优惠劵状态 + * @return 优惠劵列表 + */ + List getCouponList(Long userId, Integer status); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java new file mode 100644 index 000000000..a573e0d9c --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java @@ -0,0 +1,123 @@ +package cn.iocoder.yudao.module.promotion.service.coupon; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponMapper; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; +import static java.util.Arrays.asList; + +/** + * 优惠劵 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class CouponServiceImpl implements CouponService { + + @Resource + private CouponTemplateService couponTemplateService; + + @Resource + private CouponMapper couponMapper; + + @Resource + private MemberUserApi memberUserApi; + + @Override + public CouponDO validCoupon(Long id, Long userId) { + CouponDO coupon = couponMapper.selectByIdAndUserId(id, userId); + if (coupon == null) { + throw exception(COUPON_NOT_EXISTS); + } + validCoupon(coupon); + return coupon; + } + + @Override + public void validCoupon(CouponDO coupon) { + // 校验状态 + if (ObjectUtil.notEqual(coupon.getStatus(), CouponStatusEnum.UNUSED.getStatus())) { + throw exception(COUPON_STATUS_NOT_UNUSED); + } + // 校验有效期;为避免定时器没跑,实际优惠劵已经过期 + if (LocalDateTimeUtils.isBetween(coupon.getValidStartTime(), coupon.getValidEndTime())) { + throw exception(COUPON_VALID_TIME_NOT_NOW); + } + } + + @Override + public PageResult getCouponPage(CouponPageReqVO pageReqVO) { + // 获得用户编号 + Set userIds = null; + if (StrUtil.isNotEmpty(pageReqVO.getNickname())) { + userIds = CollectionUtils.convertSet(memberUserApi.getUserListByNickname(pageReqVO.getNickname()), + MemberUserRespDTO::getId); + if (CollUtil.isEmpty(userIds)) { + return PageResult.empty(); + } + } + // 分页查询 + return couponMapper.selectPage(pageReqVO, userIds); + } + + @Override + public void useCoupon(Long id, Long userId, Long orderId) { + // 校验优惠劵 + validCoupon(id, userId); + // 更新状态 + int updateCount = couponMapper.updateByIdAndStatus(id, CouponStatusEnum.UNUSED.getStatus(), + new CouponDO().setStatus(CouponStatusEnum.USED.getStatus()) + .setUseOrderId(orderId).setUseTime(LocalDateTime.now())); + if (updateCount == 0) { + throw exception(COUPON_STATUS_NOT_UNUSED); + } + } + + @Override + @Transactional + public void deleteCoupon(Long id) { + // 校验存在 + validateCouponExists(id); + + // 更新优惠劵 + int deleteCount = couponMapper.delete(id, + asList(CouponStatusEnum.UNUSED.getStatus(), CouponStatusEnum.EXPIRE.getStatus())); + if (deleteCount == 0) { + throw exception(COUPON_DELETE_FAIL_USED); + } + // 减少优惠劵模板的领取数量 -1 + couponTemplateService.updateCouponTemplateTakeCount(id, -1); + } + + @Override + public List getCouponList(Long userId, Integer status) { + return couponMapper.selectListByUserIdAndStatus(userId, status); + } + + private void validateCouponExists(Long id) { + if (couponMapper.selectById(id) == null) { + throw exception(COUPON_NOT_EXISTS); + } + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java new file mode 100755 index 000000000..fdf018974 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.promotion.service.coupon; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; + +import javax.validation.Valid; + +/** + * 优惠劵模板 Service 接口 + * + * @author 芋道源码 + */ +public interface CouponTemplateService { + + /** + * 创建优惠劵模板 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createCouponTemplate(@Valid CouponTemplateCreateReqVO createReqVO); + + /** + * 更新优惠劵模板 + * + * @param updateReqVO 更新信息 + */ + void updateCouponTemplate(@Valid CouponTemplateUpdateReqVO updateReqVO); + + /** + * 更新优惠劵模板的状态 + * + * @param id 编号 + * @param status 状态 + */ + void updateCouponTemplateStatus(Long id, Integer status); + + /** + * 删除优惠劵模板 + * + * @param id 编号 + */ + void deleteCouponTemplate(Long id); + + /** + * 获得优惠劵模板 + * + * @param id 编号 + * @return 优惠劵模板 + */ + CouponTemplateDO getCouponTemplate(Long id); + + /** + * 获得优惠劵模板分页 + * + * @param pageReqVO 分页查询 + * @return 优惠劵模板分页 + */ + PageResult getCouponTemplatePage(CouponTemplatePageReqVO pageReqVO); + + /** + * 更新优惠劵模板的领取数量 + * + * @param id 优惠劵模板编号 + * @param incrCount 增加数量 + */ + void updateCouponTemplateTakeCount(Long id, int incrCount); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java new file mode 100755 index 000000000..1a9cc8bfb --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java @@ -0,0 +1,94 @@ +package cn.iocoder.yudao.module.promotion.service.coupon; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; + +/** + * 优惠劵模板 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class CouponTemplateServiceImpl implements CouponTemplateService { + + @Resource + private CouponTemplateMapper couponTemplateMapper; + + @Override + public Long createCouponTemplate(CouponTemplateCreateReqVO createReqVO) { + // 插入 + CouponTemplateDO couponTemplate = CouponTemplateConvert.INSTANCE.convert(createReqVO) + .setStatus(CommonStatusEnum.ENABLE.getStatus()); + couponTemplateMapper.insert(couponTemplate); + // 返回 + return couponTemplate.getId(); + } + + @Override + public void updateCouponTemplate(CouponTemplateUpdateReqVO updateReqVO) { + // 校验存在 + CouponTemplateDO couponTemplate = validateCouponTemplateExists(updateReqVO.getId()); + // 校验发放数量不能过小 + if (updateReqVO.getTotalCount() < couponTemplate.getTakeCount()) { + throw exception(COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL, couponTemplate.getTakeCount()); + } + + // 更新 + CouponTemplateDO updateObj = CouponTemplateConvert.INSTANCE.convert(updateReqVO); + couponTemplateMapper.updateById(updateObj); + } + + @Override + public void updateCouponTemplateStatus(Long id, Integer status) { + // 校验存在 + validateCouponTemplateExists(id); + // 更新 + couponTemplateMapper.updateById(new CouponTemplateDO().setId(id).setStatus(status)); + } + + @Override + public void deleteCouponTemplate(Long id) { + // 校验存在 + validateCouponTemplateExists(id); + // 删除 + couponTemplateMapper.deleteById(id); + } + + private CouponTemplateDO validateCouponTemplateExists(Long id) { + CouponTemplateDO couponTemplate = couponTemplateMapper.selectById(id); + if (couponTemplate == null) { + throw exception(COUPON_TEMPLATE_NOT_EXISTS); + } + return couponTemplate; + } + + @Override + public CouponTemplateDO getCouponTemplate(Long id) { + return couponTemplateMapper.selectById(id); + } + + @Override + public PageResult getCouponTemplatePage(CouponTemplatePageReqVO pageReqVO) { + return couponTemplateMapper.selectPage(pageReqVO); + } + + @Override + public void updateCouponTemplateTakeCount(Long id, int incrCount) { + couponTemplateMapper.updateTakeCount(id, incrCount); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java new file mode 100644 index 000000000..8b6e5895b --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java @@ -0,0 +1,86 @@ +package cn.iocoder.yudao.module.promotion.service.discount; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; +import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 限时折扣 Service 接口 + * + * @author 芋道源码 + */ +public interface DiscountActivityService { + + /** + * 基于指定 SKU 编号数组,获得匹配的限时折扣商品 + * + * 注意,匹配的条件,仅仅是日期符合,并且处于开启状态 + * + * @param skuIds SKU 编号数组 + * @return 匹配的限时折扣商品 + */ + Map getMatchDiscountProducts(Collection skuIds); + + /** + * 创建限时折扣活动 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createDiscountActivity(@Valid DiscountActivityCreateReqVO createReqVO); + + /** + * 更新限时折扣活动 + * + * @param updateReqVO 更新信息 + */ + void updateDiscountActivity(@Valid DiscountActivityUpdateReqVO updateReqVO); + + /** + * 关闭限时折扣活动 + * + * @param id 编号 + */ + void closeRewardActivity(Long id); + + /** + * 删除限时折扣活动 + * + * @param id 编号 + */ + void deleteDiscountActivity(Long id); + + /** + * 获得限时折扣活动 + * + * @param id 编号 + * @return 限时折扣活动 + */ + DiscountActivityDO getDiscountActivity(Long id); + + /** + * 获得限时折扣活动分页 + * + * @param pageReqVO 分页查询 + * @return 限时折扣活动分页 + */ + PageResult getDiscountActivityPage(DiscountActivityPageReqVO pageReqVO); + + /** + * 获得活动编号,对应对应的商品列表 + * + * @param activityId 活动编号 + * @return 活动的商品列表 + */ + List getDiscountProductsByActivityId(Long activityId); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java new file mode 100644 index 000000000..df54d44f2 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java @@ -0,0 +1,196 @@ +package cn.iocoder.yudao.module.promotion.service.discount; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper; +import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; +import cn.iocoder.yudao.module.promotion.util.PromotionUtils; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; +import static java.util.Arrays.asList; + +/** + * 限时折扣 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class DiscountActivityServiceImpl implements DiscountActivityService { + + @Resource + private DiscountActivityMapper discountActivityMapper; + @Resource + private DiscountProductMapper discountProductMapper; + + @Override + public Map getMatchDiscountProducts(Collection skuIds) { + List discountProducts = getRewardProductListBySkuIds(skuIds, singleton(PromotionActivityStatusEnum.RUN.getStatus())); + return convertMap(discountProducts, DiscountProductDetailBO::getSkuId); + } + + @Override + public Long createDiscountActivity(DiscountActivityCreateReqVO createReqVO) { + // 校验商品是否冲突 + validateDiscountActivityProductConflicts(null, createReqVO.getProducts()); + + // 插入活动 + DiscountActivityDO discountActivity = DiscountActivityConvert.INSTANCE.convert(createReqVO) + .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime())); + discountActivityMapper.insert(discountActivity); + // 插入商品 + List discountProducts = convertList(createReqVO.getProducts(), + product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(discountActivity.getId())); + discountProductMapper.insertBatch(discountProducts); + // 返回 + return discountActivity.getId(); + } + + @Override + public void updateDiscountActivity(DiscountActivityUpdateReqVO updateReqVO) { + // 校验存在 + DiscountActivityDO discountActivity = validateDiscountActivityExists(updateReqVO.getId()); + if (discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能修改噢 + throw exception(DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); + } + // 校验商品是否冲突 + validateDiscountActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts()); + + // 更新活动 + DiscountActivityDO updateObj = DiscountActivityConvert.INSTANCE.convert(updateReqVO) + .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); + discountActivityMapper.updateById(updateObj); + // 更新商品 + updateDiscountProduct(updateReqVO); + } + + private void updateDiscountProduct(DiscountActivityUpdateReqVO updateReqVO) { + List dbDiscountProducts = discountProductMapper.selectListByActivityId(updateReqVO.getId()); + // 计算要删除的记录 + List deleteIds = convertList(dbDiscountProducts, DiscountProductDO::getId, + discountProductDO -> updateReqVO.getProducts().stream() + .noneMatch(product -> DiscountActivityConvert.INSTANCE.isEquals(discountProductDO, product))); + if (CollUtil.isNotEmpty(deleteIds)) { + discountProductMapper.deleteBatchIds(deleteIds); + } + // 计算新增的记录 + List newDiscountProducts = convertList(updateReqVO.getProducts(), + product -> DiscountActivityConvert.INSTANCE.convert(product).setActivityId(updateReqVO.getId())); + newDiscountProducts.removeIf(product -> dbDiscountProducts.stream().anyMatch( + dbProduct -> DiscountActivityConvert.INSTANCE.isEquals(dbProduct, product))); // 如果匹配到,说明是更新的 + if (CollectionUtil.isNotEmpty(newDiscountProducts)) { + discountProductMapper.insertBatch(newDiscountProducts); + } + } + + /** + * 校验商品是否冲突 + * + * @param id 编号 + * @param products 商品列表 + */ + private void validateDiscountActivityProductConflicts(Long id, List products) { + if (CollUtil.isEmpty(products)) { + return; + } + // 查询商品参加的活动 + List discountActivityProductList = getRewardProductListBySkuIds( + convertSet(products, DiscountActivityBaseVO.Product::getSkuId), + asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus())); + if (id != null) { // 排除自己这个活动 + discountActivityProductList.removeIf(product -> id.equals(product.getActivityId())); + } + // 如果非空,则说明冲突 + if (CollUtil.isNotEmpty(discountActivityProductList)) { + throw exception(DISCOUNT_ACTIVITY_SPU_CONFLICTS); + } + } + + private List getRewardProductListBySkuIds(Collection skuIds, + Collection statuses) { + // 查询商品 + List products = discountProductMapper.selectListBySkuId(skuIds); + if (CollUtil.isEmpty(products)) { + return new ArrayList<>(0); + } + + // 查询活动 + List activities = discountActivityMapper.selectBatchIds(skuIds); + activities.removeIf(activity -> !statuses.contains(activity.getStatus())); // 移除不满足 statuses 状态的 + Map activityMap = CollectionUtils.convertMap(activities, DiscountActivityDO::getId); + + // 移除不满足活动的商品 + products.removeIf(product -> !activityMap.containsKey(product.getActivityId())); + return DiscountActivityConvert.INSTANCE.convertList(products, activityMap); + } + + @Override + public void closeRewardActivity(Long id) { + // 校验存在 + DiscountActivityDO dbDiscountActivity = validateDiscountActivityExists(id); + if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能关闭噢 + throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED); + } + if (dbDiscountActivity.getStatus().equals(PromotionActivityStatusEnum.END.getStatus())) { // 已关闭的活动,不能关闭噢 + throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END); + } + + // 更新 + DiscountActivityDO updateObj = new DiscountActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); + discountActivityMapper.updateById(updateObj); + } + + @Override + public void deleteDiscountActivity(Long id) { + // 校验存在 + DiscountActivityDO discountActivity = validateDiscountActivityExists(id); + if (!discountActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 未关闭的活动,不能删除噢 + throw exception(DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED); + } + + // 删除 + discountActivityMapper.deleteById(id); + } + + private DiscountActivityDO validateDiscountActivityExists(Long id) { + DiscountActivityDO discountActivity = discountActivityMapper.selectById(id); + if (discountActivity == null) { + throw exception(DISCOUNT_ACTIVITY_NOT_EXISTS); + } + return discountActivity; + } + + @Override + public DiscountActivityDO getDiscountActivity(Long id) { + return discountActivityMapper.selectById(id); + } + + @Override + public PageResult getDiscountActivityPage(DiscountActivityPageReqVO pageReqVO) { + return discountActivityMapper.selectPage(pageReqVO); + } + + @Override + public List getDiscountProductsByActivityId(Long activityId) { + return discountProductMapper.selectListByActivityId(activityId); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java new file mode 100644 index 000000000..7b8f4a20f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.promotion.service.discount.bo; + +import lombok.Data; + +/** + * 限时折扣活动商品 BO + * + * @author 芋道源码 + */ +@Data +public class DiscountProductDetailBO { + + // ========== DiscountProductDO 字段 ========== + + /** + * 编号,主键自增 + */ + private Long id; + /** + * 限时折扣活动的编号 + */ + private Long activityId; + /** + * 商品 SPU 编号 + */ + private Long spuId; + /** + * 商品 SKU 编号 + */ + private Long skuId; + /** + * 折扣类型 + */ + private Integer discountType; + /** + * 折扣百分比 + */ + private Integer discountPercent; + /** + * 优惠金额,单位:分 + */ + private Integer discountPrice; + + // ========== DiscountActivityDO 字段 ========== + /** + * 活动标题 + */ + private String activityName; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java new file mode 100644 index 000000000..a7420e119 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.promotion.service.price; + +import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; + +import java.util.List; + +/** + * 价格计算 Service 接口 + * + * @author 芋道源码 + */ +public interface PriceService { + + /** + * 计算商品的价格 + * + * @param calculateReqDTO 价格请求 + * @return 价格响应 + */ + PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); + + /** + * 获得优惠劵的匹配信息列表 + * + * @param calculateReqDTO 价格请求 + * @return 价格响应 + */ + List getMeetCouponList(PriceCalculateReqDTO calculateReqDTO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java new file mode 100644 index 000000000..03abb061f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java @@ -0,0 +1,547 @@ +package cn.iocoder.yudao.module.promotion.service.price; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.convert.price.PriceConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; +import cn.iocoder.yudao.module.promotion.enums.common.*; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; +import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; +import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; +import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; +import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; +import com.google.common.base.Suppliers; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.*; +import java.util.function.Supplier; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; +import static java.util.Collections.singletonList; + +/** + * 价格计算 Service 实现类 + * + * 优惠计算顺序:min(限时折扣, 会员折扣) > 满减送 > 优惠券。 + * 参考文档: + * 1. 有赞文档:限时折扣、满减送、优惠券哪个优先计算? + * + * TODO 芋艿:进一步完善 + * 1. 限时折扣:指定金额、减免金额、折扣 + * 2. 满减送:循环、折扣 + * 3. 优惠劵:待定 + * + * @author 芋道源码 + */ +@Service +@Validated +@Slf4j +public class PriceServiceImpl implements PriceService { + + @Resource + private DiscountActivityService discountService; + @Resource + private RewardActivityService rewardActivityService; + @Resource + private CouponService couponService; + + @Resource + private ProductSkuApi productSkuApi; + + @Override + public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { + // 获得商品 SKU 数组 + List skuList = checkSkus(calculateReqDTO); + // 初始化 PriceCalculateRespDTO 对象 + PriceCalculateRespDTO priceCalculate = PriceConvert.INSTANCE.convert(calculateReqDTO, skuList); + + // 计算商品级别的价格 + calculatePriceForSkuLevel(calculateReqDTO.getUserId(), priceCalculate); + // 计算订单级别的价格 + calculatePriceForOrderLevel(calculateReqDTO.getUserId(), priceCalculate); + // 计算优惠劵级别的价格 + calculatePriceForCouponLevel(calculateReqDTO.getUserId(), calculateReqDTO.getCouponId(), priceCalculate); + + // 如果最终支付金额小于等于 0,则抛出业务异常 + if (priceCalculate.getOrder().getPayPrice() <= 0) { + log.error("[calculatePrice][价格计算不正确,请求 calculateReqDTO({}),结果 priceCalculate({})]", + calculateReqDTO, priceCalculate); + throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL); + } + return priceCalculate; + } + + @Override + public List getMeetCouponList(PriceCalculateReqDTO calculateReqDTO) { + // 先计算一轮价格 + PriceCalculateRespDTO priceCalculate = calculatePrice(calculateReqDTO); + + // 获得用户的待使用优惠劵 + List couponList = couponService.getCouponList(calculateReqDTO.getUserId(), CouponStatusEnum.UNUSED.getStatus()); + if (CollUtil.isEmpty(couponList)) { + return Collections.emptyList(); + } + + // 获得优惠劵的匹配信息 + return CollectionUtils.convertList(couponList, coupon -> { + CouponMeetRespDTO couponMeetRespDTO = PriceConvert.INSTANCE.convert(coupon); + try { + // 校验优惠劵 + couponService.validCoupon(coupon); + + // 获得匹配的商品 SKU 数组 + List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); + if (CollUtil.isEmpty(orderItems)) { + return couponMeetRespDTO.setMeet(false).setMeetTip("所结算商品没有符合条件的商品"); + } + + // 计算是否满足优惠劵的使用金额 + Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); + assert originPrice != null; + if (originPrice < coupon.getUsePrice()) { + return couponMeetRespDTO.setMeet(false) +// .setMeetTip(String.format("差 %s 元可用优惠劵", formatPrice(coupon.getUsePrice() - originPrice))); + .setMeetTip("所结算的商品中未满足使用的金额"); + } + } catch (ServiceException serviceException) { + couponMeetRespDTO.setMeet(false); + if (serviceException.getCode().equals(COUPON_VALID_TIME_NOT_NOW.getCode())) { + couponMeetRespDTO.setMeetTip("优惠劵未到使用时间"); + } else { + log.error("[getMeetCouponList][calculateReqDTO({}) 获得优惠劵匹配信息异常]", calculateReqDTO, serviceException); + couponMeetRespDTO.setMeetTip("优惠劵不满足使用条件"); + } + return couponMeetRespDTO; + } + // 满足 + return couponMeetRespDTO.setMeet(true); + }); + } + + private List checkSkus(PriceCalculateReqDTO calculateReqDTO) { + // 获得商品 SKU 数组 + Map skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), + PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); + List skus = productSkuApi.getSkuList(skuIdCountMap.keySet()); + + // 校验商品 SKU + skus.forEach(sku -> { + Integer count = skuIdCountMap.get(sku.getId()); + if (count == null) { + throw exception(SKU_NOT_EXISTS); + } + // 不校验库存不足,避免购物车场景,商品无货的情况 + }); + return skus; + } + + // ========== 计算商品级别的价格 ========== + + /** + * 计算商品级别的价格,例如说: + * 1. 会员折扣 + * 2. 限时折扣 {@link cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO} + * + * 其中,会员折扣、限时折扣取最低价 + * + * @param userId 用户编号 + * @param priceCalculate 价格计算的结果 + */ + private void calculatePriceForSkuLevel(Long userId, PriceCalculateRespDTO priceCalculate) { + // 获取 SKU 级别的所有优惠信息 + Supplier memberDiscountPercentSupplier = getMemberDiscountPercentSupplier(userId); + Map discountProducts = discountService.getMatchDiscountProducts( + convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSkuId)); + + // 处理每个 SKU 的优惠 + priceCalculate.getOrder().getItems().forEach(orderItem -> { + // 获取该 SKU 的优惠信息 + Double memberDiscountPercent = memberDiscountPercentSupplier.get(); + DiscountProductDetailBO discountProduct = discountProducts.get(orderItem.getSkuId()); + if (memberDiscountPercent == null && discountProduct == null) { + return; + } + // 计算价格,判断选择哪个折扣 + Integer memberPrice = memberDiscountPercent != null ? (int) (orderItem.getPayPrice() * memberDiscountPercent / 100) : null; + Integer promotionPrice = discountProduct != null ? getDiscountProductPrice(discountProduct, orderItem) : null; + if (memberPrice == null) { + calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); + } else if (promotionPrice == null) { + calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); + } else if (memberPrice < promotionPrice) { + calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); + } else { + calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); + } + }); + } + + private Integer getDiscountProductPrice(DiscountProductDetailBO discountProduct, + PriceCalculateRespDTO.OrderItem orderItem) { + Integer price = orderItem.getPayPrice(); + if (PromotionDiscountTypeEnum.PRICE.getType().equals(discountProduct.getDiscountType())) { // 减价 + price -= discountProduct.getDiscountPrice() * orderItem.getCount(); + } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discountProduct.getDiscountType())) { // 打折 + price = price * discountProduct.getDiscountPercent() / 100; + } else { + throw new IllegalArgumentException(String.format("优惠活动的商品(%s) 的优惠类型不正确", discountProduct)); + } + return price; + } + + private void calculatePriceByMemberDiscount(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, + Integer memberPrice) { + // 记录优惠明细 + addPromotion(priceCalculate, orderItem, null, PromotionTypeEnum.MEMBER.getName(), + PromotionTypeEnum.MEMBER.getType(), PromotionLevelEnum.SKU.getLevel(), memberPrice, + true, StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice))); + // 修改 SKU 的优惠 + modifyOrderItemPayPrice(orderItem, memberPrice, priceCalculate); + } + + private void calculatePriceByDiscountActivity(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, + DiscountProductDetailBO discountProduct, Integer promotionPrice) { + // 记录优惠明细 + addPromotion(priceCalculate, orderItem, discountProduct.getActivityId(), discountProduct.getActivityName(), + PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), PromotionLevelEnum.SKU.getLevel(), promotionPrice, + true, StrUtil.format("限时折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - promotionPrice))); + // 修改 SKU 的优惠 + modifyOrderItemPayPrice(orderItem, promotionPrice, priceCalculate); + } + + // TODO 芋艿:提前实现 + private Supplier getMemberDiscountPercentSupplier(Long userId) { + return Suppliers.memoize(() -> { + if (userId == 1) { + return 90d; + } + if (userId == 2) { + return 80d; + } + return null; // 无优惠 + }); + } + + // ========== 计算商品级别的价格 ========== + + /** + * 计算订单级别的价格,例如说: + * 1. 满减送 {@link cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO} + * + * @param userId 用户编号 + * @param priceCalculate 价格计算的结果 + */ + @SuppressWarnings("unused") + private void calculatePriceForOrderLevel(Long userId, PriceCalculateRespDTO priceCalculate) { + // 获取 SKU 级别的所有优惠信息 + Set spuIds = convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSpuId); + Map> rewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); + + // 处理满减送活动 + if (CollUtil.isNotEmpty(rewardActivities)) { + rewardActivities.forEach((rewardActivity, activitySpuIds) -> { + List orderItems = CollectionUtils.filterList(priceCalculate.getOrder().getItems(), + orderItem -> CollUtil.contains(activitySpuIds, orderItem.getSpuId())); + calculatePriceByRewardActivity(priceCalculate, orderItems, rewardActivity); + }); + } + } + + private void calculatePriceByRewardActivity(PriceCalculateRespDTO priceCalculate, List orderItems, + RewardActivityDO rewardActivity) { + // 获得最大匹配的满减送活动的规则 + RewardActivityDO.Rule rule = getLastMatchRewardActivityRule(rewardActivity, orderItems); + if (rule == null) { + // 获取不到的情况下,记录不满足的优惠明细 + addNotMeetPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), + PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), + getRewardActivityNotMeetTip(rewardActivity)); + return; + } + + // 分摊金额 + List discountPartPrices = dividePrice(orderItems, rule.getDiscountPrice()); + // 记录优惠明细 + addPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), + PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), discountPartPrices, + true, StrUtil.format("满减送:省 {} 元", formatPrice(rule.getDiscountPrice()))); + // 修改 SKU 的分摊 + for (int i = 0; i < orderItems.size(); i++) { + modifyOrderItemOrderPartPriceFromDiscountPrice(orderItems.get(i), discountPartPrices.get(i), priceCalculate); + } + } + + /** + * 获得最大匹配的满减送活动的规则 + * + * @param rewardActivity 满减送活动 + * @param orderItems 商品项 + * @return 匹配的活动规则 + */ + private RewardActivityDO.Rule getLastMatchRewardActivityRule(RewardActivityDO rewardActivity, + List orderItems) { + Integer count = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getCount, Integer::sum); + // price 的计算逻辑,使用 orderDividePrice 的原因,主要考虑分摊后,这个才是该 SKU 当前真实的支付总价 + Integer price = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); + assert count != null && price != null; + for (int i = rewardActivity.getRules().size() - 1; i >= 0; i--) { + RewardActivityDO.Rule rule = rewardActivity.getRules().get(i); + if (PromotionConditionTypeEnum.PRICE.getType().equals(rewardActivity.getConditionType()) + && price >= rule.getLimit()) { + return rule; + } + if (PromotionConditionTypeEnum.COUNT.getType().equals(rewardActivity.getConditionType()) + && count >= rule.getLimit()) { + return rule; + } + } + return null; + } + + /** + * 获得满减送活动部匹配时的提示 + * + * @param rewardActivity 满减送活动 + * @return 提示 + */ + private String getRewardActivityNotMeetTip(RewardActivityDO rewardActivity) { + return "TODO"; // TODO 芋艿:后面再想想 + } + + // ========== 计算优惠劵级别的价格 ========== + + private void calculatePriceForCouponLevel(Long userId, Long couponId, PriceCalculateRespDTO priceCalculate) { + // 校验优惠劵 + if (couponId == null) { + return; + } + CouponDO coupon = couponService.validCoupon(couponId, userId); + + // 获得匹配的商品 SKU 数组 + List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); + if (CollUtil.isEmpty(orderItems)) { + throw exception(COUPON_NO_MATCH_SPU); + } + + // 计算是否满足优惠劵的使用金额 + Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); + assert originPrice != null; + if (originPrice < coupon.getUsePrice()) { + throw exception(COUPON_NO_MATCH_MIN_PRICE); + } + + // 计算可以优惠的金额 + priceCalculate.getOrder().setCouponId(couponId); + Integer couponPrice = getCouponPrice(coupon, originPrice); + // 分摊金额 + List couponPartPrices = dividePrice(orderItems, couponPrice); + // 记录优惠明细 + addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getName(), + PromotionTypeEnum.COUPON.getType(), PromotionLevelEnum.COUPON.getLevel(), couponPartPrices, + true, StrUtil.format("优惠劵:省 {} 元", formatPrice(couponPrice))); + // 修改 SKU 的分摊 + for (int i = 0; i < orderItems.size(); i++) { + modifyOrderItemOrderPartPriceFromCouponPrice(orderItems.get(i), couponPartPrices.get(i), priceCalculate); + } + } + + private List getMatchCouponOrderItems(PriceCalculateRespDTO priceCalculate, + CouponDO coupon) { + if (PromotionProductScopeEnum.ALL.getScope().equals(coupon.getProductScope())) { + return priceCalculate.getOrder().getItems(); + } + return CollectionUtils.filterList(priceCalculate.getOrder().getItems(), + orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId())); + } + + private Integer getCouponPrice(CouponDO coupon, Integer originPrice) { + if (PromotionDiscountTypeEnum.PRICE.getType().equals(coupon.getDiscountType())) { // 减价 + return coupon.getDiscountPrice(); + } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(coupon.getDiscountType())) { // 打折 + int couponPrice = originPrice * coupon.getDiscountPercent() / 100; + return coupon.getDiscountLimitPrice() == null ? couponPrice + : Math.min(couponPrice, coupon.getDiscountLimitPrice()); // 优惠上限 + } + throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon)); + } + + // ========== 其它相对通用的方法 ========== + + /** + * 添加单个 OrderItem 的营销明细 + * + * @param priceCalculate 价格计算结果 + * @param orderItem 单个订单商品 SKU + * @param id 营销编号 + * @param name 营销名字 + * @param type 营销类型 + * @param level 营销级别 + * @param newPayPrice 新的单实付金额(总) + * @param meet 是否满足优惠条件 + * @param meetTip 满足条件的提示 + */ + private void addPromotion(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, + Long id, String name, Integer type, Integer level, + Integer newPayPrice, Boolean meet, String meetTip) { + // 创建营销明细 Item + // TODO 芋艿:orderItem.getPayPrice() 要不要改成 orderDividePrice;同时,newPayPrice 要不要改成直接传递 discountPrice + PriceCalculateRespDTO.PromotionItem promotionItem = new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) + .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(orderItem.getPayPrice() - newPayPrice); + // 创建营销明细 + PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() + .setId(id).setName(name).setType(type).setLevel(level) + .setOriginalPrice(promotionItem.getOriginalPrice()).setDiscountPrice(promotionItem.getDiscountPrice()) + .setItems(singletonList(promotionItem)).setMeet(meet).setMeetTip(meetTip); + priceCalculate.getPromotions().add(promotion); + } + + /** + * 添加多个 OrderItem 的营销明细 + * + * @param priceCalculate 价格计算结果 + * @param orderItems 多个订单商品 SKU + * @param id 营销编号 + * @param name 营销名字 + * @param type 营销类型 + * @param level 营销级别 + * @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应 + * @param meet 是否满足优惠条件 + * @param meetTip 满足条件的提示 + */ + private void addPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, + Long id, String name, Integer type, Integer level, + List discountPrices, Boolean meet, String meetTip) { + // 创建营销明细 Item + List promotionItems = new ArrayList<>(discountPrices.size()); + for (int i = 0; i < orderItems.size(); i++) { + PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); + promotionItems.add(new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) + .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(discountPrices.get(i))); + } + // 创建营销明细 + PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() + .setId(id).setName(name).setType(type).setLevel(level) + .setOriginalPrice(getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum)) + .setDiscountPrice(getSumValue(discountPrices, value -> value, Integer::sum)) + .setItems(promotionItems).setMeet(meet).setMeetTip(meetTip); + priceCalculate.getPromotions().add(promotion); + } + + private void addNotMeetPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, + Long id, String name, Integer type, Integer level, String meetTip) { + // 创建营销明细 Item + List promotionItems = CollectionUtils.convertList(orderItems, + orderItem -> new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) + .setOriginalPrice(orderItem.getOrderDividePrice()).setDiscountPrice(0)); + // 创建营销明细 + Integer originalPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); + PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() + .setId(id).setName(name).setType(type).setLevel(level) + .setOriginalPrice(originalPrice).setDiscountPrice(0) + .setItems(promotionItems).setMeet(false).setMeetTip(meetTip); + priceCalculate.getPromotions().add(promotion); + } + + /** + * 修改 OrderItem 的 payPrice 价格,同时会修改 Order 的 payPrice 价格 + * + * @param orderItem 订单商品 SKU + * @param newPayPrice 新的 payPrice 价格 + * @param priceCalculate 价格计算结果 + */ + private void modifyOrderItemPayPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer newPayPrice, + PriceCalculateRespDTO priceCalculate) { + // diffPayPrice 等于额外增加的商品级的优惠 + int diffPayPrice = orderItem.getPayPrice() - newPayPrice; + // 设置 OrderItem 价格相关字段 + orderItem.setDiscountPrice(orderItem.getDiscountPrice() + diffPayPrice); + orderItem.setPayPrice(newPayPrice); + orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); + // 设置 Order 相关相关字段 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + order.setPayPrice(order.getPayPrice() - diffPayPrice); + order.setOrderPrice(order.getOrderPrice() - diffPayPrice); + } + + /** + * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 discountPrice 价格 + * + * 本质:分摊 Order 的 discountPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 + * + * @param orderItem 订单商品 SKU + * @param addOrderPartPrice 新增的 discountPrice 价格 + * @param priceCalculate 价格计算结果 + */ + private void modifyOrderItemOrderPartPriceFromDiscountPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, + PriceCalculateRespDTO priceCalculate) { + // 设置 OrderItem 价格相关字段 + orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); + orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); + // 设置 Order 相关相关字段 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + order.setDiscountPrice(order.getDiscountPrice() + addOrderPartPrice); + order.setPayPrice(order.getPayPrice() - addOrderPartPrice); + } + + /** + * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 couponPrice 价格 + * + * 本质:分摊 Order 的 couponPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 + * + * @param orderItem 订单商品 SKU + * @param addOrderPartPrice 新增的 couponPrice 价格 + * @param priceCalculate 价格计算结果 + */ + private void modifyOrderItemOrderPartPriceFromCouponPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, + PriceCalculateRespDTO priceCalculate) { + // 设置 OrderItem 价格相关字段 + orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); + orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); + // 设置 Order 相关相关字段 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + order.setCouponPrice(order.getCouponPrice() + addOrderPartPrice); + order.setPayPrice(order.getPayPrice() - addOrderPartPrice); + } + + private List dividePrice(List orderItems, Integer price) { + List prices = new ArrayList<>(orderItems.size()); + Integer total = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); + assert total != null; + int remainPrice = price; + // 遍历每一个,进行分摊 + for (int i = 0; i < orderItems.size(); i++) { + PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); + int partPrice; + if (i < orderItems.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 + partPrice = (int) (price * (1.0D * orderItem.getOrderDividePrice() / total)); + remainPrice -= partPrice; + } else { + partPrice = remainPrice; + } + Assert.isTrue(partPrice > 0, "分摊金额必须大于 0"); + prices.add(partPrice); + } + return prices; + } + + private String formatPrice(Integer price) { + return String.format("%.2f", price / 100d); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java new file mode 100755 index 000000000..40bcc2836 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java @@ -0,0 +1,73 @@ +package cn.iocoder.yudao.module.promotion.service.reward; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; + +import javax.validation.Valid; +import java.util.Map; +import java.util.Set; + +/** + * 满减送活动 Service 接口 + * + * @author 芋道源码 + */ +public interface RewardActivityService { + + /** + * 创建满减送活动 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createRewardActivity(@Valid RewardActivityCreateReqVO createReqVO); + + /** + * 更新满减送活动 + * + * @param updateReqVO 更新信息 + */ + void updateRewardActivity(@Valid RewardActivityUpdateReqVO updateReqVO); + + /** + * 关闭满减送活动 + * + * @param id 活动编号 + */ + void closeRewardActivity(Long id); + + /** + * 删除满减送活动 + * + * @param id 编号 + */ + void deleteRewardActivity(Long id); + + /** + * 获得满减送活动 + * + * @param id 编号 + * @return 满减送活动 + */ + RewardActivityDO getRewardActivity(Long id); + + /** + * 获得满减送活动分页 + * + * @param pageReqVO 分页查询 + * @return 满减送活动分页 + */ + PageResult getRewardActivityPage(RewardActivityPageReqVO pageReqVO); + + /** + * 基于指定的 SPU 编号数组,获得它们匹配的满减送活动 + * + * @param spuIds SPU 编号数组 + * @return 满减送活动,与对应的 SPU 编号的映射。即,value 就是 SPU 编号的集合 + */ + Map> getMatchRewardActivities(Set spuIds); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java new file mode 100755 index 000000000..51d0ce626 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java @@ -0,0 +1,169 @@ +package cn.iocoder.yudao.module.promotion.service.reward; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.reward.RewardActivityMapper; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.util.PromotionUtils; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static cn.hutool.core.collection.CollUtil.intersectionDistinct; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; +import static java.util.Arrays.asList; +import static java.util.Collections.singleton; + +/** + * 满减送活动 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class RewardActivityServiceImpl implements RewardActivityService { + + @Resource + private RewardActivityMapper rewardActivityMapper; + + @Override + public Long createRewardActivity(RewardActivityCreateReqVO createReqVO) { + // 校验商品是否冲突 + validateRewardActivitySpuConflicts(null, createReqVO.getProductSpuIds()); + + // 插入 + RewardActivityDO rewardActivity = RewardActivityConvert.INSTANCE.convert(createReqVO) + .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime())); + rewardActivityMapper.insert(rewardActivity); + // 返回 + return rewardActivity.getId(); + } + + @Override + public void updateRewardActivity(RewardActivityUpdateReqVO updateReqVO) { + // 校验存在 + RewardActivityDO dbRewardActivity = validateRewardActivityExists(updateReqVO.getId()); + if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能修改噢 + throw exception(REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); + } + // 校验商品是否冲突 + validateRewardActivitySpuConflicts(updateReqVO.getId(), updateReqVO.getProductSpuIds()); + + // 更新 + RewardActivityDO updateObj = RewardActivityConvert.INSTANCE.convert(updateReqVO) + .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); + rewardActivityMapper.updateById(updateObj); + } + + @Override + public void closeRewardActivity(Long id) { + // 校验存在 + RewardActivityDO dbRewardActivity = validateRewardActivityExists(id); + if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 已关闭的活动,不能关闭噢 + throw exception(REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED); + } + if (dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.END.getStatus())) { // 已关闭的活动,不能关闭噢 + throw exception(REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END); + } + + // 更新 + RewardActivityDO updateObj = new RewardActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); + rewardActivityMapper.updateById(updateObj); + } + + @Override + public void deleteRewardActivity(Long id) { + // 校验存在 + RewardActivityDO dbRewardActivity = validateRewardActivityExists(id); + if (!dbRewardActivity.getStatus().equals(PromotionActivityStatusEnum.CLOSE.getStatus())) { // 未关闭的活动,不能删除噢 + throw exception(REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED); + } + + // 删除 + rewardActivityMapper.deleteById(id); + } + + private RewardActivityDO validateRewardActivityExists(Long id) { + RewardActivityDO activity = rewardActivityMapper.selectById(id); + if (activity == null) { + throw exception(REWARD_ACTIVITY_NOT_EXISTS); + } + return activity; + } + + /** + * 校验商品参加的活动是否冲突 + * + * @param id 活动编号 + * @param spuIds 商品 SPU 编号数组 + */ + private void validateRewardActivitySpuConflicts(Long id, Collection spuIds) { + if (CollUtil.isEmpty(spuIds)) { + return; + } + // 查询商品参加的活动 + List rewardActivityList = getRewardActivityListBySpuIds(spuIds, + asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus())); + if (id != null) { // 排除自己这个活动 + rewardActivityList.removeIf(activity -> id.equals(activity.getId())); + } + // 如果非空,则说明冲突 + if (CollUtil.isNotEmpty(rewardActivityList)) { + throw exception(REWARD_ACTIVITY_SPU_CONFLICTS); + } + } + + /** + * 获得商品参加的满减送活动的数组 + * + * @param spuIds 商品 SPU 编号数组 + * @param statuses 活动状态数组 + * @return 商品参加的满减送活动的数组 + */ + private List getRewardActivityListBySpuIds(Collection spuIds, + Collection statuses) { + List list = rewardActivityMapper.selectListByStatus(statuses); + return CollUtil.filter(list, activity -> CollUtil.containsAny(activity.getProductSpuIds(), spuIds)); + } + + @Override + public RewardActivityDO getRewardActivity(Long id) { + return rewardActivityMapper.selectById(id); + } + + @Override + public PageResult getRewardActivityPage(RewardActivityPageReqVO pageReqVO) { + return rewardActivityMapper.selectPage(pageReqVO); + } + + @Override + public Map> getMatchRewardActivities(Set spuIds) { + // 如果有全局活动,则直接选择它 + List allActivities = rewardActivityMapper.selectListByProductScopeAndStatus( + PromotionProductScopeEnum.ALL.getScope(), PromotionActivityStatusEnum.RUN.getStatus()); + if (CollUtil.isNotEmpty(allActivities)) { + return MapUtil.builder(allActivities.get(0), spuIds).build(); + } + + // 查询某个活动参加的活动 + List productActivityList = getRewardActivityListBySpuIds(spuIds, + singleton(PromotionActivityStatusEnum.RUN.getStatus())); + return convertMap(productActivityList, activity -> activity, + rewardActivityDO -> intersectionDistinct(rewardActivityDO.getProductSpuIds(), spuIds)); // 求交集返回 + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java new file mode 100644 index 000000000..a0ff74dc8 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity; + +import java.util.*; +import javax.validation.*; + +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; + +/** + * 秒杀活动 Service 接口 + * + * @author halfninety + */ +public interface SeckillActivityService { + + /** + * 创建秒杀活动 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createSeckillActivity(@Valid SeckillActivityCreateReqVO createReqVO); + + /** + * 更新秒杀活动 + * + * @param updateReqVO 更新信息 + */ + void updateSeckillActivity(@Valid SeckillActivityUpdateReqVO updateReqVO); + + /** + * 关闭秒杀活动 + * + * @param id 编号 + */ + void closeSeckillActivity(Long id); + + /** + * 删除秒杀活动 + * + * @param id 编号 + */ + void deleteSeckillActivity(Long id); + + /** + * 获得秒杀活动 + * + * @param id 编号 + * @return 秒杀活动 + */ + SeckillActivityDO getSeckillActivity(Long id); + + /** + * 获得秒杀活动列表 + * + * @param ids 编号 + * @return 秒杀活动列表 + */ + List getSeckillActivityList(Collection ids); + + /** + * 获得秒杀活动分页 + * + * @param pageReqVO 分页查询 + * @return 秒杀活动分页 + */ + PageResult getSeckillActivityPage(SeckillActivityPageReqVO pageReqVO); + + /** + * 通过活动编号获取活动商品 + * + * @param id 活动编号 + * @return 活动商品列表 + */ + List getSeckillProductListByActivityId(Long id); +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java new file mode 100644 index 000000000..45581d825 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java @@ -0,0 +1,226 @@ +package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityBaseVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillProductMapper; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeService; +import cn.iocoder.yudao.module.promotion.util.PromotionUtils; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; +import static java.util.Arrays.asList; + +/** + * 秒杀活动 Service 实现类 + * + * @author halfninety + */ +@Service +@Validated +public class SeckillActivityServiceImpl implements SeckillActivityService { + @Resource + private SeckillActivityMapper seckillActivityMapper; + @Resource + private SeckillProductMapper seckillProductMapper; + @Resource + private SeckillTimeService seckillTimeService; + + @Override + public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) { + // 校验商品是否冲突 + validateSeckillActivityProductConflicts(null, createReqVO.getProducts()); + // 校验秒杀时段是否存在 + seckillTimeService.validateSeckillTimeExists(createReqVO.getTimeIds()); + + // 插入秒杀活动 + SeckillActivityDO seckillActivity = SeckillActivityConvert.INSTANCE.convert(createReqVO) + .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getStartTime(), createReqVO.getEndTime())); + seckillActivityMapper.insert(seckillActivity); + // 插入商品 + List productDOS = SeckillActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), seckillActivity); + seckillProductMapper.insertBatch(productDOS); + // 更新秒杀时段的秒杀活动数量 + seckillTimeService.sekillActivityCountIncr(createReqVO.getTimeIds()); + return seckillActivity.getId(); + } + + @Override + public void updateSeckillActivity(SeckillActivityUpdateReqVO updateReqVO) { + // 校验存在 + SeckillActivityDO seckillActivity = validateSeckillActivityExists(updateReqVO.getId()); + if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) { + throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); + } + // 校验商品是否冲突 + validateSeckillActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts()); + + // 更新活动 + SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO) + .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getStartTime(), updateReqVO.getEndTime())); + seckillActivityMapper.updateById(updateObj); + // 更新商品 + updateSeckillProduct(updateReqVO); + // 更新秒杀时段的秒杀活动数量 + updateSeckillTimeActivityCount(seckillActivity, updateReqVO.getTimeIds()); + } + + + /** + * 更新秒杀时段的秒杀活动数量 + * + * @param seckillActivity 查询出的秒杀活动 + * @param updateTimeIds 更新后的秒杀时段id列表 + */ + private void updateSeckillTimeActivityCount(SeckillActivityDO seckillActivity, List updateTimeIds) { + // 查询出 timeIds + List existsTimeIds = seckillActivity.getTimeIds(); + // 需要减少的时间段 + Collection reduceIds = CollUtil.filterNew(existsTimeIds, existsTimeId -> !updateTimeIds.contains(existsTimeId)); + // 需要添加的时间段 + updateTimeIds.removeIf(existsTimeIds::contains); + // 更新减少时间段和增加时间段 + if (CollUtil.isNotEmpty(updateTimeIds)) { + seckillTimeService.sekillActivityCountIncr(updateTimeIds); + } + if (CollUtil.isNotEmpty(reduceIds)) { + seckillTimeService.sekillActivityCountDecr(reduceIds); + } + } + + /** + * 更新秒杀商品 + * 后台查出的数据和前台查出的数据进行遍历, + * 1. 对前台数据进行遍历:如果不存在于后台的 sku 中需要新增 + * 2. 对后台数据进行遍历:如果不存在于前台的 sku 中需要删除 + * 3. 最后对当前活动商品全部更新,更新秒杀时段id列表 + * + * @param updateReqVO 更新的请求VO + */ + private void updateSeckillProduct(SeckillActivityUpdateReqVO updateReqVO) { + List seckillProductDOS = seckillProductMapper.selectListByActivityId(updateReqVO.getId()); + List products = updateReqVO.getProducts(); + + // 计算需要删除的数据 + List deleteIds = CollectionUtils.convertList(seckillProductDOS, SeckillProductDO::getId, + seckillProductDO -> products.stream() + .noneMatch(product -> SeckillActivityConvert.INSTANCE.isEquals(seckillProductDO, product))); + if (CollUtil.isNotEmpty(deleteIds)) { + seckillProductMapper.deleteBatchIds(deleteIds); + } + + // 计算需要新增的数据 + List newSeckillProductDOs = CollectionUtils.convertList(products, + product -> SeckillActivityConvert.INSTANCE.convert(product).setActivityId(updateReqVO.getId())); + newSeckillProductDOs.removeIf(product -> seckillProductDOS.stream() + .anyMatch(seckillProduct -> SeckillActivityConvert.INSTANCE.isEquals(seckillProduct, product))); + if (CollUtil.isNotEmpty(newSeckillProductDOs)) { + seckillProductMapper.insertBatch(newSeckillProductDOs); + } + + //全量更新当前活动商品的秒杀时段id列表(timeIds) + seckillProductMapper.updateTimeIdsByActivityId(updateReqVO.getId(), updateReqVO.getTimeIds()); + } + + /** + * 校验商品是否冲突 + * + * @param id 秒杀活动编号 + * @param products 商品列表 + */ + private void validateSeckillActivityProductConflicts(Long id, List products) { + if (CollUtil.isEmpty(products)) { + return; + } + List seckillProductDOS = seckillProductMapper + .selectListBySkuIds(CollectionUtils.convertSet(products, SeckillActivityBaseVO.Product::getSkuId)); + if (CollUtil.isEmpty(seckillProductDOS)) { + return; + } + List seckillActivityDOS = seckillActivityMapper + .selectBatchIds(CollectionUtils.convertSet(seckillProductDOS, SeckillProductDO::getActivityId)); + if (id != null) { // 排除自己这个活动 + seckillActivityDOS.removeIf(item -> id.equals(item.getId())); + } + // 排除不满足 status 的活动 + List statuses = asList(PromotionActivityStatusEnum.WAIT.getStatus(), PromotionActivityStatusEnum.RUN.getStatus()); + seckillActivityDOS.removeIf(item -> !statuses.contains(item.getStatus())); + // 如果非空,则说明冲突 + if (CollUtil.isNotEmpty(seckillActivityDOS)) { + throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS); + } + } + + @Override + public void closeSeckillActivity(Long id) { + // 校验存在 + SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id); + if (PromotionActivityStatusEnum.CLOSE.getStatus().equals(seckillActivity.getStatus())) { + throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED); + } + if (PromotionActivityStatusEnum.END.getStatus().equals(seckillActivity.getStatus())) { + throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END); + } + // 更新 + SeckillActivityDO updateObj = new SeckillActivityDO().setId(id).setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); + seckillActivityMapper.updateById(updateObj); + } + + @Override + public void deleteSeckillActivity(Long id) { + // 校验存在 + SeckillActivityDO seckillActivity = this.validateSeckillActivityExists(id); + List statuses = asList(PromotionActivityStatusEnum.CLOSE.getStatus(), PromotionActivityStatusEnum.END.getStatus()); + if (!statuses.contains(seckillActivity.getStatus())) { + throw exception(SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END); + } + // 更新秒杀时段的秒杀活动数量 + seckillTimeService.sekillActivityCountDecr(seckillActivity.getTimeIds()); + // 删除 + seckillActivityMapper.deleteById(id); + } + + private SeckillActivityDO validateSeckillActivityExists(Long id) { + SeckillActivityDO seckillActivity = seckillActivityMapper.selectById(id); + if (seckillActivity == null) { + throw exception(SECKILL_ACTIVITY_NOT_EXISTS); + } + return seckillActivity; + } + + @Override + public SeckillActivityDO getSeckillActivity(Long id) { + return seckillActivityMapper.selectById(id); + } + + @Override + public List getSeckillActivityList(Collection ids) { + return seckillActivityMapper.selectBatchIds(ids); + } + + @Override + public PageResult getSeckillActivityPage(SeckillActivityPageReqVO pageReqVO) { + return seckillActivityMapper.selectPage(pageReqVO); + } + + @Override + public List getSeckillProductListByActivityId(Long id) { + return seckillProductMapper.selectListByActivityId(id); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java new file mode 100644 index 000000000..2e9c21249 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.promotion.service.seckill.seckilltime; + +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; + +/** + * 秒杀时段 Service 接口 + * + * @author halfninety + */ +public interface SeckillTimeService { + + /** + * 创建秒杀时段 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createSeckillTime(@Valid SeckillTimeCreateReqVO createReqVO); + + /** + * 更新秒杀时段 + * + * @param updateReqVO 更新信息 + */ + void updateSeckillTime(@Valid SeckillTimeUpdateReqVO updateReqVO); + + /** + * 删除秒杀时段 + * + * @param id 编号 + */ + void deleteSeckillTime(Long id); + + /** + * 获得秒杀时段 + * + * @param id 编号 + * @return 秒杀时段 + */ + SeckillTimeDO getSeckillTime(Long id); + + /** + * 获得所有秒杀时段列表 + * + * @return 所有秒杀时段列表 + */ + List getSeckillTimeList(); + + /** + * 校验秒杀时段是否存在 + * + * @param timeIds 秒杀时段id集合 + */ + void validateSeckillTimeExists(Collection timeIds); + + /** + * 秒杀时段列表的秒杀活动数量加 1 + * + * @param ids 秒杀时段id列表 + */ + void sekillActivityCountIncr(Collection ids); + + + /** + * 秒杀时段列表的秒杀活动数量减 1 + * + * @param ids 秒杀时段id列表 + */ + void sekillActivityCountDecr(Collection ids); +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java new file mode 100644 index 000000000..d38183860 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java @@ -0,0 +1,124 @@ +package cn.iocoder.yudao.module.promotion.service.seckill.seckilltime; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.seckill.seckilltime.SeckillTimeConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime.SeckillTimeMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.time.LocalTime; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_CONFLICTS; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_NOT_EXISTS; + +/** + * 秒杀时段 Service 实现类 + * + * @author halfninety + */ +@Service +@Validated +public class SeckillTimeServiceImpl implements SeckillTimeService { + + @Resource + private SeckillTimeMapper seckillTimeMapper; + + @Override + public Long createSeckillTime(SeckillTimeCreateReqVO createReqVO) { + // 校验时间段是否冲突 + validateSeckillTimeConflict(null, createReqVO.getStartTime(), createReqVO.getEndTime()); + // 插入 + SeckillTimeDO seckillTime = SeckillTimeConvert.INSTANCE.convert(createReqVO); + seckillTimeMapper.insert(seckillTime); + // 返回 + return seckillTime.getId(); + } + + @Override + public void updateSeckillTime(SeckillTimeUpdateReqVO updateReqVO) { + // 校验存在 + this.validateSeckillTimeExists(updateReqVO.getId()); + // 校验时间段是否冲突 + validateSeckillTimeConflict(updateReqVO.getId(), updateReqVO.getStartTime(), updateReqVO.getEndTime()); + // 更新 + SeckillTimeDO updateObj = SeckillTimeConvert.INSTANCE.convert(updateReqVO); + seckillTimeMapper.updateById(updateObj); + } + + @Override + public void deleteSeckillTime(Long id) { + // 校验存在 + this.validateSeckillTimeExists(id); + // 删除 + seckillTimeMapper.deleteById(id); + } + + private void validateSeckillTimeExists(Long id) { + if (seckillTimeMapper.selectById(id) == null) { + throw exception(SECKILL_TIME_NOT_EXISTS); + } + } + + /** + * 校验时间是否存在冲突 + * + * @param startTime 开始时间 + * @param endTime 结束时间 + */ + private void validateSeckillTimeConflict(Long id, LocalTime startTime, LocalTime endTime) { + //查询开始时间,结束时间,是否在别人的时间段内 + List startTimeList = seckillTimeMapper.selectListByTime(startTime); + List endTimeList = seckillTimeMapper.selectListByTime(endTime); + //查询自己时间段内是否有时间段 + List startEndTimeList = seckillTimeMapper.selectListByTime(startTime, endTime); + if (id != null) { + //移除自己 + startTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id)); + endTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id)); + startEndTimeList.removeIf(seckillTime -> Objects.equals(seckillTime.getId(), id)); + } + if (CollUtil.isNotEmpty(startTimeList) || CollUtil.isNotEmpty(endTimeList) + || CollUtil.isNotEmpty(startEndTimeList)) { + throw exception(SECKILL_TIME_CONFLICTS); + } + } + + @Override + public SeckillTimeDO getSeckillTime(Long id) { + return seckillTimeMapper.selectById(id); + } + + @Override + public List getSeckillTimeList() { + return seckillTimeMapper.selectList(); + } + + @Override + public void validateSeckillTimeExists(Collection timeIds) { + if (CollUtil.isEmpty(timeIds)) { + throw exception(SECKILL_TIME_NOT_EXISTS); + } + if (seckillTimeMapper.selectBatchIds(timeIds).size() != timeIds.size()) { + throw exception(SECKILL_TIME_NOT_EXISTS); + } + } + + @Override + public void sekillActivityCountIncr(Collection ids) { + seckillTimeMapper.updateActivityCount(ids, "+", 1); + } + + @Override + public void sekillActivityCountDecr(Collection ids) { + seckillTimeMapper.updateActivityCount(ids, "-", 1); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java new file mode 100644 index 000000000..fc8ca16cf --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.promotion.util; + +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; + +import java.time.LocalDateTime; + +/** + * 活动工具类 + * + * @author 芋道源码 + */ +public class PromotionUtils { + + /** + * 根据时间,计算活动状态 + * + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 活动状态 + */ + public static Integer calculateActivityStatus(LocalDateTime startTime, LocalDateTime endTime) { + if (LocalDateTimeUtils.beforeNow(endTime)) { + return PromotionActivityStatusEnum.END.getStatus(); + } + if (LocalDateTimeUtils.afterNow(startTime)) { + return PromotionActivityStatusEnum.WAIT.getStatus(); + } + return PromotionActivityStatusEnum.RUN.getStatus(); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml b/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml new file mode 100644 index 000000000..987143534 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml @@ -0,0 +1,11 @@ + + + + + + UPDATE promotion_coupon_template + SET take_count = take_count + #{incrCount} + WHERE id = #{id} + + + diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImplTest.java new file mode 100755 index 000000000..5a41563e7 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImplTest.java @@ -0,0 +1,147 @@ +package cn.iocoder.yudao.module.promotion.service.coupon; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.time.LocalDateTime; + +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS; +import static org.junit.jupiter.api.Assertions.*; + +/** +* {@link CouponTemplateServiceImpl} 的单元测试类 +* +* @author 芋道源码 +*/ +@Import(CouponTemplateServiceImpl.class) +public class CouponTemplateServiceImplTest extends BaseDbUnitTest { + + @Resource + private CouponTemplateServiceImpl couponTemplateService; + + @Resource + private CouponTemplateMapper couponTemplateMapper; + + @Test + public void testCreateCouponTemplate_success() { + // 准备参数 + CouponTemplateCreateReqVO reqVO = randomPojo(CouponTemplateCreateReqVO.class, + o -> o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()) + .setValidityType(randomEle(CouponTemplateValidityTypeEnum.values()).getType()) + .setDiscountType(randomEle(PromotionDiscountTypeEnum.values()).getType())); + + // 调用 + Long couponTemplateId = couponTemplateService.createCouponTemplate(reqVO); + // 断言 + assertNotNull(couponTemplateId); + // 校验记录的属性是否正确 + CouponTemplateDO couponTemplate = couponTemplateMapper.selectById(couponTemplateId); + assertPojoEquals(reqVO, couponTemplate); + } + + @Test + public void testUpdateCouponTemplate_success() { + // mock 数据 + CouponTemplateDO dbCouponTemplate = randomPojo(CouponTemplateDO.class); + couponTemplateMapper.insert(dbCouponTemplate);// @Sql: 先插入出一条存在的数据 + // 准备参数 + CouponTemplateUpdateReqVO reqVO = randomPojo(CouponTemplateUpdateReqVO.class, o -> { + o.setId(dbCouponTemplate.getId()); // 设置更新的 ID + // 其它通用字段 + o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()) + .setValidityType(randomEle(CouponTemplateValidityTypeEnum.values()).getType()) + .setDiscountType(randomEle(PromotionDiscountTypeEnum.values()).getType()); + }); + + // 调用 + couponTemplateService.updateCouponTemplate(reqVO); + // 校验是否更新正确 + CouponTemplateDO couponTemplate = couponTemplateMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, couponTemplate); + } + + @Test + public void testUpdateCouponTemplate_notExists() { + // 准备参数 + CouponTemplateUpdateReqVO reqVO = randomPojo(CouponTemplateUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> couponTemplateService.updateCouponTemplate(reqVO), COUPON_TEMPLATE_NOT_EXISTS); + } + + @Test + public void testDeleteCouponTemplate_success() { + // mock 数据 + CouponTemplateDO dbCouponTemplate = randomPojo(CouponTemplateDO.class); + couponTemplateMapper.insert(dbCouponTemplate);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbCouponTemplate.getId(); + + // 调用 + couponTemplateService.deleteCouponTemplate(id); + // 校验数据不存在了 + assertNull(couponTemplateMapper.selectById(id)); + } + + @Test + public void testDeleteCouponTemplate_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> couponTemplateService.deleteCouponTemplate(id), COUPON_TEMPLATE_NOT_EXISTS); + } + + @Test + public void testGetCouponTemplatePage() { + // mock 数据 + CouponTemplateDO dbCouponTemplate = randomPojo(CouponTemplateDO.class, o -> { // 等会查询到 + o.setName("芋艿"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()); + o.setCreateTime(buildTime(2022, 2, 2)); + }); + couponTemplateMapper.insert(dbCouponTemplate); + // 测试 name 不匹配 + couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setName("土豆"))); + // 测试 status 不匹配 + couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + // 测试 type 不匹配 + couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()))); + // 测试 createTime 不匹配 + couponTemplateMapper.insert(cloneIgnoreId(dbCouponTemplate, o -> o.setCreateTime(buildTime(2022, 1, 1)))); + // 准备参数 + CouponTemplatePageReqVO reqVO = new CouponTemplatePageReqVO(); + reqVO.setName("芋艿"); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()); + reqVO.setCreateTime((new LocalDateTime[]{buildTime(2022, 2, 1), buildTime(2022, 2, 3)})); + + // 调用 + PageResult pageResult = couponTemplateService.getCouponTemplatePage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbCouponTemplate, pageResult.getList().get(0)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java new file mode 100755 index 000000000..5ad517463 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java @@ -0,0 +1,210 @@ +package cn.iocoder.yudao.module.promotion.service.discount; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountActivityMapper; +import cn.iocoder.yudao.module.promotion.dal.mysql.discount.DiscountProductMapper; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.DISCOUNT_ACTIVITY_NOT_EXISTS; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.*; + +/** +* {@link DiscountActivityServiceImpl} 的单元测试类 +* +* @author 芋道源码 +*/ +@Import(DiscountActivityServiceImpl.class) +public class DiscountActivityServiceImplTest extends BaseDbUnitTest { + + @Resource + private DiscountActivityServiceImpl discountActivityService; + + @Resource + private DiscountActivityMapper discountActivityMapper; + @Resource + private DiscountProductMapper discountProductMapper; + + @Test + public void testCreateDiscountActivity_success() { + // 准备参数 + DiscountActivityCreateReqVO reqVO = randomPojo(DiscountActivityCreateReqVO.class, o -> { + // 用于触发进行中的状态 + o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); + // 设置商品 + o.setProducts(asList(new DiscountActivityBaseVO.Product().setSpuId(1L).setSkuId(2L) + .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3), + new DiscountActivityBaseVO.Product().setSpuId(10L).setSkuId(20L) + .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30))); + }); + + // 调用 + Long discountActivityId = discountActivityService.createDiscountActivity(reqVO); + // 断言 + assertNotNull(discountActivityId); + // 校验活动 + DiscountActivityDO discountActivity = discountActivityMapper.selectById(discountActivityId); + assertPojoEquals(reqVO, discountActivity); + assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); + // 校验商品 + List discountProducts = discountProductMapper.selectList(DiscountProductDO::getActivityId, discountActivity.getId()); + assertEquals(discountProducts.size(), reqVO.getProducts().size()); + for (int i = 0; i < reqVO.getProducts().size(); i++) { + DiscountActivityBaseVO.Product product = reqVO.getProducts().get(i); + DiscountProductDO discountProduct = discountProducts.get(i); + assertEquals(discountProduct.getActivityId(), discountActivity.getId()); + assertEquals(discountProduct.getSpuId(), product.getSpuId()); + assertEquals(discountProduct.getSkuId(), product.getSkuId()); + assertEquals(discountProduct.getDiscountType(), product.getDiscountType()); + assertEquals(discountProduct.getDiscountPrice(), product.getDiscountPrice()); + assertEquals(discountProduct.getDiscountPercent(), product.getDiscountPercent()); + } + } + + @Test + public void testUpdateDiscountActivity_success() { + // mock 数据(商品) + DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class); + discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 + // mock 数据(活动) + DiscountProductDO dbDiscountProduct01 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(dbDiscountActivity.getId()) + .setSpuId(1L).setSkuId(2L).setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3).setDiscountPercent(null)); + DiscountProductDO dbDiscountProduct02 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(dbDiscountActivity.getId()) + .setSpuId(10L).setSkuId(20L).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30).setDiscountPrice(null)); + discountProductMapper.insert(dbDiscountProduct01); + discountProductMapper.insert(dbDiscountProduct02); + // 准备参数 + DiscountActivityUpdateReqVO reqVO = randomPojo(DiscountActivityUpdateReqVO.class, o -> { + o.setId(dbDiscountActivity.getId()); // 设置更新的 ID + // 用于触发进行中的状态 + o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); + // 设置商品 + o.setProducts(asList(new DiscountActivityBaseVO.Product().setSpuId(1L).setSkuId(2L) + .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(3).setDiscountPercent(null), + new DiscountActivityBaseVO.Product().setSpuId(100L).setSkuId(200L) + .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(30).setDiscountPrice(null))); + }); + + // 调用 + discountActivityService.updateDiscountActivity(reqVO); + // 校验活动 + DiscountActivityDO discountActivity = discountActivityMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, discountActivity); + assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); + // 校验商品 + List discountProducts = discountProductMapper.selectList(DiscountProductDO::getActivityId, discountActivity.getId()); + assertEquals(discountProducts.size(), reqVO.getProducts().size()); + for (int i = 0; i < reqVO.getProducts().size(); i++) { + DiscountActivityBaseVO.Product product = reqVO.getProducts().get(i); + DiscountProductDO discountProduct = discountProducts.get(i); + assertEquals(discountProduct.getActivityId(), discountActivity.getId()); + assertEquals(discountProduct.getSpuId(), product.getSpuId()); + assertEquals(discountProduct.getSkuId(), product.getSkuId()); + assertEquals(discountProduct.getDiscountType(), product.getDiscountType()); + assertEquals(discountProduct.getDiscountPrice(), product.getDiscountPrice()); + assertEquals(discountProduct.getDiscountPercent(), product.getDiscountPercent()); + } + } + + @Test + public void testCloseDiscountActivity() { + // mock 数据 + DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, + o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus())); + discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbDiscountActivity.getId(); + + // 调用 + discountActivityService.closeRewardActivity(id); + // 校验状态 + DiscountActivityDO discountActivity = discountActivityMapper.selectById(id); + assertEquals(discountActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus()); + } + + @Test + public void testUpdateDiscountActivity_notExists() { + // 准备参数 + DiscountActivityUpdateReqVO reqVO = randomPojo(DiscountActivityUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> discountActivityService.updateDiscountActivity(reqVO), DISCOUNT_ACTIVITY_NOT_EXISTS); + } + + @Test + public void testDeleteDiscountActivity_success() { + // mock 数据 + DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, + o -> o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus())); + discountActivityMapper.insert(dbDiscountActivity);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbDiscountActivity.getId(); + + // 调用 + discountActivityService.deleteDiscountActivity(id); + // 校验数据不存在了 + assertNull(discountActivityMapper.selectById(id)); + } + + @Test + public void testDeleteDiscountActivity_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> discountActivityService.deleteDiscountActivity(id), DISCOUNT_ACTIVITY_NOT_EXISTS); + } + + @Test + public void testGetDiscountActivityPage() { + // mock 数据 + DiscountActivityDO dbDiscountActivity = randomPojo(DiscountActivityDO.class, o -> { // 等会查询到 + o.setName("芋艿"); + o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus()); + o.setCreateTime(buildTime(2021, 1, 15)); + }); + discountActivityMapper.insert(dbDiscountActivity); + // 测试 name 不匹配 + discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setName("土豆"))); + // 测试 status 不匹配 + discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setStatus(PromotionActivityStatusEnum.END.getStatus()))); + // 测试 createTime 不匹配 + discountActivityMapper.insert(cloneIgnoreId(dbDiscountActivity, o -> o.setCreateTime(buildTime(2021, 2, 10)))); + // 准备参数 + DiscountActivityPageReqVO reqVO = new DiscountActivityPageReqVO(); + reqVO.setName("芋艿"); + reqVO.setStatus(PromotionActivityStatusEnum.WAIT.getStatus()); + reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 1, 1), buildTime(2021, 1, 31)})); + + // 调用 + PageResult pageResult = discountActivityService.getDiscountActivityPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbDiscountActivity, pageResult.getList().get(0)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java new file mode 100644 index 000000000..0c7b2d6ec --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java @@ -0,0 +1,506 @@ +package cn.iocoder.yudao.module.promotion.service.price; + +import cn.hutool.core.map.MapUtil; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.CouponMeetRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; +import cn.iocoder.yudao.module.promotion.enums.common.*; +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum; +import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; +import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService; +import cn.iocoder.yudao.module.promotion.service.discount.bo.DiscountProductDetailBO; +import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_VALID_TIME_NOT_NOW; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; + +/** + * {@link PriceServiceImpl} 的单元测试 + * + * @author 芋道源码 + */ +public class PriceServiceTest extends BaseMockitoUnitTest { + + @InjectMocks + private PriceServiceImpl priceService; + + @Mock + private DiscountActivityService discountService; + @Mock + private RewardActivityService rewardActivityService; + @Mock + private CouponService couponService; + @Mock + private ProductSkuApi productSkuApi; + + @Test + public void testCalculatePrice_memberDiscount() { + // 准备参数 + // TODO 芋艿:userId = 1,实现 9 折;后续改成 mock + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1L) + .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2))); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); + when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); + + // 调用 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + // 断言 Order 部分 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + assertEquals(order.getOriginalPrice(), 200); + assertEquals(order.getOrderPrice(), 180); + assertEquals(order.getDiscountPrice(), 0); + assertEquals(order.getPointPrice(), 0); + assertEquals(order.getDeliveryPrice(), 0); + assertEquals(order.getPayPrice(), 180); + assertNull(order.getCouponId()); + // 断言 OrderItem 部分 + assertEquals(order.getItems().size(), 1); + PriceCalculateRespDTO.OrderItem orderItem = order.getItems().get(0); + assertEquals(orderItem.getSkuId(), 10L); + assertEquals(orderItem.getCount(), 2); + assertEquals(orderItem.getOriginalPrice(), 200); + assertEquals(orderItem.getOriginalUnitPrice(), 100); + assertEquals(orderItem.getDiscountPrice(), 20); + assertEquals(orderItem.getPayPrice(), 180); + assertEquals(orderItem.getOrderPartPrice(), 0); + assertEquals(orderItem.getOrderDividePrice(), 180); + // 断言 Promotion 部分 + assertEquals(priceCalculate.getPromotions().size(), 1); + PriceCalculateRespDTO.Promotion promotion = priceCalculate.getPromotions().get(0); + assertNull(promotion.getId()); + assertEquals(promotion.getName(), "会员折扣"); + assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); + assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); + assertEquals(promotion.getOriginalPrice(), 200); + assertEquals(promotion.getDiscountPrice(), 20); + assertTrue(promotion.getMeet()); + assertEquals(promotion.getMeetTip(), "会员折扣:省 0.20 元"); + PriceCalculateRespDTO.PromotionItem promotionItem = promotion.getItems().get(0); + assertEquals(promotion.getItems().size(), 1); + assertEquals(promotionItem.getSkuId(), 10L); + assertEquals(promotionItem.getOriginalPrice(), 200); + assertEquals(promotionItem.getDiscountPrice(), 20); + } + + @Test + public void testCalculatePrice_discountActivity() { + // 准备参数 + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) + .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), + new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3))); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); + ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50)); + when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); + // mock 方法(限时折扣 DiscountActivity 信息) + DiscountProductDetailBO discountProduct01 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(1000L) + .setActivityName("活动 1000 号").setSkuId(10L) + .setDiscountType(PromotionDiscountTypeEnum.PRICE.getType()).setDiscountPrice(40)); + DiscountProductDetailBO discountProduct02 = randomPojo(DiscountProductDetailBO.class, o -> o.setActivityId(2000L) + .setActivityName("活动 2000 号").setSkuId(20L) + .setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()).setDiscountPercent(60)); + when(discountService.getMatchDiscountProducts(eq(asSet(10L, 20L)))).thenReturn( + MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map()); + + // 10L: 100 * 2 - 40 * 2 = 120 + // 20L:50 * 3 - 50 * 3 * 0.4 = 90 + + // 调用 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + // 断言 Order 部分 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + assertEquals(order.getOriginalPrice(), 350); + assertEquals(order.getOrderPrice(), 210); + assertEquals(order.getDiscountPrice(), 0); + assertEquals(order.getPointPrice(), 0); + assertEquals(order.getDeliveryPrice(), 0); + assertEquals(order.getPayPrice(), 210); + assertNull(order.getCouponId()); + // 断言 OrderItem 部分 + assertEquals(order.getItems().size(), 2); + PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getOriginalPrice(), 200); + assertEquals(orderItem01.getOriginalUnitPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 80); + assertEquals(orderItem01.getPayPrice(), 120); + assertEquals(orderItem01.getOrderPartPrice(), 0); + assertEquals(orderItem01.getOrderDividePrice(), 120); + PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getOriginalPrice(), 150); + assertEquals(orderItem02.getOriginalUnitPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 60); + assertEquals(orderItem02.getPayPrice(), 90); + assertEquals(orderItem02.getOrderPartPrice(), 0); + assertEquals(orderItem02.getOrderDividePrice(), 90); + // 断言 Promotion 部分 + assertEquals(priceCalculate.getPromotions().size(), 2); + PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); + assertEquals(promotion01.getId(), 1000L); + assertEquals(promotion01.getName(), "活动 1000 号"); + assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); + assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); + assertEquals(promotion01.getOriginalPrice(), 200); + assertEquals(promotion01.getDiscountPrice(), 80); + assertTrue(promotion01.getMeet()); + assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.80 元"); + PriceCalculateRespDTO.PromotionItem promotionItem01 = promotion01.getItems().get(0); + assertEquals(promotion01.getItems().size(), 1); + assertEquals(promotionItem01.getSkuId(), 10L); + assertEquals(promotionItem01.getOriginalPrice(), 200); + assertEquals(promotionItem01.getDiscountPrice(), 80); + PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); + assertEquals(promotion02.getId(), 2000L); + assertEquals(promotion02.getName(), "活动 2000 号"); + assertEquals(promotion02.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); + assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); + assertEquals(promotion02.getOriginalPrice(), 150); + assertEquals(promotion02.getDiscountPrice(), 60); + assertTrue(promotion02.getMeet()); + assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.60 元"); + PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); + assertEquals(promotion02.getItems().size(), 1); + assertEquals(promotionItem02.getSkuId(), 20L); + assertEquals(promotionItem02.getOriginalPrice(), 150); + assertEquals(promotionItem02.getDiscountPrice(), 60); + } + + /** + * 测试满减送活动,匹配的情况 + */ + @Test + public void testCalculatePrice_rewardActivity() { + // 准备参数 + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) + .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), + new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), + new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); + ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); + ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); + when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); + // mock 方法(限时折扣 DiscountActivity 信息) + RewardActivityDO rewardActivity01 = randomPojo(RewardActivityDO.class, o -> o.setId(1000L).setName("活动 1000 号") + .setProductSpuIds(asList(10L, 20L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) + .setRules(singletonList(new RewardActivityDO.Rule().setLimit(200).setDiscountPrice(70)))); + RewardActivityDO rewardActivity02 = randomPojo(RewardActivityDO.class, o -> o.setId(2000L).setName("活动 2000 号") + .setProductSpuIds(singletonList(30L)).setConditionType(PromotionConditionTypeEnum.COUNT.getType()) + .setRules(asList(new RewardActivityDO.Rule().setLimit(1).setDiscountPrice(10), + new RewardActivityDO.Rule().setLimit(2).setDiscountPrice(60), // 最大可满足,因为是 4 个 + new RewardActivityDO.Rule().setLimit(10).setDiscountPrice(100)))); + Map> matchRewardActivities = new LinkedHashMap<>(); + matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); + matchRewardActivities.put(rewardActivity02, asSet(3L)); + when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities); + + // 调用 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + // 断言 Order 部分 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + assertEquals(order.getOriginalPrice(), 470); + assertEquals(order.getOrderPrice(), 470); + assertEquals(order.getDiscountPrice(), 130); + assertEquals(order.getPointPrice(), 0); + assertEquals(order.getDeliveryPrice(), 0); + assertEquals(order.getPayPrice(), 340); + assertNull(order.getCouponId()); + // 断言 OrderItem 部分 + assertEquals(order.getItems().size(), 3); + PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getOriginalPrice(), 200); + assertEquals(orderItem01.getOriginalUnitPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 200); + assertEquals(orderItem01.getOrderPartPrice(), 40); + assertEquals(orderItem01.getOrderDividePrice(), 160); + PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getOriginalPrice(), 150); + assertEquals(orderItem02.getOriginalUnitPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 150); + assertEquals(orderItem02.getOrderPartPrice(), 30); + assertEquals(orderItem02.getOrderDividePrice(), 120); + PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); + assertEquals(orderItem03.getSkuId(), 30L); + assertEquals(orderItem03.getCount(), 4); + assertEquals(orderItem03.getOriginalPrice(), 120); + assertEquals(orderItem03.getOriginalUnitPrice(), 30); + assertEquals(orderItem03.getDiscountPrice(), 0); + assertEquals(orderItem03.getPayPrice(), 120); + assertEquals(orderItem03.getOrderPartPrice(), 60); + assertEquals(orderItem03.getOrderDividePrice(), 60); + // 断言 Promotion 部分(第一个) + assertEquals(priceCalculate.getPromotions().size(), 2); + PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); + assertEquals(promotion01.getId(), 1000L); + assertEquals(promotion01.getName(), "活动 1000 号"); + assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); + assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); + assertEquals(promotion01.getOriginalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 70); + assertTrue(promotion01.getMeet()); + assertEquals(promotion01.getMeetTip(), "满减送:省 0.70 元"); + assertEquals(promotion01.getItems().size(), 2); + PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getOriginalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 40); + PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getOriginalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 30); + // 断言 Promotion 部分(第二个) + PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); + assertEquals(promotion02.getId(), 2000L); + assertEquals(promotion02.getName(), "活动 2000 号"); + assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); + assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); + assertEquals(promotion02.getOriginalPrice(), 120); + assertEquals(promotion02.getDiscountPrice(), 60); + assertTrue(promotion02.getMeet()); + assertEquals(promotion02.getMeetTip(), "满减送:省 0.60 元"); + PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); + assertEquals(promotion02.getItems().size(), 1); + assertEquals(promotionItem02.getSkuId(), 30L); + assertEquals(promotionItem02.getOriginalPrice(), 120); + assertEquals(promotionItem02.getDiscountPrice(), 60); + } + + /** + * 测试满减送活动,不匹配的情况 + */ + @Test + public void testCalculatePrice_rewardActivityNotMeet() { + // 准备参数 + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) + .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), + new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3))); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); + ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); + when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); + // mock 方法(限时折扣 DiscountActivity 信息) + RewardActivityDO rewardActivity01 = randomPojo(RewardActivityDO.class, o -> o.setId(1000L).setName("活动 1000 号") + .setProductSpuIds(asList(10L, 20L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) + .setRules(singletonList(new RewardActivityDO.Rule().setLimit(351).setDiscountPrice(70)))); + Map> matchRewardActivities = new LinkedHashMap<>(); + matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); + when(rewardActivityService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities); + + // 调用 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + // 断言 Order 部分 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + assertEquals(order.getOriginalPrice(), 350); + assertEquals(order.getOrderPrice(), 350); + assertEquals(order.getDiscountPrice(), 0); + assertEquals(order.getPointPrice(), 0); + assertEquals(order.getDeliveryPrice(), 0); + assertEquals(order.getPayPrice(), 350); + assertNull(order.getCouponId()); + // 断言 OrderItem 部分 + assertEquals(order.getItems().size(), 2); + PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getOriginalPrice(), 200); + assertEquals(orderItem01.getOriginalUnitPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 200); + assertEquals(orderItem01.getOrderPartPrice(), 0); + assertEquals(orderItem01.getOrderDividePrice(), 200); + PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getOriginalPrice(), 150); + assertEquals(orderItem02.getOriginalUnitPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 150); + assertEquals(orderItem02.getOrderPartPrice(), 0); + assertEquals(orderItem02.getOrderDividePrice(), 150); + // 断言 Promotion 部分 + assertEquals(priceCalculate.getPromotions().size(), 1); + PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); + assertEquals(promotion01.getId(), 1000L); + assertEquals(promotion01.getName(), "活动 1000 号"); + assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); + assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); + assertEquals(promotion01.getOriginalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 0); + assertFalse(promotion01.getMeet()); + assertEquals(promotion01.getMeetTip(), "TODO"); // TODO 芋艿:后面再想想 + assertEquals(promotion01.getItems().size(), 2); + PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getOriginalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 0); + PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getOriginalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 0); + } + + @Test + public void testCalculatePrice_coupon() { + // 准备参数 + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) + .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), + new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), + new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))) + .setCouponId(1024L); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); + ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); + ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); + when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); + // mock 方法(优惠劵 Coupon 信息) + CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setName("程序员节") + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)) + .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()) + .setDiscountPercent(50).setDiscountLimitPrice(70)); + when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon); + + // 调用 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + // 断言 Order 部分 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + assertEquals(order.getOriginalPrice(), 470); + assertEquals(order.getOrderPrice(), 470); + assertEquals(order.getDiscountPrice(), 0); + assertEquals(order.getPointPrice(), 0); + assertEquals(order.getDeliveryPrice(), 0); + assertEquals(order.getPayPrice(), 400); + assertEquals(order.getCouponId(), 1024L); + assertEquals(order.getCouponPrice(), 70); + // 断言 OrderItem 部分 + assertEquals(order.getItems().size(), 3); + PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getOriginalPrice(), 200); + assertEquals(orderItem01.getOriginalUnitPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 200); + assertEquals(orderItem01.getOrderPartPrice(), 40); + assertEquals(orderItem01.getOrderDividePrice(), 160); + PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getOriginalPrice(), 150); + assertEquals(orderItem02.getOriginalUnitPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 150); + assertEquals(orderItem02.getOrderPartPrice(), 30); + assertEquals(orderItem02.getOrderDividePrice(), 120); + PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); + assertEquals(orderItem03.getSkuId(), 30L); + assertEquals(orderItem03.getCount(), 4); + assertEquals(orderItem03.getOriginalPrice(), 120); + assertEquals(orderItem03.getOriginalUnitPrice(), 30); + assertEquals(orderItem03.getDiscountPrice(), 0); + assertEquals(orderItem03.getPayPrice(), 120); + assertEquals(orderItem03.getOrderPartPrice(), 0); + assertEquals(orderItem03.getOrderDividePrice(), 120); + // 断言 Promotion 部分 + assertEquals(priceCalculate.getPromotions().size(), 1); + PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); + assertEquals(promotion01.getId(), 1024L); + assertEquals(promotion01.getName(), "程序员节"); + assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); + assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); + assertEquals(promotion01.getOriginalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 70); + assertTrue(promotion01.getMeet()); + assertEquals(promotion01.getMeetTip(), "优惠劵:省 0.70 元"); + assertEquals(promotion01.getItems().size(), 2); + PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getOriginalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 40); + PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getOriginalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 30); + } + + @Test + public void testGetMeetCouponList() { + // 准备参数 + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1024L) + .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2))); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); + when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); + // mock 方法(情况一:优惠劵未到使用时间) + CouponDO coupon01 = randomPojo(CouponDO.class); + doThrow(new ServiceException(COUPON_VALID_TIME_NOT_NOW)).when(couponService).validCoupon(coupon01); + // mock 方法(情况二:所结算商品没有符合条件的商品) + CouponDO coupon02 = randomPojo(CouponDO.class); + // mock 方法(情况三:使用金额不足) + CouponDO coupon03 = randomPojo(CouponDO.class, o -> o.setProductScope(PromotionProductScopeEnum.ALL.getScope()) + .setUsePrice(300)); + // mock 方法(情况五:满足条件) + CouponDO coupon04 = randomPojo(CouponDO.class, o -> o.setProductScope(PromotionProductScopeEnum.ALL.getScope()) + .setUsePrice(190)); + // mock 方法(获得用户的待使用优惠劵) + when(couponService.getCouponList(eq(1024L), eq(CouponStatusEnum.UNUSED.getStatus()))) + .thenReturn(asList(coupon01, coupon02, coupon03, coupon04)); + // 调用 + List list = priceService.getMeetCouponList(calculateReqDTO); + // 断言 + assertEquals(list.size(), 4); + // 断言情况一:优惠劵未到使用时间 + CouponMeetRespDTO couponMeetRespDTO01 = list.get(0); + assertPojoEquals(couponMeetRespDTO01, coupon01); + assertFalse(couponMeetRespDTO01.getMeet()); + assertEquals(couponMeetRespDTO01.getMeetTip(), "优惠劵未到使用时间"); + // 断言情况二:所结算商品没有符合条件的商品 + CouponMeetRespDTO couponMeetRespDTO02 = list.get(1); + assertPojoEquals(couponMeetRespDTO02, coupon02); + assertFalse(couponMeetRespDTO02.getMeet()); + assertEquals(couponMeetRespDTO02.getMeetTip(), "所结算商品没有符合条件的商品"); + // 断言情况三:差 %s 元可用优惠劵 + CouponMeetRespDTO couponMeetRespDTO03 = list.get(2); + assertPojoEquals(couponMeetRespDTO03, coupon03); + assertFalse(couponMeetRespDTO03.getMeet()); + assertEquals(couponMeetRespDTO03.getMeetTip(), "所结算的商品中未满足使用的金额"); + // 断言情况四:满足条件 + CouponMeetRespDTO couponMeetRespDTO04 = list.get(3); + assertPojoEquals(couponMeetRespDTO04, coupon04); + assertTrue(couponMeetRespDTO04.getMeet()); + assertNull(couponMeetRespDTO04.getMeetTip()); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java new file mode 100755 index 000000000..9f9e28c07 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java @@ -0,0 +1,218 @@ +package cn.iocoder.yudao.module.promotion.service.reward; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.reward.RewardActivityMapper; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.time.Duration; +import java.util.Map; +import java.util.Set; + +import static cn.hutool.core.util.RandomUtil.randomEle; +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.REWARD_ACTIVITY_NOT_EXISTS; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.*; + +/** +* {@link RewardActivityServiceImpl} 的单元测试类 +* +* @author 芋道源码 +*/ +@Import(RewardActivityServiceImpl.class) +public class RewardActivityServiceImplTest extends BaseDbUnitTest { + + @Resource + private RewardActivityServiceImpl rewardActivityService; + + @Resource + private RewardActivityMapper rewardActivityMapper; + + @Test + public void testCreateRewardActivity_success() { + // 准备参数 + RewardActivityCreateReqVO reqVO = randomPojo(RewardActivityCreateReqVO.class, o -> { + o.setConditionType(randomEle(PromotionConditionTypeEnum.values()).getType()); + o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()); + // 用于触发进行中的状态 + o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); + }); + + // 调用 + Long rewardActivityId = rewardActivityService.createRewardActivity(reqVO); + // 断言 + assertNotNull(rewardActivityId); + // 校验记录的属性是否正确 + RewardActivityDO rewardActivity = rewardActivityMapper.selectById(rewardActivityId); + assertPojoEquals(reqVO, rewardActivity, "rules"); + assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); + for (int i = 0; i < reqVO.getRules().size(); i++) { + assertPojoEquals(reqVO.getRules().get(i), rewardActivity.getRules().get(i)); + } + } + + @Test + public void testUpdateRewardActivity_success() { + // mock 数据 + RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus())); + rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据 + // 准备参数 + RewardActivityUpdateReqVO reqVO = randomPojo(RewardActivityUpdateReqVO.class, o -> { + o.setId(dbRewardActivity.getId()); // 设置更新的 ID + o.setConditionType(randomEle(PromotionConditionTypeEnum.values()).getType()); + o.setProductScope(randomEle(PromotionProductScopeEnum.values()).getScope()); + // 用于触发进行中的状态 + o.setStartTime(addTime(Duration.ofDays(1))).setEndTime(addTime(Duration.ofDays(2))); + }); + + // 调用 + rewardActivityService.updateRewardActivity(reqVO); + // 校验是否更新正确 + RewardActivityDO rewardActivity = rewardActivityMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, rewardActivity, "rules"); + assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.WAIT.getStatus()); + for (int i = 0; i < reqVO.getRules().size(); i++) { + assertPojoEquals(reqVO.getRules().get(i), rewardActivity.getRules().get(i)); + } + } + + @Test + public void testCloseRewardActivity() { + // mock 数据 + RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.WAIT.getStatus())); + rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbRewardActivity.getId(); + + // 调用 + rewardActivityService.closeRewardActivity(id); + // 校验状态 + RewardActivityDO rewardActivity = rewardActivityMapper.selectById(id); + assertEquals(rewardActivity.getStatus(), PromotionActivityStatusEnum.CLOSE.getStatus()); + } + + @Test + public void testUpdateRewardActivity_notExists() { + // 准备参数 + RewardActivityUpdateReqVO reqVO = randomPojo(RewardActivityUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> rewardActivityService.updateRewardActivity(reqVO), REWARD_ACTIVITY_NOT_EXISTS); + } + + @Test + public void testDeleteRewardActivity_success() { + // mock 数据 + RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus())); + rewardActivityMapper.insert(dbRewardActivity);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbRewardActivity.getId(); + + // 调用 + rewardActivityService.deleteRewardActivity(id); + // 校验数据不存在了 + assertNull(rewardActivityMapper.selectById(id)); + } + + @Test + public void testDeleteRewardActivity_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> rewardActivityService.deleteRewardActivity(id), REWARD_ACTIVITY_NOT_EXISTS); + } + + @Test + public void testGetRewardActivityPage() { + // mock 数据 + RewardActivityDO dbRewardActivity = randomPojo(RewardActivityDO.class, o -> { // 等会查询到 + o.setName("芋艿"); + o.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); + }); + rewardActivityMapper.insert(dbRewardActivity); + // 测试 name 不匹配 + rewardActivityMapper.insert(cloneIgnoreId(dbRewardActivity, o -> o.setName("土豆"))); + // 测试 status 不匹配 + rewardActivityMapper.insert(cloneIgnoreId(dbRewardActivity, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()))); + // 准备参数 + RewardActivityPageReqVO reqVO = new RewardActivityPageReqVO(); + reqVO.setName("芋艿"); + reqVO.setStatus(PromotionActivityStatusEnum.CLOSE.getStatus()); + + // 调用 + PageResult pageResult = rewardActivityService.getRewardActivityPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbRewardActivity, pageResult.getList().get(0), "rules"); + } + + @Test + public void testGetRewardActivities_all() { + // mock 数据 + RewardActivityDO allActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) + .setProductScope(PromotionProductScopeEnum.ALL.getScope())); + rewardActivityMapper.insert(allActivity); + RewardActivityDO productActivity = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L))); + rewardActivityMapper.insert(productActivity); + // 准备参数 + Set spuIds = asSet(1L, 2L); + + // 调用 + Map> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); + // 断言 + assertEquals(matchRewardActivities.size(), 1); + Map.Entry> next = matchRewardActivities.entrySet().iterator().next(); + assertPojoEquals(next.getKey(), allActivity); + assertEquals(next.getValue(), spuIds); + } + + @Test + public void testGetRewardActivities_product() { + // mock 数据 + RewardActivityDO productActivity01 = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L))); + rewardActivityMapper.insert(productActivity01); + RewardActivityDO productActivity02 = randomPojo(RewardActivityDO.class, o -> o.setStatus(PromotionActivityStatusEnum.RUN.getStatus()) + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(singletonList(3L))); + rewardActivityMapper.insert(productActivity02); + // 准备参数 + Set spuIds = asSet(1L, 2L, 3L); + + // 调用 + Map> matchRewardActivities = rewardActivityService.getMatchRewardActivities(spuIds); + // 断言 + assertEquals(matchRewardActivities.size(), 2); + matchRewardActivities.forEach((activity, activitySpuIds) -> { + if (activity.getId().equals(productActivity01.getId())) { + assertPojoEquals(activity, productActivity01); + assertEquals(activitySpuIds, asSet(1L, 2L)); + } else if (activity.getId().equals(productActivity02.getId())) { + assertPojoEquals(activity, productActivity02); + assertEquals(activitySpuIds, asSet(3L)); + } else { + fail(); + } + }); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java new file mode 100644 index 000000000..853568077 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java @@ -0,0 +1,170 @@ +package cn.iocoder.yudao.module.promotion.service.seckillactivity; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper; +import cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity.SeckillActivityServiceImpl; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_NOT_EXISTS; +import static org.junit.jupiter.api.Assertions.*; + +/** +* {@link SeckillActivityServiceImpl} 的单元测试类 +* +* @author 芋道源码 +*/ +@Import(SeckillActivityServiceImpl.class) +public class SeckillActivityServiceImplTest extends BaseDbUnitTest { + + @Resource + private SeckillActivityServiceImpl seckillActivityService; + + @Resource + private SeckillActivityMapper seckillActivityMapper; + + @Test + public void testCreateSeckillActivity_success() { + // 准备参数 + SeckillActivityCreateReqVO reqVO = randomPojo(SeckillActivityCreateReqVO.class); + + // 调用 + Long seckillActivityId = seckillActivityService.createSeckillActivity(reqVO); + // 断言 + assertNotNull(seckillActivityId); + // 校验记录的属性是否正确 + SeckillActivityDO seckillActivity = seckillActivityMapper.selectById(seckillActivityId); + assertPojoEquals(reqVO, seckillActivity); + } + + @Test + public void testUpdateSeckillActivity_success() { + // mock 数据 + SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class); + seckillActivityMapper.insert(dbSeckillActivity);// @Sql: 先插入出一条存在的数据 + // 准备参数 + SeckillActivityUpdateReqVO reqVO = randomPojo(SeckillActivityUpdateReqVO.class, o -> { + o.setId(dbSeckillActivity.getId()); // 设置更新的 ID + }); + + // 调用 + seckillActivityService.updateSeckillActivity(reqVO); + // 校验是否更新正确 + SeckillActivityDO seckillActivity = seckillActivityMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, seckillActivity); + } + + @Test + public void testUpdateSeckillActivity_notExists() { + // 准备参数 + SeckillActivityUpdateReqVO reqVO = randomPojo(SeckillActivityUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> seckillActivityService.updateSeckillActivity(reqVO), SECKILL_ACTIVITY_NOT_EXISTS); + } + + @Test + public void testDeleteSeckillActivity_success() { + // mock 数据 + SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class); + seckillActivityMapper.insert(dbSeckillActivity);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbSeckillActivity.getId(); + + // 调用 + seckillActivityService.deleteSeckillActivity(id); + // 校验数据不存在了 + assertNull(seckillActivityMapper.selectById(id)); + } + + @Test + public void testDeleteSeckillActivity_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> seckillActivityService.deleteSeckillActivity(id), SECKILL_ACTIVITY_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetSeckillActivityPage() { + // mock 数据 + SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class, o -> { // 等会查询到 + o.setName(null); + o.setStatus(null); + o.setTimeIds(null); + o.setCreateTime(null); + }); + seckillActivityMapper.insert(dbSeckillActivity); + // 测试 name 不匹配 + seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setName(null))); + // 测试 status 不匹配 + seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setStatus(null))); + // 测试 timeId 不匹配 + seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setTimeIds(null))); + // 测试 createTime 不匹配 + seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setCreateTime(null))); + // 准备参数 + SeckillActivityPageReqVO reqVO = new SeckillActivityPageReqVO(); + reqVO.setName(null); + reqVO.setStatus(null); + reqVO.setTimeId(null); + reqVO.setCreateTime((new LocalDateTime[]{})); + + // 调用 + PageResult pageResult = seckillActivityService.getSeckillActivityPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbSeckillActivity, pageResult.getList().get(0)); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetSeckillActivityList() { + // mock 数据 + SeckillActivityDO dbSeckillActivity = randomPojo(SeckillActivityDO.class, o -> { // 等会查询到 + o.setName(null); + o.setStatus(null); + o.setTimeIds(null); + o.setCreateTime(null); + }); + seckillActivityMapper.insert(dbSeckillActivity); + // 测试 name 不匹配 + seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setName(null))); + // 测试 status 不匹配 + seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setStatus(null))); + // 测试 timeId 不匹配 + seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setTimeIds(null))); + // 测试 createTime 不匹配 + seckillActivityMapper.insert(cloneIgnoreId(dbSeckillActivity, o -> o.setCreateTime(null))); + // 准备参数 +// SeckillActivityExportReqVO reqVO = new SeckillActivityExportReqVO(); +// reqVO.setName(null); +// reqVO.setStatus(null); +// reqVO.setTimeId(null); +// reqVO.setCreateTime((new Date[]{})); +// +// // 调用 +// List list = seckillActivityService.getSeckillActivityList(reqVO); +// // 断言 +// assertEquals(1, list.size()); +// assertPojoEquals(dbSeckillActivity, list.get(0)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java new file mode 100644 index 000000000..e61023c66 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java @@ -0,0 +1,189 @@ +package cn.iocoder.yudao.module.promotion.service.seckilltime; + +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.time.SeckillTimeUpdateReqVO; +import cn.iocoder.yudao.module.promotion.service.seckill.seckilltime.SeckillTimeServiceImpl; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import javax.annotation.Resource; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; + +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckilltime.SeckillTimeDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckilltime.SeckillTimeMapper; + +import org.springframework.context.annotation.Import; + +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static org.junit.jupiter.api.Assertions.*; + +/** +* {@link SeckillTimeServiceImpl} 的单元测试类 +* +* @author 芋道源码 +*/ +@Import(SeckillTimeServiceImpl.class) +public class SeckillTimeServiceImplTest extends BaseDbUnitTest { + + @Resource + private SeckillTimeServiceImpl seckillTimeService; + + @Resource + private SeckillTimeMapper seckillTimeMapper; + + @Resource + private ObjectMapper objectMapper; + + @Test + public void testJacksonSerializ(){ + + // 准备参数 + SeckillTimeCreateReqVO reqVO = randomPojo(SeckillTimeCreateReqVO.class); +// ObjectMapper objectMapper = new ObjectMapper(); + try { + String string = objectMapper.writeValueAsString(reqVO); + System.out.println(string); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + + + } + + @Test + public void testCreateSeckillTime_success() { + // 准备参数 + SeckillTimeCreateReqVO reqVO = randomPojo(SeckillTimeCreateReqVO.class); + + // 调用 + Long seckillTimeId = seckillTimeService.createSeckillTime(reqVO); + // 断言 + assertNotNull(seckillTimeId); + // 校验记录的属性是否正确 + SeckillTimeDO seckillTime = seckillTimeMapper.selectById(seckillTimeId); + assertPojoEquals(reqVO, seckillTime); + } + + @Test + public void testUpdateSeckillTime_success() { + // mock 数据 + SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class); + seckillTimeMapper.insert(dbSeckillTime);// @Sql: 先插入出一条存在的数据 + // 准备参数 + SeckillTimeUpdateReqVO reqVO = randomPojo(SeckillTimeUpdateReqVO.class, o -> { + o.setId(dbSeckillTime.getId()); // 设置更新的 ID + }); + + // 调用 + seckillTimeService.updateSeckillTime(reqVO); + // 校验是否更新正确 + SeckillTimeDO seckillTime = seckillTimeMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, seckillTime); + } + + @Test + public void testUpdateSeckillTime_notExists() { + // 准备参数 + SeckillTimeUpdateReqVO reqVO = randomPojo(SeckillTimeUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> seckillTimeService.updateSeckillTime(reqVO), SECKILL_TIME_NOT_EXISTS); + } + + @Test + public void testDeleteSeckillTime_success() { + // mock 数据 + SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class); + seckillTimeMapper.insert(dbSeckillTime);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbSeckillTime.getId(); + + // 调用 + seckillTimeService.deleteSeckillTime(id); + // 校验数据不存在了 + assertNull(seckillTimeMapper.selectById(id)); + } + + @Test + public void testDeleteSeckillTime_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> seckillTimeService.deleteSeckillTime(id), SECKILL_TIME_NOT_EXISTS); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetSeckillTimePage() { + // mock 数据 +// SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class, o -> { // 等会查询到 +// o.setName(null); +// o.setStartTime(null); +// o.setEndTime(null); +// o.setCreateTime(null); +// }); +// seckillTimeMapper.insert(dbSeckillTime); +// // 测试 name 不匹配 +// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setName(null))); +// // 测试 startTime 不匹配 +// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setStartTime(null))); +// // 测试 endTime 不匹配 +// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setEndTime(null))); +// // 测试 createTime 不匹配 +// seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setCreateTime(null))); +// // 准备参数 +// SeckillTimePageReqVO reqVO = new SeckillTimePageReqVO(); +// reqVO.setName(null); +//// reqVO.setStartTime((new LocalTime())); +//// reqVO.setEndTime((new LocalTime[]{})); +//// reqVO.setCreateTime((new Date[]{})); +// +// // 调用 +// PageResult pageResult = seckillTimeService.getSeckillTimePage(reqVO); +// // 断言 +// assertEquals(1, pageResult.getTotal()); +// assertEquals(1, pageResult.getList().size()); +// assertPojoEquals(dbSeckillTime, pageResult.getList().get(0)); + } + + @Test + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 + public void testGetSeckillTimeList() { + // mock 数据 + SeckillTimeDO dbSeckillTime = randomPojo(SeckillTimeDO.class, o -> { // 等会查询到 + o.setName(null); + o.setStartTime(null); + o.setEndTime(null); + o.setCreateTime(null); + }); + seckillTimeMapper.insert(dbSeckillTime); + // 测试 name 不匹配 + seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setName(null))); + // 测试 startTime 不匹配 + seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setStartTime(null))); + // 测试 endTime 不匹配 + seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setEndTime(null))); + // 测试 createTime 不匹配 + seckillTimeMapper.insert(cloneIgnoreId(dbSeckillTime, o -> o.setCreateTime(null))); + // 准备参数 +// SeckillTimeExportReqVO reqVO = new SeckillTimeExportReqVO(); +// reqVO.setName(null); +// reqVO.setStartTime((new LocalTime[]{})); +// reqVO.setEndTime((new LocalTime[]{})); +// reqVO.setCreateTime((new Date[]{})); +// +// // 调用 +// List list = seckillTimeService.getSeckillTimeList(reqVO); +// // 断言 +// assertEquals(1, list.size()); +// assertPojoEquals(dbSeckillTime, list.get(0)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml new file mode 100644 index 000000000..a384353aa --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml @@ -0,0 +1,49 @@ +spring: + main: + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner + +--- #################### 数据库相关配置 #################### + +spring: + # 数据源配置项 + datasource: + name: ruoyi-vue-pro + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + driver-class-name: org.h2.Driver + username: sa + password: + druid: + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 + initial-size: 1 # 单元测试,配置为 1,提升启动速度 + sql: + init: + schema-locations: classpath:/sql/create_tables.sql + + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 + redis: + host: 127.0.0.1 # 地址 + port: 16379 # 端口(单元测试,使用 16379 端口) + database: 0 # 数据库索引 + +mybatis: + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 + +--- #################### 定时任务相关配置 #################### + +--- #################### 配置中心相关配置 #################### + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项(单元测试,禁用 Lock4j) + +# Resilience4j 配置项 + +--- #################### 监控相关配置 #################### + +--- #################### 芋道相关配置 #################### + +# 芋道配置项,设置当前项目所有自定义的配置 +yudao: + info: + base-package: cn.iocoder.yudao.module diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml new file mode 100644 index 000000000..daf756bff --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml @@ -0,0 +1,4 @@ + + + + diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql new file mode 100644 index 000000000..d3f8e3718 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql @@ -0,0 +1,6 @@ +DELETE FROM "market_activity"; +DELETE FROM "promotion_coupon_template"; +DELETE FROM "promotion_coupon"; +DELETE FROM "promotion_reward_activity"; +DELETE FROM "promotion_discount_activity"; +DELETE FROM "promotion_discount_product"; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql new file mode 100644 index 000000000..7ff1a7239 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql @@ -0,0 +1,124 @@ +CREATE TABLE IF NOT EXISTS "market_activity" ( + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "title" varchar(50) NOT NULL, + "activity_type" tinyint(4) NOT NULL, + "status" tinyint(4) NOT NULL, + "start_time" datetime NOT NULL, + "end_time" datetime NOT NULL, + "invalid_time" datetime, + "delete_time" datetime, + "time_limited_discount" varchar(2000), + "full_privilege" varchar(2000), + "creator" varchar(64) DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint(20) NOT NULL, + PRIMARY KEY ("id") + ) COMMENT '促销活动'; + +CREATE TABLE IF NOT EXISTS "promotion_coupon_template" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "name" varchar NOT NULL, + "status" int NOT NULL, + "total_count" int NOT NULL, + "take_limit_count" int NOT NULL, + "take_type" int NOT NULL, + "use_price" int NOT NULL, + "product_scope" int NOT NULL, + "product_spu_ids" varchar, + "validity_type" int NOT NULL, + "valid_start_time" datetime, + "valid_end_time" datetime, + "fixed_start_term" int, + "fixed_end_term" int, + "discount_type" int NOT NULL, + "discount_percent" int, + "discount_price" int, + "discount_limit_price" int, + "take_count" int NOT NULL DEFAULT 0, + "use_count" int NOT NULL DEFAULT 0, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '优惠劵模板'; + +CREATE TABLE IF NOT EXISTS "promotion_coupon" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "template_id" bigint NOT NULL, + "name" varchar NOT NULL, + "status" int NOT NULL, + "user_id" bigint NOT NULL, + "take_type" int NOT NULL, + "useprice" int NOT NULL, + "valid_start_time" datetime NOT NULL, + "valid_end_time" datetime NOT NULL, + "product_scope" int NOT NULL, + "product_spu_ids" varchar, + "discount_type" int NOT NULL, + "discount_percent" int, + "discount_price" int, + "discount_limit_price" int, + "use_order_id" bigint, + "use_time" datetime, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '优惠劵'; + +CREATE TABLE IF NOT EXISTS "promotion_reward_activity" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "name" varchar NOT NULL, + "status" int NOT NULL, + "start_time" datetime NOT NULL, + "end_time" datetime NOT NULL, + "remark" varchar, + "condition_type" int NOT NULL, + "product_scope" int NOT NULL, + "product_spu_ids" varchar, + "rules" varchar, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '满减送活动'; + +CREATE TABLE IF NOT EXISTS "promotion_discount_activity" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "name" varchar NOT NULL, + "status" int NOT NULL, + "start_time" datetime NOT NULL, + "end_time" datetime NOT NULL, + "remark" varchar, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '限时折扣活动'; + +CREATE TABLE IF NOT EXISTS "promotion_discount_product" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "activity_id" bigint NOT NULL, + "spu_id" bigint NOT NULL, + "sku_id" bigint NOT NULL, + "discount_type" int NOT NULL, + "discount_percent" int, + "discount_price" int, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '限时折扣活动'; diff --git a/yudao-module-mall/yudao-module-trade-api/pom.xml b/yudao-module-mall/yudao-module-trade-api/pom.xml new file mode 100644 index 000000000..1299ad11d --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/pom.xml @@ -0,0 +1,26 @@ + + + + cn.iocoder.boot + yudao-module-mall + ${revision} + + 4.0.0 + yudao-module-trade-api + jar + + ${project.artifactId} + + trade 模块 API,暴露给其它模块调用 + + + + + cn.iocoder.boot + yudao-common + + + + diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java new file mode 100644 index 000000000..af387ab85 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.trade.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * 交易 错误码枚举类 + * 交易系统,使用 1-011-000-000 段 + * + * @author LeeYan9 + * @since 2022-08-26 + */ +public interface ErrorCodeConstants { + + // ========== Order 模块 1-011-000-000 ========== + ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1011000001, "商品 SKU 不存在"); + ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1011000002, "商品 SPU 不可售卖"); + ErrorCode ORDER_CREATE_SKU_NOT_SALE = new ErrorCode(1011000003, "商品 SKU 不可售卖"); + ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1011000004, "商品 SKU 库存不足"); + ErrorCode ORDER_CREATE_SPU_NOT_FOUND = new ErrorCode(1011000005, "商品 SPU 不可售卖"); + ErrorCode ORDER_CREATE_ADDRESS_NOT_FOUND = new ErrorCode(1011000006, "收货地址不存在"); + + ErrorCode ORDER_ITEM_NOT_FOUND = new ErrorCode(1011000010, "交易订单项不存在"); + ErrorCode ORDER_NOT_FOUND = new ErrorCode(1011000011, "交易订单不存在"); + ErrorCode ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL = new ErrorCode(1011000012, "交易订单项更新售后状态失败,请重试"); + ErrorCode ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1011000013, "交易订单更新支付状态失败,订单不是【未支付】状态"); + ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(1011000014, "交易订单更新支付状态失败,支付单编号不匹配"); + ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1011000015, "交易订单更新支付状态失败,支付单状态不是【支付成功】状态"); + ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1011000016, "交易订单更新支付状态失败,支付单金额不匹配"); + ErrorCode ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED = new ErrorCode(1011000017, "交易订单发货失败,订单不是【待发货】状态"); + ErrorCode ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED = new ErrorCode(1011000018, "交易订单收货失败,订单不是【待收货】状态"); + + // ========== After Sale 模块 1-011-000-000 ========== + ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在"); + ErrorCode AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR = new ErrorCode(1011000101, "申请退款金额错误"); + ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_CANCELED = new ErrorCode(1011000102, "订单已关闭,无法申请售后"); + ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_PAID = new ErrorCode(1011000103, "订单未支付,无法申请售后"); + ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED = new ErrorCode(1011000104, "订单未发货,无法申请【退货退款】售后"); + ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_ITEM_APPLIED = new ErrorCode(1011000105, "订单项已申请售后,无法重复申请"); + ErrorCode AFTER_SALE_AUDIT_FAIL_STATUS_NOT_APPLY = new ErrorCode(1011000106, "审批失败,售后状态不处于审批中"); + ErrorCode AFTER_SALE_UPDATE_STATUS_FAIL = new ErrorCode(1011000107, "操作售后单失败,请刷新后重试"); + ErrorCode AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE = new ErrorCode(1011000108, "退货失败,售后单状态不处于【待买家退货】"); + ErrorCode AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY = new ErrorCode(1011000109, "确认收货失败,售后单状态不处于【待确认收货】"); + ErrorCode AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND = new ErrorCode(1011000110, "退款失败,售后单状态不是【待退款】"); + ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE = new ErrorCode(1011000111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】"); + + // ========== Cart 模块 1-011-001-000 ========== + ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在"); + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java new file mode 100644 index 000000000..88ea5230c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java @@ -0,0 +1,67 @@ +package cn.iocoder.yudao.module.trade.enums.aftersale; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +import static cn.hutool.core.util.ArrayUtil.firstMatch; + +/** + * 售后状态的枚举 + * + * 状态流转 + * + * @author 芋道源码 + */ +@AllArgsConstructor +@Getter +public enum TradeAfterSaleStatusEnum implements IntArrayValuable { + + APPLY(10,"申请中", // 【申请售后】 + "会员申请退款"), + SELLER_AGREE(20, "卖家通过", // 卖家通过售后;【商品待退货】 + "商家同意退款"), + BUYER_DELIVERY(30,"待卖家收货", // 买家已退货,等待卖家收货;【商家待收货】 + "会员填写退货物流信息"), + WAIT_REFUND(40, "等待平台退款", // 卖家已收货,等待平台退款;等待退款【等待退款】 + "商家收货"), + COMPLETE(50, "完成", // 完成退款【退款成功】 + "商家确认退款"), + + BUYER_CANCEL(61, "买家取消售后", // 【买家取消】 + "会员取消退款"), + SELLER_DISAGREE(62,"卖家拒绝", // 卖家拒绝售后;商家拒绝【商家拒绝】 + "商家拒绝退款"), + SELLER_REFUSE(63,"卖家拒绝收货", // 卖家拒绝收货,终止售后;【商家拒收货】 + "商家拒绝收货"), + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray(); + + /** + * 状态 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + /** + * 操作内容 + * + * 目的:记录售后日志的内容 + */ + private final String content; + + @Override + public int[] array() { + return ARRAYS; + } + + public static TradeAfterSaleStatusEnum valueOf(Integer status) { + return firstMatch(value -> value.getStatus().equals(status), values()); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleTypeEnum.java new file mode 100644 index 000000000..d5323aac8 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleTypeEnum.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.trade.enums.aftersale; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * 交易售后 - 类型 + * + * @author 芋道源码 + */ +@RequiredArgsConstructor +@Getter +public enum TradeAfterSaleTypeEnum implements IntArrayValuable { + + IN_SALE(10, "售中退款"), // 交易完成前买家申请退款 + AFTER_SALE(20, "售后退款"); // 交易完成后买家申请退款 + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleTypeEnum::getType).toArray(); + + /** + * 类型 + */ + private final Integer type; + /** + * 类型名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleWayEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleWayEnum.java new file mode 100644 index 000000000..1bbb35327 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleWayEnum.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.trade.enums.aftersale; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * 交易售后 - 方式 + * + * @author Sin + */ +@RequiredArgsConstructor +@Getter +public enum TradeAfterSaleWayEnum implements IntArrayValuable { + + REFUND(10, "仅退款"), + RETURN_AND_REFUND(20, "退货退款"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleWayEnum::getWay).toArray(); + + /** + * 方式 + */ + private final Integer way; + /** + * 方式名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java new file mode 100644 index 000000000..40402b6f8 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.trade.enums.order; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * 交易订单 - 售后状态 + * + * @author Sin + */ +@RequiredArgsConstructor +@Getter +public enum TradeOrderAfterSaleStatusEnum implements IntArrayValuable { + + NONE(0, "未退款"), + PART(1, "部分退款"), + ALL(2, "全部退款"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderAfterSaleStatusEnum::getStatus).toArray(); + + /** + * 状态值 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java new file mode 100644 index 000000000..1dabec194 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.trade.enums.order; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * 交易订单 - 关闭类型 + * + * @author Sin + */ +@RequiredArgsConstructor +@Getter +public enum TradeOrderCancelTypeEnum implements IntArrayValuable { + + PAY_TIMEOUT(10, "超时未支付"), + AFTER_SALE_CLOSE(20, "退款关闭"), + MEMBER_CANCEL(30, "买家取消"), + PAY_ON_DELIVERY(40, "已通过货到付款交易"),; // TODO 芋艿:这个类型,是不是可以去掉 + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderCancelTypeEnum::getType).toArray(); + + /** + * 关闭类型 + */ + private final Integer type; + /** + * 关闭类型名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java new file mode 100644 index 000000000..27b061e37 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.trade.enums.order; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 交易订单 - 发货状态 + * + * @author 芋道源码 + */ +@RequiredArgsConstructor +@Getter +public enum TradeOrderDeliveryStatusEnum { + + UNDELIVERED(0, "未发货"), + DELIVERED(1, "已发货"), + RECEIVED(2, "已收货"); + + /** + * 状态值 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java new file mode 100644 index 000000000..c4fc8a373 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.trade.enums.order; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * 交易订单项 - 售后状态 + * + * @author 芋道源码 + */ +@RequiredArgsConstructor +@Getter +public enum TradeOrderItemAfterSaleStatusEnum implements IntArrayValuable { + + NONE(0, "未售后"), + APPLY(1, "售后中"), + SUCCESS(2, "已退款"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderItemAfterSaleStatusEnum::getStatus).toArray(); + + /** + * 状态值 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + // TODO 芋艿:EXPIRED 已失效不允许申请售后 + // TODO 芋艿:PART_AFTER_SALE 部分售后 + + @Override + public int[] array() { + return ARRAYS; + } + + /** + * 判断指定状态,是否正处于【未申请】状态 + * + * @param status 指定状态 + * @return 是否 + */ + public static boolean isNone(Integer status) { + return ObjectUtil.equals(status, NONE.getStatus()); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java new file mode 100644 index 000000000..06fc3821e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java @@ -0,0 +1,118 @@ +package cn.iocoder.yudao.module.trade.enums.order; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * 交易订单 - 状态 + * + * @author Sin + */ +@RequiredArgsConstructor +@Getter +public enum TradeOrderStatusEnum implements IntArrayValuable { + + UNPAID(0, "待支付"), + UNDELIVERED(10, "待发货"), + DELIVERED(20, "已发货"), + COMPLETED(30, "已完成"), + CANCELED(40, "已取消"); + + // TODO 芋艿: TAKE("待核验"):虚拟订单需要核验商品 + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderStatusEnum::getStatus).toArray(); + + /** + * 状态值 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + + // ========== 问:为什么写了很多 isXXX 和 haveXXX 的判断逻辑呢? ========== + // ========== 答:方便找到某一类判断,哪些业务正在使用 ========== + + /** + * 判断指定状态,是否正处于【未付款】状态 + * + * @param status 指定状态 + * @return 是否 + */ + public static boolean isUnpaid(Integer status) { + return ObjectUtil.equal(UNPAID.getStatus(), status); + } + + /** + * 判断指定状态,是否正处于【待发货】状态 + * + * @param status 指定状态 + * @return 是否 + */ + public static boolean isUndelivered(Integer status) { + return ObjectUtil.equal(UNDELIVERED.getStatus(), status); + } + + /** + * 判断指定状态,是否正处于【已发货】状态 + * + * @param status 指定状态 + * @return 是否 + */ + public static boolean isDelivered(Integer status) { + return ObjectUtil.equals(status, DELIVERED.getStatus()); + } + + /** + * 判断指定状态,是否正处于【已取消】状态 + * + * @param status 指定状态 + * @return 是否 + */ + public static boolean isCanceled(Integer status) { + return ObjectUtil.equals(status, CANCELED.getStatus()); + } + + /** + * 判断指定状态,是否正处于【已完成】状态 + * + * @param status 指定状态 + * @return 是否 + */ + public static boolean isCompleted(Integer status) { + return ObjectUtil.equals(status, COMPLETED.getStatus()); + } + + /** + * 判断指定状态,是否有过【已付款】状态 + * + * @param status 指定状态 + * @return 是否 + */ + public static boolean havePaid(Integer status) { + return ObjectUtils.equalsAny(status, UNDELIVERED.getStatus(), + DELIVERED.getStatus(), COMPLETED.getStatus()); + } + + /** + * 判断指定状态,是否有过【已发货】状态 + * + * @param status 指定状态 + * @return 是否 + */ + public static boolean haveDelivered(Integer status) { + return ObjectUtils.equalsAny(status, DELIVERED.getStatus(), COMPLETED.getStatus()); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java new file mode 100644 index 000000000..c8001b490 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.trade.enums.order; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * 交易订单 - 类型 + * + * @author Sin + */ +@RequiredArgsConstructor +@Getter +public enum TradeOrderTypeEnum implements IntArrayValuable { + + NORMAL(0, "普通订单"), + SECKILL(1, "秒杀订单"), + TEAM(2, "拼团订单"), + BARGAIN(3, "砍价订单"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderTypeEnum::getType).toArray(); + + /** + * 类型 + */ + private final Integer type; + /** + * 类型名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/pom.xml b/yudao-module-mall/yudao-module-trade-biz/pom.xml new file mode 100644 index 000000000..4eb0164d4 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/pom.xml @@ -0,0 +1,94 @@ + + + + cn.iocoder.boot + yudao-module-mall + ${revision} + + 4.0.0 + yudao-module-trade-biz + jar + + ${project.artifactId} + + trade 模块,主要实现交易相关功能 + 例如:订单、退款、购物车等功能。 + + + + + cn.iocoder.boot + yudao-module-trade-api + ${revision} + + + + cn.iocoder.boot + yudao-module-product-api + ${revision} + + + cn.iocoder.boot + yudao-module-pay-api + ${revision} + + + cn.iocoder.boot + yudao-module-promotion-api + ${revision} + + + cn.iocoder.boot + yudao-module-member-api + ${revision} + + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-operatelog + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-ip + + + + + cn.iocoder.boot + yudao-spring-boot-starter-web + + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-pay + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + + cn.iocoder.boot + yudao-spring-boot-starter-test + + + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + + + diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http new file mode 100644 index 000000000..d1a2acaf7 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http @@ -0,0 +1,4 @@ +### 获得交易售后分页 => 成功 +GET {{baseUrl}}/trade/after-sale/page?pageNo=1&pageSize=10 +Authorization: Bearer {{token}} +tenant-id: {{adminTenentId}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java new file mode 100644 index 000000000..a1bf5d544 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java @@ -0,0 +1,113 @@ +package cn.iocoder.yudao.module.trade.controller.admin.aftersale; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO; +import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; +import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "管理后台 - 交易售后") +@RestController +@RequestMapping("/trade/after-sale") +@Validated +@Slf4j +public class TradeAfterSaleController { + + @Resource + private TradeAfterSaleService afterSaleService; + + @Resource + private MemberUserApi memberUserApi; + @Resource + private ProductPropertyValueApi productPropertyValueApi; + + @GetMapping("/page") + @Operation(summary = "获得交易售后分页") + @PreAuthorize("@ss.hasPermission('trade:after-sale:query')") + public CommonResult> getAfterSalePage(@Valid TradeAfterSalePageReqVO pageVO) { + // 查询售后 + PageResult pageResult = afterSaleService.getAfterSalePage(pageVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(PageResult.empty()); + } + + // 查询商品属性 + List propertyValueDetails = productPropertyValueApi + .getPropertyValueDetailList(TradeAfterSaleConvert.INSTANCE.convertPropertyValueIds(pageResult.getList())); + // 查询会员 + Map memberUsers = memberUserApi.getUserMap( + convertSet(pageResult.getList(), TradeAfterSaleDO::getUserId)); + return success(TradeAfterSaleConvert.INSTANCE.convertPage(pageResult, memberUsers, propertyValueDetails)); + } + + @PutMapping("/agree") + @Operation(summary = "同意售后") + @Parameter(name = "id", description = "售后编号", required = true, example = "1") + @PreAuthorize("@ss.hasPermission('trade:after-sale:agree')") + public CommonResult agreeAfterSale(@RequestParam("id") Long id) { + afterSaleService.agreeAfterSale(getLoginUserId(), id); + return success(true); + } + + @PutMapping("/disagree") + @Operation(summary = "拒绝售后") + @PreAuthorize("@ss.hasPermission('trade:after-sale:disagree')") + public CommonResult disagreeAfterSale(@RequestBody TradeAfterSaleDisagreeReqVO confirmReqVO) { + afterSaleService.disagreeAfterSale(getLoginUserId(), confirmReqVO); + return success(true); + } + + @PutMapping("/receive") + @Operation(summary = "确认收货") + @Parameter(name = "id", description = "售后编号", required = true, example = "1") + @PreAuthorize("@ss.hasPermission('trade:after-sale:receive')") + public CommonResult receiveAfterSale(@RequestParam("id") Long id) { + afterSaleService.receiveAfterSale(getLoginUserId(), id); + return success(true); + } + + @PutMapping("/refuse") + @Operation(summary = "确认收货") + @Parameter(name = "id", description = "售后编号", required = true, example = "1") + @PreAuthorize("@ss.hasPermission('trade:after-sale:receive')") + public CommonResult refuseAfterSale(TradeAfterSaleRefuseReqVO refuseReqVO) { + afterSaleService.refuseAfterSale(getLoginUserId(), refuseReqVO); + return success(true); + } + + @PostMapping("/refund") + @Operation(summary = "确认退款") + @Parameter(name = "id", description = "售后编号", required = true, example = "1") + @PreAuthorize("@ss.hasPermission('trade:after-sale:refund')") + public CommonResult refundAfterSale(@RequestParam("id") Long id) { + afterSaleService.refundAfterSale(getLoginUserId(), getClientIP(), id); + return success(true); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java new file mode 100644 index 000000000..a008619a0 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java @@ -0,0 +1,119 @@ +package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** +* 交易售后 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class TradeAfterSaleBaseVO { + + @Schema(description = "售后流水号", required = true, example = "202211190847450020500077") + @NotNull(message = "售后流水号不能为空") + private String no; + + @Schema(description = "售后状态", required = true, example = "10") + @NotNull(message = "售后状态不能为空") + private Integer status; + + @Schema(description = "售后类型", required = true, example = "20") + @NotNull(message = "售后类型不能为空") + private Integer type; + + @Schema(description = "售后方式", required = true, example = "10") + @NotNull(message = "售后方式不能为空") + private Integer way; + + @Schema(description = "用户编号", required = true, example = "30337") + @NotNull(message = "用户编号不能为空") + private Long userId; + + @Schema(description = "申请原因", required = true, example = "不喜欢") + @NotNull(message = "申请原因不能为空") + private String applyReason; + + @Schema(description = "补充描述", example = "你说的对") + private String applyDescription; + + @Schema(description = "补充凭证图片", example = "https://www.iocoder.cn/1.png") + private List applyPicUrls; + + @Schema(description = "订单编号", required = true, example = "18078") + @NotNull(message = "订单编号不能为空") + private Long orderId; + + @Schema(description = "订单流水号", required = true, example = "2022111917190001") + @NotNull(message = "订单流水号不能为空") + private Long orderNo; + + @Schema(description = "订单项编号", required = true, example = "572") + @NotNull(message = "订单项编号不能为空") + private Long orderItemId; + + @Schema(description = "商品 SPU 编号", required = true, example = "2888") + @NotNull(message = "商品 SPU 编号不能为空") + private Long spuId; + + @Schema(description = "商品 SPU 名称", required = true, example = "李四") + @NotNull(message = "商品 SPU 名称不能为空") + private String spuName; + + @Schema(description = "商品 SKU 编号", required = true, example = "15657") + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + @Schema(description = "商品图片", example = "https://www.iocoder.cn/2.png") + private String picUrl; + + @Schema(description = "购买数量", required = true, example = "20012") + @NotNull(message = "购买数量不能为空") + private Integer count; + + @Schema(description = "审批时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime auditTime; + + @Schema(description = "审批人", example = "30835") + private Long auditUserId; + + @Schema(description = "审批备注", example = "不香") + private String auditReason; + + @Schema(description = "退款金额,单位:分", required = true, example = "18077") + @NotNull(message = "退款金额,单位:分不能为空") + private Integer refundPrice; + + @Schema(description = "支付退款编号", example = "10271") + private Long payRefundId; + + @Schema(description = "退款时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime refundTime; + + @Schema(description = "退货物流公司编号", example = "10") + private Long logisticsId; + + @Schema(description = "退货物流单号", example = "610003952009") + private String logisticsNo; + + @Schema(description = "退货时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime deliveryTime; + + @Schema(description = "收货时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime receiveTime; + + @Schema(description = "收货备注", example = "不喜欢") + private String receiveReason; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDisagreeReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDisagreeReqVO.java new file mode 100644 index 000000000..2ef43f4ce --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDisagreeReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 交易售后拒绝 Request VO") +@Data +public class TradeAfterSaleDisagreeReqVO { + + @Schema(description = "售后编号", required = true, example = "1024") + @NotNull(message = "售后编号不能为空") + private Long id; + + @Schema(description = "审批备注", required = true, example = "你猜") + @NotEmpty(message = "审批备注不能为空") + private String auditReason; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java new file mode 100644 index 000000000..4c9431b5b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 交易售后分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class TradeAfterSalePageReqVO extends PageParam { + + @Schema(description = "售后流水号", example = "202211190847450020500077") + private String no; + + @Schema(description = "售后状态", example = "10") + @InEnum(value = TradeAfterSaleStatusEnum.class, message = "售后状态必须是 {value}") + private Integer status; + + @Schema(description = "售后类型", example = "20") + @InEnum(value = TradeAfterSaleTypeEnum.class, message = "售后类型必须是 {value}") + private Integer type; + + @Schema(description = "售后方式", example = "10") + @InEnum(value = TradeAfterSaleWayEnum.class, message = "售后方式必须是 {value}") + private Integer way; + + @Schema(description = "订单编号", example = "18078") + private String orderNo; + + @Schema(description = "商品 SPU 名称", example = "李四") + private String spuName; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRefuseReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRefuseReqVO.java new file mode 100644 index 000000000..a9db6a1a5 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRefuseReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 交易售后拒绝收货 Request VO") +@Data +public class TradeAfterSaleRefuseReqVO { + + @Schema(description = "售后编号", required = true, example = "1024") + @NotNull(message = "售后编号不能为空") + private Long id; + + @Schema(description = "收货备注", required = true, example = "你猜") + @NotNull(message = "收货备注不能为空") + private String refuseMemo; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespPageItemVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespPageItemVO.java new file mode 100644 index 000000000..29180dcaf --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespPageItemVO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo; + +import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; +import java.util.List; + +@Schema(description = "管理后台 - 交易售后分页的每一条记录 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class TradeAfterSaleRespPageItemVO extends TradeAfterSaleBaseVO { + + @Schema(description = "售后编号", required = true, example = "27630") + private Long id; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + + /** + * 商品属性数组 + */ + private List properties; + + /** + * 用户信息 + */ + private MemberUserRespVO user; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/TradeAfterSaleLogRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/TradeAfterSaleLogRespVO.java new file mode 100644 index 000000000..10b3cecbb --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/TradeAfterSaleLogRespVO.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.log; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 交易售后日志 Response VO") +@Data +public class TradeAfterSaleLogRespVO { + + @Schema(description = "编号", required = true, example = "20669") + private Long id; + + @Schema(description = "用户编号", required = true, example = "22634") + @NotNull(message = "用户编号不能为空") + private Long userId; + + @Schema(description = "用户类型", required = true, example = "2") + @NotNull(message = "用户类型不能为空") + private Integer userType; + + @Schema(description = "售后编号", required = true, example = "3023") + @NotNull(message = "售后编号不能为空") + private Long afterSaleId; + + @Schema(description = "订单编号", required = true, example = "25870") + @NotNull(message = "订单编号不能为空") + private Long orderId; + + @Schema(description = "订单项编号", required = true, example = "23154") + @NotNull(message = "订单项编号不能为空") + private Long orderItemId; + + @Schema(description = "售后状态(之前)", example = "2") + private Integer beforeStatus; + + @Schema(description = "售后状态(之后)", required = true, example = "1") + @NotNull(message = "售后状态(之后)不能为空") + private Integer afterStatus; + + @Schema(description = "操作明细", required = true, example = "维权完成,退款金额:¥37776.00") + @NotNull(message = "操作明细不能为空") + private String content; + + @Schema(description = "创建时间", required = true) + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/package-info.java new file mode 100644 index 000000000..f874e482d --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位符,可忽略 + */ +package cn.iocoder.yudao.module.trade.controller.admin.base.member; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/user/MemberUserRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/user/MemberUserRespVO.java new file mode 100644 index 000000000..4177b1c01 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/user/MemberUserRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.trade.controller.admin.base.member.user; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 会员用户 Response VO") +@Data +public class MemberUserRespVO { + + @Schema(description = "用户 ID", required = true, example = "1") + private Long id; + + @Schema(description = "用户昵称", required = true, example = "芋道源码") + private String nickname; + + @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") + private String avatar; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java new file mode 100644 index 000000000..0baa83e49 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java @@ -0,0 +1,4 @@ +/** + * 放置该模块通用的 VO 类 + */ +package cn.iocoder.yudao.module.trade.controller.admin.base; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/product/property/ProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/product/property/ProductPropertyValueDetailRespVO.java new file mode 100644 index 000000000..9b8fe88eb --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/product/property/ProductPropertyValueDetailRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.trade.controller.admin.base.product.property; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 商品属性值的明细 Response VO") +@Data +public class ProductPropertyValueDetailRespVO { + + @Schema(description = "属性的编号", required = true, example = "1") + private Long propertyId; + + @Schema(description = "属性的名称", required = true, example = "颜色") + private String propertyName; + + @Schema(description = "属性值的编号", required = true, example = "1024") + private Long valueId; + + @Schema(description = "属性值的名称", required = true, example = "红色") + private String valueName; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.http new file mode 100644 index 000000000..0bf8812b2 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.http @@ -0,0 +1,9 @@ +### 获得交易订单分页 => 成功 +GET {{baseUrl}}/trade/order/page?pageNo=1&pageSize=10 +Authorization: Bearer {{token}} +tenant-id: {{adminTenentId}} + +### 获得交易订单分页 => 成功 +GET {{baseUrl}}/trade/order/get-detail?id=21 +Authorization: Bearer {{token}} +tenant-id: {{adminTenentId}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java new file mode 100644 index 000000000..75f05ff86 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java @@ -0,0 +1,93 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "管理后台 - 交易订单") +@RestController +@RequestMapping("/trade/order") +@Validated +@Slf4j +public class TradeOrderController { + + @Resource + private TradeOrderService tradeOrderService; + + @Resource + private ProductPropertyValueApi productPropertyValueApi; + @Resource + private MemberUserApi memberUserApi; + + @GetMapping("/page") + @Operation(summary = "获得交易订单分页") + @PreAuthorize("@ss.hasPermission('trade:order:query')") + public CommonResult> getOrderPage(TradeOrderPageReqVO reqVO) { + // 查询订单 + PageResult pageResult = tradeOrderService.getOrderPage(reqVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(PageResult.empty()); + } + // 查询订单项 + List orderItems = tradeOrderService.getOrderItemListByOrderId( + convertSet(pageResult.getList(), TradeOrderDO::getId)); + // 查询商品属性 + List propertyValueDetails = productPropertyValueApi + .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); + // 最终组合 + return success(TradeOrderConvert.INSTANCE.convertPage(pageResult, orderItems, propertyValueDetails)); + } + + @GetMapping("/get-detail") + @Operation(summary = "获得交易订单详情") + @Parameter(name = "id", description = "订单编号", required = true, example = "1") + @PreAuthorize("@ss.hasPermission('trade:order:query')") + public CommonResult getOrderDetail(@RequestParam("id") Long id) { + // 查询订单 + TradeOrderDO order = tradeOrderService.getOrder(id); + // 查询订单项 + List orderItems = tradeOrderService.getOrderItemListByOrderId(id); + // 查询商品属性 + List propertyValueDetails = productPropertyValueApi + .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); + // 查询会员 + MemberUserRespDTO user = memberUserApi.getUser(order.getUserId()); + // 最终组合 + return success(TradeOrderConvert.INSTANCE.convert(order, orderItems, propertyValueDetails, user)); + } + + @PostMapping("/delivery") + @Operation(summary = "发货订单") + @PreAuthorize("@ss.hasPermission('trade:order:delivery')") + public CommonResult deliveryOrder(@RequestBody TradeOrderDeliveryReqVO deliveryReqVO) { + tradeOrderService.deliveryOrder(getLoginUserId(), deliveryReqVO); + return success(true); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java new file mode 100755 index 000000000..5fef8841f --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java @@ -0,0 +1,145 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.Date; + +/** +* 交易订单 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class TradeOrderBaseVO { + + // ========== 订单基本信息 ========== + + @Schema(description = "订单编号", required = true, example = "1024") + private Long id; + + @Schema(description = "订单流水号", required = true, example = "1146347329394184195") + private String no; + + @Schema(description = "下单时间", required = true) + private Date createTime; + + @Schema(description = "订单类型", required = true, example = "1") + private Integer type; + + @Schema(description = "订单来源", required = true, example = "1") + private Integer terminal; + + @Schema(description = "用户编号", required = true, example = "2048") + private Long userId; + + @Schema(description = "用户 IP", required = true, example = "127.0.0.1") + private String userIp; + + @Schema(description = "用户备注", required = true, example = "你猜") + private String userRemark; + + @Schema(description = "订单状态", required = true, example = "1") + private Integer status; + + @Schema(description = "购买的商品数量", required = true, example = "10") + private Integer productCount; + + @Schema(description = "订单完成时间") + private LocalDateTime finishTime; + + @Schema(description = "订单取消时间") + private LocalDateTime cancelTime; + + @Schema(description = "取消类型", example = "10") + private Integer cancelType; + + @Schema(description = "商家备注", example = "你猜一下") + private String remark; + + // ========== 价格 + 支付基本信息 ========== + + @Schema(description = "支付订单编号", required = true, example = "1024") + private Long payOrderId; + + @Schema(description = "是否已支付", required = true, example = "true") + private Boolean payed; + + @Schema(description = "付款时间") + private LocalDateTime payTime; + + @Schema(description = "支付渠道", required = true, example = "wx_lite") + private String payChannelCode; + + @Schema(description = "商品原价(总)", required = true, example = "1000") + private Integer originalPrice; + + @Schema(description = "订单原价(总)", required = true, example = "1000") + private Integer orderPrice; + + @Schema(description = "订单优惠(总)", required = true, example = "100") + private Integer discountPrice; + + @Schema(description = "运费金额", required = true, example = "100") + private Integer deliveryPrice; + + @Schema(description = "订单调价(总)", required = true, example = "100") + private Integer adjustPrice; + + @Schema(description = "应付金额(总)", required = true, example = "1000") + private Integer payPrice; + + // ========== 收件 + 物流基本信息 ========== + + @Schema(description = "配送模板编号", example = "1024") + private Long deliveryTemplateId; + + @Schema(description = "发货物流公司编号", example = "1024") + private Long logisticsId; + + @Schema(description = "发货物流单号", example = "1024") + private String logisticsNo; + + @Schema(description = "发货状态", required = true, example = "1") + private Integer deliveryStatus; + + @Schema(description = "发货时间") + private LocalDateTime deliveryTime; + + @Schema(description = "收货时间") + private LocalDateTime receiveTime; + + @Schema(description = "收件人名称", required = true, example = "张三") + private String receiverName; + + @Schema(description = "收件人手机", required = true, example = "13800138000") + private String receiverMobile; + + @Schema(description = "收件人地区编号", required = true, example = "110000") + private Integer receiverAreaId; + + @Schema(description = "收件人邮编", required = true, example = "100000") + private Integer receiverPostCode; + + @Schema(description = "收件人详细地址", required = true, example = "中关村大街 1 号") + private String receiverDetailAddress; + + // ========== 售后基本信息 ========== + + @Schema(description = "售后状态", example = "1") + private Integer afterSaleStatus; + + @Schema(description = "退款金额", required = true, example = "100") + private Integer refundPrice; + + // ========== 营销基本信息 ========== + + @Schema(description = "优惠劵编号", example = "1024") + private Long couponId; + + @Schema(description = "优惠劵减免金额", required = true, example = "100") + private Integer couponPrice; + + @Schema(description = "积分抵扣的金额", required = true, example = "100") + private Integer pointPrice; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java new file mode 100644 index 000000000..8cb16f89f --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 订单发货 Request VO") +@Data +public class TradeOrderDeliveryReqVO { + + @Schema(description = "订单编号", required = true, example = "1024") + @NotNull(message = "订单编号不能为空") + private Long id; + + @Schema(description = "发货物流公司编号", required = true, example = "1") + @NotNull(message = "发货物流公司编号不能为空") + private Long logisticsId; + + @Schema(description = "发货物流单号", required = true, example = "SF123456789") + @NotEmpty(message = "发货物流单号不能为空") + private String logisticsNo; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java new file mode 100644 index 000000000..f24716e16 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order.vo; + +import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "管理后台 - 交易订单的详情 Response VO") +@Data +public class TradeOrderDetailRespVO extends TradeOrderBaseVO { + + @Schema(description = "收件人地区名字", required = true, example = "上海 上海市 普陀区") + private String receiverAreaName; + + /** + * 订单项列表 + */ + private List items; + + /** + * 用户信息 + */ + private MemberUserRespVO user; + + @Schema(description = "管理后台 - 交易订单的详情的订单项目") + @Data + public static class Item extends TradeOrderItemBaseVO { + + /** + * 属性数组 + */ + private List properties; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java new file mode 100644 index 000000000..b927e5e9e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 交易订单项 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class TradeOrderItemBaseVO { + + // ========== 订单项基本信息 ========== + + @Schema(description = "编号", required = true, example = "1") + private Long id; + + @Schema(description = "用户编号", required = true, example = "1") + private Long userId; + + @Schema(description = "订单编号", required = true, example = "1") + private Long orderId; + + // ========== 商品基本信息 ========== + + @Schema(description = "商品 SPU 编号", required = true, example = "1") + private Long spuId; + + @Schema(description = "商品 SPU 名称", required = true, example = "芋道源码") + private String spuName; + + @Schema(description = "商品 SKU 编号", required = true, example = "1") + private Long skuId; + + @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") + private String picUrl; + + @Schema(description = "购买数量", required = true, example = "1") + private Integer count; + + // ========== 价格 + 支付基本信息 ========== + + @Schema(description = "商品原价(总)", required = true, example = "100") + private Integer originalPrice; + + @Schema(description = "商品原价(单)", required = true, example = "100") + private Integer originalUnitPrice; + + @Schema(description = "商品优惠(总)", required = true, example = "100") + private Integer discountPrice; + + @Schema(description = "商品实付金额(总)", required = true, example = "100") + private Integer payPrice; + + @Schema(description = "子订单分摊金额(总)", required = true, example = "100") + private Integer orderPartPrice; + + @Schema(description = "分摊后子订单实付金额(总)", required = true, example = "100") + private Integer orderDividePrice; + + // ========== 营销基本信息 ========== + + // TODO 芋艿:在捉摸一下 + + // ========== 售后基本信息 ========== + + @Schema(description = "售后状态", required = true, example = "1") + private Integer afterSaleStatus; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java new file mode 100644 index 000000000..fc02acbc5 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order.vo; + +import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "管理后台 - 交易订单的分页项 Response VO") +@Data +public class TradeOrderPageItemRespVO extends TradeOrderBaseVO { + + @Schema(description = "收件人地区名字", required = true, example = "上海 上海市 普陀区") + private String receiverAreaName; + + /** + * 订单项列表 + */ + private List items; + + @Schema(description = "管理后台 - 交易订单的分页项的订单项目") + @Data + public static class Item extends TradeOrderItemBaseVO { + + /** + * 属性数组 + */ + private List properties; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageReqVO.java new file mode 100644 index 000000000..a09e15271 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageReqVO.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.framework.common.validation.Mobile; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 交易订单的分页 Request VO") +@Data +public class TradeOrderPageReqVO extends PageParam { + + @Schema(description = "订单号", example = "88888888") + private String no; + + @Schema(description = "用户编号", example = "1024") + private Long userId; + + @Schema(description = "用户昵称", example = "小王") + private String userNickname; + + @Schema(description = "用户手机号", example = "小王") + @Mobile + private String userMobile; + + @Schema(description = "收件人名称", example = "小红") + private String receiverName; + + @Schema(description = "收件人手机", example = "1560") + @Mobile + private String receiverMobile; + + @Schema(description = "订单类型", example = "1") + private Integer type; + + @Schema(description = "订单状态", example = "1") + @InEnum(value = TradeOrderStatusEnum.class, message = "订单状态必须是 {value}") + private Integer status; + + @Schema(description = "支付渠道", example = "wx_lite") + private String payChannelCode; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java new file mode 100644 index 000000000..c78a10e36 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.trade.controller.app.aftersale; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; +import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "用户 App - 交易售后") +@RestController +@RequestMapping("/trade/after-sale") +@Validated +@Slf4j +public class AppTradeAfterSaleController { + + @Resource + private TradeAfterSaleService afterSaleService; + + @PostMapping(value = "/create") + @Operation(summary = "申请售后") + public CommonResult createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) { + return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO)); + } + + @PostMapping(value = "/delivery") + @Operation(summary = "退回货物") + public CommonResult deliveryAfterSale(@RequestBody AppTradeAfterSaleDeliveryReqVO deliveryReqVO) { + afterSaleService.deliveryAfterSale(getLoginUserId(), deliveryReqVO); + return success(true); + } + + @DeleteMapping(value = "/cancel") + @Operation(summary = "取消售后") + @Parameter(name = "id", description = "售后编号", required = true, example = "1") + public CommonResult cancelAfterSale(@RequestParam("id") Long id) { + afterSaleService.cancelAfterSale(getLoginUserId(), id); + return success(true); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java new file mode 100644 index 000000000..d668005e3 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo; + +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "用户 App - 交易售后创建 Request VO") +@Data +public class AppTradeAfterSaleCreateReqVO { + + @Schema(description = "订单项编号", required = true, example = "1024") + @NotNull(message = "订单项编号不能为空") + private Long orderItemId; + + @Schema(description = "售后方式", required = true, example = "1") + @NotNull(message = "售后方式不能为空") + @InEnum(value = TradeAfterSaleWayEnum.class, message = "售后方式必须是 {value}") + private Integer way; + + @Schema(description = "退款金额", required = true, example = "100") + @NotNull(message = "退款金额不能为空") + @Min(value = 1, message = "退款金额必须大于 0") + private Integer refundPrice; + + @Schema(description = "申请原因", required = true, example = "1") + @NotNull(message = "申请原因不能为空") + private String applyReason; + + @Schema(description = "补充描述", example = "商品质量不好") + private String applyDescription; + + @Schema(description = "补充凭证图片", example = "https://www.iocoder.cn/1.png, https://www.iocoder.cn/2.png") + private List applyPicUrls; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java new file mode 100644 index 000000000..9266d38d1 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +@Schema(description = "用户 App - 交易售后退回货物 Request VO") +@Data +public class AppTradeAfterSaleDeliveryReqVO { + + @Schema(description = "售后编号", required = true, example = "1024") + @NotNull(message = "售后编号不能为空") + private Long id; + + @Schema(description = "退货物流公司编号", required = true, example = "1") + @NotNull(message = "退货物流公司编号不能为空") + private Long logisticsId; + + @Schema(description = "退货物流单号", required = true, example = "SF123456789") + @NotNull(message = "退货物流单号不能为空") + private String logisticsNo; + + @Schema(description = "退货时间", required = true) + @NotEmpty(message = "退货时间不能为空") + private LocalDateTime deliveryTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/package-info.java new file mode 100644 index 000000000..08acfdbca --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/package-info.java @@ -0,0 +1,4 @@ +/** + * 基础包,放一些通用的 VO 类 + */ +package cn.iocoder.yudao.module.trade.controller.app.base; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java new file mode 100644 index 000000000..22dda6a71 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.trade.controller.app.base.property; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "用户 App - 商品属性值的明细 Response VO") +@Data +public class AppProductPropertyValueDetailRespVO { + + @Schema(description = "属性的编号", required = true, example = "1") + private Long propertyId; + + @Schema(description = "属性的名称", required = true, example = "颜色") + private String propertyName; + + @Schema(description = "属性值的编号", required = true, example = "1024") + private Long valueId; + + @Schema(description = "属性值的名称", required = true, example = "红色") + private String valueName; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java new file mode 100644 index 000000000..053e329b4 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.trade.controller.app.base.sku; + +import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 商品 SKU 基础 Response VO + * + * @author 芋道源码 + */ +@Data +public class AppProductSkuBaseRespVO { + + @Schema(description = "主键", required = true, example = "1024") + private Long id; + + @Schema(description = "商品 SKU 名字", required = true, example = "芋道") + private String name; + + @Schema(description = "图片地址", example = "https://www.iocoder.cn/xx.png") + private String picUrl; + + @Schema(description = "库存", required = true, example = "1") + private Integer stock; + + /** + * 属性数组 + */ + private List properties; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java new file mode 100644 index 000000000..b73be6e0c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.trade.controller.app.base.spu; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +/** + * 商品 SPU 基础 Response VO + * + * @author 芋道源码 + */ +@Data +public class AppProductSpuBaseRespVO { + + @Schema(description = "主键", required = true, example = "1024") + private Long id; + + @Schema(description = "商品 SPU 名字", required = true, example = "芋道") + private String name; + + @Schema(description = "商品主图地址", example = "https://www.iocoder.cn/xx.png") + private List picUrls; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http new file mode 100644 index 000000000..3ce8797fc --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http @@ -0,0 +1,47 @@ +### 请求 /trade/cart/add-count 接口 => 成功 +POST {{appApi}}/trade/cart/add-count +tenant-id: {{appTenentId}} +Authorization: Bearer {{appToken}} +Content-Type: application/json + +{ + "skuId": 1, + "count": 1 +} + +### 请求 /trade/cart/update-count 接口 => 成功 +PUT {{appApi}}/trade/cart/update-count +tenant-id: {{appTenentId}} +Authorization: Bearer {{appToken}} +Content-Type: application/json + +{ + "skuId": 1, + "count": 5 +} + +### 请求 /trade/cart/update-selected 接口 => 成功 +PUT {{appApi}}/trade/cart/update-selected +tenant-id: {{appTenentId}} +Authorization: Bearer {{appToken}} +Content-Type: application/json + +{ + "skuIds": [1], + "selected": false +} + +### 请求 /trade/cart/delete 接口 => 成功 +DELETE {{appApi}}/trade/cart/delete?skuIds=1 +tenant-id: {{appTenentId}} +Authorization: Bearer {{appToken}} + +### 请求 /trade/cart/get-count 接口 => 成功 +GET {{appApi}}/trade/cart/get-count +tenant-id: {{appTenentId}} +Authorization: Bearer {{appToken}} + +### 请求 /trade/cart/get-detail 接口 => 成功 +GET {{appApi}}/trade/cart/get-detail +tenant-id: {{appTenentId}} +Authorization: Bearer {{appToken}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java new file mode 100644 index 000000000..46512a959 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java @@ -0,0 +1,84 @@ +package cn.iocoder.yudao.module.trade.controller.app.cart; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO; +import cn.iocoder.yudao.module.trade.service.cart.TradeCartService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "用户 App - 购物车") +@RestController +@RequestMapping("/trade/cart") +@RequiredArgsConstructor +@Validated +@Slf4j +public class TradeCartController { + + @Resource + private TradeCartService cartService; + + @PostMapping("/add-count") + @Operation(summary = "添加商品到购物车") + @PreAuthenticated + public CommonResult addCartItemCount(@Valid @RequestBody AppTradeCartItemAddCountReqVO addCountReqVO) { + cartService.addCartItemCount(getLoginUserId(), addCountReqVO); + return success(true); + } + + @PutMapping("update-count") + @Operation(summary = "更新购物车商品数量") + @PreAuthenticated + public CommonResult updateCartItemQuantity(@Valid @RequestBody AppTradeCartItemUpdateCountReqVO updateCountReqVO) { + cartService.updateCartItemCount(getLoginUserId(), updateCountReqVO); + return success(true); + } + + @PutMapping("update-selected") + @Operation(summary = "更新购物车商品是否选中") + @PreAuthenticated + public CommonResult updateCartItemSelected(@Valid @RequestBody AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO) { + cartService.updateCartItemSelected(getLoginUserId(), updateSelectedReqVO); + // 获得目前购物车明细 + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除购物车商品") + @Parameter(name = "skuIds", description = "商品 SKU 编号的数组", required = true, example = "1024,2048") + @PreAuthenticated + public CommonResult deleteCartItem(@RequestParam("skuIds") List skuIds) { + cartService.deleteCartItems(getLoginUserId(), skuIds); + return success(true); + } + + @GetMapping("get-count") + @Operation(summary = "查询用户在购物车中的商品数量") + @PreAuthenticated + public CommonResult getCartCount() { + return success(cartService.getCartCount(getLoginUserId())); + } + + @GetMapping("/get-detail") + @Operation(summary = "查询用户的购物车的详情") + @PreAuthenticated + public CommonResult getCartDetail() { + return success(cartService.getCartDetail(getLoginUserId())); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java new file mode 100644 index 000000000..769418528 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java @@ -0,0 +1,117 @@ +package cn.iocoder.yudao.module.trade.controller.app.cart.vo; + +import cn.iocoder.yudao.module.trade.controller.app.base.sku.AppProductSkuBaseRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "用户 App - 用户的购物车明细 Response VO") +@Data +public class AppTradeCartDetailRespVO { + + /** + * 商品分组数组 + */ + private List itemGroups; + + /** + * 费用 + */ + private Order order; + + @Schema(description = "商品分组") // 多个商品,参加同一个活动,从而形成分组 + @Data + public static class ItemGroup { + + /** + * 商品数组 + */ + private List items; + /** + * 营销活动,订单级别 + */ + private Promotion promotion; + + } + + @Schema(description = "商品 SKU") + @Data + public static class Sku extends AppProductSkuBaseRespVO { + + /** + * SPU 信息 + */ + private AppProductSkuBaseRespVO spu; + + // ========== 购物车相关的字段 ========== + + @Schema(description = "商品数量", required = true, example = "1") + private Integer count; + @Schema(description = "是否选中", required = true, example = "true") + private Boolean selected; + + // ========== 价格相关的字段,对应 PriceCalculateRespDTO.OrderItem 的属性 ========== + + // TODO 芋艿:后续可以去除一些无用的字段 + + @Schema(description = "商品原价(单)", required = true, example = "100") + private Integer originalPrice; + @Schema(description = "商品原价(总)", required = true, example = "200") + private Integer totalOriginalPrice; + @Schema(description = "商品级优惠(总)", required = true, example = "300") + private Integer totalPromotionPrice; + @Schema(description = "最终购买金额(总)", required = true, example = "400") + private Integer totalPresentPrice; + @Schema(description = "最终购买金额(单)", required = true, example = "500") + private Integer presentPrice; + @Schema(description = "应付金额(总)", required = true, example = "600") + private Integer totalPayPrice; + + // ========== 营销相关的字段 ========== + /** + * 营销活动,商品级别 + */ + private Promotion promotion; + + } + + @Schema(description = "订单") // 对应 PriceCalculateRespDTO.Order 类,用于费用(合计) + @Data + public static class Order { + + // TODO 芋艿:后续可以去除一些无用的字段 + + @Schema(description = "商品原价(总)", required = true, example = "100") + private Integer skuOriginalPrice; + @Schema(description = "商品优惠(总)", required = true, example = "200") + private Integer skuPromotionPrice; + @Schema(description = "订单优惠(总)", required = true, example = "300") + private Integer orderPromotionPrice; + @Schema(description = "运费金额", required = true, example = "400") + private Integer deliveryPrice; + @Schema(description = "应付金额(总)", required = true, example = "500") + private Integer payPrice; + + } + + @Schema(description = "营销活动") // 对应 PriceCalculateRespDTO.Promotion 类的属性 + @Data + public static class Promotion { + + @Schema(description = "营销编号", required = true, example = "1024") // 营销活动的编号、优惠劵的编号 + private Long id; + @Schema(description = "营销名字", required = true, example = "xx 活动") + private String name; + @Schema(description = "营销类型", required = true, example = "1") + private Integer type; + + // ========== 匹配情况 ========== + @Schema(description = "是否满足优惠条件", required = true, example = "true") + private Boolean meet; + @Schema(description = "满足条件的提示", required = true, example = "圣诞价:省 150.00 元") + private String meetTip; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java new file mode 100644 index 000000000..9b4ba6929 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.trade.controller.app.cart.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +@Schema(description = "用户 App - 购物车添加购物项 Request VO") +@Data +public class AppTradeCartItemAddCountReqVO { + + @Schema(description = "商品 SKU 编号", required = true,example = "1024") + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + @Schema(description = "新增商品数量", required = true, example = "1") + @NotNull(message = "数量不能为空") + @Min(message = "数量必须大于 0", value = 1L) + private Integer count; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java new file mode 100644 index 000000000..d3d12487e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.trade.controller.app.cart.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +@Schema(description = "用户 App - 购物车更新数量 Request VO") +@Data +public class AppTradeCartItemUpdateCountReqVO { + + @Schema(description = "商品 SKU 编号", required = true, example = "1024") + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + @Schema(description = "商品数量", required = true, example = "1") + @NotNull(message = "数量不能为空") + @Min(message = "数量必须大于 0", value = 1L) + private Integer count; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java new file mode 100644 index 000000000..62327f320 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.trade.controller.app.cart.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.Collection; + +@Schema(description = "用户 App - 购物车更新是否选中 Request VO") +@Data +public class AppTradeCartItemUpdateSelectedReqVO { + + @Schema(description = "商品 SKU 编号列表", required = true, example = "1024,2048") + @NotNull(message = "商品 SKU 编号列表不能为空") + private Collection skuIds; + + @Schema(description = "是否选中", required = true, example = "true") + @NotNull(message = "是否选中不能为空") + private Boolean selected; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http new file mode 100644 index 000000000..8e7746359 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http @@ -0,0 +1,37 @@ +### /trade-order/confirm-create-order-info 基于商品,确认创建订单 +GET {{appApi}}/trade/order/get-create-info?items[0].skuId=1&items[0].count=1 +Authorization: Bearer {{user-access-token}} +tenant-id: {{appTenentId}} + +### /trade-order/confirm-create-order-info-from-cart 基于购物车,确认创建订单 +GET {{shop-api-base-url}}/trade-order/confirm-create-order-info-from-cart +Content-Type: application/x-www-form-urlencoded +Authorization: Bearer {{user-access-token}} + +### /trade-order/create 基于商品,创建订单 +POST {{appApi}}/trade/order/create +Content-Type: application/json +Authorization: Bearer {{appToken}} +tenant-id: {{appTenentId}} + +{ + "addressId": 21, + "remark": "我是备注", + "fromCart": false, + "items": [ + { + "skuId": 29, + "count": 1 + } + ] +} + +### 获得订单交易的分页 +GET {{appApi}}/trade/order/page?pageNo=1&pageSize=10 +Authorization: Bearer {{appToken}} +tenant-id: {{appTenentId}} + +### 获得订单交易的详细 +GET {{appApi}}/trade/order/get-detail?id=21 +Authorization: Bearer {{appToken}} +tenant-id: {{appTenentId}} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java new file mode 100644 index 000000000..610116c37 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -0,0 +1,102 @@ +package cn.iocoder.yudao.module.trade.controller.app.order; + +import cn.hutool.extra.servlet.ServletUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; +import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; +import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; +import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "用户 App - 交易订单") +@RestController +@RequestMapping("/trade/order") +@Validated +@Slf4j +public class AppTradeOrderController { + + @Resource + private TradeOrderService tradeOrderService; + + @Resource + private ProductPropertyValueApi productPropertyValueApi; + + @GetMapping("/get-create-info") + @Operation(summary = "基于商品,确认创建订单") + @PreAuthenticated + public CommonResult getOrderCreateInfo(AppTradeOrderCreateReqVO createReqVO) { +// return success(tradeOrderService.getOrderConfirmCreateInfo(UserSecurityContextHolder.getUserId(), skuId, quantity, couponCardId)); + return null; + } + + @PostMapping("/create") + @Operation(summary = "创建订单") + @PreAuthenticated + public CommonResult createOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO, + HttpServletRequest servletRequest) { + // 获取登录用户、用户 IP 地址 + Long loginUserId = getLoginUserId(); + String clientIp = ServletUtil.getClientIP(servletRequest); + // 创建交易订单,预支付记录 + Long orderId = tradeOrderService.createOrder(loginUserId, clientIp, createReqVO); + return success(orderId); + } + + @PostMapping("/update-paid") + @Operation(description = "更新订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob + public CommonResult updateOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { + tradeOrderService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), + notifyReqDTO.getPayOrderId()); + return success(true); + } + + @GetMapping("/get-detail") + @Operation(summary = "获得交易订单") + @Parameter(name = "id", description = "交易订单编号") + public CommonResult getOrder(@RequestParam("id") Long id) { + // 查询订单 + TradeOrderDO order = tradeOrderService.getOrder(getLoginUserId(), id); + // 查询订单项 + List orderItems = tradeOrderService.getOrderItemListByOrderId(order.getId()); + // 查询商品属性 + List propertyValueDetails = productPropertyValueApi + .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); + // 最终组合 + return success(TradeOrderConvert.INSTANCE.convert02(order, orderItems, propertyValueDetails)); + } + + @GetMapping("/page") + @Operation(summary = "获得订单交易分页") + public CommonResult> getOrderPage(AppTradeOrderPageReqVO reqVO) { + // 查询订单 + PageResult pageResult = tradeOrderService.getOrderPage(getLoginUserId(), reqVO); + // 查询订单项 + List orderItems = tradeOrderService.getOrderItemListByOrderId( + convertSet(pageResult.getList(), TradeOrderDO::getId)); + // 查询商品属性 + List propertyValueDetails = productPropertyValueApi + .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); + // 最终组合 + return success(TradeOrderConvert.INSTANCE.convertPage02(pageResult, orderItems, propertyValueDetails)); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java new file mode 100644 index 000000000..6c881defe --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.trade.controller.app.order.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + +@Schema(description = "用户 App - 交易订单创建 Request VO") +@Data +public class AppTradeOrderCreateReqVO { + + @Schema(description = "收件地址编号", required = true, example = "1") + @NotNull(message = "收件地址不能为空") + private Long addressId; + + @Schema(description = "优惠劵编号", example = "1024") + private Long couponId; + + @Schema(description = "备注", example = "这个是我的订单哟") + private String remark; + + @Schema(description = "是否来自购物车", required = true, example = "true") // true - 来自购物车;false - 立即购买 + @NotNull(message = "是否来自购物车不能为空") + private Boolean fromCart; + + /** + * 订单商品项列表 + */ + @NotEmpty(message = "必须选择购买的商品") + @Valid + private List items; + + @Schema(description = "订单商品项") + @Data + public static class Item { + + @Schema(description = "商品 SKU 编号", required = true, example = "111") + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + @Schema(description = "商品 SKU 购买数量", required = true, example = "1024") + @NotNull(message = "商品 SKU 购买数量不能为空") + @Min(value = 1, message = "商品 SKU 购买数量必须大于 0") + private Integer count; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java new file mode 100644 index 000000000..c8a57bacb --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java @@ -0,0 +1,149 @@ +package cn.iocoder.yudao.module.trade.controller.app.order.vo; + +import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.Date; +import java.util.List; + +@Schema(description = "用户 App - 订单交易的明细 Response VO") +@Data +public class AppTradeOrderDetailRespVO { + + // ========== 订单基本信息 ========== + + @Schema(description = "订单编号", required = true, example = "1024") + private Long id; + + @Schema(description = "订单流水号", required = true, example = "1146347329394184195") + private String no; + + @Schema(description = "下单时间", required = true) + private Date createTime; + + @Schema(description = "用户备注", required = true, example = "你猜") + private String userRemark; + + @Schema(description = "订单状态", required = true, example = "1") + private Integer status; + + @Schema(description = "购买的商品数量", required = true, example = "10") + private Integer productCount; + + @Schema(description = "订单完成时间") + private LocalDateTime finishTime; + + @Schema(description = "订单取消时间") + private LocalDateTime cancelTime; + + // ========== 价格 + 支付基本信息 ========== + + @Schema(description = "支付订单编号", required = true, example = "1024") + private Long payOrderId; + + @Schema(description = "付款时间") + private LocalDateTime payTime; + + @Schema(description = "商品原价(总)", required = true, example = "1000") + private Integer originalPrice; + + @Schema(description = "订单原价(总)", required = true, example = "1000") + private Integer orderPrice; + + @Schema(description = "订单优惠(总)", required = true, example = "100") + private Integer discountPrice; + + @Schema(description = "运费金额", required = true, example = "100") + private Integer deliveryPrice; + + @Schema(description = "订单调价(总)", required = true, example = "100") + private Integer adjustPrice; + + @Schema(description = "应付金额(总)", required = true, example = "1000") + private Integer payPrice; + + // ========== 收件 + 物流基本信息 ========== + + @Schema(description = "发货物流单号", example = "1024") + private String logisticsNo; + + @Schema(description = "发货时间") + private LocalDateTime deliveryTime; + + @Schema(description = "收货时间") + private LocalDateTime receiveTime; + + @Schema(description = "收件人名称", required = true, example = "张三") + private String receiverName; + + @Schema(description = "收件人手机", required = true, example = "13800138000") + private String receiverMobile; + + @Schema(description = "收件人地区编号", required = true, example = "110000") + private Integer receiverAreaId; + + @Schema(description = "收件人地区名字", required = true, example = "上海 上海市 普陀区") + private String receiverAreaName; + + @Schema(description = "收件人邮编", required = true, example = "100000") + private Integer receiverPostCode; + + @Schema(description = "收件人详细地址", required = true, example = "中关村大街 1 号") + private String receiverDetailAddress; + + // ========== 售后基本信息 ========== + + // ========== 营销基本信息 ========== + + @Schema(description = "优惠劵编号", example = "1024") + private Long couponId; + + @Schema(description = "优惠劵减免金额", required = true, example = "100") + private Integer couponPrice; + + @Schema(description = "积分抵扣的金额", required = true, example = "100") + private Integer pointPrice; + + /** + * 订单项数组 + */ + private List items; + + @Schema(description = "用户 App - 交易订单的分页项的订单项目") + @Data + public static class Item { + + @Schema(description = "编号", required = true, example = "1") + private Long id; + + @Schema(description = "商品 SPU 编号", required = true, example = "1") + private Long spuId; + + @Schema(description = "商品 SPU 名称", required = true, example = "芋道源码") + private String spuName; + + @Schema(description = "商品 SKU 编号", required = true, example = "1") + private Long skuId; + + @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") + private String picUrl; + + @Schema(description = "购买数量", required = true, example = "1") + private Integer count; + + @Schema(description = "商品原价(总)", required = true, example = "100") + private Integer originalPrice; + + @Schema(description = "商品原价(单)", required = true, example = "100") + private Integer originalUnitPrice; + + /** + * 属性数组 + */ + private List properties; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java new file mode 100644 index 000000000..86a1b61b7 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java @@ -0,0 +1,168 @@ +package cn.iocoder.yudao.module.trade.controller.app.order.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.util.List; + +@Schema(description = "用户 App - 订单获得创建信息 Response VO") +@Data +public class AppTradeOrderGetCreateInfoRespVO { + + /** + * 商品分组数组 + */ + private List itemGroups; + /** + * 费用 + */ + private Fee fee; + +// /** +// * 优惠劵列表 TODO 芋艿,后续改改 +// */ +// private List coupons; + + @Schema(description = "商品分组") // 多个商品,参加同一个活动,从而形成分组 + @Data + public static class ItemGroup { + +// /** +// * 优惠活动 +// */ +// private PromotionActivityRespDTO activity; // TODO 芋艿,偷懒 + /** + * 商品 SKU 数组 + */ + private List items; + + } + + @Schema(description = "商品 SKU") + @Data + public static class Sku { + + // SKU 自带信息 + @Schema(description = "SKU 编号", required = true, example = "1024") + private Integer id; + /** + * SPU 信息 + */ + private Spu spu; + /** + * 图片地址 + */ + private String picURL; +// /** +// * 属性数组 +// */ +// private List attrs; // TODO 后面改下 + /** + * 价格,单位:分 + */ + private Integer price; + /** + * 库存数量 + */ + private Integer stock; + + // 非 SKU 自带信息 + + /** + * 购买数量 + */ + private Integer buyQuantity; +// /** +// * 优惠活动 +// */ +// private PromotionActivityRespDTO activity; // TODO 芋艿,偷懒 + /** + * 原始单价,单位:分。 + */ + private Integer originPrice; + /** + * 购买单价,单位:分 + */ + private Integer buyPrice; + /** + * 最终价格,单位:分。 + */ + private Integer presentPrice; + /** + * 购买总金额,单位:分 + * + * 用途类似 {@link #presentTotal} + */ + private Integer buyTotal; + /** + * 优惠总金额,单位:分。 + */ + private Integer discountTotal; + /** + * 最终总金额,单位:分。 + * + * 注意,presentPrice * quantity 不一定等于 presentTotal 。 + * 因为,存在无法整除的情况。 + * 举个例子,presentPrice = 8.33 ,quantity = 3 的情况,presentTotal 有可能是 24.99 ,也可能是 25 。 + * 所以,需要存储一个该字段。 + */ + private Integer presentTotal; + + } + + @Data + public static class Spu { + + /** + * SPU 编号 + */ + private Integer id; + + // ========== 基本信息 ========= + /** + * SPU 名字 + */ + private String name; + /** + * 分类编号 + */ + private Integer cid; + /** + * 商品主图地址 + * + * 数组,以逗号分隔 + * + * 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张 + */ + private List picUrls; + + } + + @Schema(description = "费用(合计)") + @Data + @AllArgsConstructor + public static class Fee { + + @Schema(description = "购买总价", required = true, example = "1024") + private Integer buyPrice; + /** + * 优惠总价 + * + * 注意,满多少元包邮,不算在优惠中。 + */ + private Integer discountTotal; + /** + * 邮费 + */ + private Integer postageTotal; + /** + * 最终价格 + * + * 计算公式 = 总价 - 优惠总价 + 邮费 + */ + private Integer presentTotal; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java new file mode 100644 index 000000000..d601553e6 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.module.trade.controller.app.order.vo; + +import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "用户 App - 订单交易的分页项 Response VO") +@Data +public class AppTradeOrderPageItemRespVO { + + @Schema(description = "订单编号", required = true, example = "1024") + private Long id; + + @Schema(description = "订单流水号", required = true, example = "1146347329394184195") + private String no; + + @Schema(description = "订单状态", required = true, example = "1") + private Integer status; + + @Schema(description = "购买的商品数量", required = true, example = "10") + private Integer productCount; + + /** + * 订单项数组 + */ + private List items; + + @Schema(description = "用户 App - 交易订单的明细的订单项目") + @Data + public static class Item { + + @Schema(description = "编号", required = true, example = "1") + private Long id; + + @Schema(description = "商品 SPU 编号", required = true, example = "1") + private Long spuId; + + @Schema(description = "商品 SPU 名称", required = true, example = "芋道源码") + private String spuName; + + @Schema(description = "商品 SKU 编号", required = true, example = "1") + private Long skuId; + + @Schema(description = "商品图片", required = true, example = "https://www.iocoder.cn/1.png") + private String picUrl; + + @Schema(description = "购买数量", required = true, example = "1") + private Integer count; + + @Schema(description = "商品原价(总)", required = true, example = "100") + private Integer originalPrice; + + @Schema(description = "商品原价(单)", required = true, example = "100") + private Integer originalUnitPrice; + + /** + * 属性数组 + */ + private List properties; + + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java new file mode 100644 index 000000000..180deadbf --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.trade.controller.app.order.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +// TODO 芋艿:字段优化 +@Schema(description = "交易订单分页 Request VO") +@Data +public class AppTradeOrderPageReqVO extends PageParam { + + @Schema(description = "订单状态", example = "1") + @InEnum(value = TradeOrderStatusEnum.class, message = "订单状态必须是 {value}") + private Integer status; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java new file mode 100644 index 000000000..aa2f99f35 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java @@ -0,0 +1,6 @@ +/** + * 提供 RESTful API 给前端: + * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目 + * 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分 + */ +package cn.iocoder.yudao.module.trade.controller; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java new file mode 100644 index 000000000..fe1e3bd01 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java @@ -0,0 +1,89 @@ +package cn.iocoder.yudao.module.trade.convert.aftersale; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO; +import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.util.*; +import java.util.stream.Collectors; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; + +@Mapper +public interface TradeAfterSaleConvert { + + TradeAfterSaleConvert INSTANCE = Mappers.getMapper(TradeAfterSaleConvert.class); + + @Mappings({ + @Mapping(target = "id", ignore = true), + @Mapping(target = "createTime", ignore = true), + @Mapping(target = "updateTime", ignore = true), + @Mapping(target = "creator", ignore = true), + @Mapping(target = "updater", ignore = true), + }) + TradeAfterSaleDO convert(AppTradeAfterSaleCreateReqVO createReqVO, TradeOrderItemDO tradeOrderItem); + + @Mappings({ + @Mapping(source = "afterSale.orderId", target = "merchantOrderId"), + @Mapping(source = "afterSale.applyReason", target = "reason"), + @Mapping(source = "afterSale.refundPrice", target = "amount") + }) + PayRefundCreateReqDTO convert(String userIp, TradeAfterSaleDO afterSale, + TradeOrderProperties orderProperties); + + MemberUserRespVO convert(MemberUserRespDTO bean); + + PageResult convertPage(PageResult page); + + default PageResult convertPage(PageResult pageResult, + Map memberUsers, List propertyValueDetails) { + PageResult pageVOResult = convertPage(pageResult); + // 处理会员 + 商品属性等关联信息 + Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); + for (int i = 0; i < pageResult.getList().size(); i++) { + TradeAfterSaleRespPageItemVO afterSaleVO = pageVOResult.getList().get(i); + TradeAfterSaleDO afterSaleDO = pageResult.getList().get(i); + // 会员 + afterSaleVO.setUser(convert(memberUsers.get(afterSaleDO.getUserId()))); + // 商品属性 + if (CollUtil.isNotEmpty(afterSaleDO.getProperties())) { + afterSaleVO.setProperties(new ArrayList<>(afterSaleDO.getProperties().size())); + // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 + afterSaleDO.getProperties().forEach(property -> { + ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); + if (propertyValueDetail == null) { + return; + } + afterSaleVO.getProperties().add(convert(propertyValueDetail)); + }); + } + } + return pageVOResult; + } + + ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean); + + default Set convertPropertyValueIds(List list) { + if (CollUtil.isEmpty(list)) { + return new HashSet<>(); + } + return list.stream().filter(item -> item.getProperties() != null) + .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 + .map(TradeOrderItemDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 + .collect(Collectors.toSet()); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java new file mode 100644 index 000000000..eb696ae30 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.trade.convert.cart; + +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.util.Collections; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; + +@Mapper +public interface TradeCartConvert { + + TradeCartConvert INSTANCE = Mappers.getMapper(TradeCartConvert.class); + + default AppTradeCartDetailRespVO buildEmptyAppTradeCartDetailRespVO() { + return new AppTradeCartDetailRespVO().setItemGroups(Collections.emptyList()) + .setOrder(new AppTradeCartDetailRespVO.Order().setSkuOriginalPrice(0).setSkuPromotionPrice(0) + .setOrderPromotionPrice(0).setDeliveryPrice(0).setPayPrice(0)); + } + + default PriceCalculateReqDTO convert(Long userId, List cartItems) { + return new PriceCalculateReqDTO().setUserId(userId) + .setItems(convertList(cartItems, cartItem -> new PriceCalculateReqDTO.Item().setSkuId(cartItem.getSkuId()) + .setCount(cartItem.getSelected() ? cartItem.getCount() : 0))); + } + + // ========== AppTradeCartDetailRespVO 相关 ========== + + AppTradeCartDetailRespVO.Promotion convert(PriceCalculateRespDTO.Promotion bean); + + @Mappings({ + @Mapping(source = "cartItem.count", target = "count") + }) + AppTradeCartDetailRespVO.Sku convert(PriceCalculateRespDTO.OrderItem orderItem, TradeCartItemDO cartItem); + + AppTradeCartDetailRespVO.Order convert(PriceCalculateRespDTO.Order bean); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java new file mode 100644 index 000000000..b1f0b4b2a --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -0,0 +1,241 @@ +package cn.iocoder.yudao.module.trade.convert.order; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO; +import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageItemRespVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.util.*; +import java.util.stream.Collectors; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime; + +@Mapper +public interface TradeOrderConvert { + + TradeOrderConvert INSTANCE = Mappers.getMapper(TradeOrderConvert.class); + + @Mappings({ + @Mapping(target = "id", ignore = true), + @Mapping(source = "createReqVO.couponId", target = "couponId"), + @Mapping(target = "remark", ignore = true), + @Mapping(source = "createReqVO.remark", target = "userRemark"), + @Mapping(source = "address.name", target = "receiverName"), + @Mapping(source = "address.mobile", target = "receiverMobile"), + @Mapping(source = "address.areaId", target = "receiverAreaId"), + @Mapping(source = "address.postCode", target = "receiverPostCode"), + @Mapping(source = "address.detailAddress", target = "receiverDetailAddress"), + }) + TradeOrderDO convert(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO, + PriceCalculateRespDTO.Order order, AddressRespDTO address); + + @Mappings({ + @Mapping(target = "id", ignore = true), + @Mapping(source = "sku.spuId", target = "spuId"), + }) + TradeOrderItemDO convert(PriceCalculateRespDTO.OrderItem orderItem, ProductSkuRespDTO sku); + + default List convertList(TradeOrderDO tradeOrderDO, + List orderItems, List skus) { + Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); + return CollectionUtils.convertList(orderItems, orderItem -> { + TradeOrderItemDO tradeOrderItemDO = convert(orderItem, skuMap.get(orderItem.getSkuId())); + tradeOrderItemDO.setOrderId(tradeOrderDO.getId()); + tradeOrderItemDO.setUserId(tradeOrderDO.getUserId()); + tradeOrderItemDO.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); // 退款信息 +// tradeOrderItemDO.setCommented(false); + return tradeOrderItemDO; + }); + } + + @Mapping(source = "userId" , target = "userId") + PriceCalculateReqDTO convert(AppTradeOrderCreateReqVO createReqVO, Long userId); + + @Mappings({ + @Mapping(source = "skuId", target = "id"), + @Mapping(source = "count", target = "incrCount"), + }) + ProductSkuUpdateStockReqDTO.Item convert(TradeOrderItemDO bean); + List convertList(List list); + + default PayOrderCreateReqDTO convert(TradeOrderDO tradeOrderDO, List tradeOrderItemDOs, + List spus, TradeOrderProperties tradeOrderProperties) { + PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO() + .setAppId(tradeOrderProperties.getAppId()).setUserIp(tradeOrderDO.getUserIp()); + // 商户相关字段 + createReqDTO.setMerchantOrderId(String.valueOf(tradeOrderDO.getId())); + String subject = spus.get(0).getName(); + if (spus.size() > 1) { + subject += " 等多件"; + } + createReqDTO.setSubject(subject); + // 订单相关字段 + createReqDTO.setAmount(tradeOrderDO.getPayPrice()).setExpireTime(addTime(tradeOrderProperties.getExpireTime())); + return createReqDTO; + } + + default Set convertPropertyValueIds(List list) { + if (CollUtil.isEmpty(list)) { + return new HashSet<>(); + } + return list.stream().filter(item -> item.getProperties() != null) + .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 + .map(TradeOrderItemDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 + .collect(Collectors.toSet()); + } + + default PageResult convertPage(PageResult pageResult, List orderItems, + List propertyValueDetails) { + Map> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId); + Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); + // 转化 List + List orderVOs = CollectionUtils.convertList(pageResult.getList(), order -> { + List xOrderItems = orderItemMap.get(order.getId()); + TradeOrderPageItemRespVO orderVO = convert(order, xOrderItems); + if (CollUtil.isNotEmpty(xOrderItems)) { + // 处理商品属性 + for (int i = 0; i < xOrderItems.size(); i++) { + List properties = xOrderItems.get(i).getProperties(); + if (CollUtil.isEmpty(properties)) { + continue; + } + TradeOrderPageItemRespVO.Item item = orderVO.getItems().get(i); + item.setProperties(new ArrayList<>(properties.size())); + // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 + properties.forEach(property -> { + ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); + if (propertyValueDetail == null) { + return; + } + item.getProperties().add(convert(propertyValueDetail)); + }); + } + } + // 处理收货地址 + orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); + return orderVO; + }); + return new PageResult<>(orderVOs, pageResult.getTotal()); + } + TradeOrderPageItemRespVO convert(TradeOrderDO order, List items); + ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean); + + default TradeOrderDetailRespVO convert(TradeOrderDO order, List orderItems, + List propertyValueDetails, MemberUserRespDTO user) { + TradeOrderDetailRespVO orderVO = convert2(order, orderItems); + // 处理商品属性 + Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); + for (int i = 0; i < orderItems.size(); i++) { + List properties = orderItems.get(i).getProperties(); + if (CollUtil.isEmpty(properties)) { + continue; + } + TradeOrderDetailRespVO.Item item = orderVO.getItems().get(i); + item.setProperties(new ArrayList<>(properties.size())); + // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 + properties.forEach(property -> { + ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); + if (propertyValueDetail == null) { + return; + } + item.getProperties().add(convert(propertyValueDetail)); + }); + } + // 处理收货地址 + orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); + // 处理用户信息 + orderVO.setUser(convert(user)); + return orderVO; + } + TradeOrderDetailRespVO convert2(TradeOrderDO order, List items); + MemberUserRespVO convert(MemberUserRespDTO bean); + + default PageResult convertPage02(PageResult pageResult, List orderItems, + List propertyValueDetails) { + Map> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId); + Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); + // 转化 List + List orderVOs = CollectionUtils.convertList(pageResult.getList(), order -> { + List xOrderItems = orderItemMap.get(order.getId()); + AppTradeOrderPageItemRespVO orderVO = convert02(order, xOrderItems); + if (CollUtil.isNotEmpty(xOrderItems)) { + // 处理商品属性 + for (int i = 0; i < xOrderItems.size(); i++) { + List properties = xOrderItems.get(i).getProperties(); + if (CollUtil.isEmpty(properties)) { + continue; + } + AppTradeOrderPageItemRespVO.Item item = orderVO.getItems().get(i); + item.setProperties(new ArrayList<>(properties.size())); + // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 + properties.forEach(property -> { + ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); + if (propertyValueDetail == null) { + return; + } + item.getProperties().add(convert02(propertyValueDetail)); + }); + } + } + return orderVO; + }); + return new PageResult<>(orderVOs, pageResult.getTotal()); + } + AppTradeOrderPageItemRespVO convert02(TradeOrderDO order, List items); + AppProductPropertyValueDetailRespVO convert02(ProductPropertyValueDetailRespDTO bean); + + default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List orderItems, + List propertyValueDetails) { + AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems); + // 处理商品属性 + Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); + for (int i = 0; i < orderItems.size(); i++) { + List properties = orderItems.get(i).getProperties(); + if (CollUtil.isEmpty(properties)) { + continue; + } + AppTradeOrderDetailRespVO.Item item = orderVO.getItems().get(i); + item.setProperties(new ArrayList<>(properties.size())); + // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 + properties.forEach(property -> { + ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); + if (propertyValueDetail == null) { + return; + } + item.getProperties().add(convert02(propertyValueDetail)); + }); + } + // 处理收货地址 + orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); + return orderVO; + } + AppTradeOrderDetailRespVO convert3(TradeOrderDO order, List items); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java new file mode 100644 index 000000000..1b703d9e7 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java @@ -0,0 +1,201 @@ +package cn.iocoder.yudao.module.trade.dal.dataobject.aftersale; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 交易售后,用于处理 {@link TradeOrderDO} 交易订单的退款退货流程 + * + * @author 芋道源码 + */ +@TableName(value = "trade_after_sale", autoResultMap = true) +@Data +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +public class TradeAfterSaleDO extends BaseDO { + + /** + * 售后编号,主键自增 + */ + private Long id; + /** + * 售后流水号 + * + * 例如说,1146347329394184195 + */ + private String no; + /** + * 退款状态 + * + * 枚举 {@link TradeAfterSaleStatusEnum} + */ + private Integer status; + /** + * 售后方式 + * + * 枚举 {@link TradeAfterSaleWayEnum} + */ + private Integer way; + /** + * 售后类型 + * + * 枚举 {@link TradeAfterSaleTypeEnum} + */ + private Integer type; + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 编号 + */ + private Long userId; + /** + * 申请原因 + * + * type = 退款,对应 trade_after_sale_refund_reason 类型 + * type = 退货退款,对应 trade_after_sale_refund_and_return_reason 类型 + */ + private String applyReason; + /** + * 补充描述 + */ + private String applyDescription; + /** + * 补充凭证图片 + * + * 数组,以逗号分隔 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List applyPicUrls; + + // ========== 交易订单相关 ========== + /** + * 交易订单编号 + * + * 关联 {@link TradeOrderDO#getId()} + */ + private Long orderId; + /** + * 订单流水号 + * + * 冗余 {@link TradeOrderDO#getNo()} + */ + private String orderNo; + /** + * 交易订单项编号 + * + * 关联 {@link TradeOrderItemDO#getId()} + */ + private Long orderItemId; + /** + * 商品 SPU 编号 + * + * 关联 ProductSpuDO 的 id 字段 + * 冗余 {@link TradeOrderItemDO#getSpuId()} + */ + private Long spuId; + /** + * 商品 SPU 名称 + * + * 关联 ProductSkuDO 的 name 字段 + * 冗余 {@link TradeOrderItemDO#getSpuName()} + */ + private String spuName; + /** + * 商品 SKU 编号 + * + * 关联 ProductSkuDO 的编号 + */ + private Long skuId; + /** + * 属性数组,JSON 格式 + * + * 冗余 {@link TradeOrderItemDO#getProperties()} + */ + @TableField(typeHandler = TradeOrderItemDO.PropertyTypeHandler.class) + private List properties; + /** + * 商品图片 + * + * 冗余 {@link TradeOrderItemDO#getPicUrl()} + */ + private String picUrl; + /** + * 退货商品数量 + */ + private Integer count; + + // ========== 审批相关 ========== + + /** + * 审批时间 + */ + private LocalDateTime auditTime; + /** + * 审批人 + * + * 关联 AdminUserDO 的 id 编号 + */ + private Long auditUserId; + /** + * 审批备注 + * + * 注意,只有审批不通过才会填写 + */ + private String auditReason; + + // ========== 退款相关 ========== + /** + * 退款金额,单位:分。 + */ + private Integer refundPrice; + /** + * 支付退款编号 + * + * 对接 pay-module-biz 支付服务的退款订单编号,即 PayRefundDO 的 id 编号 + */ + private Long payRefundId; + /** + * 退款时间 + */ + private LocalDateTime refundTime; + + // ========== 退货相关 ========== + /** + * 退货物流公司编号 + * + * 关联 LogisticsDO 的 id 编号 + */ + private Long logisticsId; + /** + * 退货物流单号 + */ + private String logisticsNo; + /** + * 退货时间 + */ + private LocalDateTime deliveryTime; + /** + * 收货时间 + */ + private LocalDateTime receiveTime; + /** + * 收货备注 + * + * 注意,只有拒绝收货才会填写 + */ + private String receiveReason; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java new file mode 100644 index 000000000..5aa627403 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java @@ -0,0 +1,83 @@ +package cn.iocoder.yudao.module.trade.dal.dataobject.aftersale; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 交易售后日志 DO + * + * // TODO 可优化:参考淘宝或者有赞:1)增加 action 表示什么操作;2)content 记录每个操作的明细 + * + * @author 芋道源码 + */ +@TableName("trade_after_sale_log") +@KeySequence("trade_after_sale_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class TradeAfterSaleLogDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + /** + * 用户编号 + * + * 关联 1:AdminUserDO 的 id 字段 + * 关联 2:MemberUserDO 的 id 字段 + */ + private Long userId; + /** + * 用户类型 + * + * 枚举 {@link UserTypeEnum} + */ + private Integer userType; + /** + * 售后编号 + * + * 关联 {@link TradeAfterSaleDO#getId()} + */ + private Long afterSaleId; + /** + * 订单编号 + * + * 关联 {@link TradeOrderDO#getId()} + */ + private Long orderId; + /** + * 订单项编号 + * + * 关联 {@link TradeOrderItemDO#getId()} + */ + private Long orderItemId; + /** + * 售后状态(之前) + * + * 枚举 {@link TradeAfterSaleStatusEnum} + */ + private Integer beforeStatus; + /** + * 售后状态(之后) + * + * 枚举 {@link TradeAfterSaleStatusEnum} + */ + private Integer afterStatus; + /** + * 操作明细 + */ + private String content; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java new file mode 100644 index 000000000..05fbb801d --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java @@ -0,0 +1,90 @@ +package cn.iocoder.yudao.module.trade.dal.dataobject.cart; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 购物车的商品信息 DO + * + * @author 芋道源码 + */ +@TableName("trade_cart_item") +@Data +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +public class TradeCartItemDO extends BaseDO { + + // ========= 基础字段 BEGIN ========= + + /** + * 编号,唯一自增 + */ + private Long id; + /** + * 是否选中 + */ + private Boolean selected; + + // ========= 基础字段 END ========= + + // ========= 买家信息 BEGIN ========= + + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 编号 + */ + private Long userId; + + // ========= 买家信息 END ========= + + // ========= 商品信息 BEGIN ========= + + /** + * 商品 SPU 编号 + * + * 关联 ProductSpuDO 的 id 编号 + */ + private Long spuId; + /** + * 商品 SKU 编号 + * + * 关联 ProductSkuDO 的 id 编号 + */ + private Long skuId; + /** + * 商品购买数量 + */ + private Integer count; + + // ========= 商品信息 END ========= + + // ========= 优惠信息 BEGIN ========= + +// /** +// * 商品营销活动编号 +// */ +// private Long activityId; // discount_id +// /** +// * 商品营销活动类型 +// */ +// private Integer activityType; + // TODO 芋艿:combination_id 拼团 ID + // TODO 芋艿:seckill_id 秒杀产品 ID + // TODO 芋艿:bargain_id 砍价 ID + + // ========= 优惠信息 END ========= + + // TODO 待确定字段:mf + // TODO 芋艿:distribution_card_no 推广员 + // TODO 芋艿:is_pay 未购买、已购买 + // TODO 芋艿:is_new 是否立即购买 + + // TODO 待确定字段: yv + // TODO isPay: 是否购买 + // TODO isNew:是否立即购买 + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java new file mode 100644 index 000000000..49d60ee37 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -0,0 +1,257 @@ +package cn.iocoder.yudao.module.trade.dal.dataobject.order; + +import cn.iocoder.yudao.framework.common.enums.TerminalEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO.OrderItem; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderDeliveryStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.time.LocalDateTime; + +/** + * 交易订单 DO + * + * @author 芋道源码 + */ +@TableName("trade_order") +@KeySequence("trade_order_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class TradeOrderDO extends BaseDO { + + // ========== 订单基本信息 ========== + /** + * 订单编号,主键自增 + */ + private Long id; + /** + * 订单流水号 + * + * 例如说,1146347329394184195 + */ + private String no; + /** + * 订单类型 + * + * 枚举 {@link TradeOrderTypeEnum} + */ + private Integer type; + /** + * 订单来源 + * + * 枚举 {@link TerminalEnum} + */ + private Integer terminal; + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 编号 + */ + private Long userId; + /** + * 用户 IP + */ + private String userIp; + /** + * 用户备注 + */ + private String userRemark; + /** + * 订单状态 + * + * 枚举 {@link TradeOrderStatusEnum} + */ + private Integer status; + /** + * 购买的商品数量 + */ + private Integer productCount; + /** + * 订单完成时间 + */ + private LocalDateTime finishTime; + /** + * 订单取消时间 + */ + private LocalDateTime cancelTime; + /** + * 取消类型 + * + * 枚举 {@link TradeOrderCancelTypeEnum} + */ + private Integer cancelType; + /** + * 商家备注 + */ + private String remark; + + // ========== 价格 + 支付基本信息 ========== + + // 价格文档 - 淘宝:https://open.taobao.com/docV3.htm?docId=108471&docType=1 + // 价格文档 - 京东到家:https://openo2o.jddj.com/api/getApiDetail/182/4d1494c5e7ac4679bfdaaed950c5bc7f.htm + // 价格文档 - 有赞:https://doc.youzanyun.com/detail/API/0/906 + + /** + * 支付订单编号 + * + * 对接 pay-module-biz 支付服务的支付订单编号,即 PayOrderDO 的 id 编号 + */ + private Long payOrderId; + /** + * 是否已支付 + * + * true - 已经支付过 + * false - 没有支付过 + */ + private Boolean payed; + /** + * 付款时间 + */ + private LocalDateTime payTime; + /** + * 支付渠道 + * + * 对应 PayChannelEnum 枚举 + */ + private String payChannelCode; + + /** + * 商品原价(总),单位:分 + * + * 基于 {@link TradeOrderItemDO#getOriginalPrice()} 求和 + * + * 对应 taobao 的 trade.total_fee 字段 + */ + private Integer originalPrice; + /** + * 订单原价(总),单位:分 + * + * 基于 {@link OrderItem#getPayPrice()} 求和 + * 和 {@link #originalPrice} 的差异:去除商品级优惠 + */ + private Integer orderPrice; + /** + * 订单优惠(总),单位:分 + * + * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。 + * + * 对应 taobao 的 order.discount_fee 字段 + */ + private Integer discountPrice; + /** + * 运费金额,单位:分 + */ + private Integer deliveryPrice; + /** + * 订单调价(总),单位:分 + * + * 正数,加价;负数,减价 + */ + private Integer adjustPrice; + /** + * 应付金额(总),单位:分 + * + * = {@link OrderItem#getPayPrice()} 求和 + * - {@link #couponPrice} + * - {@link #pointPrice} + * + {@link #deliveryPrice} + * - {@link #discountPrice} + * + {@link #adjustPrice} + */ + private Integer payPrice; + + // ========== 收件 + 物流基本信息 ========== + /** + * 配置模板的编号 + * + * 关联 DeliveryTemplateDO 的 id 编号 + */ + private Long deliveryTemplateId; + /** + * 发货物流公司编号 + */ + private Long logisticsId; + /** + * 发货物流单号 + */ + private String logisticsNo; + /** + * 发货状态 + * + * 枚举 {@link TradeOrderDeliveryStatusEnum} + */ + private Integer deliveryStatus; + /** + * 发货时间 + */ + private LocalDateTime deliveryTime; + + /** + * 收货时间 + */ + private LocalDateTime receiveTime; + /** + * 收件人名称 + */ + private String receiverName; + /** + * 收件人手机 + */ + private String receiverMobile; + /** + * 收件人地区编号 + */ + private Integer receiverAreaId; + /** + * 收件人邮编 + */ + private Integer receiverPostCode; + /** + * 收件人详细地址 + */ + private String receiverDetailAddress; + + // ========== 售后基本信息 ========== + /** + * 收货状态 + * + * 枚举 {@link TradeOrderAfterSaleStatusEnum} + */ + private Integer afterSaleStatus; + /** + * 退款金额,单位:分 + * + * 注意,退款并不会影响 {@link #payPrice} 实际支付金额 + * 也就说,一个订单最终产生多少金额的收入 = payPrice - refundPrice + */ + private Integer refundPrice; + + // ========== 营销基本信息 ========== + /** + * 优惠劵编号 + */ + private Long couponId; + /** + * 优惠劵减免金额,单位:分 + * + * 对应 taobao 的 trade.coupon_fee 字段 + */ + private Integer couponPrice; + /** + * 积分抵扣的金额,单位:分 + * + * 对应 taobao 的 trade.point_fee 字段 + */ + private Integer pointPrice; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java new file mode 100644 index 000000000..f8438030b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java @@ -0,0 +1,190 @@ +package cn.iocoder.yudao.module.trade.dal.dataobject.order; + +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + * 交易订单项 DO + * + * @author 芋道源码 + */ +@TableName(value = "trade_order_item", autoResultMap = true) +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +public class TradeOrderItemDO extends BaseDO { + + // ========== 订单项基本信息 ========== + /** + * 编号 + */ + private Long id; + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 编号 + */ + private Long userId; + /** + * 订单编号 + * + * 关联 {@link TradeOrderDO#getId()} + */ + private Long orderId; + + // ========== 商品基本信息; 冗余较多字段,减少关联查询 ========== + /** + * 商品 SPU 编号 + * + * 关联 ProductSkuDO 的 spuId 编号 + */ + private Long spuId; + /** + * 商品 SPU 名称 + * + * 冗余 ProductSkuDO 的 spuName 编号 + */ + private String spuName; + /** + * 商品 SKU 编号 + * + * 关联 ProductSkuDO 的 id 编号 + */ + private Long skuId; + /** + * 属性数组,JSON 格式 + * + * 冗余 ProductSkuDO 的 properties 字段 + */ + @TableField(typeHandler = PropertyTypeHandler.class) + private List properties; + /** + * 商品图片 + */ + private String picUrl; + /** + * 购买数量 + */ + private Integer count; +// /** +// * 是否评论 TODO +// * +// * false - 未评论 +// * true - 已评论 +// */ +// private Boolean commented; + + // ========== 价格 + 支付基本信息 ========== + + /** + * 商品原价(总),单位:分 + * + * = {@link #originalUnitPrice} * {@link #getCount()} + */ + private Integer originalPrice; + /** + * 商品原价(单),单位:分 + * + * 对应 ProductSkuDO 的 price 字段 + * 对应 taobao 的 order.price 字段 + */ + private Integer originalUnitPrice; + /** + * 商品优惠(总),单位:分 + * + * 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元 + * + * 对应 taobao 的 order.discount_fee 字段 + */ + private Integer discountPrice; + /** + * 子订单实付金额,不算主订单分摊金额,单位:分 + * + * = {@link #originalPrice} + * - {@link #discountPrice} + * + * 对应 taobao 的 order.payment 字段 + */ + private Integer payPrice; + + /** + * 子订单分摊金额(总),单位:分 + * 需要分摊 {@link TradeOrderDO#getDiscountPrice()}、{@link TradeOrderDO#getCouponPrice()}、{@link TradeOrderDO#getPointPrice()} + * + * 对应 taobao 的 order.part_mjz_discount 字段 + * 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。 + */ + private Integer orderPartPrice; + /** + * 分摊后子订单实付金额(总),单位:分 + * + * = {@link #payPrice} + * - {@link #orderPartPrice} + * + * 对应 taobao 的 divide_order_fee 字段 + */ + private Integer orderDividePrice; + + // ========== 营销基本信息 ========== + + // TODO 芋艿:在捉摸一下 + + // ========== 售后基本信息 ========== + /** + * 售后状态 + * + * 枚举 {@link TradeOrderItemAfterSaleStatusEnum} + * + * @see TradeAfterSaleDO + */ + private Integer afterSaleStatus; + + /** + * 商品属性 + */ + @Data + public static class Property implements Serializable { + + /** + * 属性编号 + * + * 关联 ProductPropertyDO 的 id 编号 + */ + private Long propertyId; + /** + * 属性值编号 + * + * 关联 ProductPropertyValueDO 的 id 编号 + */ + private Long valueId; + + } + + // TODO @芋艿:可以找一些新的思路 + public static class PropertyTypeHandler extends AbstractJsonTypeHandler> { + + @Override + protected List parse(String json) { + return JsonUtils.parseArray(json, Property.class); + } + + @Override + protected String toJson(List obj) { + return JsonUtils.toJsonString(obj); + } + + } + +} + diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleLogMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleLogMapper.java new file mode 100644 index 000000000..b92ce075f --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleLogMapper.java @@ -0,0 +1,9 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.aftersale; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface TradeAfterSaleLogMapper extends BaseMapperX { +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java new file mode 100644 index 000000000..175d7d2b0 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.aftersale; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface TradeAfterSaleMapper extends BaseMapperX { + + default PageResult selectPage(TradeAfterSalePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(TradeAfterSaleDO::getNo, reqVO.getNo()) + .eqIfPresent(TradeAfterSaleDO::getStatus, reqVO.getStatus()) + .eqIfPresent(TradeAfterSaleDO::getType, reqVO.getType()) + .eqIfPresent(TradeAfterSaleDO::getWay, reqVO.getWay()) + .likeIfPresent(TradeAfterSaleDO::getOrderNo, reqVO.getOrderNo()) + .likeIfPresent(TradeAfterSaleDO::getSpuName, reqVO.getSpuName()) + .betweenIfPresent(TradeAfterSaleDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(TradeAfterSaleDO::getId)); + } + + default int updateByIdAndStatus(Long id, Integer status, TradeAfterSaleDO update) { + return update(update, new LambdaUpdateWrapper() + .eq(TradeAfterSaleDO::getId, id).eq(TradeAfterSaleDO::getStatus, status)); + } + + default TradeAfterSaleDO selectByPayRefundId(Long payRefundId) { + return selectOne(TradeAfterSaleDO::getPayRefundId, payRefundId); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java new file mode 100644 index 000000000..fa6adbf41 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.cart; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +@Mapper +public interface TradeCartItemMapper extends BaseMapperX { + + default TradeCartItemDO selectByUserIdAndSkuId(Long userId, Long skuId) { + return selectOne(TradeCartItemDO::getUserId, userId, + TradeCartItemDO::getSkuId, skuId); + } + + default List selectListByUserIdAndSkuIds(Long userId, Collection skuIds) { + return selectList(new LambdaQueryWrapper().eq(TradeCartItemDO::getUserId, userId) + .in(TradeCartItemDO::getSkuId, skuIds)); + } + + default void updateByIds(Collection ids, TradeCartItemDO updateObject) { + update(updateObject, new LambdaQueryWrapper().in(TradeCartItemDO::getId, ids)); + } + + default Integer selectSumByUserId(Long userId) { + // SQL sum 查询 + List> result = selectMaps(new QueryWrapper() + .select("SUM(count) AS sumCount") + .eq("user_id", userId)); + // 获得数量 + return CollUtil.isNotEmpty(result) ? MapUtil.getInt(result.get(0), "sumCount") : 0; + } + + default List selectListByUserId(Long userId, Boolean selected) { + return selectList(new LambdaQueryWrapperX().eq(TradeCartItemDO::getUserId, userId) + .eqIfPresent(TradeCartItemDO::getSelected, selected)); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java new file mode 100644 index 000000000..edb45fb62 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.order; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +@Mapper +public interface TradeOrderItemMapper extends BaseMapperX { + + default int updateAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus) { + return update(new TradeOrderItemDO().setAfterSaleStatus(newAfterSaleStatus), + new LambdaUpdateWrapper<>(new TradeOrderItemDO().setId(id).setAfterSaleStatus(oldAfterSaleStatus))); + } + + default List selectListByOrderId(Long orderId) { + return selectList(TradeOrderItemDO::getOrderId, orderId); + } + + default List selectListByOrderId(Collection orderIds) { + return selectList(TradeOrderItemDO::getOrderId, orderIds); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java new file mode 100644 index 000000000..7be224744 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.order; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Set; + +@Mapper +public interface TradeOrderMapper extends BaseMapperX { + + default int updateByIdAndStatus(Long id, Integer status, TradeOrderDO update) { + return update(update, new LambdaUpdateWrapper() + .eq(TradeOrderDO::getId, id).eq(TradeOrderDO::getStatus, status)); + } + + default TradeOrderDO selectByIdAndUserId(Long id, Long userId) { + return selectOne(TradeOrderDO::getId, id, TradeOrderDO::getUserId, userId); + } + + default PageResult selectPage(TradeOrderPageReqVO reqVO, Set userIds) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(TradeOrderDO::getNo, reqVO.getNo()) + .eqIfPresent(TradeOrderDO::getUserId, reqVO.getUserId()) + .inIfPresent(TradeOrderDO::getUserId, userIds) + .likeIfPresent(TradeOrderDO::getReceiverName, reqVO.getReceiverName()) + .likeIfPresent(TradeOrderDO::getReceiverMobile, reqVO.getReceiverMobile()) + .eqIfPresent(TradeOrderDO::getType, reqVO.getType()) + .eqIfPresent(TradeOrderDO::getStatus, reqVO.getStatus()) + .eqIfPresent(TradeOrderDO::getPayChannelCode, reqVO.getPayChannelCode()) + .betweenIfPresent(TradeOrderDO::getCreateTime, reqVO.getCreateTime())); + } + + default PageResult selectPage(AppTradeOrderPageReqVO reqVO, Long userId) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eq(TradeOrderDO::getUserId, userId) + .eqIfPresent(TradeOrderDO::getStatus, reqVO.getStatus()) + .orderByDesc(TradeOrderDO::getId)); // TODO 芋艿:未来不同的 status,不同的排序 + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/package-info.java new file mode 100644 index 000000000..37e0ba7d6 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/package-info.java @@ -0,0 +1,4 @@ +/** + * TODO 占位 + */ +package cn.iocoder.yudao.module.trade.dal.mysql; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java new file mode 100644 index 000000000..715169275 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.trade.framework.order.config; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +// TODO @LeeYan9: 可以直接给 TradeOrderProperties 一个 @Component生效哈 +/** + * @author LeeYan9 + * @since 2022-09-15 + */ +@Configuration +@EnableConfigurationProperties(TradeOrderProperties.class) +public class TradeOrderConfig { +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java new file mode 100644 index 000000000..4d584f4c9 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.trade.framework.order.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotNull; +import java.time.Duration; + +/** + * 交易订单的配置项 + * + * @author LeeYan9 + * @since 2022-09-15 + */ +@ConfigurationProperties(prefix = "yudao.trade.order") +@Data +@Validated +public class TradeOrderProperties { + + /** + * 应用编号 + */ + @NotNull(message = "应用编号不能为空") + private Long appId; + + /** + * 支付超时时间 + */ + @NotNull(message = "支付超时时间不能为空") + private Duration expireTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/package-info.java new file mode 100644 index 000000000..02e4c81bd --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/package-info.java @@ -0,0 +1,6 @@ +/** + * 属于 order 模块的 framework 封装 + * + * @author 芋道源码 + */ +package cn.iocoder.yudao.module.trade.framework; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/web/config/OrderWebConfiguration.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/web/config/OrderWebConfiguration.java new file mode 100644 index 000000000..d979dbace --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/web/config/OrderWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.trade.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * order 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class OrderWebConfiguration { + + /** + * order 模块的 API 分组 + */ + @Bean + public GroupedOpenApi orderGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("order"); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/web/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/web/package-info.java new file mode 100644 index 000000000..d383c9eca --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * order 模块的 web 配置 + */ +package cn.iocoder.yudao.module.trade.framework.web; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/package-info.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/package-info.java new file mode 100644 index 000000000..eba4aa766 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/package-info.java @@ -0,0 +1,8 @@ +/** + * trade 模块,product 模块,主要实现商品相关功能 + * 例如:品牌、商品分类、spu、sku等功能。 + * + * 1. Controller URL:以 /product/ 开头,避免和其它 Module 冲突 + * 2. DataObject 表名:以 product_ 开头,方便在数据库中区分 + */ +package cn.iocoder.yudao.module.trade; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java new file mode 100644 index 000000000..d0d86c033 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java @@ -0,0 +1,94 @@ +package cn.iocoder.yudao.module.trade.service.aftersale; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO; +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; + +/** + * 交易售后 Service 接口 + * + * @author 芋道源码 + */ +public interface TradeAfterSaleService { + + /** + * 获得交易售后分页 + * + * @param pageReqVO 分页查询 + * @return 交易售后分页 + */ + PageResult getAfterSalePage(TradeAfterSalePageReqVO pageReqVO); + + /** + * 【会员】创建交易售后 + *

+ * 一般是用户发起售后请求 + * + * @param userId 会员用户编号 + * @param createReqVO 创建 Request 信息 + * @return 交易售后编号 + */ + Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO); + + /** + * 【管理员】同意交易售后 + * + * @param userId 管理员用户编号 + * @param id 交易售后编号 + */ + void agreeAfterSale(Long userId, Long id); + + /** + * 【管理员】拒绝交易售后 + * + * @param userId 管理员用户编号 + * @param auditReqVO 审批 Request 信息 + */ + void disagreeAfterSale(Long userId, TradeAfterSaleDisagreeReqVO auditReqVO); + + /** + * 【会员】退回货物 + * + * @param userId 会员用户编号 + * @param deliveryReqVO 退货 Request 信息 + */ + void deliveryAfterSale(Long userId, AppTradeAfterSaleDeliveryReqVO deliveryReqVO); + + /** + * 【管理员】确认收货 + * + * @param userId 管理员编号 + * @param id 交易售后编号 + */ + void receiveAfterSale(Long userId, Long id); + + /** + * 【管理员】拒绝收货 + * + * @param userId 管理员用户编号 + * @param refuseReqVO 拒绝收货 Request 信息 + */ + void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO refuseReqVO); + + /** + * 【管理员】确认退款 + * + * @param userId 管理员用户编号 + * @param userIp 管理员用户 IP + * @param id 售后编号 + */ + void refundAfterSale(Long userId, String userIp, Long id); + + /** + * 【会员】取消售后 + * + * @param userId 会员用户编号 + * @param id 交易售后编号 + */ + void cancelAfterSale(Long userId, Long id); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java new file mode 100644 index 000000000..2da892d61 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java @@ -0,0 +1,392 @@ +package cn.iocoder.yudao.module.trade.service.aftersale; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; +import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; +import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO; +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleDeliveryReqVO; +import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleLogMapper; +import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleMapper; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; +import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.support.TransactionSynchronizationManager; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; + +/** + * 交易售后 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class TradeAfterSaleServiceImpl implements TradeAfterSaleService { + + @Resource + private TradeOrderService tradeOrderService; + + @Resource + private TradeAfterSaleMapper tradeAfterSaleMapper; + @Resource + private TradeAfterSaleLogMapper tradeAfterSaleLogMapper; + + @Resource + private PayRefundApi payRefundApi; + + @Resource + private TradeOrderProperties tradeOrderProperties; + + @Override + public PageResult getAfterSalePage(TradeAfterSalePageReqVO pageReqVO) { + return tradeAfterSaleMapper.selectPage(pageReqVO); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createAfterSale(Long userId, AppTradeAfterSaleCreateReqVO createReqVO) { + // 第一步,前置校验 + TradeOrderItemDO tradeOrderItem = validateOrderItemApplicable(userId, createReqVO); + + // 第二步,存储交易售后 + TradeAfterSaleDO afterSale = createAfterSale(createReqVO, tradeOrderItem); + return afterSale.getId(); + } + + /** + * 校验交易订单项是否可以申请售后 + * + * @param userId 用户编号 + * @param createReqVO 售后创建信息 + * @return 交易订单项 + */ + private TradeOrderItemDO validateOrderItemApplicable(Long userId, AppTradeAfterSaleCreateReqVO createReqVO) { + // 校验订单项存在 + TradeOrderItemDO orderItem = tradeOrderService.getOrderItem(userId, createReqVO.getOrderItemId()); + if (orderItem == null) { + throw exception(ORDER_ITEM_NOT_FOUND); + } + + // 已申请售后,不允许再发起售后申请 + if (!TradeOrderItemAfterSaleStatusEnum.isNone(orderItem.getAfterSaleStatus())) { + throw exception(AFTER_SALE_CREATE_FAIL_ORDER_ITEM_APPLIED); + } + + // 申请的退款金额,不能超过商品的价格 + if (createReqVO.getRefundPrice() > orderItem.getOrderDividePrice()) { + throw exception(AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR); + } + + // 校验订单存在 + TradeOrderDO order = tradeOrderService.getOrder(userId, orderItem.getOrderId()); + if (order == null) { + throw exception(ORDER_NOT_FOUND); + } + // TODO 芋艿:超过一定时间,不允许售后 + // 已取消,无法发起售后 + if (TradeOrderStatusEnum.isCanceled(order.getStatus())) { + throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_CANCELED); + } + // 未支付,无法发起售后 + if (!TradeOrderStatusEnum.havePaid(order.getStatus())) { + throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_PAID); + } + // 如果是【退货退款】的情况,需要额外校验是否发货 + if (createReqVO.getWay().equals(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay()) + && !TradeOrderStatusEnum.haveDelivered(order.getStatus())) { + throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED); + } + return orderItem; + } + + private TradeAfterSaleDO createAfterSale(AppTradeAfterSaleCreateReqVO createReqVO, + TradeOrderItemDO orderItem) { + // 创建售后单 + TradeAfterSaleDO afterSale = TradeAfterSaleConvert.INSTANCE.convert(createReqVO, orderItem); + afterSale.setNo(RandomUtil.randomString(10)); // TODO 芋艿:优化 no 生成逻辑 + afterSale.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus()); + // 标记是售中还是售后 + TradeOrderDO order = tradeOrderService.getOrder(orderItem.getUserId(), orderItem.getOrderId()); + afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索 + afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus()) + ? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType()); + // TODO 退还积分 + tradeAfterSaleMapper.insert(afterSale); + + // 更新交易订单项的售后状态 + tradeOrderService.updateOrderItemAfterSaleStatus(orderItem.getId(), + TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), + TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), null); + + // 记录售后日志 + createAfterSaleLog(orderItem.getUserId(), UserTypeEnum.MEMBER.getValue(), + afterSale, null, afterSale.getStatus()); + + // TODO 发送售后消息 + return afterSale; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void agreeAfterSale(Long userId, Long id) { + // 校验售后单存在,并状态未审批 + TradeAfterSaleDO afterSale = validateAfterSaleAuditable(id); + + // 更新售后单的状态 + // 情况一:退款:标记为 WAIT_REFUND 状态。后续等退款发起成功后,在标记为 COMPLETE 状态 + // 情况二:退货退款:需要等用户退货后,才能发起退款 + Integer newStatus = afterSale.getType().equals(TradeAfterSaleWayEnum.REFUND.getWay()) ? + TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus() : TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus(); + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO() + .setStatus(newStatus).setAuditUserId(userId).setAuditTime(LocalDateTime.now())); + + // 记录售后日志 + createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), + afterSale, afterSale.getStatus(), newStatus); + + // TODO 发送售后消息 + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void disagreeAfterSale(Long userId, TradeAfterSaleDisagreeReqVO auditReqVO) { + // 校验售后单存在,并状态未审批 + TradeAfterSaleDO afterSale = validateAfterSaleAuditable(auditReqVO.getId()); + + // 更新售后单的状态 + Integer newStatus = TradeAfterSaleStatusEnum.SELLER_DISAGREE.getStatus(); + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.APPLY.getStatus(), new TradeAfterSaleDO() + .setStatus(newStatus).setAuditUserId(userId).setAuditTime(LocalDateTime.now()) + .setAuditReason(auditReqVO.getAuditReason())); + + // 记录售后日志 + createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), + afterSale, afterSale.getStatus(), newStatus); + + // TODO 发送售后消息 + + // 更新交易订单项的售后状态为【未申请】 + tradeOrderService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(), + TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), + TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null); + } + + /** + * 校验售后单是否可审批(同意售后、拒绝售后) + * + * @param id 售后编号 + * @return 售后单 + */ + private TradeAfterSaleDO validateAfterSaleAuditable(Long id) { + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); + if (afterSale == null) { + throw exception(AFTER_SALE_NOT_FOUND); + } + if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus())) { + throw exception(AFTER_SALE_AUDIT_FAIL_STATUS_NOT_APPLY); + } + return afterSale; + } + + private void updateAfterSaleStatus(Long id, Integer status, TradeAfterSaleDO updateObj) { + int updateCount = tradeAfterSaleMapper.updateByIdAndStatus(id, status, updateObj); + if (updateCount == 0) { + throw exception(AFTER_SALE_UPDATE_STATUS_FAIL); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deliveryAfterSale(Long userId, AppTradeAfterSaleDeliveryReqVO deliveryReqVO) { + // 校验售后单存在,并状态未退货 + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(deliveryReqVO.getId()); + if (afterSale == null) { + throw exception(AFTER_SALE_NOT_FOUND); + } + if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus())) { + throw exception(AFTER_SALE_DELIVERY_FAIL_STATUS_NOT_SELLER_AGREE); + } + + // 更新售后单的物流信息 + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus(), new TradeAfterSaleDO() + .setStatus(TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus()) + .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()) + .setDeliveryTime(deliveryReqVO.getDeliveryTime())); + + // 记录售后日志 + createAfterSaleLog(userId, UserTypeEnum.MEMBER.getValue(), + afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus()); + + // TODO 发送售后消息 + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void receiveAfterSale(Long userId, Long id) { + // 校验售后单存在,并状态为已退货 + TradeAfterSaleDO afterSale = validateAfterSaleReceivable(id); + + // 更新售后单的状态 + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new TradeAfterSaleDO() + .setStatus(TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus()).setReceiveTime(LocalDateTime.now())); + + // 记录售后日志 + createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), + afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus()); + + // TODO 发送售后消息 + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void refuseAfterSale(Long userId, TradeAfterSaleRefuseReqVO refuseReqVO) { + // 校验售后单存在,并状态为已退货 + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(refuseReqVO.getId()); + if (afterSale == null) { + throw exception(AFTER_SALE_NOT_FOUND); + } + if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) { + throw exception(AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY); + } + + // 更新售后单的状态 + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus(), new TradeAfterSaleDO() + .setStatus(TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()).setReceiveTime(LocalDateTime.now()) + .setReceiveReason(refuseReqVO.getRefuseMemo())); + + // 记录售后日志 + createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), + afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()); + + // TODO 发送售后消息 + + // 更新交易订单项的售后状态为【未申请】 + tradeOrderService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(), + TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), + TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null); + } + + /** + * 校验售后单是否可收货,即处于买家已发货 + * + * @param id 售后编号 + * @return 售后单 + */ + private TradeAfterSaleDO validateAfterSaleReceivable(Long id) { + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); + if (afterSale == null) { + throw exception(AFTER_SALE_NOT_FOUND); + } + if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_DELIVERY.getStatus())) { + throw exception(AFTER_SALE_CONFIRM_FAIL_STATUS_NOT_BUYER_DELIVERY); + } + return afterSale; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void refundAfterSale(Long userId, String userIp, Long id) { + // 校验售后单的状态,并状态待退款 + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectByPayRefundId(id); + if (afterSale == null) { + throw exception(AFTER_SALE_NOT_FOUND); + } + if (ObjectUtil.notEqual(afterSale.getStatus(), TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus())) { + throw exception(AFTER_SALE_REFUND_FAIL_STATUS_NOT_WAIT_REFUND); + } + + // 发起退款单。注意,需要在事务提交后,再进行发起,避免重复发起 + createPayRefund(userIp, afterSale); + + // 更新售后单的状态为【已完成】 + updateAfterSaleStatus(afterSale.getId(), TradeAfterSaleStatusEnum.WAIT_REFUND.getStatus(), new TradeAfterSaleDO() + .setStatus(TradeAfterSaleStatusEnum.COMPLETE.getStatus()).setRefundTime(LocalDateTime.now())); + + // 记录售后日志 + createAfterSaleLog(userId, UserTypeEnum.ADMIN.getValue(), + afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.COMPLETE.getStatus()); + + // TODO 发送售后消息 + + // 更新交易订单项的售后状态为【已完成】 + tradeOrderService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(), + TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), + TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus(), afterSale.getRefundPrice()); + } + + private void createPayRefund(String userIp, TradeAfterSaleDO afterSale) { + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + + @Override + public void afterCommit() { + // 创建退款单 + PayRefundCreateReqDTO createReqDTO = TradeAfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties); + Long payRefundId = payRefundApi.createPayRefund(createReqDTO); + // 更新售后单的退款单号 + tradeAfterSaleMapper.updateById(new TradeAfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId)); + } + }); + } + + @Override + public void cancelAfterSale(Long userId, Long id) { + // 校验售后单的状态,并状态待退款 + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectByPayRefundId(id); + if (afterSale == null) { + throw exception(AFTER_SALE_NOT_FOUND); + } + if (ObjectUtils.equalsAny(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus(), + TradeAfterSaleStatusEnum.SELLER_AGREE.getStatus())) { + throw exception(AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE); + } + + // 更新售后单的状态为【已取消】 + updateAfterSaleStatus(afterSale.getId(), afterSale.getStatus(), new TradeAfterSaleDO() + .setStatus(TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus())); + + // 记录售后日志 + createAfterSaleLog(userId, UserTypeEnum.MEMBER.getValue(), + afterSale, afterSale.getStatus(), TradeAfterSaleStatusEnum.BUYER_CANCEL.getStatus()); + + // TODO 发送售后消息 + + // 更新交易订单项的售后状态为【未申请】 + tradeOrderService.updateOrderItemAfterSaleStatus(afterSale.getOrderItemId(), + TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), + TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null); + } + + private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale, + Integer beforeStatus, Integer afterStatus) { + TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO().setUserId(userId).setUserType(userType) + .setAfterSaleId(afterSale.getId()).setOrderId(afterSale.getOrderId()) + .setOrderItemId(afterSale.getOrderItemId()).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus) + .setContent(TradeAfterSaleStatusEnum.valueOf(afterStatus).getContent()); + tradeAfterSaleLogMapper.insert(afterSaleLog); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java new file mode 100644 index 000000000..3f46f5102 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java @@ -0,0 +1,66 @@ +package cn.iocoder.yudao.module.trade.service.cart; + +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO; + +import javax.validation.Valid; +import java.util.Collection; + +/** + * 购物车 Service 接口 + * + * @author 芋道源码 + */ +public interface TradeCartService { + + /** + * 添加商品到购物车 + * + * @param userId 用户编号 + * @param addCountReqVO 添加信息 + */ + void addCartItemCount(Long userId, @Valid AppTradeCartItemAddCountReqVO addCountReqVO); + + /** + * 更新购物车商品数量 + * + * @param userId 用户编号 + * @param updateCountReqVO 更新信息 + */ + void updateCartItemCount(Long userId, AppTradeCartItemUpdateCountReqVO updateCountReqVO); + + /** + * 更新购物车商品是否选中 + * + * @param userId 用户编号 + * @param updateSelectedReqVO 更新信息 + */ + void updateCartItemSelected(Long userId, AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO); + + /** + * 删除购物车商品 + * + * @param userId 用户编号 + * @param skuIds SKU 编号的数组 + */ + void deleteCartItems(Long userId, Collection skuIds); + + /** + * 查询用户在购物车中的商品数量 + * + * @param userId 用户编号 + * @return 商品数量 + */ + Integer getCartCount(Long userId); + + /** + * 查询用户的购物车详情 + * + * @param userId 用户编号 + * @return 购物车详情 + */ + AppTradeCartDetailRespVO getCartDetail(Long userId); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java new file mode 100644 index 000000000..ae0301e83 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java @@ -0,0 +1,184 @@ +package cn.iocoder.yudao.module.trade.service.cart; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.promotion.api.price.PriceApi; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemAddCountReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateCountReqVO; +import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartItemUpdateSelectedReqVO; +import cn.iocoder.yudao.module.trade.convert.cart.TradeCartConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO; +import cn.iocoder.yudao.module.trade.dal.mysql.cart.TradeCartItemMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.CARD_ITEM_NOT_FOUND; + +/** + * 购物车 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class TradeCartServiceImpl implements TradeCartService { + + @Resource + private TradeCartItemMapper cartItemMapper; + + @Resource + private ProductSkuApi productSkuApi; + @Resource + private PriceApi priceApi; + + @Override + public void addCartItemCount(Long userId, AppTradeCartItemAddCountReqVO addCountReqVO) { + Long skuId = addCountReqVO.getSkuId(); + Integer count = addCountReqVO.getCount(); + // 查询 CartItemDO + TradeCartItemDO tradeItem = cartItemMapper.selectByUserIdAndSkuId(userId, addCountReqVO.getSkuId()); + + // 存在,则进行数量更新 + if (tradeItem != null) { + checkProductSku(skuId, tradeItem.getCount() + count); + cartItemMapper.updateById(new TradeCartItemDO().setId(tradeItem.getId()) + .setSelected(true).setCount(tradeItem.getCount() + count)); + return; + } + + // 不存在,则进行插入 + ProductSkuRespDTO sku = checkProductSku(skuId, count); + cartItemMapper.insert(new TradeCartItemDO().setUserId(userId).setSpuId(sku.getSpuId()).setSkuId(sku.getId()) + .setSelected(true).setCount(count)); + } + + @Override + public void updateCartItemCount(Long userId, AppTradeCartItemUpdateCountReqVO updateCountReqVO) { + // 校验 TradeCartItemDO 存在 + TradeCartItemDO tradeItem = cartItemMapper.selectByUserIdAndSkuId(userId, updateCountReqVO.getSkuId()); + if (tradeItem == null) { + throw exception(CARD_ITEM_NOT_FOUND); + } + // 校验商品 SKU + checkProductSku(updateCountReqVO.getSkuId(), updateCountReqVO.getCount()); + + // 更新数量 + cartItemMapper.updateById(new TradeCartItemDO().setId(tradeItem.getId()).setCount(updateCountReqVO.getCount())); + } + + @Override + public void updateCartItemSelected(Long userId, AppTradeCartItemUpdateSelectedReqVO updateSelectedReqVO) { + // 查询 CartItemDO 列表 + List cartItems = cartItemMapper.selectListByUserIdAndSkuIds(userId, updateSelectedReqVO.getSkuIds()); + if (CollUtil.isEmpty(cartItems)) { + return; + } + + // 更新选中 + cartItemMapper.updateByIds(CollectionUtils.convertList(cartItems, TradeCartItemDO::getId), + new TradeCartItemDO().setSelected(updateSelectedReqVO.getSelected())); + } + + /** + * 购物车删除商品 + * + * @param userId 用户编号 + * @param skuIds 商品 SKU 编号的数组 + */ + @Override + public void deleteCartItems(Long userId, Collection skuIds) { + // 查询 CartItemDO 列表 + List cartItems = cartItemMapper.selectListByUserIdAndSkuIds(userId, skuIds); + if (CollUtil.isEmpty(cartItems)) { + return; + } + + // 批量标记删除 + cartItemMapper.deleteBatchIds(CollectionUtils.convertSet(cartItems, TradeCartItemDO::getId)); + } + + @Override + public Integer getCartCount(Long userId) { + return cartItemMapper.selectSumByUserId(userId); + } + + @Override + public AppTradeCartDetailRespVO getCartDetail(Long userId) { + // 获得购物车的商品 + List cartItems = cartItemMapper.selectListByUserId(userId, null); + // 如果未空,则返回空结果 + if (CollUtil.isEmpty(cartItems)) { + return TradeCartConvert.INSTANCE.buildEmptyAppTradeCartDetailRespVO(); + } + + // 调用价格服务,计算价格 + PriceCalculateRespDTO priceCalculate = priceApi.calculatePrice(TradeCartConvert.INSTANCE.convert(userId, cartItems)); + + // 转换返回 + Map cartItemMap = convertMap(cartItems, TradeCartItemDO::getSkuId); + Map orderItemMap = convertMap(priceCalculate.getOrder().getItems(), + PriceCalculateRespDTO.OrderItem::getSkuId); + List itemGroups = new ArrayList<>(cartItems.size()); + // ① 场景一,营销活动,订单级别 TODO 芋艿:待测试 + priceCalculate.getPromotions().stream().filter(promotion -> PromotionLevelEnum.ORDER.getLevel().equals(promotion.getLevel())) + .forEach(promotion -> { + AppTradeCartDetailRespVO.ItemGroup itemGroup = new AppTradeCartDetailRespVO.ItemGroup().setItems(new ArrayList<>()) + .setPromotion(TradeCartConvert.INSTANCE.convert(promotion)); + itemGroups.add(itemGroup); + promotion.getItems().forEach(promotionItem -> { + PriceCalculateRespDTO.OrderItem orderItem = orderItemMap.remove(promotionItem.getSkuId()); + Assert.notNull(orderItem, "商品 SKU({}) 对应的订单项不能为空", promotionItem.getSkuId()); + TradeCartItemDO cartItem = cartItemMap.get(orderItem.getSkuId()); + itemGroup.getItems().add(TradeCartConvert.INSTANCE.convert(orderItem, cartItem)); // TODO spu + }); + }); + // ② 场景二,营销活动,商品级别 + orderItemMap.values().forEach(orderItem -> { + AppTradeCartDetailRespVO.ItemGroup itemGroup = new AppTradeCartDetailRespVO.ItemGroup().setItems(new ArrayList<>(1)).setPromotion(null); + itemGroups.add(itemGroup); + TradeCartItemDO cartItem = cartItemMap.get(orderItem.getSkuId()); + itemGroup.getItems().add(TradeCartConvert.INSTANCE.convert(orderItem, cartItem)); // TODO spu + }); + return new AppTradeCartDetailRespVO().setItemGroups(itemGroups) + .setOrder(TradeCartConvert.INSTANCE.convert(priceCalculate.getOrder())); + } + + /** + * 校验商品 SKU 是否合法 + * 1. 是否存在 + * 2. 是否下架 + * 3. 库存不足 + * + * @param skuId 商品 SKU 编号 + * @param count 商品数量 + * @return 商品 SKU + */ + private ProductSkuRespDTO checkProductSku(Long skuId, Integer count) { + ProductSkuRespDTO sku = productSkuApi.getSku(skuId); + if (sku == null || CommonStatusEnum.DISABLE.getStatus().equals(sku.getStatus())) { + throw exception(SKU_NOT_EXISTS); + } + if (count > sku.getStock()) { + throw exception(SKU_STOCK_NOT_ENOUGH); + } + return sku; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java new file mode 100644 index 000000000..086f65edd --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java @@ -0,0 +1,142 @@ +package cn.iocoder.yudao.module.trade.service.order; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; + +import java.util.Collection; +import java.util.List; + +import static java.util.Collections.singleton; + +/** + * 交易订单 Service 接口 + * + * @author LeeYan9 + * @since 2022-08-26 + */ +public interface TradeOrderService { + + // =================== Order =================== + + /** + * 【会员】创建交易订单 + * + * @param userId 登录用户 + * @param userIp 用户 IP 地址 + * @param createReqVO 创建交易订单请求模型 + * @return 交易订单的编号 + */ + Long createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO); + + /** + * 更新交易订单已支付 + * + * @param id 交易订单编号 + * @param payOrderId 支付订单编号 + */ + void updateOrderPaid(Long id, Long payOrderId); + + /** + * 【管理员】发货交易订单 + * + * @param userId 管理员编号 + * @param deliveryReqVO 发货请求 + */ + void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO); + + /** + * 【会员】收货交易订单 + * + * @param userId 用户编号 + * @param id 订单编号 + */ + void receiveOrder(Long userId, Long id); + + /** + * 获得指定编号的交易订单 + * + * @param id 交易订单编号 + * @return 交易订单 + */ + TradeOrderDO getOrder(Long id); + + /** + * 获得指定用户,指定的交易订单 + * + * @param userId 用户编号 + * @param id 交易订单编号 + * @return 交易订单 + */ + TradeOrderDO getOrder(Long userId, Long id); + + /** + * 【管理员】获得交易订单分页 + * + * @param reqVO 分页请求 + * @return 交易订单 + */ + PageResult getOrderPage(TradeOrderPageReqVO reqVO); + + /** + * 【会员】获得交易订单分页 + * + * @param userId 用户编号 + * @param reqVO 分页请求 + * @return 交易订单 + */ + PageResult getOrderPage(Long userId, AppTradeOrderPageReqVO reqVO); + + // =================== Order Item =================== + + /** + * 获得指定用户,指定的交易订单项 + * + * @param userId 用户编号 + * @param itemId 交易订单项编号 + * @return 交易订单项 + */ + TradeOrderItemDO getOrderItem(Long userId, Long itemId); + + /** + * 更新交易订单项的售后状态 + * + * @param id 交易订单项编号 + * @param oldAfterSaleStatus 当前售后状态;如果不符,更新后会抛出异常 + * @param newAfterSaleStatus 目标售后状态 + * @param refundPrice 退款金额;当订单项退款成功时,必须传递该值 + */ + void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, + Integer newAfterSaleStatus, Integer refundPrice); + + /** + * 根据交易订单项编号数组,查询交易订单项 + * + * @param ids 交易订单项编号数组 + * @return 交易订单项数组 + */ + List getOrderItemList(Collection ids); + + /** + * 根据交易订单编号,查询交易订单项 + * + * @param orderId 交易订单编号 + * @return 交易订单项数组 + */ + default List getOrderItemListByOrderId(Long orderId) { + return getOrderItemListByOrderId(singleton(orderId)); + } + + /** + * 根据交易订单编号数组,查询交易订单项 + * + * @param orderIds 交易订单编号数组 + * @return 交易订单项数组 + */ + List getOrderItemListByOrderId(Collection orderIds); + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java new file mode 100644 index 000000000..86d84c415 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -0,0 +1,530 @@ +package cn.iocoder.yudao.module.trade.service.order; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.core.KeyValue; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.enums.TerminalEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.module.member.api.address.AddressApi; +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; +import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.PriceApi; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO.Item; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; +import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; +import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants; +import cn.iocoder.yudao.module.trade.enums.order.*; +import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_ORDER_NOT_FOUND; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; + +/** + * 交易订单 Service 实现类 + * + * @author LeeYan9 + * @since 2022-08-26 + */ +@Service +@Slf4j +public class TradeOrderServiceImpl implements TradeOrderService { + + @Resource + private TradeOrderMapper tradeOrderMapper; + @Resource + private TradeOrderItemMapper tradeOrderItemMapper; + + @Resource + private PriceApi priceApi; + @Resource + private ProductSkuApi productSkuApi; + @Resource + private ProductSpuApi productSpuApi; + @Resource + private PayOrderApi payOrderApi; + @Resource + private AddressApi addressApi; + @Resource + private CouponApi couponApi; + @Resource + private MemberUserApi memberUserApi; + + @Resource + private TradeOrderProperties tradeOrderProperties; + + // =================== Order =================== + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) { + // 商品 SKU 检查:可售状态、库存 + List skus = validateSkuSaleable(createReqVO.getItems()); + // 商品 SPU 检查:可售状态 + List spus = validateSpuSaleable(convertSet(skus, ProductSkuRespDTO::getSpuId)); + // 用户收件地址的校验 + AddressRespDTO address = validateAddress(userId, createReqVO.getAddressId()); + + // 价格计算 + PriceCalculateRespDTO priceResp = priceApi.calculatePrice(TradeOrderConvert.INSTANCE.convert(createReqVO, userId)); + + // 插入 TradeOrderDO 订单 + TradeOrderDO tradeOrderDO = createTradeOrder(userId, userIp, createReqVO, priceResp.getOrder(), address); + // 插入 TradeOrderItemDO 订单项 + List tradeOrderItems = createTradeOrderItems(tradeOrderDO, priceResp.getOrder().getItems(), skus); + + // 订单创建完后的逻辑 + afterCreateTradeOrder(userId, createReqVO, tradeOrderDO, tradeOrderItems, spus); + // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! + return tradeOrderDO.getId(); + } + + /** + * 校验商品 SKU 是否可出售 + * + * @param items 商品 SKU + * @return 商品 SKU 数组 + */ + private List validateSkuSaleable(List items) { + List skus = productSkuApi.getSkuList(convertSet(items, Item::getSkuId)); + // SKU 不存在 + if (items.size() != skus.size()) { + throw exception(ORDER_CREATE_SKU_NOT_FOUND); + } + // 校验是否禁用 or 库存不足 + Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); + items.forEach(item -> { + ProductSkuRespDTO sku = skuMap.get(item.getSkuId()); + // SKU 禁用 + if (ObjectUtil.notEqual(CommonStatusEnum.ENABLE.getStatus(), sku.getStatus())) { + throw exception(ORDER_CREATE_SKU_NOT_SALE); + } + // SKU 库存不足 + if (item.getCount() > sku.getStock()) { + throw exception(ErrorCodeConstants.ORDER_CREATE_SKU_STOCK_NOT_ENOUGH); + } + }); + return skus; + } + + /** + * 校验商品 SPU 是否可出售 + * + * @param spuIds 商品 SPU 编号数组 + * @return 商品 SPU 数组 + */ + private List validateSpuSaleable(Set spuIds) { + List spus = productSpuApi.getSpuList(spuIds); + // SPU 不存在 + if (spus.size() != spuIds.size()) { + throw exception(ORDER_CREATE_SPU_NOT_FOUND); + } + // 校验是否存在禁用的 SPU + ProductSpuRespDTO spu = CollectionUtils.findFirst(spus, + spuDTO -> ObjectUtil.notEqual(ProductSpuStatusEnum.ENABLE.getStatus(), spuDTO.getStatus())); + if (spu != null) { + throw exception(ErrorCodeConstants.ORDER_CREATE_SPU_NOT_SALE); + } + return spus; + } + + /** + * 校验收件地址是否存在 + * + * @param userId 用户编号 + * @param addressId 收件地址编号 + * @return 收件地址 + */ + private AddressRespDTO validateAddress(Long userId, Long addressId) { + AddressRespDTO address = addressApi.getAddress(addressId, userId); + if (Objects.isNull(address)) { + throw exception(ErrorCodeConstants.ORDER_CREATE_ADDRESS_NOT_FOUND); + } + return address; + } + + private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO, + PriceCalculateRespDTO.Order order, AddressRespDTO address) { + TradeOrderDO tradeOrderDO = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, order, address); + tradeOrderDO.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @LeeYan9: 思考下, 怎么生成好点哈; 这个是会展示给用户的; + tradeOrderDO.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); + tradeOrderDO.setType(TradeOrderTypeEnum.NORMAL.getType()); + tradeOrderDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NONE.getStatus()); + tradeOrderDO.setProductCount(getSumValue(order.getItems(), PriceCalculateRespDTO.OrderItem::getCount, Integer::sum)); + tradeOrderDO.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源? + tradeOrderDO.setAdjustPrice(0).setPayed(false); // 支付信息 + tradeOrderDO.setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); // 物流信息 + tradeOrderDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NONE.getStatus()).setRefundPrice(0); // 退款信息 + tradeOrderMapper.insert(tradeOrderDO); + return tradeOrderDO; + } + + private List createTradeOrderItems(TradeOrderDO tradeOrderDO, + List orderItems, List skus) { + List tradeOrderItemDOs = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, orderItems, skus); + tradeOrderItemMapper.insertBatch(tradeOrderItemDOs); + return tradeOrderItemDOs; + } + + /** + * 执行创建完创建完订单后的逻辑 + * + * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等 + * + * @param userId 用户编号 + * @param createReqVO 创建订单请求 + * @param tradeOrderDO 交易订单 + */ + private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, + TradeOrderDO tradeOrderDO, List tradeOrderItemDOs, + List spus) { + // 下单时扣减商品库存 + productSkuApi.updateSkuStock(new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(tradeOrderItemDOs))); + + // 删除购物车商品 TODO 芋艿:待实现 + + // 扣减积分,抵扣金额 TODO 芋艿:待实现 + + // 有使用优惠券时更新 + if (createReqVO.getCouponId() != null) { + couponApi.useCoupon(new CouponUseReqDTO().setId(createReqVO.getCouponId()).setUserId(userId) + .setOrderId(tradeOrderDO.getId())); + } + + // 生成预支付 + createPayOrder(tradeOrderDO, tradeOrderItemDOs, spus); + + // 增加订单日志 TODO 芋艿:待实现 + } + + private void createPayOrder(TradeOrderDO tradeOrderDO, List tradeOrderItemDOs, + List spus) { + // 创建支付单,用于后续的支付 + PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert( + tradeOrderDO, tradeOrderItemDOs, spus, tradeOrderProperties); + Long payOrderId = payOrderApi.createOrder(payOrderCreateReqDTO); + + // 更新到交易单上 + tradeOrderMapper.updateById(new TradeOrderDO().setId(tradeOrderDO.getId()).setPayOrderId(payOrderId)); + } + + @Override + public void updateOrderPaid(Long id, Long payOrderId) { + // 校验并获得交易订单(可支付) + KeyValue orderResult = validateOrderPayable(id, payOrderId); + TradeOrderDO order = orderResult.getKey(); + PayOrderRespDTO payOrder = orderResult.getValue(); + + // 更新 TradeOrderDO 状态为已支付,等待发货 + int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(), + new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayed(true) + .setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode())); + if (updateCount == 0) { + throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); + } + + // TODO 芋艿:发送订单变化的消息 + + // TODO 芋艿:发送站内信 + + // TODO 芋艿:OrderLog + } + + /** + * 校验交易订单满足被支付的条件 + * + * 1. 交易订单未支付 + * 2. 支付单已支付 + * + * @param id 交易订单编号 + * @param payOrderId 支付订单编号 + * @return 交易订单 + */ + private KeyValue validateOrderPayable(Long id, Long payOrderId) { + // 校验订单是否存在 + TradeOrderDO order = tradeOrderMapper.selectById(id); + if (order == null) { + throw exception(ORDER_NOT_FOUND); + } + // 校验订单未支付 + if (!TradeOrderStatusEnum.isUnpaid(order.getStatus()) || order.getPayed()) { + log.error("[validateOrderPaid][order({}) 不处于待支付状态,请进行处理!order 数据是:{}]", + id, JsonUtils.toJsonString(order)); + throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); + } + // 校验支付订单匹配 + if (ObjectUtil.notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号 + log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]", + id, payOrderId, JsonUtils.toJsonString(order)); + throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); + } + + // 校验支付单是否存在 + PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); + if (payOrder == null) { + log.error("[validateOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId); + throw exception(PAY_ORDER_NOT_FOUND); + } + // 校验支付单已支付 + if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { + log.error("[validateOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", + id, payOrderId, JsonUtils.toJsonString(payOrder)); + throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); + } + // 校验支付金额一致 + if (ObjectUtil.notEqual(payOrder.getAmount(), order.getPayPrice())) { + log.error("[validateOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]", + id, payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder)); + throw exception(ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH); + } + // 校验支付订单匹配(二次) + if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), id.toString())) { + log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", + id, payOrderId, JsonUtils.toJsonString(payOrder)); + throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); + } + return new KeyValue<>(order, payOrder); + } + + // TODO 芋艿:如果无需发货,需要怎么存储? + @Override + public void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO) { + // 校验并获得交易订单(可发货) + TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId()); + + // TODO 芋艿:logisticsId 校验存在 + + // 更新 TradeOrderDO 状态为已发货,等待收货 + int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), + new TradeOrderDO().setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()) + .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()) + .setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now())); + if (updateCount == 0) { + throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); + } + + // TODO 芋艿:发送订单变化的消息 + + // TODO 芋艿:发送站内信 + + // TODO 芋艿:OrderLog + + // TODO 设计:like:是否要单独一个 delivery 发货单表??? + // TODO 设计:niu:要不要支持一个订单下,多个 order item 单独发货,类似有赞 + // TODO 设计:lili:是不是发货后,才支持售后? + } + + /** + * 校验交易订单满足被发货的条件 + * + * 1. 交易订单未发货 + * + * @param id 交易订单编号 + * @return 交易订单 + */ + private TradeOrderDO validateOrderDeliverable(Long id) { + // 校验订单是否存在 + TradeOrderDO order = tradeOrderMapper.selectById(id); + if (order == null) { + throw exception(ORDER_NOT_FOUND); + } + // 校验订单是否是待发货状态 + if (!TradeOrderStatusEnum.isUndelivered(order.getStatus()) + || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) { + throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); + } + return order; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void receiveOrder(Long userId, Long id) { + // 校验并获得交易订单(可收货) + TradeOrderDO order = validateOrderReceivable(userId, id); + + // 更新 TradeOrderDO 状态为已完成 + int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), + new TradeOrderDO().setStatus(TradeOrderStatusEnum.COMPLETED.getStatus()) + .setDeliveryStatus(TradeOrderDeliveryStatusEnum.RECEIVED.getStatus()).setReceiveTime(LocalDateTime.now())); + if (updateCount == 0) { + throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED); + } + + // TODO 芋艿:OrderLog + + // TODO 芋艿:lili 发送订单变化的消息 + + // TODO 芋艿:lili 发送商品被购买完成的数据 + } + + @Override + public TradeOrderDO getOrder(Long id) { + return tradeOrderMapper.selectById(id); + } + + /** + * 校验交易订单满足可售货的条件 + * + * 1. 交易订单待收货 + * + * @param userId 用户编号 + * @param id 交易订单编号 + * @return 交易订单 + */ + private TradeOrderDO validateOrderReceivable(Long userId, Long id) { + // 校验订单是否存在 + TradeOrderDO order = tradeOrderMapper.selectByIdAndUserId(id, userId); + if (order == null) { + throw exception(ORDER_NOT_FOUND); + } + // 校验订单是否是待收货状态 + if (!TradeOrderStatusEnum.isDelivered(order.getStatus()) + || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus())) { + throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED); + } + return order; + } + + @Override + public TradeOrderDO getOrder(Long userId, Long id) { + TradeOrderDO order = tradeOrderMapper.selectById(id); + if (order != null + && ObjectUtil.notEqual(order.getUserId(), userId)) { + return null; + } + return order; + } + + @Override + public PageResult getOrderPage(TradeOrderPageReqVO reqVO) { + // 获得 userId 相关的查询 + Set userIds = new HashSet<>(); + if (StrUtil.isNotEmpty(reqVO.getUserMobile())) { + MemberUserRespDTO user = memberUserApi.getUserByMobile(reqVO.getUserMobile()); + if (user == null) { // 没查询到用户,说明肯定也没他的订单 + return new PageResult<>(); + } + userIds.add(user.getId()); + } + if (StrUtil.isNotEmpty(reqVO.getUserNickname())) { + List users = memberUserApi.getUserListByNickname(reqVO.getUserNickname()); + if (CollUtil.isEmpty(users)) { // 没查询到用户,说明肯定也没他的订单 + return new PageResult<>(); + } + userIds.addAll(convertSet(users, MemberUserRespDTO::getId)); + } + // 分页查询 + return tradeOrderMapper.selectPage(reqVO, userIds); + } + + @Override + public PageResult getOrderPage(Long userId, AppTradeOrderPageReqVO reqVO) { + return tradeOrderMapper.selectPage(reqVO, userId); + } + + // =================== Order Item =================== + + @Override + public TradeOrderItemDO getOrderItem(Long userId, Long itemId) { + TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(itemId); + if (orderItem != null + && ObjectUtil.notEqual(orderItem.getUserId(), userId)) { + return null; + } + return orderItem; + } + + @Override + public void updateOrderItemAfterSaleStatus(Long id, Integer oldAfterSaleStatus, Integer newAfterSaleStatus, Integer refundPrice) { + // 如果退款成功,则 refundPrice 非空 + if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus()) + && refundPrice == null) { + throw new IllegalArgumentException(StrUtil.format("id({}) 退款成功,退款金额不能为空", id)); + } + + // 更新订单项 + int updateCount = tradeOrderItemMapper.updateAfterSaleStatus(id, oldAfterSaleStatus, newAfterSaleStatus); + if (updateCount <= 0) { + throw exception(ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL); + } + + // 如果有退款金额,则需要更新订单 + if (refundPrice == null) { + return; + } + // 计算总的退款金额 + TradeOrderDO order = tradeOrderMapper.selectById(tradeOrderItemMapper.selectById(id).getOrderId()); + Integer orderRefundPrice = order.getRefundPrice() + refundPrice; + if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单 + tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) + .setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.ALL.getStatus()).setRefundPrice(orderRefundPrice) + .setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now())); + + // TODO 芋艿:记录订单日志 + + // TODO 芋艿:站内信? + } else { // 如果部分售后,则更新退款金额 + tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()) + .setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice)); + } + + // TODO 芋艿:未来如果有分佣,需要更新相关分佣订单为已失效 + } + + @Override + public List getOrderItemList(Collection ids) { + return tradeOrderItemMapper.selectBatchIds(ids); + } + + @Override + public List getOrderItemListByOrderId(Collection orderIds) { + return tradeOrderItemMapper.selectListByOrderId(orderIds); + } + + /** + * 判断指定订单的所有订单项,是不是都售后成功 + * + * @param id 订单编号 + * @return 是否都售后成功 + */ + private boolean isAllOrderItemAfterSaleSuccess(Long id) { + List orderItems = tradeOrderItemMapper.selectListByOrderId(id); + return orderItems.stream().allMatch(orderItem -> Objects.equals(orderItem.getAfterSaleStatus(), + TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java new file mode 100644 index 000000000..f628cef4a --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java @@ -0,0 +1,154 @@ +package cn.iocoder.yudao.module.trade.service.aftersale; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi; +import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO; +import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleLogDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleLogMapper; +import cn.iocoder.yudao.module.trade.dal.mysql.aftersale.TradeAfterSaleMapper; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleTypeEnum; +import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; +import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static java.util.Arrays.asList; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +/** + * {@link TradeAfterSaleService} 的单元测试 + * + * @author 芋道源码 + */ +@Import(TradeAfterSaleServiceImpl.class) +public class TradeAfterSaleServiceTest extends BaseDbUnitTest { + + @Resource + private TradeAfterSaleServiceImpl tradeAfterSaleService; + + @Resource + private TradeAfterSaleMapper tradeAfterSaleMapper; + @Resource + private TradeAfterSaleLogMapper tradeAfterSaleLogMapper; + + @MockBean + private TradeOrderService tradeOrderService; + @MockBean + private PayRefundApi payRefundApi; + + @MockBean + private TradeOrderProperties tradeOrderProperties; + + @Test + public void testCreateAfterSale() { + // 准备参数 + Long userId = 1024L; + AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO() + .setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay()) + .setApplyReason("退钱").setApplyDescription("快退") + .setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png")); + // mock 方法(交易订单项) + TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> { + o.setOrderId(111L).setUserId(userId).setOrderDividePrice(200); + o.setAfterSaleStatus(TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); + }); + when(tradeOrderService.getOrderItem(eq(1024L), eq(1L))) + .thenReturn(orderItem); + // mock 方法(交易订单) + TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> o.setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()) + .setNo("202211301234")); + when(tradeOrderService.getOrder(eq(1024L), eq(111L))).thenReturn(order); + + // 调用 + Long afterSaleId = tradeAfterSaleService.createAfterSale(userId, createReqVO); + // 断言(TradeAfterSaleDO) + TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(afterSaleId); + assertNotNull(afterSale.getNo()); + assertEquals(afterSale.getStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus()); + assertEquals(afterSale.getType(), TradeAfterSaleTypeEnum.IN_SALE.getType()); + assertPojoEquals(afterSale, createReqVO); + assertEquals(afterSale.getUserId(), 1024L); + assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime"); + assertEquals(afterSale.getOrderNo(), "202211301234"); + assertNull(afterSale.getPayRefundId()); + assertNull(afterSale.getRefundTime()); + assertNull(afterSale.getLogisticsId()); + assertNull(afterSale.getLogisticsNo()); + assertNull(afterSale.getDeliveryTime()); + assertNull(afterSale.getReceiveReason()); + // 断言(TradeAfterSaleLogDO) + TradeAfterSaleLogDO afterSaleLog = tradeAfterSaleLogMapper.selectList().get(0); + assertEquals(afterSaleLog.getUserId(), userId); + assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue()); + assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId); + assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime"); + assertNull(afterSaleLog.getBeforeStatus()); + assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus()); + assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent()); + } + + @Test + public void testGetAfterSalePage() { + // mock 数据 + TradeAfterSaleDO dbAfterSale = randomPojo(TradeAfterSaleDO.class, o -> { // 等会查询到 + o.setNo("202211190847450020500077"); + o.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus()); + o.setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay()); + o.setType(TradeAfterSaleTypeEnum.IN_SALE.getType()); + o.setOrderNo("202211190847450020500011"); + o.setSpuName("芋艿"); + o.setCreateTime(buildTime(2022, 1, 15)); + }); + tradeAfterSaleMapper.insert(dbAfterSale); + // 测试 no 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setNo("202211190847450020500066"))); + // 测试 status 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setStatus(TradeAfterSaleStatusEnum.SELLER_REFUSE.getStatus()))); + // 测试 way 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setWay(TradeAfterSaleWayEnum.REFUND.getWay()))); + // 测试 type 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setType(TradeAfterSaleTypeEnum.AFTER_SALE.getType()))); + // 测试 orderNo 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setOrderNo("202211190847450020500022"))); + // 测试 spuName 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setSpuName("土豆"))); + // 测试 createTime 不匹配 + tradeAfterSaleMapper.insert(cloneIgnoreId(dbAfterSale, o -> o.setCreateTime(buildTime(2022, 1, 20)))); + // 准备参数 + TradeAfterSalePageReqVO reqVO = new TradeAfterSalePageReqVO(); + reqVO.setNo("20221119084745002050007"); + reqVO.setStatus(TradeAfterSaleStatusEnum.APPLY.getStatus()); + reqVO.setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay()); + reqVO.setType(TradeAfterSaleTypeEnum.IN_SALE.getType()); + reqVO.setOrderNo("20221119084745002050001"); + reqVO.setSpuName("芋"); + reqVO.setCreateTime(new LocalDateTime[]{buildTime(2022, 1, 1), buildTime(2022, 1, 16)}); + + // 调用 + PageResult pageResult = tradeAfterSaleService.getAfterSalePage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbAfterSale, pageResult.getList().get(0)); + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java new file mode 100644 index 000000000..55bff8de6 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java @@ -0,0 +1,320 @@ +package cn.iocoder.yudao.module.trade.service.order; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.enums.TerminalEnum; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.member.api.address.AddressApi; +import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; +import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; +import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; +import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; +import cn.iocoder.yudao.module.promotion.api.price.PriceApi; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; +import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; +import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; +import cn.iocoder.yudao.module.trade.enums.order.*; +import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderConfig; +import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.time.Duration; +import java.util.Arrays; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static java.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * {@link TradeOrderServiceImpl} 的单元测试类 + * + * @author LeeYan9 + * @since 2022-09-07 + */ +@Import({TradeOrderServiceImpl.class, TradeOrderConfig.class}) +public class TradeOrderServiceTest extends BaseDbUnitTest { + + @Resource + private TradeOrderServiceImpl tradeOrderService; + + @Resource + private TradeOrderMapper tradeOrderMapper; + @Resource + private TradeOrderItemMapper tradeOrderItemMapper; + + @MockBean + private ProductSpuApi productSpuApi; + @MockBean + private ProductSkuApi productSkuApi; + @MockBean + private PriceApi priceApi; + @MockBean + private PayOrderApi payOrderApi; + @MockBean + private AddressApi addressApi; + @MockBean + private CouponApi couponApi; + + @MockBean + private TradeOrderProperties tradeOrderProperties; + + @BeforeEach + public void setUp() { + when(tradeOrderProperties.getAppId()).thenReturn(888L); + when(tradeOrderProperties.getExpireTime()).thenReturn(Duration.ofDays(1)); + } + + @Test + public void testCreateTradeOrder_success() { + // 准备参数 + Long userId = 100L; + String userIp = "127.0.0.1"; + AppTradeOrderCreateReqVO reqVO = new AppTradeOrderCreateReqVO() + .setAddressId(10L).setCouponId(101L).setRemark("我是备注").setFromCart(true) + .setItems(Arrays.asList(new AppTradeOrderCreateReqVO.Item().setSkuId(1L).setCount(3), + new AppTradeOrderCreateReqVO.Item().setSkuId(2L).setCount(4))); + // mock 方法(商品 SKU 检查) + ProductSkuRespDTO sku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(1L).setSpuId(11L) + .setPrice(50).setStock(100).setStatus(CommonStatusEnum.ENABLE.getStatus()) + .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(111L).setValueId(222L)))); + ProductSkuRespDTO sku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(2L).setSpuId(21L) + .setPrice(20).setStock(50).setStatus(CommonStatusEnum.ENABLE.getStatus())) + .setProperties(singletonList(new ProductSkuRespDTO.Property().setPropertyId(333L).setValueId(444L))); + when(productSkuApi.getSkuList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(sku01, sku02)); + // mock 方法(商品 SPU 检查) + ProductSpuRespDTO spu01 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(11L) + .setStatus(ProductSpuStatusEnum.ENABLE.getStatus()).setName("商品 1")); + ProductSpuRespDTO spu02 = randomPojo(ProductSpuRespDTO.class, o -> o.setId(21L) + .setStatus(ProductSpuStatusEnum.ENABLE.getStatus())); + when(productSpuApi.getSpuList(eq(asSet(11L, 21L)))).thenReturn(Arrays.asList(spu01, spu02)); + // mock 方法(用户收件地址的校验) + AddressRespDTO addressRespDTO = new AddressRespDTO().setId(10L).setUserId(userId).setName("芋艿") + .setMobile("15601691300").setAreaId(3306L).setPostCode("85757").setDetailAddress("土豆村"); + when(addressApi.getAddress(eq(10L), eq(userId))).thenReturn(addressRespDTO); + // mock 方法(价格计算) + PriceCalculateRespDTO.OrderItem priceOrderItem01 = new PriceCalculateRespDTO.OrderItem() + .setSpuId(11L).setSkuId(1L).setCount(3).setOriginalPrice(150).setOriginalUnitPrice(50) + .setDiscountPrice(20).setPayPrice(130).setOrderPartPrice(7).setOrderDividePrice(35); + PriceCalculateRespDTO.OrderItem priceOrderItem02 = new PriceCalculateRespDTO.OrderItem() + .setSpuId(21L).setSkuId(2L).setCount(4).setOriginalPrice(80).setOriginalUnitPrice(20) + .setDiscountPrice(40).setPayPrice(40).setOrderPartPrice(15).setOrderDividePrice(25); + PriceCalculateRespDTO.Order priceOrder = new PriceCalculateRespDTO.Order() + .setOriginalPrice(230).setOrderPrice(100).setDiscountPrice(0).setCouponPrice(30) + .setPointPrice(10).setDeliveryPrice(20).setPayPrice(80).setCouponId(101L).setCouponPrice(30) + .setItems(Arrays.asList(priceOrderItem01, priceOrderItem02)); + when(priceApi.calculatePrice(argThat(priceCalculateReqDTO -> { + assertEquals(priceCalculateReqDTO.getUserId(), 100L); + assertEquals(priceCalculateReqDTO.getCouponId(), 101L); + assertEquals(priceCalculateReqDTO.getItems().get(0).getSkuId(), 1L); + assertEquals(priceCalculateReqDTO.getItems().get(0).getCount(), 3); + assertEquals(priceCalculateReqDTO.getItems().get(1).getSkuId(), 2L); + assertEquals(priceCalculateReqDTO.getItems().get(1).getCount(), 4); + return true; + }))).thenReturn(new PriceCalculateRespDTO().setOrder(priceOrder)); + // mock 方法(创建支付单) + when(payOrderApi.createOrder(argThat(createReqDTO -> { + assertEquals(createReqDTO.getAppId(), 888L); + assertEquals(createReqDTO.getUserIp(), userIp); + assertNotNull(createReqDTO.getMerchantOrderId()); // 由于 tradeOrderId 后生成,只能校验非空 + assertEquals(createReqDTO.getSubject(), "商品 1 等多件"); + assertNull(createReqDTO.getBody()); + assertEquals(createReqDTO.getAmount(), 80); + assertNotNull(createReqDTO.getExpireTime()); + return true; + }))).thenReturn(1000L); + + // 调用方法 + Long tradeOrderId = tradeOrderService.createOrder(userId, userIp, reqVO); + // 断言 TradeOrderDO 订单 + List tradeOrderDOs = tradeOrderMapper.selectList(); + assertEquals(tradeOrderDOs.size(), 1); + TradeOrderDO tradeOrderDO = tradeOrderDOs.get(0); + assertEquals(tradeOrderDO.getId(), tradeOrderId); + assertNotNull(tradeOrderDO.getNo()); + assertEquals(tradeOrderDO.getType(), TradeOrderTypeEnum.NORMAL.getType()); + assertEquals(tradeOrderDO.getTerminal(), TerminalEnum.H5.getTerminal()); + assertEquals(tradeOrderDO.getUserId(), userId); + assertEquals(tradeOrderDO.getUserIp(), userIp); + assertEquals(tradeOrderDO.getStatus(), TradeOrderStatusEnum.UNPAID.getStatus()); + assertEquals(tradeOrderDO.getProductCount(), 7); + assertNull(tradeOrderDO.getFinishTime()); + assertNull(tradeOrderDO.getCancelTime()); + assertNull(tradeOrderDO.getCancelType()); + assertEquals(tradeOrderDO.getUserRemark(), "我是备注"); + assertNull(tradeOrderDO.getRemark()); + assertFalse(tradeOrderDO.getPayed()); + assertNull(tradeOrderDO.getPayTime()); + assertEquals(tradeOrderDO.getOriginalPrice(), 230); + assertEquals(tradeOrderDO.getOrderPrice(), 100); + assertEquals(tradeOrderDO.getDiscountPrice(), 0); + assertEquals(tradeOrderDO.getAdjustPrice(), 0); + assertEquals(tradeOrderDO.getPayPrice(), 80); + assertEquals(tradeOrderDO.getPayOrderId(), 1000L); + assertNull(tradeOrderDO.getPayChannelCode()); + assertNull(tradeOrderDO.getDeliveryTemplateId()); + assertNull(tradeOrderDO.getLogisticsId()); + assertEquals(tradeOrderDO.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); + assertNull(tradeOrderDO.getDeliveryTime()); + assertNull(tradeOrderDO.getReceiveTime()); + assertEquals(tradeOrderDO.getReceiverName(), "芋艿"); + assertEquals(tradeOrderDO.getReceiverMobile(), "15601691300"); + assertEquals(tradeOrderDO.getReceiverAreaId(), 3306); + assertEquals(tradeOrderDO.getReceiverPostCode(), 85757); + assertEquals(tradeOrderDO.getReceiverDetailAddress(), "土豆村"); + assertEquals(tradeOrderDO.getAfterSaleStatus(), TradeOrderAfterSaleStatusEnum.NONE.getStatus()); + assertEquals(tradeOrderDO.getRefundPrice(), 0); + assertEquals(tradeOrderDO.getCouponPrice(), 30); + assertEquals(tradeOrderDO.getPointPrice(), 10); + // 断言 TradeOrderItemDO 订单(第 1 个) + List tradeOrderItemDOs = tradeOrderItemMapper.selectList(); + assertEquals(tradeOrderItemDOs.size(), 2); + TradeOrderItemDO tradeOrderItemDO01 = tradeOrderItemDOs.get(0); + assertNotNull(tradeOrderItemDO01.getId()); + assertEquals(tradeOrderItemDO01.getUserId(), userId); + assertEquals(tradeOrderItemDO01.getOrderId(), tradeOrderId); + assertEquals(tradeOrderItemDO01.getSpuId(), 11L); + assertEquals(tradeOrderItemDO01.getSkuId(), 1L); + assertEquals(tradeOrderItemDO01.getProperties().size(), 1); + assertEquals(tradeOrderItemDO01.getProperties().get(0).getPropertyId(), 111L); + assertEquals(tradeOrderItemDO01.getProperties().get(0).getValueId(), 222L); + assertEquals(tradeOrderItemDO01.getSpuName(), sku01.getSpuName()); + assertEquals(tradeOrderItemDO01.getPicUrl(), sku01.getPicUrl()); + assertEquals(tradeOrderItemDO01.getCount(), 3); + assertEquals(tradeOrderItemDO01.getOriginalPrice(), 150); + assertEquals(tradeOrderItemDO01.getOriginalUnitPrice(), 50); + assertEquals(tradeOrderItemDO01.getDiscountPrice(), 20); + assertEquals(tradeOrderItemDO01.getPayPrice(), 130); + assertEquals(tradeOrderItemDO01.getOrderPartPrice(), 7); + assertEquals(tradeOrderItemDO01.getOrderDividePrice(), 35); + assertEquals(tradeOrderItemDO01.getAfterSaleStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); + // 断言 TradeOrderItemDO 订单(第 2 个) + TradeOrderItemDO tradeOrderItemDO02 = tradeOrderItemDOs.get(1); + assertNotNull(tradeOrderItemDO02.getId()); + assertEquals(tradeOrderItemDO02.getUserId(), userId); + assertEquals(tradeOrderItemDO02.getOrderId(), tradeOrderId); + assertEquals(tradeOrderItemDO02.getSpuId(), 21L); + assertEquals(tradeOrderItemDO02.getSkuId(), 2L); + assertEquals(tradeOrderItemDO02.getProperties().size(), 1); + assertEquals(tradeOrderItemDO02.getProperties().get(0).getPropertyId(), 333L); + assertEquals(tradeOrderItemDO02.getProperties().get(0).getValueId(), 444L); + assertEquals(tradeOrderItemDO02.getSpuName(), sku02.getSpuName()); + assertEquals(tradeOrderItemDO02.getPicUrl(), sku02.getPicUrl()); + assertEquals(tradeOrderItemDO02.getCount(), 4); + assertEquals(tradeOrderItemDO02.getOriginalPrice(), 80); + assertEquals(tradeOrderItemDO02.getOriginalUnitPrice(), 20); + assertEquals(tradeOrderItemDO02.getDiscountPrice(), 40); + assertEquals(tradeOrderItemDO02.getPayPrice(), 40); + assertEquals(tradeOrderItemDO02.getOrderPartPrice(), 15); + assertEquals(tradeOrderItemDO02.getOrderDividePrice(), 25); + assertEquals(tradeOrderItemDO02.getAfterSaleStatus(), TradeOrderItemAfterSaleStatusEnum.NONE.getStatus()); + // 校验调用 + verify(productSkuApi).updateSkuStock(argThat(updateStockReqDTO -> { + assertEquals(updateStockReqDTO.getItems().size(), 2); + assertEquals(updateStockReqDTO.getItems().get(0).getId(), 1L); + assertEquals(updateStockReqDTO.getItems().get(0).getIncrCount(), 3); + assertEquals(updateStockReqDTO.getItems().get(1).getId(), 2L); + assertEquals(updateStockReqDTO.getItems().get(1).getIncrCount(), 4); + return true; + })); + verify(couponApi).useCoupon(argThat(reqDTO -> { + assertEquals(reqDTO.getId(), reqVO.getCouponId()); + assertEquals(reqDTO.getUserId(), userId); + assertEquals(reqDTO.getOrderId(), tradeOrderId); + return true; + })); + } + + @Test + public void testUpdateOrderPaid() { + // mock 数据(TradeOrder) + TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { + o.setId(1L).setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); + o.setPayOrderId(10L).setPayed(false).setPayPrice(100).setPayTime(null); + }); + tradeOrderMapper.insert(order); + // 准备参数 + Long id = 1L; + Long payOrderId = 10L; + // mock 方法(支付单) + when(payOrderApi.getOrder(eq(10L))).thenReturn(randomPojo(PayOrderRespDTO.class, + o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()).setChannelCode("wx_pub") + .setMerchantOrderId("1")).setAmount(100)); + + // 调用 + tradeOrderService.updateOrderPaid(id, payOrderId); + // 断言 + TradeOrderDO dbOrder = tradeOrderMapper.selectById(id); + assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus()); + assertTrue(dbOrder.getPayed()); + assertNotNull(dbOrder.getPayTime()); + assertEquals(dbOrder.getPayChannelCode(), "wx_pub"); + } + + @Test + public void testDeliveryOrder() { + // mock 数据(TradeOrder) + TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { + o.setId(1L).setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()); + o.setLogisticsId(null).setLogisticsNo(null).setDeliveryTime(null) + .setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); + }); + tradeOrderMapper.insert(order); + // 准备参数 + TradeOrderDeliveryReqVO deliveryReqVO = new TradeOrderDeliveryReqVO().setId(1L) + .setLogisticsId(10L).setLogisticsNo("100"); + // mock 方法(支付单) + + // 调用 + tradeOrderService.deliveryOrder(randomLongId(), deliveryReqVO); + // 断言 + TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L); + assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.DELIVERED.getStatus()); + assertEquals(dbOrder.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()); + assertPojoEquals(dbOrder, deliveryReqVO); + assertNotNull(dbOrder.getDeliveryTime()); + } + + @Test + public void testReceiveOrder() { + // mock 数据(TradeOrder) + TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { + o.setId(1L).setUserId(10L).setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()); + o.setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setReceiveTime(null); + }); + tradeOrderMapper.insert(order); + // 准备参数 + Long id = 1L; + Long userId = 10L; + // mock 方法(支付单) + + // 调用 + tradeOrderService.receiveOrder(userId, id); + // 断言 + TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L); + assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus()); + assertEquals(dbOrder.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.RECEIVED.getStatus()); + assertNotNull(dbOrder.getReceiveTime()); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml new file mode 100644 index 000000000..19dd0e97b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml @@ -0,0 +1,53 @@ +spring: + main: + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner + +--- #################### 数据库相关配置 #################### + +spring: + # 数据源配置项 + datasource: + name: ruoyi-vue-pro + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + driver-class-name: org.h2.Driver + username: sa + password: + druid: + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 + initial-size: 1 # 单元测试,配置为 1,提升启动速度 + sql: + init: + schema-locations: classpath:/sql/create_tables.sql + + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 + redis: + host: 127.0.0.1 # 地址 + port: 16379 # 端口(单元测试,使用 16379 端口) + database: 0 # 数据库索引 + +mybatis: + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 + +--- #################### 定时任务相关配置 #################### + +--- #################### 配置中心相关配置 #################### + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项(单元测试,禁用 Lock4j) + +# Resilience4j 配置项 + +--- #################### 监控相关配置 #################### + +--- #################### 芋道相关配置 #################### + +# 芋道配置项,设置当前项目所有自定义的配置 +yudao: + info: + base-package: cn.iocoder.yudao.module + trade: + order: + app-id: 1 + merchant-order-id: 1 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/logback.xml b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/logback.xml new file mode 100644 index 000000000..daf756bff --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/logback.xml @@ -0,0 +1,4 @@ + + + + diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/clean.sql new file mode 100644 index 000000000..dfa4a5b42 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/clean.sql @@ -0,0 +1,4 @@ +DELETE FROM trade_order; +DELETE FROM trade_order_item; +DELETE FROM trade_after_sale; +DELETE FROM trade_after_sale_log; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql new file mode 100644 index 000000000..452362eb5 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql @@ -0,0 +1,128 @@ +CREATE TABLE IF NOT EXISTS "trade_order" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "no" varchar NOT NULL, + "type" int NOT NULL, + "terminal" int NOT NULL, + "user_id" bigint NOT NULL, + "user_ip" varchar NOT NULL, + "user_remark" varchar, + "status" int NOT NULL, + "product_count" int NOT NULL, + "cancel_type" int, + "remark" varchar, + "payed" bit NOT NULL, + "pay_time" datetime, + "finish_time" datetime, + "cancel_time" datetime, + "original_price" int NOT NULL, + "order_price" int NOT NULL, + "discount_price" int NOT NULL, + "delivery_price" int NOT NULL, + "adjust_price" int NOT NULL, + "pay_price" int NOT NULL, + "pay_order_id" bigint, + "pay_channel_code" varchar, + "delivery_template_id" bigint, + "logistics_id" bigint, + "logistics_no" varchar, + "delivery_status" smallint NOT NULL, + "delivery_time" datetime, + "receive_time" datetime, + "receiver_name" varchar NOT NULL, + "receiver_mobile" varchar NOT NULL, + "receiver_area_id" int NOT NULL, + "receiver_post_code" int, + "receiver_detail_address" varchar NOT NULL, + "after_sale_status" int NOT NULL, + "refund_price" int NOT NULL, + "coupon_id" bigint NOT NULL, + "coupon_price" int NOT NULL, + "point_price" int NOT NULL, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '交易订单表'; + +CREATE TABLE IF NOT EXISTS "trade_order_item" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "user_id" bigint NOT NULL, + "order_id" bigint NOT NULL, + "spu_id" bigint NOT NULL, + "spu_name" varchar NOT NULL, + "sku_id" bigint NOT NULL, + "properties" varchar, + "pic_url" varchar, + "count" int NOT NULL, + "original_price" int NOT NULL, + "original_unit_price" int NOT NULL, + "discount_price" int NOT NULL, + "pay_price" int NOT NULL, + "order_part_price" int NOT NULL, + "order_divide_price" int NOT NULL, + "after_sale_status" int NOT NULL, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '交易订单明细表'; + +CREATE TABLE IF NOT EXISTS "trade_after_sale" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "no" varchar NOT NULL, + "status" int NOT NULL, + "type" int NOT NULL, + "way" int NOT NULL, + "user_id" bigint NOT NULL, + "apply_reason" varchar NOT NULL, + "apply_description" varchar, + "apply_pic_urls" varchar, + "order_id" bigint NOT NULL, + "order_no" varchar NOT NULL, + "order_item_id" bigint NOT NULL, + "spu_id" bigint NOT NULL, + "spu_name" varchar NOT NULL, + "sku_id" bigint NOT NULL, + "properties" varchar, + "pic_url" varchar, + "count" int NOT NULL, + "audit_time" varchar, + "audit_user_id" bigint, + "audit_reason" varchar, + "refund_price" int NOT NULL, + "pay_refund_id" bigint, + "refund_time" varchar, + "logistics_id" bigint, + "logistics_no" varchar, + "delivery_time" varchar, + "receive_time" varchar, + "receive_reason" varchar, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '交易售后表'; + +CREATE TABLE IF NOT EXISTS "trade_after_sale_log" ( + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "user_id" bigint NOT NULL, + "user_type" int NOT NULL, + "after_sale_id" bigint NOT NULL, + "order_id" bigint NOT NULL, + "order_item_id" bigint NOT NULL, + "before_status" int, + "after_status" int NOT NULL, + "content" varchar NOT NULL, + "creator" varchar DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + PRIMARY KEY ("id") +) COMMENT '交易售后日志'; diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 546eff421..40b35b9cb 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -84,7 +84,6 @@ - org.springframework.boot From 73d55118995a9237576f29c6b56578c64a0b4a4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=A7=E6=B5=B7?= Date: Sat, 4 Feb 2023 06:15:22 +0000 Subject: [PATCH 59/59] update README.md. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 沧海 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b9b5b5096..08c388145 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -**严肃声明:现在、未来都不会有商业版本,所有代码全部开源!** +**严肃声明:现在、未来都不会有商业版本,所有代码全部开源!!** **「我喜欢写代码,乐此不疲」** **「我喜欢做开源,以此为乐」**

+ * * 例如说 String、Boolean 等等 + * + * 关联 {@link TableField#getColumnType()} */ private String javaType; /** * Java 属性名 + * + * 关联 {@link TableField#getPropertyName()} */ private String javaField; /** diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenTableDO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenTableDO.java index b821d210c..4f4a644a7 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenTableDO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/codegen/CodegenTableDO.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum; import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.generator.config.po.TableInfo; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; @@ -44,10 +45,14 @@ public class CodegenTableDO extends BaseDO { /** * 表名称 + * + * 关联 {@link TableInfo#getName()} */ private String tableName; /** * 表描述 + * + * 关联 {@link TableInfo#getComment()} */ private String tableComment; /** diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImpl.java index d0c80ba61..17fb5cea3 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImpl.java @@ -41,7 +41,7 @@ public class DatabaseTableServiceImpl implements DatabaseTableService { return CollUtil.getFirst(getTableList0(dataSourceConfigId, name)); } - public List getTableList0(Long dataSourceConfigId, String name) { + private List getTableList0(Long dataSourceConfigId, String name) { // 获得数据源配置 DataSourceConfigDO config = dataSourceConfigService.getDataSourceConfig(dataSourceConfigId); Assert.notNull(config, "数据源({}) 不存在!", dataSourceConfigId); diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImplTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImplTest.java new file mode 100644 index 000000000..6ce8c7d41 --- /dev/null +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/db/DatabaseTableServiceImplTest.java @@ -0,0 +1,89 @@ +package cn.iocoder.yudao.module.infra.service.db; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO; +import com.baomidou.mybatisplus.generator.config.po.TableField; +import com.baomidou.mybatisplus.generator.config.po.TableInfo; +import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; +import org.apache.ibatis.type.JdbcType; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +@Import(DatabaseTableServiceImpl.class) +public class DatabaseTableServiceImplTest extends BaseDbUnitTest { + + @Resource + private DatabaseTableServiceImpl databaseTableService; + + @MockBean + private DataSourceConfigService dataSourceConfigService; + + @Test + public void testGetTableList() { + // 准备参数 + Long dataSourceConfigId = randomLongId(); + // mock 方法 + DataSourceConfigDO dataSourceConfig = new DataSourceConfigDO().setUsername("sa").setPassword("") + .setUrl("jdbc:h2:mem:testdb"); + when(dataSourceConfigService.getDataSourceConfig(eq(dataSourceConfigId))) + .thenReturn(dataSourceConfig); + + // 调用 + List tables = databaseTableService.getTableList(dataSourceConfigId, + "config", "参数"); + // 断言 + assertEquals(1, tables.size()); + assertTableInfo(tables.get(0)); + } + + @Test + public void testGetTable() { + // 准备参数 + Long dataSourceConfigId = randomLongId(); + // mock 方法 + DataSourceConfigDO dataSourceConfig = new DataSourceConfigDO().setUsername("sa").setPassword("") + .setUrl("jdbc:h2:mem:testdb"); + when(dataSourceConfigService.getDataSourceConfig(eq(dataSourceConfigId))) + .thenReturn(dataSourceConfig); + + // 调用 + TableInfo tableInfo = databaseTableService.getTable(dataSourceConfigId, "infra_config"); + // 断言 + assertTableInfo(tableInfo); + } + + private void assertTableInfo(TableInfo tableInfo) { + assertEquals("infra_config", tableInfo.getName()); + assertEquals("参数配置表", tableInfo.getComment()); + assertEquals(13, tableInfo.getFields().size()); + // id 字段 + TableField idField = tableInfo.getFields().get(0); + assertEquals("id", idField.getName()); + assertEquals(JdbcType.BIGINT, idField.getMetaInfo().getJdbcType()); + assertEquals("编号", idField.getComment()); + assertFalse(idField.getMetaInfo().isNullable()); + assertTrue(idField.isKeyFlag()); + assertTrue(idField.isKeyIdentityFlag()); + assertEquals(DbColumnType.LONG, idField.getColumnType()); + assertEquals("id", idField.getPropertyName()); + // name 字段 + TableField nameField = tableInfo.getFields().get(3); + assertEquals("name", nameField.getName()); + assertEquals(JdbcType.VARCHAR, nameField.getMetaInfo().getJdbcType()); + assertEquals("名字", nameField.getComment()); + assertFalse(nameField.getMetaInfo().isNullable()); + assertFalse(nameField.isKeyFlag()); + assertFalse(nameField.isKeyIdentityFlag()); + assertEquals(DbColumnType.STRING, nameField.getColumnType()); + assertEquals("name", nameField.getPropertyName()); + } +} diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql index 5825e0fef..9d4e57e67 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/resources/sql/create_tables.sql @@ -1,9 +1,9 @@ CREATE TABLE IF NOT EXISTS "infra_config" ( - "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '编号', "category" varchar(50) NOT NULL, "type" tinyint NOT NULL, - "name" varchar(100) NOT NULL DEFAULT '', + "name" varchar(100) NOT NULL DEFAULT '' COMMENT '名字', "config_key" varchar(100) NOT NULL DEFAULT '', "value" varchar(500) NOT NULL DEFAULT '', "visible" bit NOT NULL, From 71cb5fdcb8310ab3b7376e6e0ba442a9c30067e5 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 10:24:41 +0800 Subject: [PATCH 57/59] =?UTF-8?q?=E5=90=88=E5=B9=B6=E6=9C=80=E6=96=B0=20ma?= =?UTF-8?q?ster=20=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/controller/admin/config/ConfigController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java index e3f704bc0..afaee6fa4 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java @@ -8,9 +8,10 @@ import cn.iocoder.yudao.module.infra.controller.admin.config.vo.*; import cn.iocoder.yudao.module.infra.convert.config.ConfigConvert; import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO; import cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; +import cn.iocoder.yudao.module.infra.service.config.ConfigService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; From 6bf5eb013385e4b46ef5763a38114c5ec41eb515 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Feb 2023 13:06:54 +0800 Subject: [PATCH 58/59] =?UTF-8?q?=E9=80=82=E9=85=8D=20mall=20=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E7=9A=84=20openapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 +- yudao-module-mall/README.md | 4 - yudao-module-mall/pom.xml | 29 + yudao-module-mall/yudao-module-mall.zip | Bin 426292 -> 0 bytes .../yudao-module-product-api/pom.xml | 34 ++ .../module/product/api/package-info.java | 4 + .../api/property/ProductPropertyValueApi.java | 23 + .../ProductPropertyValueDetailRespDTO.java | 33 ++ .../module/product/api/sku/ProductSkuApi.java | 40 ++ .../api/sku/dto/ProductSkuRespDTO.java | 95 +++ .../sku/dto/ProductSkuUpdateStockReqDTO.java | 47 ++ .../module/product/api/spu/ProductSpuApi.java | 24 + .../api/spu/dto/ProductSpuRespDTO.java | 127 ++++ .../product/enums/ErrorCodeConstants.java | 45 ++ .../ProductCommentAuditStatusEnum.java | 38 ++ .../enums/delivery/DeliveryTypeEnum.java | 38 ++ .../enums/group/ProductGroupStyleEnum.java | 38 ++ .../enums/spu/ProductSpuSpecTypeEnum.java | 37 ++ .../enums/spu/ProductSpuStatusEnum.java | 48 ++ .../yudao-module-product-biz/pom.xml | 62 ++ .../module/product/api/package-info.java | 1 + .../property/ProductPropertyValueApiImpl.java | 31 + .../product/api/sku/ProductSkuApiImpl.java | 49 ++ .../product/api/spu/ProductSpuApiImpl.java | 38 ++ .../admin/brand/ProductBrandController.java | 82 +++ .../admin/brand/vo/ProductBrandBaseVO.java | 34 ++ .../brand/vo/ProductBrandCreateReqVO.java | 14 + .../admin/brand/vo/ProductBrandListReqVO.java | 13 + .../admin/brand/vo/ProductBrandPageReqVO.java | 30 + .../admin/brand/vo/ProductBrandRespVO.java | 22 + .../brand/vo/ProductBrandUpdateReqVO.java | 20 + .../category/ProductCategoryController.java | 76 +++ .../category/vo/ProductCategoryBaseVO.java | 38 ++ .../vo/ProductCategoryCreateReqVO.java | 14 + .../category/vo/ProductCategoryListReqVO.java | 13 + .../category/vo/ProductCategoryRespVO.java | 22 + .../vo/ProductCategoryUpdateReqVO.java | 20 + .../property/ProductPropertyController.java | 99 ++++ .../ProductPropertyValueController.java | 70 +++ .../ProductPropertyAndValueRespVO.java | 35 ++ .../vo/property/ProductPropertyBaseVO.java | 22 + .../property/ProductPropertyCreateReqVO.java | 15 + .../vo/property/ProductPropertyListReqVO.java | 15 + .../vo/property/ProductPropertyPageReqVO.java | 30 + .../vo/property/ProductPropertyRespVO.java | 22 + .../property/ProductPropertyUpdateReqVO.java | 20 + .../vo/value/ProductPropertyValueBaseVO.java | 27 + .../ProductPropertyValueCreateReqVO.java | 14 + .../ProductPropertyValueDetailRespVO.java | 22 + .../value/ProductPropertyValuePageReqVO.java | 24 + .../vo/value/ProductPropertyValueRespVO.java | 22 + .../ProductPropertyValueUpdateReqVO.java | 20 + .../admin/sku/ProductSkuController.java | 57 ++ .../admin/sku/vo/ProductSkuBaseVO.java | 75 +++ .../sku/vo/ProductSkuCreateOrUpdateReqVO.java | 21 + .../admin/sku/vo/ProductSkuOptionRespVO.java | 30 + .../admin/sku/vo/ProductSkuRespVO.java | 28 + .../admin/spu/ProductSpuController.http | 4 + .../admin/spu/ProductSpuController.java | 101 ++++ .../admin/spu/vo/ProductSpuBaseVO.java | 76 +++ .../admin/spu/vo/ProductSpuCreateReqVO.java | 24 + .../admin/spu/vo/ProductSpuDetailRespVO.java | 38 ++ .../admin/spu/vo/ProductSpuPageReqVO.java | 45 ++ .../admin/spu/vo/ProductSpuRespVO.java | 40 ++ .../admin/spu/vo/ProductSpuSimpleRespVO.java | 26 + .../admin/spu/vo/ProductSpuUpdateReqVO.java | 29 + .../app/category/AppCategoryController.java | 38 ++ .../app/category/vo/AppCategoryRespVO.java | 28 + .../controller/app/property/package-info.java | 4 + .../property/vo/property/package-info.java | 4 + .../AppProductPropertyValueDetailRespVO.java | 22 + .../app/spu/AppProductSpuController.http | 8 + .../app/spu/AppProductSpuController.java | 79 +++ .../app/spu/vo/AppProductSpuDetailRespVO.java | 91 +++ .../spu/vo/AppProductSpuPageItemRespVO.java | 39 ++ .../app/spu/vo/AppProductSpuPageReqVO.java | 43 ++ .../convert/brand/ProductBrandConvert.java | 33 ++ .../category/ProductCategoryConvert.java | 32 + .../property/ProductPropertyConvert.java | 48 ++ .../ProductPropertyValueConvert.java | 55 ++ .../convert/sku/ProductSkuConvert.java | 93 +++ .../convert/spu/ProductSpuConvert.java | 108 ++++ .../dal/dataobject/brand/ProductBrandDO.java | 53 ++ .../category/ProductCategoryDO.java | 67 +++ .../dataobject/comment/ProductCommentDO.java | 129 +++++ .../delivery/DeliveryTemplateDO.java | 30 + .../favorite/ProductFavoriteDO.java | 45 ++ .../dataobject/group/ProductGroupBindDO.java | 43 ++ .../dal/dataobject/group/ProductGroupDO.java | 63 ++ .../property/ProductPropertyDO.java | 38 ++ .../property/ProductPropertyValueDO.java | 46 ++ .../dataobject/search/ProductHotSearchDO.java | 38 ++ .../product/dal/dataobject/shop/ShopDO.java | 26 + .../dal/dataobject/sku/ProductSkuDO.java | 137 +++++ .../dal/dataobject/spu/ProductSpuDO.java | 212 +++++++ .../dal/mysql/brand/ProductBrandMapper.java | 34 ++ .../mysql/category/ProductCategoryMapper.java | 33 ++ .../mysql/property/ProductPropertyMapper.java | 32 + .../property/ProductPropertyValueMapper.java | 43 ++ .../dal/mysql/sku/ProductSkuMapper.java | 75 +++ .../dal/mysql/spu/ProductSpuMapper.java | 75 +++ .../product/framework/package-info.java | 6 + .../web/config/ProductWebConfiguration.java | 24 + .../product/framework/web/package-info.java | 4 + .../yudao/module/product/package-info.java | 8 + .../service/brand/ProductBrandService.java | 79 +++ .../brand/ProductBrandServiceImpl.java | 117 ++++ .../category/ProductCategoryService.java | 78 +++ .../category/ProductCategoryServiceImpl.java | 138 +++++ .../property/ProductPropertyService.java | 72 +++ .../property/ProductPropertyServiceImpl.java | 113 ++++ .../property/ProductPropertyValueService.java | 90 +++ .../ProductPropertyValueServiceImpl.java | 127 ++++ .../bo/ProductPropertyValueDetailRespBO.java | 33 ++ .../service/sku/ProductSkuService.java | 122 ++++ .../service/sku/ProductSkuServiceImpl.java | 214 +++++++ .../service/spu/ProductSpuService.java | 101 ++++ .../service/spu/ProductSpuServiceImpl.java | 180 ++++++ .../brand/ProductBrandServiceImplTest.java | 133 +++++ .../ProductCategoryServiceImplTest.java | 145 +++++ .../service/sku/ProductSkuServiceTest.java | 171 ++++++ .../spu/ProductSpuServiceImplTest.java | 359 ++++++++++++ .../test/resources/application-unit-test.yaml | 50 ++ .../src/test/resources/logback.xml | 4 + .../src/test/resources/sql/clean.sql | 5 +- .../src/test/resources/sql/create_tables.sql | 16 + .../yudao-module-promotion-api/pom.xml | 33 ++ .../promotion/api/coupon/CouponApi.java | 21 + .../api/coupon/dto/CouponUseReqDTO.java | 33 ++ .../module/promotion/api/package-info.java | 4 + .../module/promotion/api/price/PriceApi.java | 21 + .../api/price/dto/CouponMeetRespDTO.java | 35 ++ .../api/price/dto/PriceCalculateReqDTO.java | 56 ++ .../api/price/dto/PriceCalculateRespDTO.java | 257 ++++++++ .../promotion/enums/ErrorCodeConstants.java | 60 ++ .../common/PromotionActivityStatusEnum.java | 39 ++ .../common/PromotionConditionTypeEnum.java | 37 ++ .../common/PromotionDiscountTypeEnum.java | 38 ++ .../enums/common/PromotionLevelEnum.java | 40 ++ .../common/PromotionProductScopeEnum.java | 38 ++ .../enums/common/PromotionTypeEnum.java | 40 ++ .../enums/coupon/CouponStatusEnum.java | 39 ++ .../enums/coupon/CouponTakeTypeEnum.java | 37 ++ .../CouponTemplateValidityTypeEnum.java | 38 ++ .../yudao-module-promotion-biz/pom.xml | 77 +++ .../promotion/api/coupon/CouponApiImpl.java | 27 + .../promotion/api/discount/package-info.java | 1 + .../promotion/api/price/PriceApiImpl.java | 26 + .../admin/banner/BannerController.java | 74 +++ .../admin/banner/vo/BannerBaseVO.java | 42 ++ .../admin/banner/vo/BannerCreateReqVO.java | 17 + .../admin/banner/vo/BannerPageReqVO.java | 37 ++ .../admin/banner/vo/BannerRespVO.java | 25 + .../admin/banner/vo/BannerUpdateReqVO.java | 23 + .../admin/coupon/CouponController.java | 75 +++ .../coupon/CouponTemplateController.java | 79 +++ .../admin/coupon/vo/coupon/CouponBaseVO.java | 103 ++++ .../vo/coupon/CouponPageItemRespVO.java | 17 + .../coupon/vo/coupon/CouponPageReqVO.java | 33 ++ .../admin/coupon/vo/coupon/CouponRespVO.java | 22 + .../vo/template/CouponTemplateBaseVO.java | 154 +++++ .../template/CouponTemplateCreateReqVO.java | 14 + .../vo/template/CouponTemplatePageReqVO.java | 33 ++ .../vo/template/CouponTemplateRespVO.java | 34 ++ .../template/CouponTemplateUpdateReqVO.java | 20 + .../CouponTemplateUpdateStatusReqVO.java | 23 + .../discount/DiscountActivityController.java | 87 +++ .../discount/vo/DiscountActivityBaseVO.java | 81 +++ .../vo/DiscountActivityCreateReqVO.java | 25 + .../vo/DiscountActivityDetailRespVO.java | 21 + .../vo/DiscountActivityPageReqVO.java | 30 + .../discount/vo/DiscountActivityRespVO.java | 27 + .../vo/DiscountActivityUpdateReqVO.java | 30 + .../reward/RewardActivityController.java | 83 +++ .../admin/reward/vo/RewardActivityBaseVO.java | 98 ++++ .../reward/vo/RewardActivityCreateReqVO.java | 14 + .../reward/vo/RewardActivityPageReqVO.java | 21 + .../admin/reward/vo/RewardActivityRespVO.java | 25 + .../reward/vo/RewardActivityUpdateReqVO.java | 20 + .../seckill/SeckillActivityController.java | 96 +++ .../admin/seckill/SeckillTimeController.java | 72 +++ .../vo/activity/SeckillActivityBaseVO.java | 65 +++ .../activity/SeckillActivityCreateReqVO.java | 37 ++ .../activity/SeckillActivityDetailRespVO.java | 21 + .../vo/activity/SeckillActivityPageReqVO.java | 36 ++ .../vo/activity/SeckillActivityRespVO.java | 41 ++ .../activity/SeckillActivityUpdateReqVO.java | 41 ++ .../seckill/vo/time/SeckillTimeBaseVO.java | 28 + .../vo/time/SeckillTimeCreateReqVO.java | 14 + .../seckill/vo/time/SeckillTimePageReqVO.java | 29 + .../seckill/vo/time/SeckillTimeRespVO.java | 25 + .../vo/time/SeckillTimeUpdateReqVO.java | 20 + .../app/AppMarketTestController.java | 24 + .../app/banner/AppBannerController.java | 42 ++ .../convert/banner/BannerConvert.java | 28 + .../convert/coupon/CouponConvert.java | 21 + .../convert/coupon/CouponTemplateConvert.java | 29 + .../discount/DiscountActivityConvert.java | 102 ++++ .../promotion/convert/price/PriceConvert.java | 49 ++ .../convert/reward/RewardActivityConvert.java | 29 + .../SeckillActivityConvert.java | 83 +++ .../seckilltime/SeckillTimeConvert.java | 34 ++ .../dal/dataobject/banner/BannerDO.java | 53 ++ .../dal/dataobject/coupon/CouponDO.java | 139 +++++ .../dataobject/coupon/CouponTemplateDO.java | 162 ++++++ .../discount/DiscountActivityDO.java | 55 ++ .../discount/DiscountProductDO.java | 65 +++ .../dataobject/reward/RewardActivityDO.java | 133 +++++ .../seckillactivity/SeckillActivityDO.java | 78 +++ .../seckillactivity/SeckillProductDO.java | 65 +++ .../seckill/seckilltime/SeckillTimeDO.java | 47 ++ .../dal/mysql/banner/BannerMapper.java | 26 + .../dal/mysql/coupon/CouponMapper.java | 52 ++ .../mysql/coupon/CouponTemplateMapper.java | 30 + .../discount/DiscountActivityMapper.java | 30 + .../mysql/discount/DiscountProductMapper.java | 26 + .../mysql/reward/RewardActivityMapper.java | 38 ++ .../SeckillActivityMapper.java | 26 + .../seckillactivity/SeckillProductMapper.java | 35 ++ .../seckilltime/SeckillTimeMapper.java | 37 ++ .../promotion/framework/package-info.java | 6 + .../web/config/PromotionWebConfiguration.java | 24 + .../promotion/framework/web/package-info.java | 4 + .../yudao/module/promotion/package-info.java | 8 + .../service/banner/BannerService.java | 63 ++ .../service/banner/BannerServiceImpl.java | 78 +++ .../service/coupon/CouponService.java | 70 +++ .../service/coupon/CouponServiceImpl.java | 123 ++++ .../service/coupon/CouponTemplateService.java | 72 +++ .../coupon/CouponTemplateServiceImpl.java | 94 +++ .../discount/DiscountActivityService.java | 86 +++ .../discount/DiscountActivityServiceImpl.java | 196 +++++++ .../discount/bo/DiscountProductDetailBO.java | 50 ++ .../promotion/service/price/PriceService.java | 32 + .../service/price/PriceServiceImpl.java | 547 ++++++++++++++++++ .../service/reward/RewardActivityService.java | 73 +++ .../reward/RewardActivityServiceImpl.java | 169 ++++++ .../SeckillActivityService.java | 80 +++ .../SeckillActivityServiceImpl.java | 226 ++++++++ .../seckilltime/SeckillTimeService.java | 76 +++ .../seckilltime/SeckillTimeServiceImpl.java | 124 ++++ .../module/promotion/util/PromotionUtils.java | 32 + .../mapper/coupon/CouponTemplateMapper.xml | 11 + .../coupon/CouponTemplateServiceImplTest.java | 147 +++++ .../DiscountActivityServiceImplTest.java | 210 +++++++ .../service/price/PriceServiceTest.java | 506 ++++++++++++++++ .../reward/RewardActivityServiceImplTest.java | 218 +++++++ .../SeckillActivityServiceImplTest.java | 170 ++++++ .../SeckillTimeServiceImplTest.java | 189 ++++++ .../test/resources/application-unit-test.yaml | 49 ++ .../src/test/resources/logback.xml | 4 + .../src/test/resources/sql/clean.sql | 6 + .../src/test/resources/sql/create_tables.sql | 124 ++++ .../yudao-module-trade-api/pom.xml | 26 + .../trade/enums/ErrorCodeConstants.java | 49 ++ .../aftersale/TradeAfterSaleStatusEnum.java | 67 +++ .../aftersale/TradeAfterSaleTypeEnum.java | 37 ++ .../aftersale/TradeAfterSaleWayEnum.java | 37 ++ .../order/TradeOrderAfterSaleStatusEnum.java | 38 ++ .../enums/order/TradeOrderCancelTypeEnum.java | 39 ++ .../order/TradeOrderDeliveryStatusEnum.java | 28 + .../TradeOrderItemAfterSaleStatusEnum.java | 52 ++ .../enums/order/TradeOrderStatusEnum.java | 118 ++++ .../trade/enums/order/TradeOrderTypeEnum.java | 39 ++ .../yudao-module-trade-biz/pom.xml | 94 +++ .../aftersale/TradeAfterSaleController.http | 4 + .../aftersale/TradeAfterSaleController.java | 113 ++++ .../aftersale/vo/TradeAfterSaleBaseVO.java | 119 ++++ .../vo/TradeAfterSaleDisagreeReqVO.java | 21 + .../aftersale/vo/TradeAfterSalePageReqVO.java | 49 ++ .../vo/TradeAfterSaleRefuseReqVO.java | 20 + .../vo/TradeAfterSaleRespPageItemVO.java | 35 ++ .../vo/log/TradeAfterSaleLogRespVO.java | 50 ++ .../admin/base/member/package-info.java | 4 + .../base/member/user/MemberUserRespVO.java | 19 + .../controller/admin/base/package-info.java | 4 + .../ProductPropertyValueDetailRespVO.java | 22 + .../admin/order/TradeOrderController.http | 9 + .../admin/order/TradeOrderController.java | 93 +++ .../admin/order/vo/TradeOrderBaseVO.java | 145 +++++ .../order/vo/TradeOrderDeliveryReqVO.java | 25 + .../order/vo/TradeOrderDetailRespVO.java | 38 ++ .../admin/order/vo/TradeOrderItemBaseVO.java | 70 +++ .../order/vo/TradeOrderPageItemRespVO.java | 32 + .../admin/order/vo/TradeOrderPageReqVO.java | 53 ++ .../AppTradeAfterSaleController.java | 50 ++ .../vo/AppTradeAfterSaleCreateReqVO.java | 40 ++ .../vo/AppTradeAfterSaleDeliveryReqVO.java | 30 + .../controller/app/base/package-info.java | 4 + .../AppProductPropertyValueDetailRespVO.java | 22 + .../app/base/sku/AppProductSkuBaseRespVO.java | 34 ++ .../app/base/spu/AppProductSpuBaseRespVO.java | 25 + .../app/cart/TradeCartController.http | 47 ++ .../app/cart/TradeCartController.java | 84 +++ .../app/cart/vo/AppTradeCartDetailRespVO.java | 117 ++++ .../vo/AppTradeCartItemAddCountReqVO.java | 22 + .../vo/AppTradeCartItemUpdateCountReqVO.java | 22 + .../AppTradeCartItemUpdateSelectedReqVO.java | 21 + .../app/order/AppTradeOrderController.http | 37 ++ .../app/order/AppTradeOrderController.java | 102 ++++ .../order/vo/AppTradeOrderCreateReqVO.java | 52 ++ .../order/vo/AppTradeOrderDetailRespVO.java | 149 +++++ .../vo/AppTradeOrderGetCreateInfoRespVO.java | 168 ++++++ .../order/vo/AppTradeOrderPageItemRespVO.java | 65 +++ .../app/order/vo/AppTradeOrderPageReqVO.java | 18 + .../module/trade/controller/package-info.java | 6 + .../aftersale/TradeAfterSaleConvert.java | 89 +++ .../trade/convert/cart/TradeCartConvert.java | 45 ++ .../convert/order/TradeOrderConvert.java | 241 ++++++++ .../aftersale/TradeAfterSaleDO.java | 201 +++++++ .../aftersale/TradeAfterSaleLogDO.java | 83 +++ .../dal/dataobject/cart/TradeCartItemDO.java | 90 +++ .../dal/dataobject/order/TradeOrderDO.java | 257 ++++++++ .../dataobject/order/TradeOrderItemDO.java | 190 ++++++ .../aftersale/TradeAfterSaleLogMapper.java | 9 + .../mysql/aftersale/TradeAfterSaleMapper.java | 35 ++ .../dal/mysql/cart/TradeCartItemMapper.java | 47 ++ .../dal/mysql/order/TradeOrderItemMapper.java | 27 + .../dal/mysql/order/TradeOrderMapper.java | 46 ++ .../module/trade/dal/mysql/package-info.java | 4 + .../order/config/TradeOrderConfig.java | 14 + .../order/config/TradeOrderProperties.java | 33 ++ .../module/trade/framework/package-info.java | 6 + .../web/config/OrderWebConfiguration.java | 24 + .../trade/framework/web/package-info.java | 4 + .../yudao/module/trade/package-info.java | 8 + .../aftersale/TradeAfterSaleService.java | 94 +++ .../aftersale/TradeAfterSaleServiceImpl.java | 392 +++++++++++++ .../trade/service/cart/TradeCartService.java | 66 +++ .../service/cart/TradeCartServiceImpl.java | 184 ++++++ .../service/order/TradeOrderService.java | 142 +++++ .../service/order/TradeOrderServiceImpl.java | 530 +++++++++++++++++ .../aftersale/TradeAfterSaleServiceTest.java | 154 +++++ .../service/order/TradeOrderServiceTest.java | 320 ++++++++++ .../test/resources/application-unit-test.yaml | 53 ++ .../src/test/resources/logback.xml | 4 + .../src/test/resources/sql/clean.sql | 4 + .../src/test/resources/sql/create_tables.sql | 128 ++++ yudao-server/pom.xml | 1 - 339 files changed, 21163 insertions(+), 11 deletions(-) delete mode 100644 yudao-module-mall/README.md create mode 100644 yudao-module-mall/pom.xml delete mode 100755 yudao-module-mall/yudao-module-mall.zip create mode 100644 yudao-module-mall/yudao-module-product-api/pom.xml create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/dto/ProductPropertyValueDetailRespDTO.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuUpdateStockReqDTO.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentAuditStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-product-biz/pom.xml create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/propertyvalue/ProductPropertyValueConvert.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/package-info.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/web/config/ProductWebConfiguration.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/framework/web/package-info.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/package-info.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/bo/ProductPropertyValueDetailRespBO.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImplTest.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java create mode 100755 yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java create mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml create mode 100644 yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml create mode 100644 yudao-module-mall/yudao-module-promotion-api/pom.xml create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponUseReqDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/CouponMeetRespDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionDiscountTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTakeTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTemplateValidityTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/pom.xml create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponController.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/CouponTemplateController.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageItemRespVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponPageReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponRespVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateCreateReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateRespVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateUpdateStatusReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityBaseVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityCreateReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityPageReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/RewardActivityController.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityBaseVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityCreateReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityPageReqVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityRespVO.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/reward/vo/RewardActivityUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillTimeController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeBaseVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeRespVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/time/SeckillTimeUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/reward/RewardActivityConvert.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckilltime/SeckillTimeConvert.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckilltime/SeckillTimeDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountActivityMapper.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckilltime/SeckillTimeMapper.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/web/config/PromotionWebConfiguration.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/framework/web/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateService.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/bo/DiscountProductDetailBO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityService.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckilltime/SeckillTimeServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/resources/mapper/coupon/CouponTemplateMapper.xml create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImplTest.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImplTest.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java create mode 100755 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImplTest.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckilltime/SeckillTimeServiceImplTest.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql create mode 100644 yudao-module-mall/yudao-module-trade-api/pom.xml create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/aftersale/TradeAfterSaleWayEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderAfterSaleStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderCancelTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderItemAfterSaleStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/pom.xml create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.http create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleBaseVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDisagreeReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSalePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRefuseReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleRespPageItemVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/log/TradeAfterSaleLogRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/member/user/MemberUserRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/base/product/property/ProductPropertyValueDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.http create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java create mode 100755 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderItemBaseVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/AppTradeAfterSaleController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/property/AppProductPropertyValueDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/sku/AppProductSkuBaseRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/base/spu/AppProductSpuBaseRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.http create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/TradeCartController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemAddCountReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateCountReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/vo/AppTradeCartItemUpdateSelectedReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderGetCreateInfoRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleDO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/TradeAfterSaleLogDO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/cart/TradeCartItemDO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleLogMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/aftersale/TradeAfterSaleMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/TradeCartItemMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderItemMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderConfig.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/web/config/OrderWebConfiguration.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/web/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/package-info.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleService.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartService.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceTest.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/application-unit-test.yaml create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/logback.xml create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/clean.sql create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql diff --git a/pom.xml b/pom.xml index 439f56046..9a2cf0e72 100644 --- a/pom.xml +++ b/pom.xml @@ -17,10 +17,10 @@ yudao-module-system yudao-module-infra yudao-module-pay - yudao-module-bpm + - + yudao-example diff --git a/yudao-module-mall/README.md b/yudao-module-mall/README.md deleted file mode 100644 index 6664ebef7..000000000 --- a/yudao-module-mall/README.md +++ /dev/null @@ -1,4 +0,0 @@ -mall 后端的代码,暂时归档成一个 yudao-module-mall 的压缩包。 - -精力有限,近期还是以管理后台的工作流、大屏报表等功能为主! - diff --git a/yudao-module-mall/pom.xml b/yudao-module-mall/pom.xml new file mode 100644 index 000000000..37484f00c --- /dev/null +++ b/yudao-module-mall/pom.xml @@ -0,0 +1,29 @@ + + + + yudao + cn.iocoder.boot + ${revision} + + 4.0.0 + + yudao-module-mall + pom + + ${project.artifactId} + + + 商城大模块,由 product 商品、promotion 营销、trade 交易等组成 + + + yudao-module-promotion-api + yudao-module-promotion-biz + yudao-module-product-api + yudao-module-product-biz + yudao-module-trade-api + yudao-module-trade-biz + + + diff --git a/yudao-module-mall/yudao-module-mall.zip b/yudao-module-mall/yudao-module-mall.zip deleted file mode 100755 index 9f361e3f73c2001b4d89fa2cdbde6b896ae831c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 426292 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 z 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 z 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 vjS3Q(FjFFS#egzyahS9w^54hB-Eo5&2_4rQ0{w zrKRJo&VR$uq7~Yh`>d%Wlmb5uH#NjkM)p-SIN!YS1rS#^5Lf!tDTl{70l%9vEEv*Q z;-!!JJ(>FH^P)NXr>}(`cmwf|iM)W|*wNB#)-BKvI)Q#;$^tBRuHk~C2DpQH>{z(J zJZFPlA&;i_n!IW}zdVlwUg(L|xEBmziH4i|rYk4yj}@G}0K^qeXcFy$wSCDJnZB#r z0)hB8GwrF)kRuYIl9ts%1>F1P?bUR_0f1jRw^&wxdu>_xE&%~1u)7QiJXX#6uhki# zC34$|Pf0!j`6Mh1n?_a%C5Ndu=`5!eoz~r@OsjE=fbzQ_F|>j!{Lyl-1&Q%ghQW3( zWq`EM4C`^HR}HnxzVgt5{y;uQ3{5pB|IDxjnh6S~oN$0>X96~*j%-|N&Xp$tPe8td z3yI;DM|s%Ei44OGNKPBy%kffB~YPgzJM)5J!^)r zqO?Jzcp}~)Lrp5#KD+b5WtATY>OVr!|8DnSyyPi?8_(*!m zDKbLVsuu~y868@HCG1cUqul~GSPioe!{#>?)Dz99bwS3^2u4GVGb%$jyR3ij{^#JP zc4jvxjRLhZ}Cy7MsLg?42> zGQ(sT86A>2Igvyb$rmtN;}!2mp!0=*lu$Ib4cYUGb+Q~>>zDQxhG`t?fOt@9LsF9YBc zDBz#qrbCMX|4Ka9s$}-Ut2@5*t`4Ys6%fZmrkK0OUQDfw6d^GpLvN)D;+X4qrg22@g)b);?IQ z4WPkei7aYvPf5-d+rSoofz)PP-v+ zCB?SsRFXcu-?2|eR?z*$k;%-}J;-36C^C7QEwFH9xIdLkj?l>+&#w?#PO~XSTgG}h z+MOwJI(%S6qA9)nJbzjl`^?cF@fJM=Cq>Kze8h^#;5~6tY!t5%(%tSDo>? zr4s%U39i*#fi9LnZZayB5s?dD0?0qK`&rzBDPV}D0* z%K(%N`lpmU{(0Tm&^`F>iG1KJFCt*8xi)Y_0~=GO(MftL1*G2=`1+$pr@JOfs)c(KSM6(Rjw1-6A`$4833MQ~3J& ztxh<(hJ%bpk|;HImkl6|!_2~y`HD=t6z#ye8E$5%f*&o&oeaeeXqN9qyRf5wfH8jofl!W@JItRlf*B~mp*&}_wKG#Gl3Ley)tQD*dKh&@Ir6FYB<4+FbuC;DKg#R zEC~j?+u8?nvcddd46Rw`h}pk|-Rk=$4V;iBVA1HKMH;4=ogXbE!BF5;9?7%3WvE%n zfXcHM7I(lwm(cv;W%GWMm}8a1iBJ*$3l;Poi+_Xp0`BHb>1M|%ZPCs~49P0x)u?(F z!1)cjn>G>6r!s^^+cXFkN-`-!ox2357p`xcw+i%lS{$dY&wI#9z0 z&pY@hfPce1-+!jr@fsMl@UXJmXXWcWZ80!-0~i$MqL{&3j1ckG!o=v_kSWXe{)&^0 z2XNLA{)9CzjMQO{*|{@0BWmUod5`Z*c%ggty*betxj&#tlRk115su$zA1rG_=bDi( z0+FFb@$@csr@~*O|H{Y<6OUrz>mjV>vBX826^SEfn+13mD9y0cM1%jSnF2l@mD?Yqqk%Y+zs9XMDLd zaLblJxE>B&fI&ou85(Y52#Yc@1`NWCzP(qS$2%V^w+G*+Bm4zYy`DGAOi)dll@GGi zMFb2{pl$vxGhtFl949@@?jpGsD>_4{)NV6FF*GDjNiJ_oM9bu5!PP&|SR81}U;{|7 zAh0SadGxZoOHyC53kUKAY==FLn3*?el{{?gpq=lX7LT$4m0S;0GRK3$8tyN4plDre zjKg(tH6fBJJpTME=5WMGGjnL5)y|ClqkET#5*;JKYfc8OMn_maF~P&DGh?J3O*lrL zhKOoWq~-eStEA}`TpZ<5!NmHN3@snz_=|kS-p&s}NqR#}pg#X$EIggQ?ZXnMZH7)7 zIFtA!a^efPw-e8O6L9f)n;#lC+QxqmUK;WR{PEM@{&9nYsHPXqe87JcUWCO+TtlVv z-wa^_!jU9v%9kRmX~7q8HSs@Ejp#5c_v9H6F%}*-{uS4B_6KW{I*v*akVfu# zK%J->8(sJT3QZnJHLP{+)qGX((t|JHmd^XB^-3H`b-*g^3tuC=&@oY)i$Am3y6W|d zs-$EE{a$E034@M_CYlq5G9orShEO)J>^$C^npo2@QFO_SoM^!ejE;;YkKU1?dIicf zIlMO@?iA?1JmA-kBFIv6iOe8rm%lq;e4eWKFl9R+&mhizHnHWu1U}K?*|RHV=T8wC z9HBjbO{)&3=Ad{2;nTMtL#8&Ic%%N=n@+ctnyUJRk1M=T*^?s zitV{AH#rX_Kn{a7zc>o^tLtWm-7Y#hGP-SK06y_OMkS9>iI4e0Xuzb;B9!n$~SzGPgh%H&5?WTfD zFpOsi&xJQIgT&i6oW(08dKFh!I_{sF^QZ-)cN+eLtXK>*?;8f(>7)*fu#~Ko2n;w+ zkSCJ0{cp_;kUBa5<{kMID@ZuBthu~n07ooqzGEDE_iVm5_hirOBEN5^7hbWUE`+uysDnemzm(=j^>{!EV$(Gq0CIV!* zKU*|B27F=wSwB2NC5DF#ed^lhi))<@rP_i}wt_!lfe(-0QLy3VE2-FE=5Z#vCYpzX kVnS5OAS5D+4PbvoVwJ)gL=bOgP*|N#$c4Hh2qmNc1N9_j)c^nh diff --git a/yudao-module-mall/yudao-module-product-api/pom.xml b/yudao-module-mall/yudao-module-product-api/pom.xml new file mode 100644 index 000000000..123e7c334 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + cn.iocoder.boot + yudao-module-mall + ${revision} + + + yudao-module-product-api + jar + + ${project.artifactId} + + product 模块 API,暴露给其它模块调用 + + + + + cn.iocoder.boot + yudao-common + + + + + org.springframework.boot + spring-boot-starter-validation + true + + + + diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java new file mode 100644 index 000000000..b19092853 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位 + */ +package cn.iocoder.yudao.module.product.api; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java new file mode 100644 index 000000000..83269f91d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.product.api.property; + +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; + +import java.util.Collection; +import java.util.List; + +/** + * 商品属性值 API 接口 + * + * @author 芋道源码 + */ +public interface ProductPropertyValueApi { + + /** + * 根据编号数组,获得属性值列表 + * + * @param ids 编号数组 + * @return 属性值明细列表 + */ + List getPropertyValueDetailList(Collection ids); + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/dto/ProductPropertyValueDetailRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/dto/ProductPropertyValueDetailRespDTO.java new file mode 100644 index 000000000..2a1ab71a9 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/dto/ProductPropertyValueDetailRespDTO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.product.api.property.dto; + +import lombok.Data; + +/** + * 商品属性项的明细 Response DTO + * + * @author 芋道源码 + */ +@Data +public class ProductPropertyValueDetailRespDTO { + + /** + * 属性的编号 + */ + private Long propertyId; + + /** + * 属性的名称 + */ + private String propertyName; + + /** + * 属性值的编号 + */ + private Long valueId; + + /** + * 属性值的名称 + */ + private String valueName; + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java new file mode 100644 index 000000000..d5d93dc37 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.product.api.sku; + +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; + +import java.util.Collection; +import java.util.List; + +/** + * 商品 SKU API 接口 + * + * @author LeeYan9 + * @since 2022-08-26 + */ +public interface ProductSkuApi { + + /** + * 查询 SKU 信息 + * + * @param id SKU 编号 + * @return SKU 信息 + */ + ProductSkuRespDTO getSku(Long id); + + /** + * 批量查询 SKU 数组 + * + * @param ids SKU 编号列表 + * @return SKU 数组 + */ + List getSkuList(Collection ids); + + /** + * 更新 SKU 库存 + * + * @param updateStockReqDTO 更新请求 + */ + void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO); + +} diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java new file mode 100644 index 000000000..aaaf767f2 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.product.api.sku.dto; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import lombok.Data; + +import java.util.List; + +/** + * 商品 SKU 信息 Response DTO + * + * @author LeeYan9 + * @since 2022-08-26 + */ +@Data +public class ProductSkuRespDTO { + + /** + * 商品 SKU 编号,自增 + */ + private Long id; + /** + * SPU 编号 + */ + private Long spuId; + /** + * SPU 名字 + */ + private String spuName; + + /** + * 属性数组,JSON 格式 + */ + private List properties; + /** + * 销售价格,单位:分 + */ + private Integer price; + /** + * 市场价,单位:分 + */ + private Integer marketPrice; + /** + * 成本价,单位:分 + */ + private Integer costPrice; + /** + * SKU 的条形码 + */ + private String barCode; + /** + * 图片地址 + */ + private String picUrl; + /** + * SKU 状态 + *