158 files added
8 files modified
7659 ■■■■■ changed files
.gitignore 34 ●●●●● patch | view | raw | blame | history
.idea/vcs.xml 6 ●●●●● patch | view | raw | blame | history
oying-common/src/main/java/com/oying/utils/HttpRequest.java 101 ●●●●● patch | view | raw | blame | history
oying-common/src/main/java/com/oying/utils/RedisUtils.java 10 ●●●●● patch | view | raw | blame | history
oying-generator/src/main/resources/template/admin/Entity.ftl 6 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/AppRun.java 1 ●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/domain/MessageOrderBuyer.java 50 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/domain/MessageOrderLeave.java 50 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/domain/MessageOrderSeller.java 50 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/domain/MessageSystem.java 42 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/domain/dto/MessageOrderBuyerQueryCriteria.java 18 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/domain/dto/MessageOrderLeaveQueryCriteria.java 18 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/domain/dto/MessageOrderSellerQueryCriteria.java 18 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/domain/dto/MessageSystemQueryCriteria.java 18 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/mapper/MessageOrderBuyerMapper.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/mapper/MessageOrderLeaveMapper.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/mapper/MessageOrderSellerMapper.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/mapper/MessageSystemMapper.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/rest/MessageOrderBuyerController.java 107 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/rest/MessageOrderLeaveController.java 192 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/rest/MessageOrderSellerController.java 108 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/rest/MessageSystemController.java 105 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/service/MessageOrderBuyerService.java 63 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/service/MessageOrderLeaveService.java 69 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/service/MessageOrderSellerService.java 62 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/service/MessageSystemService.java 64 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/service/impl/MessageOrderBuyerServiceImpl.java 83 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/service/impl/MessageOrderLeaveServiceImpl.java 89 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/service/impl/MessageOrderSellerServiceImpl.java 84 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/message/service/impl/MessageSystemServiceImpl.java 79 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryDtoAssembler.java 10 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryViewAssembler.java 25 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/domain/PlatformCategory.java 72 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryCreateRequest.java 33 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryQueryCriteria.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateDto.java 21 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateRequest.java 24 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/mapper/PlatformCategoryMapper.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryAdminController.java 83 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryCustomerController.java 43 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/service/PlatformCategoryService.java 59 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/service/impl/PlatformCategoryServiceImpl.java 90 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryCustomerView.java 16 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryView.java 33 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/common/core/constrant/Constants.java 50 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/common/core/domain/R.java 102 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/common/exception/LevelExceededException.java 13 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdGenerator.java 15 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdentifierGenerator.java 11 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/common/id/StoreQualificationIdGenerator.java 15 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/domain/Product.java 120 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductCategory.java 52 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCategoryQueryCriteria.java 18 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCustomerQueryCriteria.java 21 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageCreateRequest.java 9 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelCreateRequest.java 16 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantCreateRequest.java 52 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantUpdateRequest.java 45 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java 34 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductCategoryMapper.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductMapper.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java 73 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java 84 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductMerchantController.java 141 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductCategoryService.java 60 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductMerchantService.java 16 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductService.java 60 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductCategoryServiceImpl.java 79 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantCreateServiceImpl.java 59 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java 106 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerDetailsView.java 24 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java 25 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductImageCustomerView.java 12 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductLabelCustomerView.java 13 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantDetailsView.java 25 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantSimpleView.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductOverviewView.java 4 ●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductSimpleView.java 21 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/NearbyStoreQueryCriteria.java 38 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/StoreSearchDto.java 17 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/search/rest/StoreSearchController.java 58 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/search/service/StoreSearchService.java 10 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/search/service/impl/StoreSearchServiceImpl.java 25 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/search/view/StoreSearchView.java 27 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreDtoAssembler.java 7 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreViewAssembler.java 7 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/Store.java 135 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreCategory.java 70 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreLocation.java 57 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreQualification.java 75 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreStatus.java 5 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreBusinessHoursRequest.java 18 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryCreateRequest.java 18 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantCreateRequest.java 20 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantUpdateRequest.java 16 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryQueryCriteria.java 26 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryUpdateRequest.java 20 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java 90 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java 26 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerQueryCriteria.java 16 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreFieldUpdateRequest.java 92 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreLocationUpdateRequest.java 17 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationCreateRequest.java 26 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationQueryCriteria.java 24 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationUpdateRequest.java 27 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java 31 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreStatusEnum.java 21 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreCategoryMapper.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java 34 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreQualificationMapper.java 24 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryController.java 65 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryCustomerController.java 71 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryMerchantController.java 136 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java 68 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java 36 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java 263 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationController.java 67 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java 55 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationMerchantController.java 100 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCategoryService.java 52 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreateService.java 7 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreationCoordinator.java 31 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreMerchantOwnershipService.java 12 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java 57 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQueryService.java 10 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java 56 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCategoryServiceImpl.java 96 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java 51 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantOwnershipServiceImpl.java 59 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java 79 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQueryServiceImpl.java 33 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java 159 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreCategoryView.java 25 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreQualificationView.java 21 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreView.java 28 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreCategoryMerchantView.java 23 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreMerchantView.java 48 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreQualificationMerchantView.java 24 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreSimpleView.java 16 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/pc/utils/WrapperUtils.java 18 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/security/config/SwiftPassProperties.java 40 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/security/config/WeiXinProperties.java 31 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/security/rest/AuthController.java 2 ●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/security/rest/VerificationController.java 44 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/security/service/WeiXinService.java 112 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/system/domain/Merchants.java 68 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/system/domain/dto/MerchantsQueryCriteria.java 36 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/system/mapper/MerchantsMapper.java 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/system/rest/MerchantsController.java 73 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/system/service/MerchantsService.java 59 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/system/service/impl/MerchantsServiceImpl.java 86 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/config/application-dev.yml 58 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/config/application-prod.yml 53 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/config/application.yml 8 ●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/message/MessageOrderBuyerMapper.xml 25 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/message/MessageOrderLeaveMapper.xml 25 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/message/MessageOrderSellerMapper.xml 25 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/message/MessageSystemMapper.xml 22 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/pc/category/PlatformCategoryMapper.xml 34 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml 60 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/pc/search/SearchMapper.xml 56 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml 40 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml 108 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/pc/store/StoreQualificationMapper.xml 36 ●●●●● patch | view | raw | blame | history
oying-system/src/main/resources/mapper/system/MerchantsMapper.xml 48 ●●●●● patch | view | raw | blame | history
pom.xml 14 ●●●●● patch | view | raw | blame | history
.gitignore
New file
@@ -0,0 +1,34 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
*.pid
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
.idea/vcs.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="$PROJECT_DIR$" vcs="Git" />
  </component>
</project>
oying-common/src/main/java/com/oying/utils/HttpRequest.java
New file
@@ -0,0 +1,101 @@
package com.oying.utils;
import com.alibaba.fastjson2.JSONObject;
import com.oying.exception.BadRequestException;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.SSLContext;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
/**
 * 功能描述:
 *
 * @author LIX
 * @date 创建时间 :2022/6/15 下午4:19
 */
public class HttpRequest {
    /**
     * 读取请求数据流
     *
     * @param request 请求数据
     * @return String
     */
    public static String getRequestBody(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        try (ServletInputStream inputStream = request.getInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            throw new BadRequestException("读取数据流异常");
        }
        return sb.toString();
    }
    /**
     * 忽略ssl证书验证
     *
     * @return HttpComponentsClientHttpRequestFactory
     */
    public static HttpComponentsClientHttpRequestFactory getFactory() {
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        try {
            TrustStrategy acceptingTrustStrategy = (chain, authType) -> true;
            SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
            HttpClientBuilder clientBuilder = HttpClients.custom();
            CloseableHttpClient httpClient = clientBuilder.setSSLSocketFactory(socketFactory).build();
            requestFactory.setHttpClient(httpClient);
        } catch (Exception e) {
            throw new BadRequestException("忽略ssl证书验证失败!!!");
        }
        return requestFactory;
    }
    private static HttpHeaders getHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        return headers;
    }
    /**
     * http返回String
     */
    public static String exchangeString(HttpMethod httpMethod, String url, Map<String, Object> map) {
        HttpHeaders headers = getHeaders();
        HttpEntity<Object> httpEntity = new HttpEntity<>(map, headers);
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.exchange(url, httpMethod, httpEntity, String.class).getBody();
    }
    /**
     * http返回JSONObject
     */
    public static JSONObject exchangeJsonObject(HttpMethod httpMethod, String url, Map<String, Object> map) {
        HttpHeaders headers = getHeaders();
        HttpEntity<Object> httpEntity = new HttpEntity<>(map, headers);
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.exchange(url, httpMethod, httpEntity, JSONObject.class).getBody();
    }
}
oying-common/src/main/java/com/oying/utils/RedisUtils.java
@@ -31,6 +31,16 @@
    }
    /**
     * 判断key是否过期
     *
     * @param key
     * @return
     */
    public boolean isExpire(Object key) {
        return getExpire(key) > 1 ? false : true;
    }
    /**
     * 指定缓存失效时间
     *
     * @param key  键
oying-generator/src/main/resources/template/admin/Entity.ftl
@@ -1,6 +1,7 @@
package ${package}.domain;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
@@ -41,7 +42,8 @@
* @author ${author}
* @date ${date}
**/
@Data
@Getter
@Setter
@TableName("${tableName}")
public class ${className} implements Serializable {
<#if columns??>
oying-system/src/main/java/com/oying/AppRun.java
@@ -5,6 +5,7 @@
import lombok.extern.slf4j.Slf4j;
import com.oying.annotation.rest.AnonymousGetMapping;
import com.oying.utils.SpringBeanHolder;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.ApplicationPidFileWriter;
oying-system/src/main/java/com/oying/modules/message/domain/MessageOrderBuyer.java
New file
@@ -0,0 +1,50 @@
package com.oying.modules.message.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import java.sql.Timestamp;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* @description /
* @author 李萌
* @date 2025-05-20
**/
@Data
@TableName("message_order_buyer")
public class MessageOrderBuyer implements Serializable {
    @TableId(value = "id", type = IdType.AUTO)
    @ApiModelProperty(value = "主键,自增 用户id")
    private Integer id;
    @NotNull
    @ApiModelProperty(value = "订单ID")
    private Integer orderId;
    @NotBlank
    @ApiModelProperty(value = "消息类型(订单状态变化、订单送达)")
    private String messageType;
    @NotBlank
    @ApiModelProperty(value = "消息内容")
    private String messageContent;
    @NotBlank
    @ApiModelProperty(value = "跳转链接")
    private String link;
    @ApiModelProperty(value = "创建时间")
    private Timestamp createTime;
    public void copy(MessageOrderBuyer source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/message/domain/MessageOrderLeave.java
New file
@@ -0,0 +1,50 @@
package com.oying.modules.message.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import java.sql.Timestamp;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* @description /
* @author 李萌
* @date 2025-05-20
**/
@Data
@TableName("message_order_leave")
public class MessageOrderLeave implements Serializable {
    @TableId(value = "id", type = IdType.AUTO)
    @ApiModelProperty(value = "主键,自增")
    private Integer id;
    @NotNull
    @ApiModelProperty(value = "订单ID")
    private Integer orderId;
    @NotBlank
    @ApiModelProperty(value = "顾客评价内容")
    private String customerReview="顾客尚未评价";
    @NotBlank
    @ApiModelProperty(value = "商家回复内容")
    private String sellerReply="商家尚未回复";
    @NotBlank
    @ApiModelProperty(value = "跳转链接")
    private String link="https://example.com/default-link";
    @ApiModelProperty(value = "创建时间")
    private Timestamp createTime;
    public void copy(MessageOrderLeave source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/message/domain/MessageOrderSeller.java
New file
@@ -0,0 +1,50 @@
package com.oying.modules.message.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import java.sql.Timestamp;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* @description /
* @author 李萌
* @date 2025-05-20
**/
@Data
@TableName("message_order_seller")
public class MessageOrderSeller implements Serializable {
    @TableId(value = "id", type = IdType.AUTO)
    @ApiModelProperty(value = "id")
    private Integer id;
    @NotNull
    @ApiModelProperty(value = "orderId")
    private Integer orderId;
    @NotBlank
    @ApiModelProperty(value = "messageType")
    private String messageType;
    @NotBlank
    @ApiModelProperty(value = "messageContent")
    private String messageContent;
    @NotBlank
    @ApiModelProperty(value = "link")
    private String link;
    @ApiModelProperty(value = "createTime")
    private Timestamp createTime;
    public void copy(MessageOrderSeller source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/message/domain/MessageSystem.java
New file
@@ -0,0 +1,42 @@
package com.oying.modules.message.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import java.sql.Timestamp;
import javax.rmi.CORBA.Tie;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
 * @description /
 * @author 李萌
 * @date 2025-05-20
 **/
@Data
@TableName("message_system")
public class MessageSystem implements Serializable {
    //使用数据库的自增策略来生成id
    @TableId(value = "id", type = IdType.AUTO)
    @ApiModelProperty(value = "id")
    private Integer id;
    @NotNull
    @ApiModelProperty(value = "系统维护开始时间")
    private Timestamp startTime;
    @NotNull
    @ApiModelProperty(value = "系统维护截至时间")
    private Timestamp endTime;
    public void copy(MessageSystem source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/message/domain/dto/MessageOrderBuyerQueryCriteria.java
New file
@@ -0,0 +1,18 @@
package com.oying.modules.message.domain.dto;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
/**
* @author 李萌
* @date 2025-05-20
**/
@Data
public class MessageOrderBuyerQueryCriteria{
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
}
oying-system/src/main/java/com/oying/modules/message/domain/dto/MessageOrderLeaveQueryCriteria.java
New file
@@ -0,0 +1,18 @@
package com.oying.modules.message.domain.dto;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
/**
* @author 李萌
* @date 2025-05-20
**/
@Data
public class MessageOrderLeaveQueryCriteria{
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
}
oying-system/src/main/java/com/oying/modules/message/domain/dto/MessageOrderSellerQueryCriteria.java
New file
@@ -0,0 +1,18 @@
package com.oying.modules.message.domain.dto;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
/**
* @author 李萌
* @date 2025-05-20
**/
@Data
public class MessageOrderSellerQueryCriteria{
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
}
oying-system/src/main/java/com/oying/modules/message/domain/dto/MessageSystemQueryCriteria.java
New file
@@ -0,0 +1,18 @@
package com.oying.modules.message.domain.dto;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
/**
 * @author 李萌
 * @date 2025-05-20
 **/
@Data
public class MessageSystemQueryCriteria{
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
}
oying-system/src/main/java/com/oying/modules/message/mapper/MessageOrderBuyerMapper.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.message.mapper;
import com.oying.modules.message.domain.MessageOrderBuyer;
import com.oying.modules.message.domain.dto.MessageOrderBuyerQueryCriteria;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @author 李萌
* @date 2025-05-20
**/
@Mapper
public interface MessageOrderBuyerMapper extends BaseMapper<MessageOrderBuyer> {
    IPage<MessageOrderBuyer> findAll(@Param("criteria") MessageOrderBuyerQueryCriteria criteria, Page<Object> page);
    List<MessageOrderBuyer> findAll(@Param("criteria") MessageOrderBuyerQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/message/mapper/MessageOrderLeaveMapper.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.message.mapper;
import com.oying.modules.message.domain.MessageOrderLeave;
import com.oying.modules.message.domain.dto.MessageOrderLeaveQueryCriteria;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @author 李萌
* @date 2025-05-20
**/
@Mapper
public interface MessageOrderLeaveMapper extends BaseMapper<MessageOrderLeave> {
    IPage<MessageOrderLeave> findAll(@Param("criteria") MessageOrderLeaveQueryCriteria criteria, Page<Object> page);
    List<MessageOrderLeave> findAll(@Param("criteria") MessageOrderLeaveQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/message/mapper/MessageOrderSellerMapper.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.message.mapper;
import com.oying.modules.message.domain.MessageOrderSeller;
import com.oying.modules.message.domain.dto.MessageOrderSellerQueryCriteria;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @author 李萌
* @date 2025-05-20
**/
@Mapper
public interface MessageOrderSellerMapper extends BaseMapper<MessageOrderSeller> {
    IPage<MessageOrderSeller> findAll(@Param("criteria") MessageOrderSellerQueryCriteria criteria, Page<Object> page);
    List<MessageOrderSeller> findAll(@Param("criteria") MessageOrderSellerQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/message/mapper/MessageSystemMapper.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.message.mapper;
import com.oying.modules.message.domain.MessageSystem;
import com.oying.modules.message.domain.dto.MessageSystemQueryCriteria;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
 * @author 李萌
 * @date 2025-05-20
 **/
@Mapper
public interface MessageSystemMapper extends BaseMapper<MessageSystem> {
    IPage<MessageSystem> findAll(@Param("criteria") MessageSystemQueryCriteria criteria, Page<Object> page);
    List<MessageSystem> findAll(@Param("criteria") MessageSystemQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/message/rest/MessageOrderBuyerController.java
New file
@@ -0,0 +1,107 @@
package com.oying.modules.message.rest;
import com.oying.annotation.Log;
import com.oying.modules.message.domain.MessageOrderBuyer;
import com.oying.modules.message.service.MessageOrderBuyerService;
import com.oying.modules.message.domain.dto.MessageOrderBuyerQueryCriteria;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.utils.PageResult;
/**
* @author 李萌
* @date 2025-05-20
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "买家端订单消息通知")
@RequestMapping("/api/message/messageOrderBuyer")
public class MessageOrderBuyerController {
    private final MessageOrderBuyerService messageOrderBuyerService;
//    @ApiOperation("导出数据")
//    @GetMapping(value = "/download")
//    @PreAuthorize("@el.check('messageOrderBuyer:list')")
//    public void exportMessageOrderBuyer(HttpServletResponse response, MessageOrderBuyerQueryCriteria criteria) throws IOException {
//        messageOrderBuyerService.download(messageOrderBuyerService.queryAll(criteria), response);
//    }
    @GetMapping
    @ApiOperation("查询买家端订单消息通知")
    @PreAuthorize("@el.check('messageOrderBuyer:list')")
    public ResponseEntity<PageResult<MessageOrderBuyer>> queryMessageOrderBuyer(MessageOrderBuyerQueryCriteria criteria){
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        return new ResponseEntity<>(messageOrderBuyerService.queryAll(criteria,page),HttpStatus.OK);
    }
//    @PostMapping
//    @Log("新增买家端订单消息通知")
//    @ApiOperation("新增买家端订单消息通知")
//    @PreAuthorize("@el.check('messageOrderBuyer:add')")
//    public ResponseEntity<Object> createMessageOrderBuyer(@Validated @RequestBody MessageOrderBuyer resources){
//        messageOrderBuyerService.create(resources);
//        return new ResponseEntity<>(HttpStatus.CREATED);
//    }
//
//    @PutMapping
//    @Log("修改买家端订单消息通知")
//    @ApiOperation("修改买家端订单消息通知")
//    @PreAuthorize("@el.check('messageOrderBuyer:edit')")
//    public ResponseEntity<Object> updateMessageOrderBuyer(@Validated @RequestBody MessageOrderBuyer resources){
//        messageOrderBuyerService.update(resources);
//        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
//    }
//
//    @DeleteMapping
//    @Log("删除买家端订单消息通知")
//    @ApiOperation("删除买家端订单消息通知")
//    @PreAuthorize("@el.check('messageOrderBuyer:del')")
//    public ResponseEntity<Object> deleteMessageOrderBuyer(@ApiParam(value = "传ID数组[]") @RequestBody List<Integer> ids) {
//        messageOrderBuyerService.deleteAll(ids);
//        return new ResponseEntity<>(HttpStatus.OK);
//    }
    //订单状态变化通知
    @GetMapping("/status/{order_id}")
    @ApiOperation("查询一条订单状态变化通知")
    public ResponseEntity<String> getMessageOrderBuyer(@PathVariable Integer order_id) {
        MessageOrderBuyer messageOrderBuyer = messageOrderBuyerService.findByOrderId(order_id);
        String message = messageOrderBuyer.getMessageType();
        return new ResponseEntity<>(message, HttpStatus.OK);
    }
    //订单送达通知
    @GetMapping("/deliver/{order_id}")
    @ApiOperation("查询一条订单送达通知")
    public ResponseEntity<String> getMessageOrderBuyerDeliver(@PathVariable Integer order_id) {
        MessageOrderBuyer messageOrderBuyer = messageOrderBuyerService.findByOrderId(order_id);
        String message = messageOrderBuyer.getMessageType();
        //如果MessageType为订单送达,则返回message——content
        if (message.equals("订单送达")) {
            String messageContent = messageOrderBuyer.getMessageContent();
            return new ResponseEntity<>(messageContent, HttpStatus.OK);
        }else{
            //返回没送达
            return new ResponseEntity<>("没送达", HttpStatus.OK);
        }
    }
    //实现点击跳转到订单详情
    @GetMapping("/link/{order_id}")
    @ApiOperation("点击跳转到订单详情")
    public ResponseEntity<String> getMessageOrderBuyerLink(@PathVariable Integer order_id) {
        MessageOrderBuyer messageOrderBuyer = messageOrderBuyerService.findByOrderId(order_id);
        String link = messageOrderBuyer.getLink();
        return new ResponseEntity<>(link, HttpStatus.OK);
    }
}
oying-system/src/main/java/com/oying/modules/message/rest/MessageOrderLeaveController.java
New file
@@ -0,0 +1,192 @@
package com.oying.modules.message.rest;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.oying.annotation.Log;
import com.oying.modules.message.domain.MessageOrderLeave;
import com.oying.modules.message.service.MessageOrderLeaveService;
import com.oying.modules.message.domain.dto.MessageOrderLeaveQueryCriteria;
import lombok.RequiredArgsConstructor;
import java.sql.Timestamp;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.utils.PageResult;
/**
* @author 李萌
* @date 2025-05-20
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "消息留言")
@RequestMapping("/api/message/messageOrderLeave")
public class MessageOrderLeaveController {
    private final MessageOrderLeaveService messageOrderLeaveService;
//    @ApiOperation("导出数据")
//    @GetMapping(value = "/download")
//    @PreAuthorize("@el.check('messageOrderLeave:list')")
//    public void exportMessageOrderLeave(HttpServletResponse response, MessageOrderLeaveQueryCriteria criteria) throws IOException {
//        messageOrderLeaveService.download(messageOrderLeaveService.queryAll(criteria), response);
//    }
    @GetMapping
    @ApiOperation("查询消息留言")
    @PreAuthorize("@el.check('messageOrderLeave:list')")
    public ResponseEntity<PageResult<MessageOrderLeave>> queryMessageOrderLeave(MessageOrderLeaveQueryCriteria criteria){
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        return new ResponseEntity<>(messageOrderLeaveService.queryAll(criteria,page),HttpStatus.OK);
    }
//    @PostMapping
//    @Log("新增消息留言")
//    @ApiOperation("新增消息留言")
//    @PreAuthorize("@el.check('messageOrderLeave:add')")
//    public ResponseEntity<Object> createMessageOrderLeave(@Validated @RequestBody MessageOrderLeave resources){
//        messageOrderLeaveService.create(resources);
//        return new ResponseEntity<>(HttpStatus.CREATED);
//    }
//    @PutMapping
//    @Log("修改消息留言")
//    @ApiOperation("修改消息留言")
//    @PreAuthorize("@el.check('messageOrderLeave:edit')")
//    public ResponseEntity<Object> updateMessageOrderLeave(@Validated @RequestBody MessageOrderLeave resources){
//        messageOrderLeaveService.update(resources);
//        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
//    }
//    @DeleteMapping
//    @Log("删除消息留言")
//    @ApiOperation("删除消息留言")
//    @PreAuthorize("@el.check('messageOrderLeave:del')")
//    public ResponseEntity<Object> deleteMessageOrderLeave(@ApiParam(value = "传ID数组[]") @RequestBody List<Integer> ids) {
//        messageOrderLeaveService.deleteAll(ids);
//        return new ResponseEntity<>(HttpStatus.OK);
//    }
    //顾客点击订单,传回订单id,根据订单id生成一条 消息留言
//    @PutMapping("/customer/{order_id}")
//    @ApiOperation("顾客点击订单,传回订单id,根据订单id生成一条 留言,此时顾客可以留言")
//    public ResponseEntity<Object> createMessageOrderLeave(@PathVariable("order_id") Integer id,@RequestParam String customerReview) {
//        //创建对象
//        MessageOrderLeave messageOrderLeave = new MessageOrderLeave();
//        messageOrderLeave.setOrderId(id);
//        //如果customerReview为空,默认为“用户未留言”
//        messageOrderLeave.setCustomerReview(customerReview);
//        //设置创建时间为当前时间
//        messageOrderLeave.setCreateTime(new Timestamp(System.currentTimeMillis()));
//        //若表中order_id订单还没存在则调用update留言
//
//
//        if(messageOrderLeaveService.findByOrderId(id)==null){
//            messageOrderLeaveService.updateById(messageOrderLeave);
//            return new ResponseEntity<>(HttpStatus.CREATED);
//        } else {
//            // 已存在则不保存,返回 OK 表示成功但无新资源创建
//            return new ResponseEntity<>(HttpStatus.OK);
//        }
//
//    }
    @PutMapping("/customer/{order_id}")
    @ApiOperation("顾客点击订单,传回订单id,根据订单id更新一条留言")
    public ResponseEntity<Object> updateMessageOrderLeaveCustomer(@PathVariable("order_id") Integer id, @RequestBody MessageOrderLeave messageOrderLeave1) {
        // 根据 order_id 查找留言信息
        MessageOrderLeave messageOrderLeave = messageOrderLeaveService.findByOrderId(id);
        // 如果留言信息不存在,返回 404 Not Found
        if (messageOrderLeave == null) {
            return new ResponseEntity<>("Message order leave not found for order ID: " + id, HttpStatus.NOT_FOUND);
        }
        // 设置顾客评价内容
        if (messageOrderLeave1.getCustomerReview() != null && !messageOrderLeave1.getCustomerReview().trim().isEmpty()) {
            messageOrderLeave.setCustomerReview(messageOrderLeave1.getCustomerReview());
        } else {
            messageOrderLeave.setCustomerReview("用户未留言");
        }
        // 更新最后一次操作的时间
        messageOrderLeave.setCreateTime(new Timestamp(System.currentTimeMillis()));
        // 调用服务层更新数据
        boolean updated = messageOrderLeaveService.updateById(messageOrderLeave);
        // 如果更新失败,返回 500 Internal Server Error
        if (!updated) {
            return new ResponseEntity<>("Failed to update message order leave", HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }
    //商家对订单id进行回复
//    @PutMapping("/seller/{order_id}")
//    @ApiOperation("商家对订单id进行回复")
//    public ResponseEntity<Object> updateMessageOrderLeave(@PathVariable("order_id") Integer id, @RequestParam String sellerReply) {
//        // 检查 sellerReply 是否为空
//        if (sellerReply == null || sellerReply.trim().isEmpty()) {
//            return new ResponseEntity<>("sellerReply is required", HttpStatus.BAD_REQUEST);
//        }
//
//        // 根据 order_id 查找留言信息
//        MessageOrderLeave messageOrderLeave = messageOrderLeaveService.findByOrderId(id);
//
//        // 如果没有找到对应的留言信息,返回 404 Not Found
//        if (messageOrderLeave == null) {
//            return new ResponseEntity<>("Message order leave not found for order ID: " + id, HttpStatus.NOT_FOUND);
//        }
//
//        // 设置商家回复内容
//        messageOrderLeave.setSellerReply(sellerReply);
//        // 更新最后一次操作的时间
//        messageOrderLeave.setCreateTime(new Timestamp(System.currentTimeMillis()));
//
//        // 调用服务层更新数据
//        boolean updated = messageOrderLeaveService.updateById(messageOrderLeave);
//
//        // 如果更新失败,返回 500 Internal Server Error
//        if (!updated) {
//            return new ResponseEntity<>("Failed to update message order leave", HttpStatus.INTERNAL_SERVER_ERROR);
//        }
//
//        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
//    }
    //商家对订单id进行回复 订单id必须唯一限制 否则会报错
    @PutMapping("/seller/{order_id}")
    @ApiOperation("商家对订单id进行回复")
    public ResponseEntity<Object> updateMessageOrderLeaveSeller(@PathVariable("order_id") Integer id, @RequestBody MessageOrderLeave messageOrderLeave1) {
        // 根据 order_id 查找留言信息
        MessageOrderLeave messageOrderLeave = messageOrderLeaveService.findByOrderId(id);
        // 如果没有找到对应的留言信息,返回 404 Not Found
        if (messageOrderLeave == null) {
            return new ResponseEntity<>("Message order leave not found for order ID: " + id, HttpStatus.NOT_FOUND);
        }
        // 设置商家回复内容
        messageOrderLeave.setSellerReply(messageOrderLeave1.getSellerReply());
        // 更新最后一次操作的时间
        messageOrderLeave.setCreateTime(new Timestamp(System.currentTimeMillis()));
        // 调用服务层更新数据
        boolean updated = messageOrderLeaveService.updateById(messageOrderLeave);
        // 如果更新失败,返回 500 Internal Server Error
        if (!updated) {
            return new ResponseEntity<>("Failed to update message order leave", HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }
}
oying-system/src/main/java/com/oying/modules/message/rest/MessageOrderSellerController.java
New file
@@ -0,0 +1,108 @@
package com.oying.modules.message.rest;
import com.oying.annotation.Log;
import com.oying.modules.message.domain.MessageOrderSeller;
import com.oying.modules.message.domain.MessageOrderSeller;
import com.oying.modules.message.service.MessageOrderSellerService;
import com.oying.modules.message.domain.dto.MessageOrderSellerQueryCriteria;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.utils.PageResult;
/**
* @author 李萌
* @date 2025-05-20
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "卖家端订单消息通知")
@RequestMapping("/api/message/messageOrderSeller")
public class MessageOrderSellerController {
    private final MessageOrderSellerService messageOrderSellerService;
//    @ApiOperation("导出数据")
//    @GetMapping(value = "/download")
//    @PreAuthorize("@el.check('messageOrderSeller:list')")
//    public void exportMessageOrderSeller(HttpServletResponse response, MessageOrderSellerQueryCriteria criteria) throws IOException {
//        messageOrderSellerService.download(messageOrderSellerService.queryAll(criteria), response);
//    }
    @GetMapping
    @ApiOperation("查询卖家端订单消息通知")
    @PreAuthorize("@el.check('messageOrderSeller:list')")
    public ResponseEntity<PageResult<MessageOrderSeller>> queryMessageOrderSeller(MessageOrderSellerQueryCriteria criteria){
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        return new ResponseEntity<>(messageOrderSellerService.queryAll(criteria,page),HttpStatus.OK);
    }
//    @PostMapping
//    @Log("新增卖家端订单消息通知")
//    @ApiOperation("新增卖家端订单消息通知")
//    @PreAuthorize("@el.check('messageOrderSeller:add')")
//    public ResponseEntity<Object> createMessageOrderSeller(@Validated @RequestBody MessageOrderSeller resources){
//        messageOrderSellerService.create(resources);
//        return new ResponseEntity<>(HttpStatus.CREATED);
//    }
//
//    @PutMapping
//    @Log("修改卖家端订单消息通知")
//    @ApiOperation("修改卖家端订单消息通知")
//    @PreAuthorize("@el.check('messageOrderSeller:edit')")
//    public ResponseEntity<Object> updateMessageOrderSeller(@Validated @RequestBody MessageOrderSeller resources){
//        messageOrderSellerService.update(resources);
//        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
//    }
//
//    @DeleteMapping
//    @Log("删除卖家端订单消息通知")
//    @ApiOperation("删除卖家端订单消息通知")
//    @PreAuthorize("@el.check('messageOrderSeller:del')")
//    public ResponseEntity<Object> deleteMessageOrderSeller(@ApiParam(value = "传ID数组[]") @RequestBody List<Integer> ids) {
//        messageOrderSellerService.deleteAll(ids);
//        return new ResponseEntity<>(HttpStatus.OK);
//    }
    //订单状态变化通知
    @GetMapping("/status/{order_id}")
    @ApiOperation("查询一条订单状态变化通知")
    public ResponseEntity<String> getMessageOrderSeller(@PathVariable Integer order_id) {
        MessageOrderSeller messageOrderSeller = messageOrderSellerService.findByOrderId(order_id);
        String message = messageOrderSeller.getMessageType();
        return new ResponseEntity<>(message, HttpStatus.OK);
    }
    //订单送达通知
    @GetMapping("/deliver/{order_id}")
    @ApiOperation("查询一条订单送达通知")
    public ResponseEntity<String> getMessageOrderSellerDeliver(@PathVariable Integer order_id) {
        MessageOrderSeller messageOrderSeller = messageOrderSellerService.findByOrderId(order_id);
        String message = messageOrderSeller.getMessageType();
        //如果MessageType为订单送达,则返回message——content
        if (message.equals("买家下单")) {
            String messageContent = messageOrderSeller.getMessageContent();
            return new ResponseEntity<>(messageContent, HttpStatus.OK);
        }else{
            //返回没送达
            return new ResponseEntity<>("买家没下单", HttpStatus.OK);
        }
    }
    //实现点击跳转到订单详情
    @GetMapping("/link/{order_id}")
    @ApiOperation("点击跳转到订单详情")
    public ResponseEntity<String> getMessageOrderSellerLink(@PathVariable Integer order_id) {
        MessageOrderSeller messageOrderSeller = messageOrderSellerService.findByOrderId(order_id);
        String link = messageOrderSeller.getLink();
        return new ResponseEntity<>(link, HttpStatus.OK);
    }
}
oying-system/src/main/java/com/oying/modules/message/rest/MessageSystemController.java
New file
@@ -0,0 +1,105 @@
package com.oying.modules.message.rest;
import com.oying.annotation.Log;
import com.oying.modules.message.domain.MessageSystem;
import com.oying.modules.message.service.MessageSystemService;
import com.oying.modules.message.domain.dto.MessageSystemQueryCriteria;
import lombok.RequiredArgsConstructor;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.utils.PageResult;
/**
 * @author 李萌
 * @date 2025-05-20
 **/
@RestController
@RequiredArgsConstructor
@Api(tags = "消息_系统")
@RequestMapping("/api/message/messageSystem")
public class MessageSystemController {
    private final MessageSystemService messageSystemService;
//    @ApiOperation("导出数据")
//    @GetMapping(value = "/download")
//    @PreAuthorize("@el.check('messageSystem:list')")
//    public void exportMessageSystem(HttpServletResponse response, MessageSystemQueryCriteria criteria) throws IOException {
//        messageSystemService.download(messageSystemService.queryAll(criteria), response);
//    }
    @GetMapping
    @ApiOperation("查询消息_系统")
    @PreAuthorize("@el.check('messageSystem:list')")
    public ResponseEntity<PageResult<MessageSystem>> queryMessageSystem(MessageSystemQueryCriteria criteria){
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        return new ResponseEntity<>(messageSystemService.queryAll(criteria,page),HttpStatus.OK);
    }
//    @PostMapping
//    @Log("新增消息_系统")
//    @ApiOperation("新增消息_系统")
//    @PreAuthorize("@el.check('messageSystem:add')")
//    public ResponseEntity<Object> createMessageSystem(@Validated @RequestBody MessageSystem resources){
//        messageSystemService.create(resources);
//        return new ResponseEntity<>(HttpStatus.CREATED);
//    }
//    @PutMapping
//    @Log("修改消息_系统")
//    @ApiOperation("修改消息_系统")
//    @PreAuthorize("@el.check('messageSystem:edit')")
//    public ResponseEntity<Object> updateMessageSystem(@Validated @RequestBody MessageSystem resources){
//        messageSystemService.update(resources);
//        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
//    }
//    @DeleteMapping
//    @Log("删除消息_系统")
//    @ApiOperation("删除消息_系统")
//    @PreAuthorize("@el.check('messageSystem:del')")
//    public ResponseEntity<Object> deleteMessageSystem(@ApiParam(value = "传ID数组[]") @RequestBody List<Integer> ids) {
//        messageSystemService.deleteAll(ids);
//        return new ResponseEntity<>(HttpStatus.OK);
//    }
    //查询一条系统消息
    @GetMapping("/{id}")
    @ApiOperation("查询一条系统消息")
    public ResponseEntity<MessageSystem> getMessageSystem(@PathVariable Integer id){
        MessageSystem messageSystem = messageSystemService.getById(id);
        return new ResponseEntity<>(messageSystem,HttpStatus.OK);
    }
    //插入一条系统消息 带两个参数start与end
    @PostMapping()
    @ApiOperation("插入一条系统消息")
    public ResponseEntity<Object> insertMessageSystem(
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date start,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date end) {
        // 创建 MessageSystem 对象
        MessageSystem messageSystem = new MessageSystem();
        messageSystem.setStartTime(new Timestamp(start.getTime()));
        messageSystem.setEndTime(new Timestamp(end.getTime()));
        // 调用服务层保存数据
        messageSystemService.save(messageSystem);
        return new ResponseEntity<>(HttpStatus.OK);
    }
}
oying-system/src/main/java/com/oying/modules/message/service/MessageOrderBuyerService.java
New file
@@ -0,0 +1,63 @@
package com.oying.modules.message.service;
import com.oying.modules.message.domain.MessageOrderBuyer;
import com.oying.modules.message.domain.MessageOrderLeave;
import com.oying.modules.message.domain.dto.MessageOrderBuyerQueryCriteria;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.utils.PageResult;
/**
* @description 服务接口
* @author 李萌
* @date 2025-05-20
**/
public interface MessageOrderBuyerService extends IService<MessageOrderBuyer> {
    /**
    * 查询数据分页
    * @param criteria 条件
    * @param page 分页参数
    * @return PageResult
    */
    PageResult<MessageOrderBuyer> queryAll(MessageOrderBuyerQueryCriteria criteria, Page<Object> page);
    /**
    * 查询所有数据不分页
    * @param criteria 条件参数
    * @return List<MessageOrderBuyerDto>
    */
    List<MessageOrderBuyer> queryAll(MessageOrderBuyerQueryCriteria criteria);
    /**
    * 创建
    * @param resources /
    */
    void create(MessageOrderBuyer resources);
    /**
    * 编辑
    * @param resources /
    */
    void update(MessageOrderBuyer resources);
    /**
    * 多选删除
    * @param ids /
    */
    void deleteAll(List<Integer> ids);
    /**
    * 导出数据
    * @param all 待导出的数据
    * @param response /
    * @throws IOException /
    */
    void download(List<MessageOrderBuyer> all, HttpServletResponse response) throws IOException;
    public MessageOrderBuyer findByOrderId(Integer orderId) ;
}
oying-system/src/main/java/com/oying/modules/message/service/MessageOrderLeaveService.java
New file
@@ -0,0 +1,69 @@
package com.oying.modules.message.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.oying.modules.message.domain.MessageOrderLeave;
import com.oying.modules.message.domain.dto.MessageOrderLeaveQueryCriteria;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.utils.PageResult;
/**
* @description 服务接口
* @author 李萌
* @date 2025-05-20
**/
public interface MessageOrderLeaveService extends IService<MessageOrderLeave> {
    /**
    * 查询数据分页
    * @param criteria 条件
    * @param page 分页参数
    * @return PageResult
    */
    PageResult<MessageOrderLeave> queryAll(MessageOrderLeaveQueryCriteria criteria, Page<Object> page);
    /**
    * 查询所有数据不分页
    * @param criteria 条件参数
    * @return List<MessageOrderLeaveDto>
    */
    List<MessageOrderLeave> queryAll(MessageOrderLeaveQueryCriteria criteria);
    /**
    * 创建
    * @param resources /
    */
    void create(MessageOrderLeave resources);
    /**
    * 编辑
    * @param resources /
    */
//    void update(MessageOrderLeave resources);
    /**
    * 多选删除
    * @param ids /
    */
    void deleteAll(List<Integer> ids);
    /**
    * 导出数据
    * @param all 待导出的数据
    * @param response /
    * @throws IOException /
    */
    void download(List<MessageOrderLeave> all, HttpServletResponse response) throws IOException;
    /**
     * 根据订单ID查找留言信息
     * @param orderId 订单ID
     * @return 匹配的留言记录,若不存在则返回 null
     */
    public MessageOrderLeave findByOrderId(Integer orderId) ;
}
oying-system/src/main/java/com/oying/modules/message/service/MessageOrderSellerService.java
New file
@@ -0,0 +1,62 @@
package com.oying.modules.message.service;
import com.oying.modules.message.domain.MessageOrderBuyer;
import com.oying.modules.message.domain.MessageOrderSeller;
import com.oying.modules.message.domain.dto.MessageOrderSellerQueryCriteria;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.utils.PageResult;
/**
* @description 服务接口
* @author 李萌
* @date 2025-05-20
**/
public interface MessageOrderSellerService extends IService<MessageOrderSeller> {
    /**
    * 查询数据分页
    * @param criteria 条件
    * @param page 分页参数
    * @return PageResult
    */
    PageResult<MessageOrderSeller> queryAll(MessageOrderSellerQueryCriteria criteria, Page<Object> page);
    /**
    * 查询所有数据不分页
    * @param criteria 条件参数
    * @return List<MessageOrderSellerDto>
    */
    List<MessageOrderSeller> queryAll(MessageOrderSellerQueryCriteria criteria);
    /**
    * 创建
    * @param resources /
    */
    void create(MessageOrderSeller resources);
    /**
    * 编辑
    * @param resources /
    */
    void update(MessageOrderSeller resources);
    /**
    * 多选删除
    * @param ids /
    */
    void deleteAll(List<Integer> ids);
    /**
    * 导出数据
    * @param all 待导出的数据
    * @param response /
    * @throws IOException /
    */
    void download(List<MessageOrderSeller> all, HttpServletResponse response) throws IOException;
    public MessageOrderSeller findByOrderId(Integer orderId) ;
}
oying-system/src/main/java/com/oying/modules/message/service/MessageSystemService.java
New file
@@ -0,0 +1,64 @@
package com.oying.modules.message.service;
import com.oying.modules.message.domain.MessageSystem;
import com.oying.modules.message.domain.dto.MessageSystemQueryCriteria;
import java.util.Date;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.utils.PageResult;
/**
 * @description 服务接口
 * @author 李萌
 * @date 2025-05-20
 **/
public interface MessageSystemService extends IService<MessageSystem> {
    /**
     * 查询数据分页
     * @param criteria 条件
     * @param page 分页参数
     * @return PageResult
     */
    PageResult<MessageSystem> queryAll(MessageSystemQueryCriteria criteria, Page<Object> page);
    /**
     * 查询所有数据不分页
     * @param criteria 条件参数
     * @return List<MessageSystemDto>
     */
    List<MessageSystem> queryAll(MessageSystemQueryCriteria criteria);
    /**
     * 创建
     * @param resources /
     */
    void create(MessageSystem resources);
    /**
     * 编辑
     * @param resources /
     */
    void update(MessageSystem resources);
    /**
     * 多选删除
     * @param ids /
     */
    void deleteAll(List<Integer> ids);
    /**
     * 导出数据
     * @param all 待导出的数据
     * @param response /
     * @throws IOException /
     */
    void download(List<MessageSystem> all, HttpServletResponse response) throws IOException;
}
oying-system/src/main/java/com/oying/modules/message/service/impl/MessageOrderBuyerServiceImpl.java
New file
@@ -0,0 +1,83 @@
package com.oying.modules.message.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.oying.modules.message.domain.MessageOrderBuyer;
import com.oying.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oying.modules.message.service.MessageOrderBuyerService;
import com.oying.modules.message.domain.dto.MessageOrderBuyerQueryCriteria;
import com.oying.modules.message.mapper.MessageOrderBuyerMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.oying.utils.PageUtil;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import com.oying.utils.PageResult;
/**
* @description 服务实现
* @author 李萌
* @date 2025-05-20
**/
@Service
@RequiredArgsConstructor
public class MessageOrderBuyerServiceImpl extends ServiceImpl<MessageOrderBuyerMapper, MessageOrderBuyer> implements MessageOrderBuyerService {
    private final MessageOrderBuyerMapper messageOrderBuyerMapper;
    @Override
    public PageResult<MessageOrderBuyer> queryAll(MessageOrderBuyerQueryCriteria criteria, Page<Object> page){
        return PageUtil.toPage(messageOrderBuyerMapper.findAll(criteria, page));
    }
    @Override
    public List<MessageOrderBuyer> queryAll(MessageOrderBuyerQueryCriteria criteria){
        return messageOrderBuyerMapper.findAll(criteria);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(MessageOrderBuyer resources) {
        messageOrderBuyerMapper.insert(resources);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(MessageOrderBuyer resources) {
        MessageOrderBuyer messageOrderBuyer = getById(resources.getId());
        messageOrderBuyer.copy(resources);
        messageOrderBuyerMapper.updateById(messageOrderBuyer);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Integer> ids) {
        messageOrderBuyerMapper.deleteBatchIds(ids);
    }
    @Override
    public void download(List<MessageOrderBuyer> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (MessageOrderBuyer messageOrderBuyer : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("订单ID", messageOrderBuyer.getOrderId());
            map.put("消息类型(订单状态变化、订单送达)", messageOrderBuyer.getMessageType());
            map.put("消息内容", messageOrderBuyer.getMessageContent());
            map.put("跳转链接", messageOrderBuyer.getLink());
            map.put("创建时间", messageOrderBuyer.getCreateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
    @Override
    public MessageOrderBuyer findByOrderId(Integer orderId) {
        return baseMapper.selectOne(new QueryWrapper<MessageOrderBuyer>().eq("order_id", orderId));
    }
}
oying-system/src/main/java/com/oying/modules/message/service/impl/MessageOrderLeaveServiceImpl.java
New file
@@ -0,0 +1,89 @@
package com.oying.modules.message.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.oying.modules.message.domain.MessageOrderLeave;
import com.oying.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oying.modules.message.service.MessageOrderLeaveService;
import com.oying.modules.message.domain.dto.MessageOrderLeaveQueryCriteria;
import com.oying.modules.message.mapper.MessageOrderLeaveMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.oying.utils.PageUtil;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import com.oying.utils.PageResult;
/**
* @description 服务实现
* @author 李萌
* @date 2025-05-20
**/
@Service
@RequiredArgsConstructor
public class MessageOrderLeaveServiceImpl extends ServiceImpl<MessageOrderLeaveMapper, MessageOrderLeave> implements MessageOrderLeaveService {
    private final MessageOrderLeaveMapper messageOrderLeaveMapper;
    @Override
    public PageResult<MessageOrderLeave> queryAll(MessageOrderLeaveQueryCriteria criteria, Page<Object> page){
        return PageUtil.toPage(messageOrderLeaveMapper.findAll(criteria, page));
    }
    @Override
    public List<MessageOrderLeave> queryAll(MessageOrderLeaveQueryCriteria criteria){
        return messageOrderLeaveMapper.findAll(criteria);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(MessageOrderLeave resources) {
        messageOrderLeaveMapper.insert(resources);
    }
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void update(MessageOrderLeave resources) {
//        MessageOrderLeave messageOrderLeave = getById(resources.getId());
//        messageOrderLeave.copy(resources);
//        messageOrderLeaveMapper.updateById(messageOrderLeave);
//    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Integer> ids) {
        messageOrderLeaveMapper.deleteBatchIds(ids);
    }
    @Override
    public void download(List<MessageOrderLeave> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (MessageOrderLeave messageOrderLeave : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("订单ID", messageOrderLeave.getOrderId());
            map.put("顾客评价内容", messageOrderLeave.getCustomerReview());
            map.put("商家回复内容", messageOrderLeave.getSellerReply());
            map.put("跳转链接", messageOrderLeave.getLink());
            map.put("创建时间", messageOrderLeave.getCreateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
    /**
     * 根据订单ID查找留言信息
     * @param orderId 订单ID
     * @return 匹配的留言记录,若不存在则返回 null
     */
    public MessageOrderLeave findByOrderId(Integer orderId) {
        return baseMapper.selectOne(new QueryWrapper<MessageOrderLeave>()
                .eq("order_id", orderId));
    }
}
oying-system/src/main/java/com/oying/modules/message/service/impl/MessageOrderSellerServiceImpl.java
New file
@@ -0,0 +1,84 @@
package com.oying.modules.message.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.oying.modules.message.domain.MessageOrderBuyer;
import com.oying.modules.message.domain.MessageOrderSeller;
import com.oying.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oying.modules.message.service.MessageOrderSellerService;
import com.oying.modules.message.domain.dto.MessageOrderSellerQueryCriteria;
import com.oying.modules.message.mapper.MessageOrderSellerMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.oying.utils.PageUtil;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import com.oying.utils.PageResult;
/**
* @description 服务实现
* @author 李萌
* @date 2025-05-20
**/
@Service
@RequiredArgsConstructor
public class MessageOrderSellerServiceImpl extends ServiceImpl<MessageOrderSellerMapper, MessageOrderSeller> implements MessageOrderSellerService {
    private final MessageOrderSellerMapper messageOrderSellerMapper;
    @Override
    public PageResult<MessageOrderSeller> queryAll(MessageOrderSellerQueryCriteria criteria, Page<Object> page){
        return PageUtil.toPage(messageOrderSellerMapper.findAll(criteria, page));
    }
    @Override
    public List<MessageOrderSeller> queryAll(MessageOrderSellerQueryCriteria criteria){
        return messageOrderSellerMapper.findAll(criteria);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(MessageOrderSeller resources) {
        messageOrderSellerMapper.insert(resources);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(MessageOrderSeller resources) {
        MessageOrderSeller messageOrderSeller = getById(resources.getId());
        messageOrderSeller.copy(resources);
        messageOrderSellerMapper.updateById(messageOrderSeller);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Integer> ids) {
        messageOrderSellerMapper.deleteBatchIds(ids);
    }
    @Override
    public void download(List<MessageOrderSeller> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (MessageOrderSeller messageOrderSeller : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put(" orderId",  messageOrderSeller.getOrderId());
            map.put(" messageType",  messageOrderSeller.getMessageType());
            map.put(" messageContent",  messageOrderSeller.getMessageContent());
            map.put(" link",  messageOrderSeller.getLink());
            map.put(" createTime",  messageOrderSeller.getCreateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
    @Override
    public MessageOrderSeller findByOrderId(Integer orderId) {
        return baseMapper.selectOne(new QueryWrapper<MessageOrderSeller>().eq("order_id", orderId));
    }
}
oying-system/src/main/java/com/oying/modules/message/service/impl/MessageSystemServiceImpl.java
New file
@@ -0,0 +1,79 @@
package com.oying.modules.message.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.oying.modules.message.domain.MessageOrderLeave;
import com.oying.modules.message.domain.MessageSystem;
import com.oying.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oying.modules.message.service.MessageSystemService;
import com.oying.modules.message.domain.dto.MessageSystemQueryCriteria;
import com.oying.modules.message.mapper.MessageSystemMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.oying.utils.PageUtil;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.oying.utils.PageResult;
/**
 * @description 服务实现
 * @author 李萌
 * @date 2025-05-20
 **/
@Service
@RequiredArgsConstructor
public class MessageSystemServiceImpl extends ServiceImpl<MessageSystemMapper, MessageSystem> implements MessageSystemService {
    private final MessageSystemMapper messageSystemMapper;
    @Override
    public PageResult<MessageSystem> queryAll(MessageSystemQueryCriteria criteria, Page<Object> page){
        return PageUtil.toPage(messageSystemMapper.findAll(criteria, page));
    }
    @Override
    public List<MessageSystem> queryAll(MessageSystemQueryCriteria criteria){
        return messageSystemMapper.findAll(criteria);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(MessageSystem resources) {
        messageSystemMapper.insert(resources);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(MessageSystem resources) {
        MessageSystem messageSystem = getById(resources.getId());
        messageSystem.copy(resources);
        messageSystemMapper.updateById(messageSystem);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Integer> ids) {
        messageSystemMapper.deleteBatchIds(ids);
    }
    @Override
    public void download(List<MessageSystem> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (MessageSystem messageSystem : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("系统维护开始时间", messageSystem.getStartTime());
            map.put("系统维护截至时间", messageSystem.getEndTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}
oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryDtoAssembler.java
New file
@@ -0,0 +1,10 @@
package com.oying.modules.pc.category.converter;
import com.oying.modules.pc.category.domain.PlatformCategory;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryCreateRequest;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryUpdateRequest;
import org.springframework.stereotype.Component;
@Component
public class PlatformCategoryDtoAssembler {
}
oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryViewAssembler.java
New file
@@ -0,0 +1,25 @@
package com.oying.modules.pc.category.converter;
import cn.hutool.core.bean.BeanUtil;
import com.oying.modules.pc.category.domain.PlatformCategory;
import com.oying.modules.pc.category.view.PlatformCategoryCustomerView;
import com.oying.modules.pc.category.view.PlatformCategoryView;
import org.springframework.stereotype.Component;
@Component
public class PlatformCategoryViewAssembler {
    public PlatformCategoryView toPlatformCategoryResponse(PlatformCategory category) {
        PlatformCategoryView categoryView = new PlatformCategoryView();
        BeanUtil.copyProperties(category, categoryView);
        categoryView.setIconUrl("");
        return categoryView;
    }
    public PlatformCategoryCustomerView toCustomerPlatformCategoryResponse(PlatformCategory category) {
        PlatformCategoryCustomerView categoryView = new PlatformCategoryCustomerView();
        BeanUtil.copyProperties(category, categoryView);
        categoryView.setIconUrl("");
        return categoryView;
    }
}
oying-system/src/main/java/com/oying/modules/pc/category/domain/PlatformCategory.java
New file
@@ -0,0 +1,72 @@
package com.oying.modules.pc.category.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import java.sql.Timestamp;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* @description /
* @author lzp
* @date 2025-04-28
**/
@Data
@TableName("pc_platform_category")
public class PlatformCategory implements Serializable {
    @TableId(value = "category_id", type = IdType.AUTO)
    @ApiModelProperty(value = "类目ID")
    private Long categoryId;
    @NotNull
    @ApiModelProperty(value = "父类目ID")
    private Long parentId;
    @NotBlank
    @ApiModelProperty(value = "类目名称")
    private String name;
    @NotNull
    @ApiModelProperty(value = "类目层级:1-级类目 ")
    private Integer level;
    @NotNull
    @ApiModelProperty(value = "排序权重")
    private Integer sortWeight;
    @ApiModelProperty(value = "类目图标ID")
    private Long iconId;
    @NotNull
    @ApiModelProperty(value = "状态")
    private Integer status;
    @NotNull
    @ApiModelProperty(value = "是否启用(0-否 1-是)")
    private Integer active;
    @ApiModelProperty(value = "创建人")
    private Long createBy;
    @NotNull
    @ApiModelProperty(value = "创建时间")
    private Timestamp createTime;
    @ApiModelProperty(value = "修改人")
    private Long updateBy;
    @NotNull
    @ApiModelProperty(value = "更新时间")
    private Timestamp updateTime;
    public void copy(PlatformCategory source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryCreateRequest.java
New file
@@ -0,0 +1,33 @@
package com.oying.modules.pc.category.domain.dto;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class PlatformCategoryCreateRequest {
    @NotBlank
    @ApiModelProperty(value = "类目名称", example = "超市")
    private String name;
    @ApiModelProperty(value = "排序权重", example = "1")
    private Integer sortWeight;
    @ApiModelProperty(value = "是否启用", example = "1")
    private int active;
    @ApiModelProperty(value = "上传类目图标文件ID", example = "4682827376555999")
    private Long iconUploadFileId;
    public static void main(String[] args) {
        PlatformCategoryCreateRequest platformCategory = new PlatformCategoryCreateRequest();
        platformCategory.setName("美食");
        platformCategory.setSortWeight(1);
        platformCategory.setIconUploadFileId(1L);
        platformCategory.setActive(1);
        System.out.println(JSONUtil.toJsonStr(platformCategory));
    }
}
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryQueryCriteria.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.pc.category.domain.dto;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
/**
* @author lzp
* @date 2025-04-30
**/
@Data
public class PlatformCategoryQueryCriteria{
    @ApiModelProperty(value = "是否启用", example = "1")
    private Integer active = 1;
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
}
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateDto.java
New file
@@ -0,0 +1,21 @@
package com.oying.modules.pc.category.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class PlatformCategoryUpdateDto {
    private Long categoryId;
    private String name;
    private Integer sortWeight;
    private Long iconUploadFileId;
    private int active;
}
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateRequest.java
New file
@@ -0,0 +1,24 @@
package com.oying.modules.pc.category.domain.dto;
import com.oying.modules.pc.category.domain.PlatformCategory;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class PlatformCategoryUpdateRequest {
    @ApiModelProperty(value = "类目名称", example = "超市")
    private String name;
    @ApiModelProperty(value = "排序权重", example = "1")
    private Integer sortWeight;
    @ApiModelProperty(value = "上传类目图标文件ID", example = "2682827376555999239484")
    private Long iconUploadFileId;
    @ApiModelProperty(value = "是否启用", example = "1")
    private int active;
}
oying-system/src/main/java/com/oying/modules/pc/category/mapper/PlatformCategoryMapper.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.pc.category.mapper;
import com.oying.modules.pc.category.domain.PlatformCategory;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryQueryCriteria;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @author lzp
* @date 2025-04-30
**/
@Mapper
public interface PlatformCategoryMapper extends BaseMapper<PlatformCategory> {
    IPage<PlatformCategory> findAll(@Param("criteria") PlatformCategoryQueryCriteria criteria, Page<Object> page);
    List<PlatformCategory> findAll(@Param("criteria") PlatformCategoryQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryAdminController.java
New file
@@ -0,0 +1,83 @@
package com.oying.modules.pc.category.rest;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.annotation.Log;
import com.oying.modules.pc.category.converter.PlatformCategoryViewAssembler;
import com.oying.modules.pc.category.domain.PlatformCategory;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryCreateRequest;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryQueryCriteria;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryUpdateDto;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryUpdateRequest;
import com.oying.modules.pc.category.service.PlatformCategoryService;
import com.oying.modules.pc.category.view.PlatformCategoryView;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.utils.PageResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
 * @author lzp
 * @date 2025-04-28
 **/
@RestController
@RequiredArgsConstructor
@Api(tags = "平台类目")
@RequestMapping("/api/pc/admin/platformCategory")
public class PlatformCategoryAdminController {
    private final PlatformCategoryService categoryService;
    private final PlatformCategoryViewAssembler assembler;
    @GetMapping
    @ApiOperation("查询平台类目(支持分页)")
    @PreAuthorize("@el.check('admin:platformCategory:list')")
    public ResponseEntity<?> queryPlatformCategory(PlatformCategoryQueryCriteria criteria) {
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        PageResult<PlatformCategory> pageResult = categoryService.queryAll(criteria, page);
        List<PlatformCategoryView> responseList = Optional.ofNullable(pageResult.getContent()).orElse(new ArrayList<>()).stream().map(assembler::toPlatformCategoryResponse).collect(Collectors.toList());
        PageResult<PlatformCategoryView> responsePageResult = new PageResult<>(responseList, pageResult.getTotalElements());
        return ResponseEntity.ok(R.success(responsePageResult));
    }
    @PostMapping
    @ApiOperation("新增平台类目")
    //@PreAuthorize("@el.check('admin:platformCategory:create')")
    public ResponseEntity<?> create(@Validated @RequestBody PlatformCategoryCreateRequest request) {
        categoryService.create(request);
        return ResponseEntity.status(HttpStatus.CREATED).build();
    }
    @PutMapping("/{categoryId}")
    @ApiOperation("修改平台类目")
    //@PreAuthorize("@el.check('admin:platformCategory:updateById')")
    public ResponseEntity<?> updateById(@PathVariable Long categoryId,
                       @Validated @RequestBody PlatformCategoryUpdateRequest request) {
        PlatformCategoryUpdateDto updateDto = new PlatformCategoryUpdateDto();
        BeanUtils.copyProperties(request, updateDto);
        updateDto.setCategoryId(categoryId);
        categoryService.update(updateDto);
        return ResponseEntity.noContent().build();
    }
    @DeleteMapping
    @Log("删除平台类目")
    @ApiOperation("删除平台类目")
    //@PreAuthorize("@el.check('admin:platformCategory:batchDel')")
    public ResponseEntity<?> batchDelete(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
        categoryService.deleteAll(ids);
        return ResponseEntity.noContent().build();
    }
}
oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryCustomerController.java
New file
@@ -0,0 +1,43 @@
package com.oying.modules.pc.category.rest;
import com.oying.modules.pc.category.converter.PlatformCategoryViewAssembler;
import com.oying.modules.pc.category.domain.PlatformCategory;
import com.oying.modules.pc.category.view.PlatformCategoryCustomerView;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryQueryCriteria;
import com.oying.modules.pc.category.service.PlatformCategoryService;
import com.oying.modules.pc.common.core.domain.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @author lzp
 * @date 2025-04-28
 **/
@RestController
@RequiredArgsConstructor
@Api(tags = "平台类目(客户端)")
@RequestMapping("/api/pc/customer/platformCategory")
public class PlatformCategoryCustomerController {
    private final PlatformCategoryService categoryService;
    private final PlatformCategoryViewAssembler assembler;
    @GetMapping("/list")
    @ApiOperation("查询平台类目")
    //@PreAuthorize("@el.check('customer:platformCategory:list')")
    public ResponseEntity<?> queryPlatformCategory() {
        PlatformCategoryQueryCriteria criteria = new PlatformCategoryQueryCriteria();
        criteria.setActive(1);
        List<PlatformCategory> platformCategoryList = categoryService.queryAll(criteria);
        List<PlatformCategoryCustomerView> responseList = platformCategoryList.stream().map(assembler::toCustomerPlatformCategoryResponse).collect(Collectors.toList());
        return ResponseEntity.ok(R.success(responseList));
    }
}
oying-system/src/main/java/com/oying/modules/pc/category/service/PlatformCategoryService.java
New file
@@ -0,0 +1,59 @@
package com.oying.modules.pc.category.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.modules.pc.category.domain.PlatformCategory;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryCreateRequest;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryQueryCriteria;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryUpdateDto;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryUpdateRequest;
import com.oying.utils.PageResult;
import java.util.List;
/**
 * 平台类目服务接口
 *
 * @author lzp
 * @date 2025-04-30
 **/
public interface PlatformCategoryService extends IService<PlatformCategory> {
    /**
     * 查询数据分页
     *
     * @param criteria 条件
     * @param page     分页参数
     * @return PageResult
     */
    PageResult<PlatformCategory> queryAll(PlatformCategoryQueryCriteria criteria, Page<Object> page);
    /**
     * 查询所有数据不分页
     *
     * @param criteria 条件参数
     * @return List<PlatformCategoryDto>
     */
    List<PlatformCategory> queryAll(PlatformCategoryQueryCriteria criteria);
    /**
     * 创建
     *
     * @param resources /
     */
    void create(PlatformCategoryCreateRequest resources);
    /**
     * 编辑
     *
     * @param resources /
     */
    void update(PlatformCategoryUpdateDto resources);
    /**
     * 多选删除
     *
     * @param ids /
     */
    void deleteAll(List<Long> ids);
}
oying-system/src/main/java/com/oying/modules/pc/category/service/impl/PlatformCategoryServiceImpl.java
New file
@@ -0,0 +1,90 @@
package com.oying.modules.pc.category.service.impl;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oying.exception.EntityExistException;
import com.oying.modules.pc.category.converter.PlatformCategoryDtoAssembler;
import com.oying.modules.pc.category.domain.PlatformCategory;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryCreateRequest;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryQueryCriteria;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryUpdateDto;
import com.oying.modules.pc.category.domain.dto.PlatformCategoryUpdateRequest;
import com.oying.modules.pc.category.mapper.PlatformCategoryMapper;
import com.oying.modules.pc.category.service.PlatformCategoryService;
import com.oying.utils.PageResult;
import com.oying.utils.PageUtil;
import com.oying.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
/**
 * 平台类目服务实现
 *
 * @author lzp
 * @date 2025-04-30
 **/
@Service
@RequiredArgsConstructor
public class PlatformCategoryServiceImpl extends ServiceImpl<PlatformCategoryMapper, PlatformCategory> implements PlatformCategoryService {
    private final PlatformCategoryMapper platformCategoryMapper;
    @Override
    public PageResult<PlatformCategory> queryAll(PlatformCategoryQueryCriteria criteria, Page<Object> page) {
        return PageUtil.toPage(platformCategoryMapper.findAll(criteria, page));
    }
    @Override
    public List<PlatformCategory> queryAll(PlatformCategoryQueryCriteria criteria) {
        return platformCategoryMapper.findAll(criteria);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(PlatformCategoryCreateRequest request) {
        PlatformCategory platformCategoryCreate = new PlatformCategory();
        platformCategoryCreate.setName(request.getName());
        platformCategoryCreate.setSortWeight(request.getSortWeight());
        platformCategoryCreate.setIconId(request.getIconUploadFileId());
        platformCategoryCreate.setActive(request.getActive());
        platformCategoryCreate.setCreateBy(SecurityUtils.getCurrentUserId());
        // 使用处理图标文件
        platformCategoryMapper.insert(platformCategoryCreate);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(PlatformCategoryUpdateDto updateDto) {
        Long categoryId = updateDto.getCategoryId();
        PlatformCategory existingPlatformCategory = this.getById(categoryId);
        if (ObjUtil.isEmpty(existingPlatformCategory)) {
            throw new EntityExistException(PlatformCategory.class, "categoryId", Optional.ofNullable(categoryId).map(Object::toString).orElse("null"));
        }
        PlatformCategory platformCategoryUpdate = new PlatformCategory();
        platformCategoryUpdate.setCategoryId(updateDto.getCategoryId());
        platformCategoryUpdate.setName(updateDto.getName());
        platformCategoryUpdate.setSortWeight(updateDto.getSortWeight());
        platformCategoryUpdate.setIconId(updateDto.getIconUploadFileId());
        platformCategoryUpdate.setActive(updateDto.getActive());
        existingPlatformCategory.copy(platformCategoryUpdate);
        existingPlatformCategory.setUpdateBy(SecurityUtils.getCurrentUserId());
        platformCategoryMapper.updateById(existingPlatformCategory);
        // 使用处理图标文件
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        platformCategoryMapper.deleteBatchIds(ids);
    }
}
oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryCustomerView.java
New file
@@ -0,0 +1,16 @@
package com.oying.modules.pc.category.view;
import lombok.Data;
@Data
public class PlatformCategoryCustomerView {
    private Long categoryId;
    private String name;
    private Integer sortWeight;
    private String iconUrl;
}
oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryView.java
New file
@@ -0,0 +1,33 @@
package com.oying.modules.pc.category.view;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
@Data
public class PlatformCategoryView implements Serializable {
    private Long categoryId;
    private String name;
    private Integer sort;
    private String icon;
    private String iconUrl;
    private Integer status;
    private Integer visible;
    private Long createBy;
    private Timestamp createTime;
    private Long updateBy;
    private Timestamp updateTime;
}
oying-system/src/main/java/com/oying/modules/pc/common/core/constrant/Constants.java
New file
@@ -0,0 +1,50 @@
package com.oying.modules.pc.common.core.constrant;
/**
 * 通用常量信息
 *
 * @author lzp
 * @date 2025-04-22
 */
public class Constants {
    /**
     * UTF-8 字符集
     */
    public static final String UTF8 = "UTF-8";
    /**
     * GBK 字符集
     */
    public static final String GBK = "GBK";
    /**
     * www主域
     */
    public static final String WWW = "www.";
    /**
     * RMI 远程方法调用
     */
    public static final String LOOKUP_RMI = "rmi:";
    /**
     * LDAP 远程方法调用
     */
    public static final String LOOKUP_LDAP = "ldap:";
    /**
     * LDAPS 远程方法调用
     */
    public static final String LOOKUP_LDAPS = "ldaps:";
    /**
     * http请求
     */
    public static final String HTTP = "http://";
    /**
     * https请求
     */
    public static final String HTTPS = "https://";
}
oying-system/src/main/java/com/oying/modules/pc/common/core/domain/R.java
New file
@@ -0,0 +1,102 @@
package com.oying.modules.pc.common.core.domain;
import java.io.Serializable;
/**
 * 响应信息主体
 *
 * @author lzp
 * @date 2025-04-22
 */
public class R<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 成功
     */
    public static final int SUCCESS = 0;
    /**
     * 失败
     */
    public static final int FAIL = 1;
    private int status;
    private String message;
    private T data;
    public static <T> R<T> success() {
        return restResult(null, SUCCESS, null);
    }
    public static <T> R<T> success(T data) {
        return restResult(data, SUCCESS, null);
    }
    public static <T> R<T> success(T data, String msg) {
        return restResult(data, SUCCESS, msg);
    }
    public static <T> R<T> fail() {
        return restResult(null, FAIL, null);
    }
    public static <T> R<T> fail(String msg) {
        return restResult(null, FAIL, msg);
    }
    public static <T> R<T> fail(T data) {
        return restResult(data, FAIL, null);
    }
    public static <T> R<T> fail(T data, String msg) {
        return restResult(data, FAIL, msg);
    }
    public static <T> R<T> fail(int code, String msg) {
        return restResult(null, code, msg);
    }
    private static <T> R<T> restResult(T data, int code, String msg) {
        R<T> apiResult = new R<>();
        apiResult.setStatus(code);
        apiResult.setData(data);
        apiResult.setMessage(msg);
        return apiResult;
    }
    public int getStatus() {
        return status;
    }
    public void setStatus(int status) {
        this.status = status;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public static <T> Boolean isError(R<T> ret) {
        return !isSuccess(ret);
    }
    public static <T> Boolean isSuccess(R<T> ret) {
        return R.SUCCESS == ret.getStatus();
    }
}
oying-system/src/main/java/com/oying/modules/pc/common/exception/LevelExceededException.java
New file
@@ -0,0 +1,13 @@
package com.oying.modules.pc.common.exception;
public class LevelExceededException extends RuntimeException {
    public LevelExceededException(Integer level, Integer maxLevel) {
        super(generateMessage(level, maxLevel));
    }
    private static String generateMessage(Integer level, Integer maxLevel) {
        return String.format("层级 %d 超过了允许的最大层级 (%d)", level, maxLevel);
    }
}
oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdGenerator.java
New file
@@ -0,0 +1,15 @@
package com.oying.modules.pc.common.id;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import org.springframework.stereotype.Component;
@Component
public class StoreIdGenerator {
    private static final Snowflake snowflake = IdUtil.getSnowflake(1,1);
    public static long getId() {
        return snowflake.nextId();
    }
}
oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdentifierGenerator.java
New file
@@ -0,0 +1,11 @@
package com.oying.modules.pc.common.id;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
public class StoreIdentifierGenerator implements IdentifierGenerator {
    @Override
    public Number nextId(Object entity) {
        return null;
    }
}
oying-system/src/main/java/com/oying/modules/pc/common/id/StoreQualificationIdGenerator.java
New file
@@ -0,0 +1,15 @@
package com.oying.modules.pc.common.id;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import org.springframework.stereotype.Component;
@Component
public class StoreQualificationIdGenerator {
    private static final Snowflake snowflake = IdUtil.getSnowflake(1,1);
    public static long getId() {
        return snowflake.nextId();
    }
}
oying-system/src/main/java/com/oying/modules/pc/product/domain/Product.java
New file
@@ -0,0 +1,120 @@
package com.oying.modules.pc.product.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import java.sql.Timestamp;
import java.math.BigDecimal;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* @description /
* @author lzp
* @date 2025-04-30
**/
@Data
@TableName("pc_product")
public class Product implements Serializable {
    @TableId(value = "product_id")
    @ApiModelProperty(value = "ID")
    private Long productId;
    @NotBlank
    @ApiModelProperty(value = "店铺ID")
    private Long storeId;
    @NotBlank
    @ApiModelProperty(value = "条形码")
    private String barcode;
    @NotBlank
    @ApiModelProperty(value = "商品名称")
    private String name;
    @NotBlank
    @ApiModelProperty(value = "商品标题")
    private String title;
    @NotNull
    @ApiModelProperty(value = "一级分类ID")
    private Long categoryId;
    @NotNull
    @ApiModelProperty(value = "二级分类ID")
    private Long secondCategoryId;
    @NotNull
    @ApiModelProperty(value = "状态:1000-草稿 1001上架 1002下架")
    private Integer status;
    @NotBlank
    @ApiModelProperty(value = "主图片")
    private String mainImage;
    @ApiModelProperty(value = "详情图片")
    private String detailImage;
    @ApiModelProperty(value = "商品描述")
    private String description;
    @NotNull
    @ApiModelProperty(value = "销售价格")
    private BigDecimal price;
    @NotNull
    @ApiModelProperty(value = "库存数量")
    private Integer stockQuantity;
    @NotNull
    @ApiModelProperty(value = "起售数量")
    private Integer minPurchaseQuantity;
    @ApiModelProperty(value = "预警库存")
    private Integer warnStock;
    @ApiModelProperty(value = "重量(单位:g)")
    private Integer weight;
    @ApiModelProperty(value = "宽度(单位:厘米)")
    private Integer width;
    @ApiModelProperty(value = "长度(单位:厘米)")
    private Integer length;
    @ApiModelProperty(value = "高度(单位:厘米)")
    private Integer height;
    @NotNull
    @ApiModelProperty(value = "是否删除")
    private Integer deletedFlag;
    @NotNull
    @ApiModelProperty(value = "创建人")
    private Long createBy;
    @NotNull
    @ApiModelProperty(value = "创建时间")
    private Timestamp createTime;
    @NotNull
    @ApiModelProperty(value = "修改人")
    private Long updateBy;
    @NotNull
    @ApiModelProperty(value = "修改时间")
    private Timestamp updateTime;
    @NotNull
    @ApiModelProperty(value = "版本号")
    private Long version;
    public void copy(Product source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductCategory.java
New file
@@ -0,0 +1,52 @@
package com.oying.modules.pc.product.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import java.sql.Timestamp;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* @description /
* @author lzp
* @date 2025-05-13
**/
@Data
@TableName("pc_product_category")
public class ProductCategory implements Serializable {
    @TableId(value = "id", type = IdType.AUTO)
    @ApiModelProperty(value = "商品类目唯一标识")
    private Long id;
    @NotNull
    @ApiModelProperty(value = "商品ID")
    private Long productId;
    @ApiModelProperty(value = "所属一级店铺类目ID")
    private Long storeCategoryId;
    @ApiModelProperty(value = "所属二级店铺类目ID")
    private Long storeCategorySecondId;
    @ApiModelProperty(value = "创建者")
    private Long createBy;
    @ApiModelProperty(value = "创建时间")
    private Timestamp createTime;
    @ApiModelProperty(value = "修改者")
    private Long updateBy;
    @ApiModelProperty(value = "修改时间")
    private Timestamp updateTime;
    public void copy(ProductCategory source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCategoryQueryCriteria.java
New file
@@ -0,0 +1,18 @@
package com.oying.modules.pc.product.domain.dto;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
/**
* @author lzp
* @date 2025-05-13
**/
@Data
public class ProductCategoryQueryCriteria{
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
}
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCustomerQueryCriteria.java
New file
@@ -0,0 +1,21 @@
package com.oying.modules.pc.product.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author lzp
 * @date 2025-04-30
 **/
@Data
public class ProductCustomerQueryCriteria {
    private Long categoryId;
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
}
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageCreateRequest.java
New file
@@ -0,0 +1,9 @@
package com.oying.modules.pc.product.domain.dto;
public class ProductImageCreateRequest {
    private Long uploadId;
    private Integer type;
}
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelCreateRequest.java
New file
@@ -0,0 +1,16 @@
package com.oying.modules.pc.product.domain.dto;
import lombok.Data;
@Data
public class ProductLabelCreateRequest {
    private String category;
    private String labelName;
    private String labelValue;
    private String unit;
}
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantCreateRequest.java
New file
@@ -0,0 +1,52 @@
package com.oying.modules.pc.product.domain.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
@Data
public class ProductMerchantCreateRequest {
    @NotBlank
    private String barcode;
    @NotBlank
    private String name;
    @NotBlank
    private String title;
    @NotNull
    private Long categoryId;
    private Long secondCategoryId;
    @NotNull
    private BigDecimal price;
    @NotNull
    private Integer stockQuantity;
    private Integer minPurchaseQuantity;
    private Integer warnStock;
    @NotNull
    private Integer weight;
    private Integer length;
    private Integer width;
    private Integer height;
    private Integer allowReturns;
    private List<ProductImageCreateRequest> imageList;
    private List<ProductLabelCreateRequest> labelList;
}
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantUpdateRequest.java
New file
@@ -0,0 +1,45 @@
package com.oying.modules.pc.product.domain.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
@Data
public class ProductMerchantUpdateRequest {
    private String barcode;
    private String name;
    private String title;
    private Long categoryId;
    private Long secondCategoryId;
    private BigDecimal price;
    private Integer stockQuantity;
    private Integer minPurchaseQuantity;
    private Integer warnStock;
    private Integer weight;
    private Integer length;
    private Integer width;
    private Integer height;
    private Integer allowReturns;
    private List<ProductImageCreateRequest> imageList;
    private List<ProductLabelCreateRequest> specList;
}
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java
New file
@@ -0,0 +1,34 @@
package com.oying.modules.pc.product.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author lzp
 * @date 2025-04-30
 **/
@Data
public class ProductQueryCriteria {
    @ApiModelProperty(value = "搜索字段", example = "柚子")
    private String blurry;
    private Long productId;
    private Long storeId;
    private Integer status;
    private Long categoryId;
    private Long secondCategoryId;
    private Integer active;
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
}
oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductCategoryMapper.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.pc.product.mapper;
import com.oying.modules.pc.product.domain.ProductCategory;
import com.oying.modules.pc.product.domain.dto.ProductCategoryQueryCriteria;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @author lzp
* @date 2025-05-13
**/
@Mapper
public interface ProductCategoryMapper extends BaseMapper<ProductCategory> {
    IPage<ProductCategory> findAll(@Param("criteria") ProductCategoryQueryCriteria criteria, Page<Object> page);
    List<ProductCategory> findAll(@Param("criteria") ProductCategoryQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductMapper.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.pc.product.mapper;
import com.oying.modules.pc.product.domain.Product;
import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @author lzp
* @date 2025-04-30
**/
@Mapper
public interface ProductMapper extends BaseMapper<Product> {
    IPage<Product> findAll(@Param("criteria") ProductQueryCriteria criteria, Page<Object> page);
    List<Product> findAll(@Param("criteria") ProductQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java
New file
@@ -0,0 +1,73 @@
package com.oying.modules.pc.product.rest;
import com.oying.annotation.Log;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.product.domain.Product;
import com.oying.modules.pc.product.service.ProductService;
import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.utils.PageResult;
/**
* @author lzp
* @date 2025-04-30
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "商品")
@RequestMapping("/api/product")
public class ProductController {
    private final ProductService productService;
    @ApiOperation("导出数据")
    @GetMapping(value = "/download")
    @PreAuthorize("@el.check('product:list')")
    public void exportProduct(HttpServletResponse response, ProductQueryCriteria criteria) throws IOException {
        productService.download(productService.queryAll(criteria), response);
    }
    @GetMapping
    @ApiOperation("查询商品")
    @PreAuthorize("@el.check('product:list')")
    public R<PageResult<Product>> queryProduct(ProductQueryCriteria criteria){
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        return R.success(productService.queryAll(criteria,page));
    }
    @PostMapping
    @Log("新增商品")
    @ApiOperation("新增商品")
    @PreAuthorize("@el.check('product:add')")
    public R<?> createProduct(@Validated @RequestBody Product resources){
        productService.create(resources);
        return R.success();
    }
    @PutMapping
    @Log("修改商品")
    @ApiOperation("修改商品")
    @PreAuthorize("@el.check('product:edit')")
    public R<?> updateProduct(@Validated @RequestBody Product resources){
        productService.update(resources);
        return R.success();
    }
    @DeleteMapping
    @Log("删除商品")
    @ApiOperation("删除商品")
    @PreAuthorize("@el.check('product:del')")
    public R<?> deleteProduct(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
        productService.deleteAll(ids);
        return R.success();
    }
}
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java
New file
@@ -0,0 +1,84 @@
package com.oying.modules.pc.product.rest;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.product.domain.Product;
import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
import com.oying.modules.pc.product.service.ProductService;
import com.oying.modules.pc.product.view.ProductCustomerView;
import com.oying.modules.pc.product.view.ProductMerchantSimpleView;
import com.oying.utils.PageResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/*
*
 * @author lzp
 * @date 2025-04-30
 *
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "商品(客户端)")
@RequestMapping("/api/pc/customer/store/{storeId}/product")
public class ProductCustomerController {
    private final ProductService productService;
    @GetMapping(value = "/page")
    @ApiOperation("根据商品名称模糊匹配店铺内的商品")
    /*@PreAuthorize("@el.check('merchant:product:page')")*/
    public ResponseEntity<?> query(@PathVariable Long storeId,
                                   @RequestParam(value = "categoryId", required = false) Long categoryId,
                                   @RequestParam(value = "secondCategoryId", required = false) Long secondCategoryId,
                                   @RequestParam(value = "blurry", required = false) String blurry) {
        ProductQueryCriteria criteria = new ProductQueryCriteria();
        criteria.setStoreId(storeId);
        criteria.setCategoryId(categoryId);
        criteria.setSecondCategoryId(secondCategoryId);
        criteria.setBlurry(blurry);
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        PageResult<Product> productPageResult = productService.queryAll(criteria, page);
        List<Product> productList = Optional.ofNullable(productPageResult.getContent()).orElse(ListUtil.empty());
        PageResult<ProductCustomerView> viewPageResult = new PageResult<>(
                productList.stream().map(i -> {
                    ProductCustomerView view = new ProductCustomerView();
                    BeanUtils.copyProperties(i, view);
                    view.setScore(5.0D);
                    view.setSold(0);
                    return view;
                }).collect(Collectors.toList()),
                productPageResult.getTotalElements());
        return ResponseEntity.ok(R.success(viewPageResult));
    }
    @GetMapping(value = "/{productId}/details")
    @ApiOperation("查询商品")
    /*@PreAuthorize("@el.check('merchant:product:byProductId')")*/
    public ResponseEntity<?> getDetails(@PathVariable Long productId) {
        Product product = productService.getById(productId);
        ProductCustomerView customerView = new ProductCustomerView();
        customerView.setProductId(product.getProductId());
        customerView.setTitle(product.getTitle());
        customerView.setPrice(product.getPrice());
        customerView.setScore(5.0D);
        customerView.setSold(0);
        customerView.setLabelList(ListUtil.empty());
        customerView.setMainImageList(ListUtil.empty());
        return ResponseEntity.ok(R.success(customerView));
    }
}
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductMerchantController.java
New file
@@ -0,0 +1,141 @@
package com.oying.modules.pc.product.rest;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.annotation.Log;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.product.domain.Product;
import com.oying.modules.pc.product.domain.dto.ProductMerchantCreateRequest;
import com.oying.modules.pc.product.domain.dto.ProductMerchantUpdateRequest;
import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
import com.oying.modules.pc.product.service.ProductMerchantService;
import com.oying.modules.pc.product.service.ProductService;
import com.oying.modules.pc.product.view.ProductMerchantDetailsView;
import com.oying.modules.pc.product.view.ProductMerchantSimpleView;
import com.oying.utils.PageResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
 * @author lzp
 * @date 2025-04-30
 **/
@RestController
@RequiredArgsConstructor
@Api(tags = "商品(商户端)")
@RequestMapping("/api/pc/merchant/store/{storeId}/product")
public class ProductMerchantController {
    private final ProductService productService;
    private final ProductMerchantService productMerchantService;
    @GetMapping(value = "/page")
    @ApiOperation("获取指定商户店铺的商品列表(支持分页)")
    /*@PreAuthorize("@el.check('merchant:product:page') " +
            "and @storeMerchantOwnershipService.check(#storeId)")*/
    public ResponseEntity<?> query(@PathVariable Long storeId,
                                   ProductQueryCriteria criteria) {
        criteria.setStoreId(storeId);
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        PageResult<Product> productPageResult = productService.queryAll(criteria, page);
        List<Product> productList = Optional.ofNullable(productPageResult.getContent()).orElse(ListUtil.empty());
        PageResult<ProductMerchantSimpleView> viewPageResult = new PageResult<>(
                productList.stream().map(i -> {
                    ProductMerchantSimpleView view = new ProductMerchantSimpleView();
                    BeanUtils.copyProperties(i, view);
                    return view;
                }).collect(Collectors.toList()),
                productPageResult.getTotalElements());
        return ResponseEntity.ok(R.success(viewPageResult));
    }
    @GetMapping(value = "/{productId}")
    @ApiOperation("查询商品")
    /*@PreAuthorize("@el.check('merchant:product:byProductId') " +
            "and @storeMerchantOwnershipService.check(#storeId)")*/
    public ResponseEntity<?> getById(@PathVariable Long productId) {
        return ResponseEntity.ok(R.success(productService.getById(productId)));
    }
    @GetMapping(value = "/{productId}/details")
    @ApiOperation("查询商品详情")
    /*@PreAuthorize("@el.check('merchant:product:byProductId') " +
            "and @storeMerchantOwnershipService.check(#storeId)")*/
    public ResponseEntity<?> getDetailsById(@PathVariable Long productId) {
        Product product = productService.getById(productId);
        ProductMerchantDetailsView view = null;
        if (product != null) {
            view = new ProductMerchantDetailsView();
            BeanUtils.copyProperties(product, view);
            view.setMainImageList(ListUtil.empty());
            view.setLabelList(ListUtil.empty());
        }
        return ResponseEntity.ok(R.success(view));
    }
    @PostMapping
    @Log("新增商品")
    @ApiOperation("新增商品")
    //@PreAuthorize("@el.check('merchant:product:add') " +
    //        "and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> createProduct(@PathVariable Long storeId,
                                           @Validated @RequestBody ProductMerchantCreateRequest request) {
        productMerchantService.create(storeId, request);
        return ResponseEntity.noContent().build();
    }
    @PutMapping(value = "/{productId}")
    @Log("修改商品")
    @ApiOperation("修改商品")
    /*@PreAuthorize("@el.check('merchant:product:edit') " +
            "and @storeMerchantOwnershipService.check(#storeId)")*/
    public ResponseEntity<?> updateProduct(@PathVariable Long productId,
                                           @Validated @RequestBody ProductMerchantUpdateRequest request) {
        productMerchantService.update(productId, request);
        return ResponseEntity.noContent().build();
    }
    @DeleteMapping
    @Log("批量删除商品")
    @ApiOperation("批量删除商品")
    //@PreAuthorize("@el.check('merchant:product:batchDel') " +
    //        "and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> deleteProduct(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
        productMerchantService.batchDelete(ids);
        return ResponseEntity.noContent().build();
    }
    @PutMapping(value = "/{productId}/on")
    @Log("上架商品")
    @ApiOperation("上架商品")
    /*@PreAuthorize("@el.check('merchant:product:on') " +
            "and @storeMerchantOwnershipService.check(#storeId)")*/
    public ResponseEntity<?> putOnShelf(@PathVariable("productId") Long productId) {
        productMerchantService.putOnShelf(productId);
        return ResponseEntity.noContent().build();
    }
    @PutMapping(value = "/{productId}/off")
    @Log("下架商品")
    @ApiOperation("下架商品")
    /*@PreAuthorize("@el.check('merchant:product:off') " +
            "and @storeMerchantOwnershipService.check(#storeId)")*/
    public ResponseEntity<?> takeOffShelf(@PathVariable("productId") Long productId) {
        productMerchantService.takeOffShelf(productId);
        return ResponseEntity.noContent().build();
    }
}
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductCategoryService.java
New file
@@ -0,0 +1,60 @@
package com.oying.modules.pc.product.service;
import com.oying.modules.pc.product.domain.ProductCategory;
import com.oying.modules.pc.product.domain.dto.ProductCategoryQueryCriteria;
import java.util.Map;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.utils.PageResult;
/**
* @description 服务接口
* @author lzp
* @date 2025-05-13
**/
public interface ProductCategoryService extends IService<ProductCategory> {
    /**
    * 查询数据分页
    * @param criteria 条件
    * @param page 分页参数
    * @return PageResult
    */
    PageResult<ProductCategory> queryAll(ProductCategoryQueryCriteria criteria, Page<Object> page);
    /**
    * 查询所有数据不分页
    * @param criteria 条件参数
    * @return List<ProductCategoryDto>
    */
    List<ProductCategory> queryAll(ProductCategoryQueryCriteria criteria);
    /**
    * 创建
    * @param resources /
    */
    void create(ProductCategory resources);
    /**
    * 编辑
    * @param resources /
    */
    void update(ProductCategory resources);
    /**
    * 多选删除
    * @param ids /
    */
    void deleteAll(List<Long> ids);
    /**
    * 导出数据
    * @param all 待导出的数据
    * @param response /
    * @throws IOException /
    */
    void download(List<ProductCategory> all, HttpServletResponse response) throws IOException;
}
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductMerchantService.java
New file
@@ -0,0 +1,16 @@
package com.oying.modules.pc.product.service;
import com.oying.modules.pc.product.domain.dto.ProductMerchantCreateRequest;
import com.oying.modules.pc.product.domain.dto.ProductMerchantUpdateRequest;
import java.util.List;
public interface ProductMerchantService {
    void create(Long storeId, ProductMerchantCreateRequest request);
    void update(Long storeId, ProductMerchantUpdateRequest request);
    void batchDelete(List<Long> ids);
    void putOnShelf(Long productId);
    void takeOffShelf(Long productId);
}
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductService.java
New file
@@ -0,0 +1,60 @@
package com.oying.modules.pc.product.service;
import com.oying.modules.pc.product.domain.Product;
import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.utils.PageResult;
/**
* @description 服务接口
* @author lzp
* @date 2025-04-30
**/
public interface ProductService extends IService<Product> {
    /**
    * 查询数据分页
    * @param criteria 条件
    * @param page 分页参数
    * @return PageResult
    */
    PageResult<Product> queryAll(ProductQueryCriteria criteria, Page<Object> page);
    /**
    * 查询所有数据不分页
    * @param criteria 条件参数
    * @return List<ProductDto>
    */
    List<Product> queryAll(ProductQueryCriteria criteria);
    /**
    * 创建
    * @param resources /
    */
    void create(Product resources);
    /**
    * 编辑
    * @param resources /
    */
    void update(Product resources);
    /**
    * 多选删除
    * @param ids /
    */
    void deleteAll(List<Long> ids);
    /**
    * 导出数据
    * @param all 待导出的数据
    * @param response /
    * @throws IOException /
    */
    void download(List<Product> all, HttpServletResponse response) throws IOException;
}
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductCategoryServiceImpl.java
New file
@@ -0,0 +1,79 @@
package com.oying.modules.pc.product.service.impl;
import com.oying.modules.pc.product.domain.ProductCategory;
import com.oying.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oying.modules.pc.product.service.ProductCategoryService;
import com.oying.modules.pc.product.domain.dto.ProductCategoryQueryCriteria;
import com.oying.modules.pc.product.mapper.ProductCategoryMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.oying.utils.PageUtil;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import com.oying.utils.PageResult;
/**
* @description 服务实现
* @author lzp
* @date 2025-05-13
**/
@Service
@RequiredArgsConstructor
public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMapper, ProductCategory> implements ProductCategoryService {
    private final ProductCategoryMapper productCategoryMapper;
    @Override
    public PageResult<ProductCategory> queryAll(ProductCategoryQueryCriteria criteria, Page<Object> page){
        return PageUtil.toPage(productCategoryMapper.findAll(criteria, page));
    }
    @Override
    public List<ProductCategory> queryAll(ProductCategoryQueryCriteria criteria){
        return productCategoryMapper.findAll(criteria);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(ProductCategory resources) {
        productCategoryMapper.insert(resources);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ProductCategory resources) {
        ProductCategory productCategory = getById(resources.getId());
        productCategory.copy(resources);
        productCategoryMapper.updateById(productCategory);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        productCategoryMapper.deleteBatchIds(ids);
    }
    @Override
    public void download(List<ProductCategory> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (ProductCategory productCategory : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("商品ID", productCategory.getProductId());
            map.put("所属一级店铺类目ID", productCategory.getStoreCategoryId());
            map.put("所属二级店铺类目ID", productCategory.getStoreCategorySecondId());
            map.put("创建者", productCategory.getCreateBy());
            map.put("创建时间", productCategory.getCreateTime());
            map.put("修改者", productCategory.getUpdateBy());
            map.put("修改时间", productCategory.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantCreateServiceImpl.java
New file
@@ -0,0 +1,59 @@
package com.oying.modules.pc.product.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.oying.modules.pc.product.domain.Product;
import com.oying.modules.pc.product.domain.dto.ProductMerchantCreateRequest;
import com.oying.modules.pc.product.domain.dto.ProductMerchantUpdateRequest;
import com.oying.modules.pc.product.service.ProductMerchantService;
import com.oying.modules.pc.product.service.ProductService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ProductMerchantCreateServiceImpl implements ProductMerchantService {
    private final ProductService productService;
    @Override
    public void create(Long storeId, ProductMerchantCreateRequest request) {
        Product product = new Product();
        BeanUtils.copyProperties(request, product);
        product.setStoreId(storeId);
        productService.create(product);
    }
    @Override
    public void update(Long productId, ProductMerchantUpdateRequest request) {
        Product product = new Product();
        BeanUtils.copyProperties(request, product);
        product.setProductId(productId);
        productService.update(product);
    }
    @Transactional
    @Override
    public void batchDelete(List<Long> ids) {
        productService.deleteAll(ids);
    }
    @Override
    public void putOnShelf(Long productId) {
        LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>()
                .eq(Product::getProductId, productId)
                .set(Product::getStatus, 1001);
        productService.update(wrapper);
    }
    @Override
    public void takeOffShelf(Long productId) {
        LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>()
                .eq(Product::getProductId, productId)
                .set(Product::getStatus, 1002);
        productService.update(wrapper);
    }
}
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java
New file
@@ -0,0 +1,106 @@
package com.oying.modules.pc.product.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oying.modules.pc.product.domain.Product;
import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
import com.oying.modules.pc.product.mapper.ProductMapper;
import com.oying.modules.pc.product.service.ProductService;
import com.oying.utils.FileUtil;
import com.oying.utils.PageResult;
import com.oying.utils.PageUtil;
import com.oying.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
 * @author lzp
 * @description 服务实现
 * @date 2025-04-30
 **/
@Service
@RequiredArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
    private final ProductMapper productMapper;
    @Override
    public PageResult<Product> queryAll(ProductQueryCriteria criteria, Page<Object> page) {
        return PageUtil.toPage(productMapper.findAll(criteria, page));
    }
    @Override
    public List<Product> queryAll(ProductQueryCriteria criteria) {
        return productMapper.findAll(criteria);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Product resources) {
        resources.setCreateBy(SecurityUtils.getCurrentUserId());
        productMapper.insert(resources);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Product resources) {
        Product product = getById(resources.getProductId());
        product.copy(resources);
        product.setUpdateBy(SecurityUtils.getCurrentUserId());
        productMapper.updateById(product);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        for (Long id : ids) {
            LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>()
                    .eq(Product::getProductId, id)
                    .set(Product::getDeletedFlag, 1);
            // set状态
            this.update(wrapper);
        }
    }
    @Override
    public void download(List<Product> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Product product : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("商品编号", product.getStoreId());
            map.put("条形码", product.getBarcode());
            map.put("商品名称", product.getName());
            map.put("商品标题", product.getTitle());
            map.put("分类ID", product.getCategoryId());
            map.put("状态:1000-草稿 1001上架 1002下架", product.getStatus());
            map.put("主图片", product.getMainImage());
            map.put("详情图片", product.getDetailImage());
            map.put("商品描述", product.getDescription());
            map.put("销售价格", product.getPrice());
            map.put("库存数量", product.getStockQuantity());
            map.put("起售数量", product.getMinPurchaseQuantity());
            map.put("预警库存", product.getWarnStock());
            map.put("重量(单位:g)", product.getWeight());
            map.put("宽度(单位:厘米)", product.getWidth());
            map.put("长度(单位:厘米)", product.getLength());
            map.put("高度(单位:厘米)", product.getHeight());
            map.put("是否删除", product.getDeletedFlag());
            map.put("创建人", product.getCreateBy());
            map.put("创建时间", product.getCreateTime());
            map.put("修改人", product.getUpdateBy());
            map.put("修改时间", product.getUpdateTime());
            map.put("版本号", product.getVersion());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerDetailsView.java
New file
@@ -0,0 +1,24 @@
package com.oying.modules.pc.product.view;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
 * 简单商品vo
 * @author lzp
 * @date 2025-04-25
 */
@Data
public class ProductCustomerDetailsView {
    private Long id;
    private String title;
    private BigDecimal price;
    private Integer sold;
    private List<ProductImageCustomerView> mainImageList;
    private List<ProductLabelCustomerView> labelList;
}
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java
New file
@@ -0,0 +1,25 @@
package com.oying.modules.pc.product.view;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
 * 简单商品vo
 * @author lzp
 * @date 2025-04-25
 */
@Data
public class ProductCustomerView {
    private Long productId;
    private String title;
    private BigDecimal price;
    private Double score;           // 评分
    private Integer sold;    // 月销量
    private List<ProductImageCustomerView> mainImageList;
    private List<ProductLabelCustomerView> labelList;
}
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductImageCustomerView.java
New file
@@ -0,0 +1,12 @@
package com.oying.modules.pc.product.view;
import lombok.Data;
@Data
public class ProductImageCustomerView {
    private String url;
    private Integer primaryFlag;
    private Integer sortWeight;
}
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductLabelCustomerView.java
New file
@@ -0,0 +1,13 @@
package com.oying.modules.pc.product.view;
import lombok.Data;
@Data
public class ProductLabelCustomerView {
    private Integer categoryId;
    private String categoryName;
    private String labelName;
    private String labelValue;
}
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantDetailsView.java
New file
@@ -0,0 +1,25 @@
package com.oying.modules.pc.product.view;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
 * 简单商品vo
 * @author lzp
 * @date 2025-04-25
 */
@Data
public class ProductMerchantDetailsView {
    private Long productId;
    private String name;
    private BigDecimal price;
    private Integer sold;
    private Integer status;
    private List<ProductImageCustomerView> mainImageList;
    private List<ProductLabelCustomerView> labelList;
}
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantSimpleView.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.pc.product.view;
import lombok.Data;
import java.math.BigDecimal;
/**
 * 简单商品vo
 * @author lzp
 * @date 2025-04-25
 */
@Data
public class ProductMerchantSimpleView {
    private Long productId;
    private String name;
    private BigDecimal price;
    private Integer stockQuantity;
    private Integer sold;
    private Integer status;
}
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductOverviewView.java
New file
@@ -0,0 +1,4 @@
package com.oying.modules.pc.product.view;
public class ProductOverviewView {
}
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductSimpleView.java
New file
@@ -0,0 +1,21 @@
package com.oying.modules.pc.product.view;
import java.math.BigDecimal;
/**
 * 简单商品vo
 * @author lzp
 * @date 2025-04-25
 */
public class ProductSimpleView {
    private Long productId;
    private String productTitle;
    private String mainImage;
    private BigDecimal price;
    private BigDecimal originalPrice;  // 原价(用于显示划线价)
    //private Double rating;           // 评分
    //private Integer monthlySales;    // 月销量
}
oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/NearbyStoreQueryCriteria.java
New file
@@ -0,0 +1,38 @@
package com.oying.modules.pc.search.domain.dto;
import lombok.Data;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
@Data
public class NearbyStoreQueryCriteria {
    @NotNull
    private Double longitude; // 中心点经度
    @NotNull
    private Double latitude;  // 中心点纬度
    @Min(100)
    @Max(5000)
    private Integer radius = 1000; // 搜索半径(米)
    private Boolean onlyOpenNow = true; // 是否只查当前营业的
    @Min(1)
    @Max(50)
    private Integer limit = 20; // 返回数量限制
    // 分页参数
    private Integer page = 1;
    private Integer size = 10;
    private String blurry;
    private Long status;
    private Long platformCategoryId;
}
oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/StoreSearchDto.java
New file
@@ -0,0 +1,17 @@
package com.oying.modules.pc.search.domain.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@Data
public class StoreSearchDto {
    // 店铺基础信息
    private Long storeId;
    private String storeName;
    private String logoImage;
    private Integer deliveryTime;
    private Integer distance;
}
oying-system/src/main/java/com/oying/modules/pc/search/rest/StoreSearchController.java
New file
@@ -0,0 +1,58 @@
package com.oying.modules.pc.search.rest;
import cn.hutool.core.collection.CollUtil;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.search.domain.dto.NearbyStoreQueryCriteria;
import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
import com.oying.modules.pc.search.view.StoreSearchView;
import com.oying.modules.pc.search.service.StoreSearchService;
import com.oying.utils.PageResult;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.stream.Collectors;
/**
 * 店铺
 *
 * @author lzp
 * @date 2025-04-22
 */
@RestController
@RequestMapping("/api/pc/search")
@RequiredArgsConstructor
public class StoreSearchController {
    private final StoreSearchService storeSearchService;
    /**
     * 查询最近的店铺
     */
    @GetMapping("/near")
    public R<PageResult<StoreSearchView>> list(NearbyStoreQueryCriteria criteria) {
        return R.success(toStoreSearchVo(storeSearchService.findNearStores(criteria)));
    }
    private PageResult<StoreSearchView> toStoreSearchVo(PageResult<StoreSearchDto> resources) {
        PageResult<StoreSearchView> t = new PageResult<>();
        t.setTotalElements(resources.getTotalElements());
        if (CollUtil.isNotEmpty(resources.getContent())) {
            t.setContent(resources.getContent().stream().map(storeSearchDto -> {
                StoreSearchView searchView = new StoreSearchView();
                searchView.setStoreId(storeSearchDto.getStoreId());
                searchView.setStoreName(storeSearchDto.getStoreName());
                searchView.setStoreLogoUrl(""); // 获取obs
                searchView.setDistance(storeSearchDto.getDistance());
                searchView.setRecommendedProducts(Collections.emptyList());
                return searchView;
            }).collect(Collectors.toList()));
        }
        if (CollUtil.isEmpty(t.getContent())) {
            t.setContent(Collections.emptyList());
        }
        return t;
    }
}
oying-system/src/main/java/com/oying/modules/pc/search/service/StoreSearchService.java
New file
@@ -0,0 +1,10 @@
package com.oying.modules.pc.search.service;
import com.oying.modules.pc.search.domain.dto.NearbyStoreQueryCriteria;
import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
import com.oying.utils.PageResult;
public interface StoreSearchService {
    PageResult<StoreSearchDto> findNearStores(NearbyStoreQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/pc/search/service/impl/StoreSearchServiceImpl.java
New file
@@ -0,0 +1,25 @@
package com.oying.modules.pc.search.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.modules.pc.search.domain.dto.NearbyStoreQueryCriteria;
import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
import com.oying.modules.pc.store.mapper.StoreMapper;
import com.oying.modules.pc.search.service.StoreSearchService;
import com.oying.utils.PageResult;
import com.oying.utils.PageUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class StoreSearchServiceImpl implements StoreSearchService {
    private final StoreMapper storeMapper;
    @Override
    public PageResult<StoreSearchDto> findNearStores(NearbyStoreQueryCriteria criteria) {
        Page<StoreSearchDto> page = new Page<>(criteria.getPage(), criteria.getSize());
        return PageUtil.toPage(storeMapper.queryNearStores(criteria, page));
    }
}
oying-system/src/main/java/com/oying/modules/pc/search/view/StoreSearchView.java
New file
@@ -0,0 +1,27 @@
package com.oying.modules.pc.search.view;
import com.oying.modules.pc.product.view.ProductSimpleView;
import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
import lombok.Data;
import java.util.Collections;
import java.util.List;
/**
 * 搜索结果VO - 包含店铺和推荐商品
 * @author lzp
 * @date 2025-04-25
 */
@Data
public class StoreSearchView {
    // 店铺基础信息
    private Long storeId;
    private String storeName;
    private String storeLogoUrl;
    private Integer deliveryTime;
    private Integer distance;
    // 商品列表(通常3-5个推荐商品)
    private List<ProductSimpleView> recommendedProducts;
}
oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreDtoAssembler.java
New file
@@ -0,0 +1,7 @@
package com.oying.modules.pc.store.converter;
import org.springframework.stereotype.Component;
@Component
public class StoreDtoAssembler {
}
oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreViewAssembler.java
New file
@@ -0,0 +1,7 @@
package com.oying.modules.pc.store.converter;
import org.springframework.stereotype.Component;
@Component
public class StoreViewAssembler {
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/Store.java
New file
@@ -0,0 +1,135 @@
package com.oying.modules.pc.store.domain;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.geo.Point;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.time.ZonedDateTime;
/**
 * @author lzp
 * @date 2025-04-21
 **/
@Data
@TableName("pc_store")
public class Store implements Serializable {
    @TableId(value = "store_id", type = IdType.AUTO)
    @ApiModelProperty(value = "唯一标识")
    private Long storeId;
    @NotNull
    @ApiModelProperty(value = "商户ID")
    private Long merchantId;
    @NotNull
    @ApiModelProperty(value = "平台类目")
    private Long platformCategoryId;
    @NotNull
    @ApiModelProperty(value = "店铺类型:1-自营 2-加盟 3-第三方")
    private Integer storeType;
    @ApiModelProperty(value = "店铺编码")
    private String storeCode;
    @NotBlank
    @ApiModelProperty(value = "店铺名称")
    private String storeName;
    @ApiModelProperty(value = "经营范围")
    private String businessScope;
    @NotNull
    @ApiModelProperty(value = "状态:1000-草稿  1002-正常  1003-暂停营业 1004-关闭")
    private Integer status;
    @NotBlank
    @ApiModelProperty(value = "店铺logo图片")
    private Long logoImageId;
    @NotBlank
    @ApiModelProperty(value = "店铺封面图")
    private Long coverImageId;
    @ApiModelProperty(value = "店铺描述")
    private String description;
    @ApiModelProperty(value = "店铺标签,逗号分隔")
    private String tags;
    @ApiModelProperty(value = "配送费用")
    private BigDecimal deliveryFee;
    @ApiModelProperty(value = "起送金额")
    private BigDecimal deliveryMinimum;
    @ApiModelProperty(value = "联系电话")
    private String contactPhone;
    @ApiModelProperty(value = "营业开始时间")
    private LocalTime openTime;
    @ApiModelProperty(value = "营业结束时间")
    private LocalTime closeTime;
    @ApiModelProperty(value = "省级代码")
    private String provinceCode;
    @ApiModelProperty(value = "市级代码")
    private String cityCode;
    @ApiModelProperty(value = "区/县级代码")
    private String districtCode;
    @ApiModelProperty(value = "详细地址")
    private String address;
    @ApiModelProperty(value = "经度")
    private Double longitude;
    @ApiModelProperty(value = "纬度")
    private Double latitude;
    @ApiModelProperty(value = "GeoHash编码")
    private String geoHash;
    @ApiModelProperty(value = "空间坐标")
    private Point geoPoint;
    @ApiModelProperty(value = "坐标系:WGS84/GCJ02/BD09/CGCS2000")
    private String coordinateSystem;
    @ApiModelProperty(value = "营业半径(米)")
    private Integer radius;
    @NotNull
    @ApiModelProperty(value = "创建人")
    private Long createBy;
    @NotNull
    @ApiModelProperty(value = "创建日期")
    private ZonedDateTime createTime;
    @NotNull
    @ApiModelProperty(value = "修改人")
    private Long updateBy;
    @NotNull
    @ApiModelProperty(value = "修改时间")
    private ZonedDateTime updateTime;
    public void copy(Store source) {
        BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreCategory.java
New file
@@ -0,0 +1,70 @@
package com.oying.modules.pc.store.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import java.sql.Timestamp;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* @description /
* @author lzp
* @date 2025-04-27
**/
@Data
@TableName("pc_store_category")
public class StoreCategory implements Serializable {
    @TableId(value = "category_id")
    @ApiModelProperty(value = "ID")
    private Long categoryId;
    @NotNull
    @ApiModelProperty(value = "店铺ID")
    private Long storeId;
    @NotNull
    @ApiModelProperty(value = "父ID")
    private Long parentId;
    @NotBlank
    @ApiModelProperty(value = "类目名称")
    private String name;
    @NotNull
    @ApiModelProperty(value = "类目层级:1-级类目 2-级类目")
    private Integer level;
    @ApiModelProperty(value = "排序权重")
    private Integer sortWeight;
    @ApiModelProperty(value = "类目图标")
    private String iconId;
    @ApiModelProperty(value = "状态(暂不使用)")
    private Integer status;
    @ApiModelProperty(value = "是否启用(0-否 1-是)")
    private Integer active;
    @ApiModelProperty(value = "创建人")
    private Long createBy;
    @ApiModelProperty(value = "创建时间")
    private Timestamp createTime;
    @ApiModelProperty(value = "更新人")
    private Long updateBy;
    @ApiModelProperty(value = "更新时间")
    private Timestamp updateTime;
    public void copy(StoreCategory source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreLocation.java
New file
@@ -0,0 +1,57 @@
package com.oying.modules.pc.store.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import java.math.BigDecimal;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import org.springframework.data.geo.Point;
/**
* @description /
* @author lzp
* @date 2025-04-23
**/
@Data
@TableName("store_location")
public class StoreLocation implements Serializable {
    @TableId(value = "address_id", type = IdType.AUTO)
    @ApiModelProperty(value = "地址ID")
    private Long locationId;
    @NotNull
    @ApiModelProperty(value = "关联的店铺ID")
    private Long storeId;
    @ApiModelProperty(value = "省份")
    private String province;
    @ApiModelProperty(value = "城市")
    private String city;
    @ApiModelProperty(value = "区县")
    private String district;
    @ApiModelProperty(value = "详细地址")
    private String address;
    @ApiModelProperty(value = "经度")
    private BigDecimal longitude;
    @ApiModelProperty(value = "纬度")
    private BigDecimal latitude;
    @ApiModelProperty(value = "空间坐标")
    private Point getPoint;
    public void copy(StoreLocation source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreQualification.java
New file
@@ -0,0 +1,75 @@
package com.oying.modules.pc.store.domain;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* @description /
* @author lzp
* @date 2025-04-22
**/
@Data
@TableName("pc_store_qualification")
public class StoreQualification implements Serializable {
    @TableId(value = "qualification_id", type = IdType.AUTO)
    @ApiModelProperty(value = "资质ID")
    private Long qualificationId;
    @NotNull
    @ApiModelProperty(value = "关联的店铺ID")
    private Long storeId;
    @NotNull
    @ApiModelProperty(value = "资质类型")
    private Integer qualificationType;
    @ApiModelProperty(value = "资质编号")
    private String qualificationNumber;
    @ApiModelProperty(value = "资质名称")
    private String qualificationName;
    @ApiModelProperty(value = "资质图片")
    private String qualificationImageId;
    @ApiModelProperty(value = "有效期开始日期")
    private LocalTime startDate;
    @ApiModelProperty(value = "有效期结束日期")
    private LocalTime endDate;
    @ApiModelProperty(value = "状态:1000-草稿 1001-有效 1002-无效")
    private Integer status;
    @NotNull
    @ApiModelProperty(value = "创建人")
    private Long createBy;
    @NotNull
    @ApiModelProperty(value = "创建日期")
    private ZonedDateTime createTime;
    @NotNull
    @ApiModelProperty(value = "修改人")
    private Long updateBy;
    @NotNull
    @ApiModelProperty(value = "修改时间")
    private ZonedDateTime updateTime;
    public void copy(StoreQualification source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreStatus.java
New file
@@ -0,0 +1,5 @@
package com.oying.modules.pc.store.domain;
public class StoreStatus {
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreBusinessHoursRequest.java
New file
@@ -0,0 +1,18 @@
package com.oying.modules.pc.store.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.time.LocalTime;
@Data
public class StoreBusinessHoursRequest {
    @NotNull
    private LocalTime openTime;
    @NotNull
    private LocalTime closeTime;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryCreateRequest.java
New file
@@ -0,0 +1,18 @@
package com.oying.modules.pc.store.domain.dto;
import lombok.Data;
@Data
public class StoreCategoryCreateRequest {
    private Long storeId;
    private Long parentId;
    private String name;
    private Integer sortWeight;
    private Integer active;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantCreateRequest.java
New file
@@ -0,0 +1,20 @@
package com.oying.modules.pc.store.domain.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class StoreCategoryMerchantCreateRequest {
    private Long parentId;
    @NotBlank
    private String name;
    private Integer sortWeight;
    private Integer active;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantUpdateRequest.java
New file
@@ -0,0 +1,16 @@
package com.oying.modules.pc.store.domain.dto;
import lombok.Data;
@Data
public class StoreCategoryMerchantUpdateRequest {
    private Long parentId;
    private String name;
    private Integer sortWeight;
    private Integer active;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryQueryCriteria.java
New file
@@ -0,0 +1,26 @@
package com.oying.modules.pc.store.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author lzp
 * @date 2025-04-27
 **/
@Data
public class StoreCategoryQueryCriteria {
    private Long storeId;
    private Integer level;
    private Boolean recursive;
    private Integer active;
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryUpdateRequest.java
New file
@@ -0,0 +1,20 @@
package com.oying.modules.pc.store.domain.dto;
import lombok.Data;
@Data
public class StoreCategoryUpdateRequest {
    private Long storeId;
    private Long parentId;
    private Long categoryId;
    private String name;
    private Integer sortWeight;
    private Integer active;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java
New file
@@ -0,0 +1,90 @@
package com.oying.modules.pc.store.domain.dto;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
@Data
public class StoreCreateRequest {
    @NotBlank
    @ApiModelProperty(value = "店铺全称", example = "重庆永辉超市新纪元店")
    private String storeName;
    /*@NotBlank
    @ApiModelProperty(value = "店铺简称", example = "永辉超市(新纪元店)")
    private String storeShortName;*/
    @NotBlank
    @ApiModelProperty(value = "店铺LOGO文件ID", example = "14567785444763247876234")
    private Long logoUploadFileId;
    /*@NotBlank
    @ApiModelProperty(value = "店铺门户图片ID", example = "276409837458893793939")
    private Long coverUploadFileId;*/
    @NotBlank
    @ApiModelProperty(value = "平台类目ID", example = "29784639387324848347230")
    private Long platformCategoryId;
    //private String businessCategory;
    @NotBlank
    @ApiModelProperty(value = "简介", example = "")
    private String description;
    @NotBlank
    @ApiModelProperty(value = "店铺联系电话", example = "13800000001")
    private String contactPhone;
    @NotBlank
    @ApiModelProperty(value = "店铺地址", example = "276409837458893793939")
    private String address;
    @NotBlank
    @ApiModelProperty(value = "店铺坐标经度", example = "121.505978")
    private Double longitude;
    @NotBlank
    @ApiModelProperty(value = "店铺坐标纬度", example = "31.144515")
    private Double latitude;
    @ApiModelProperty(value = "店铺资质", example = "")
    private List<StoreQualificationCreateRequest> qualificationList;
    public boolean hasQualificationList() {
        return CollUtil.isNotEmpty(this.qualificationList);
    }
    public static void main(String[] args) {
        StoreCreateRequest request = new StoreCreateRequest();
        request.setStoreName("上海三林小学");
        request.setLogoUploadFileId(1L);
        request.setDescription("");
        // request.setCoverUploadFileId(1L);
        request.setPlatformCategoryId(1L);
        request.setContactPhone("13599873421");
        request.setAddress("上海");
        request.setLongitude(121.505978D);
        request.setLatitude(31.144515D);
        List<StoreQualificationCreateRequest> qualificationList = new ArrayList<>();
        StoreQualificationCreateRequest sq1 = new StoreQualificationCreateRequest();
        sq1.setType(10001);
        // sq1.setName("营业执照");
        sq1.setImageUploadFileId("");
        qualificationList.add(sq1);
        StoreQualificationCreateRequest sq2 = new StoreQualificationCreateRequest();
        sq2.setType(10002);
        // sq2.setName("许可证");
        sq2.setImageUploadFileId("");
        qualificationList.add(sq2);
        request.setQualificationList(qualificationList);
        System.out.println(JSONUtil.toJsonStr(request));
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java
New file
@@ -0,0 +1,26 @@
package com.oying.modules.pc.store.domain.dto;
import lombok.Data;
@Data
public class StoreCustomerDetailDto {
    private String name;
    private String logoUrl;
    private String description;
    private String address;
    private String businessHours;
    private String contactPhone;
    private Integer score;
    private Integer deliveryDuration;
    private Integer monthlySales;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerQueryCriteria.java
New file
@@ -0,0 +1,16 @@
package com.oying.modules.pc.store.domain.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class StoreCustomerQueryCriteria {
    private Long StoreId;
    private Double longitude; // 中心点经度
    private Double latitude;  // 中心点纬度
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreFieldUpdateRequest.java
New file
@@ -0,0 +1,92 @@
package com.oying.modules.pc.store.domain.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalTime;
@Data
public class StoreFieldUpdateRequest {
    @NotNull
    private Long storeId;
    public interface UpdateStorePlatformCategoryGroup{}
    @NotNull(groups = UpdateStorePlatformCategoryGroup.class)
    private Long platformCategoryId;
    public interface UpdateStoreNameGroup{}
    @NotBlank(groups = UpdateStoreNameGroup.class)
    private String storeName;
    public interface UpdateStoreTitleGroup{}
    @NotBlank(groups = UpdateStoreTitleGroup.class)
    private String storeTitle;
    public interface UpdateStoreBusinessStatusGroup {}
    @NotNull(groups = UpdateStoreBusinessStatusGroup.class)
    private Integer businessStatus;
    public interface UpdateStoreLogoImageGroup{}
    @NotBlank(groups = UpdateStoreLogoImageGroup.class)
    private String logoImageUploadId;
    public interface UpdateStoreCoverImageGroup{}
    @NotBlank(groups = UpdateStoreCoverImageGroup.class)
    private String coverImageUploadId;
    public interface UpdateStoreDescriptionGroup{}
    @NotBlank(groups = UpdateStoreDescriptionGroup.class)
    private String description;
    public interface UpdateStoreDeliveryFeeGroup{}
    @NotBlank(groups = UpdateStoreDeliveryFeeGroup.class)
    private BigDecimal deliveryFee;
    public interface UpdateStoreDeliveryMinimumGroup{}
    @NotBlank(groups = UpdateStoreDeliveryMinimumGroup.class)
    private BigDecimal deliveryMinimum;
    public interface UpdateStoreContactPhoneGroup{}
    @NotBlank(groups = UpdateStoreContactPhoneGroup.class)
    private String contactPhone;
    public interface UpdateStoreBusinessHoursGroup{}
    @NotBlank(groups = UpdateStoreBusinessHoursGroup.class)
    private LocalTime openTime;
    @NotBlank(groups = UpdateStoreBusinessHoursGroup.class)
    private LocalTime closeTime;
    public interface UpdateStoreAddressGroup{}
    @NotBlank(groups = UpdateStoreAddressGroup.class)
    private String address;
    public interface UpdateStoreLocationGroup{}
    @NotBlank(groups = UpdateStoreLocationGroup.class)
    private Double longitude;
    @NotBlank(groups = UpdateStoreLocationGroup.class)
    private Double latitude;
    public interface UpdateStoreRadiusGroup{}
    @NotBlank(groups = UpdateStoreRadiusGroup.class)
    private Integer radius;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreLocationUpdateRequest.java
New file
@@ -0,0 +1,17 @@
package com.oying.modules.pc.store.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class StoreLocationUpdateRequest {
    @NotNull
    private Double longitude;
    @NotNull
    private Double latitude;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationCreateRequest.java
New file
@@ -0,0 +1,26 @@
package com.oying.modules.pc.store.domain.dto;
import com.oying.modules.pc.store.domain.StoreQualification;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class StoreQualificationCreateRequest {
    @NotNull
    @ApiModelProperty(value = "资质类型", example = "1001")
    private Integer type;
    /*@NotBlank
    @ApiModelProperty(value = "资质名称", example = "营业执照")
    private String name;*/
    @NotBlank
    @ApiModelProperty(value = "资质图片ID", example = "30975645483838730008921")
    private String imageUploadFileId;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationQueryCriteria.java
New file
@@ -0,0 +1,24 @@
package com.oying.modules.pc.store.domain.dto;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
/**
* @author lzp
* @date 2025-04-23
**/
@Data
public class StoreQualificationQueryCriteria{
    @ApiModelProperty(value = "店铺资质ID", example = "1")
    private Long id;
    @ApiModelProperty(value = "店铺ID", example = "1")
    private Long storeId;
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationUpdateRequest.java
New file
@@ -0,0 +1,27 @@
package com.oying.modules.pc.store.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class StoreQualificationUpdateRequest {
    @NotBlank
    @ApiModelProperty(value = "资质ID", example = "317640956839788210948")
    private Long id;
    @NotBlank(groups = {UpdateGroup.class})
    @ApiModelProperty(value = "资质类型", example = "1001")
    private Integer type;
    @NotBlank(groups = {UpdateGroup.class})
    @ApiModelProperty(value = "资质图片ID", example = "30975645483838730008921")
    private String imageUploadFileId;
    public interface UpdateGroup {
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java
New file
@@ -0,0 +1,31 @@
package com.oying.modules.pc.store.domain.dto;
import lombok.Data;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
/**
 * @author lzp
 * @date 2025-04-22
 **/
@Data
public class StoreQueryCriteria implements Serializable {
    @ApiModelProperty(value = "商户ID", example = "1")
    private Long merchantId;
    private String storeName;
    private Integer status;
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
    @ApiModelProperty(value = "偏移量", hidden = true)
    private long offset;
}
oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreStatusEnum.java
New file
@@ -0,0 +1,21 @@
package com.oying.modules.pc.store.domain.enums;
public enum StoreStatusEnum {
    creating(1000, "筹备中"),
    reviewing(2000, "审核中"),
    business_open(3000, ""),
    business_paused(3001, ""),
    business_banned(3002, ""),
    business_suspended(3003, ""),
    closed(1001, ""),
    deleted(1002, "");
    private final int value;
    private final String reasonPhrase;
    private StoreStatusEnum(int value, String reasonPhrase) {
        this.value = value;
        this.reasonPhrase = reasonPhrase;
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreCategoryMapper.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.pc.store.mapper;
import com.oying.modules.pc.store.domain.StoreCategory;
import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @author lzp
* @date 2025-04-24
**/
@Mapper
public interface StoreCategoryMapper extends BaseMapper<StoreCategory> {
    IPage<StoreCategory> findAll(@Param("criteria") StoreCategoryQueryCriteria criteria, Page<Object> page);
    List<StoreCategory> findAll(@Param("criteria") StoreCategoryQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java
New file
@@ -0,0 +1,34 @@
package com.oying.modules.pc.store.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.search.domain.dto.NearbyStoreQueryCriteria;
import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * 店铺Mapper接口
 *
 * @author lzp
 * @date 2025-04-22
 */
@Mapper
public interface StoreMapper extends BaseMapper<Store> {
    List<Store> selectStoreList(@Param("criteria") StoreQueryCriteria criteria, Page<Store> page);
    List<Store> selectStoreList(@Param("criteria") StoreQueryCriteria criteria);
    Store selectStoreByMerchantId(@Param("merchantId") Long merchantId);
    IPage<StoreSearchDto> queryNearStores(@Param("criteria") NearbyStoreQueryCriteria criteria, Page<StoreSearchDto> page);
    IPage<StoreSearchDto> queryNearStoreWithProduct(@Param("criteria") NearbyStoreQueryCriteria criteria, Page<StoreSearchDto> page);
}
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreQualificationMapper.java
New file
@@ -0,0 +1,24 @@
package com.oying.modules.pc.store.mapper;
import java.util.List;
import com.oying.modules.pc.store.domain.StoreQualification;
import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @author lzp
* @date 2025-04-23
**/
@Mapper
public interface StoreQualificationMapper extends BaseMapper<StoreQualification> {
    IPage<StoreQualification> findAll(@Param("criteria") StoreQualificationQueryCriteria criteria, Page<Object> page);
    List<StoreQualification> findAll(@Param("criteria") StoreQualificationQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryController.java
New file
@@ -0,0 +1,65 @@
package com.oying.modules.pc.store.rest;
import com.oying.annotation.Log;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.store.domain.StoreCategory;
import com.oying.modules.pc.store.service.StoreCategoryService;
import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.utils.PageResult;
/**
* @author lzp
* @date 2025-04-24
**/
@Api(tags = "商品中心:店铺类目")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/pc/storeCategory")
public class StoreCategoryController {
    private final StoreCategoryService storeCategoryService;
    @GetMapping
    @ApiOperation("查询api/store/category")
    public ResponseEntity<?> queryStoreCategory(StoreCategoryQueryCriteria criteria){
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        return ResponseEntity.ok(R.success(storeCategoryService.queryAll(criteria, page)));
    }
    @PostMapping
    @Log("新增api/store")
    @ApiOperation("新增api/store")
    @PreAuthorize("@el.check('storeCategory:add')")
    public ResponseEntity<?> createStoreCategory(@Validated @RequestBody StoreCategory resources){
        storeCategoryService.create(resources);
        return ResponseEntity.status(HttpStatus.CREATED).build();
    }
    @PutMapping
    @Log("修改api/store")
    @ApiOperation("修改api/store")
    @PreAuthorize("@el.check('storeCategory:edit')")
    public ResponseEntity<?> updateStoreCategory(@Validated @RequestBody StoreCategory resources){
        storeCategoryService.update(resources);
        return ResponseEntity.noContent().build();
    }
    @DeleteMapping
    @Log("删除api/store")
    @ApiOperation("删除api/store")
    @PreAuthorize("@el.check('storeCategory:del')")
    public ResponseEntity<?> deleteStoreCategory(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
        storeCategoryService.deleteAll(ids);
        return ResponseEntity.noContent().build();
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryCustomerController.java
New file
@@ -0,0 +1,71 @@
package com.oying.modules.pc.store.rest;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.BooleanUtil;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.store.domain.StoreCategory;
import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
import com.oying.modules.pc.store.service.StoreCategoryService;
import com.oying.modules.pc.store.view.CustomerStoreCategoryView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
 * @author lzp
 * @date 2025-04-24
 **/
@Api(tags = "店铺类目(客户端)")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/pc/customer/store/{storeId}/category")
public class StoreCategoryCustomerController {
    private final StoreCategoryService storeCategoryService;
    @GetMapping(value = "/list")
    @ApiOperation("查询店铺类目")
    public ResponseEntity<?> getList(@PathVariable("storeId") Long storeId,
                                     @RequestParam(value = "recursive", required = false) Boolean recursive) {
        StoreCategoryQueryCriteria criteria = new StoreCategoryQueryCriteria();
        criteria.setStoreId(storeId);
        criteria.setActive(1);
        List<StoreCategory> categoryList = storeCategoryService.queryAll(criteria);
        List<CustomerStoreCategoryView> categoryViewList = Optional.ofNullable(categoryList).orElse(ListUtil.empty()).stream().map(i -> {
            CustomerStoreCategoryView view = new CustomerStoreCategoryView();
            view.setCategoryId(i.getCategoryId());
            view.setParentId(i.getParentId());
            view.setName(i.getName());
            view.setSortWeight(i.getSortWeight());
            return view;
        }).collect(Collectors.toList());
        if (BooleanUtil.isFalse(recursive)) {
            return ResponseEntity.ok(R.success(categoryViewList));
        }
        TreeNodeConfig config = new TreeNodeConfig();
        config.setIdKey("categoryId");
        config.setWeightKey("sortWeight");
        //config.setDeep(3);
        List<Tree<Long>> tree = TreeUtil.build(categoryViewList, 0L, config, (c, treeNode) -> {
            treeNode.setId(c.getCategoryId());
            treeNode.setParentId(c.getParentId());
            treeNode.setName(c.getName());
            treeNode.setWeight(c.getSortWeight());
        });
        return ResponseEntity.ok(R.success(tree));
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryMerchantController.java
New file
@@ -0,0 +1,136 @@
package com.oying.modules.pc.store.rest;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.BooleanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.oying.annotation.Log;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.store.domain.StoreCategory;
import com.oying.modules.pc.store.domain.dto.*;
import com.oying.modules.pc.store.service.StoreCategoryService;
import com.oying.modules.pc.store.view.StoreCategoryMerchantView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
 * @author lzp
 * @date 2025-04-24
 **/
@Api(tags = "店铺类目(商户端)")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/pc/merchant/store/{storeId}/category")
public class StoreCategoryMerchantController {
    private final StoreCategoryService storeCategoryService;
    @GetMapping(value = "/list")
    @ApiOperation("查询店铺类目")
    //@PreAuthorize("@el.check('merchant:storeCategory:list')" +
    //        " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> getList(@PathVariable Long storeId,
                                     @RequestParam(value = "recursive", required = false) Boolean recursive) {
        StoreCategoryQueryCriteria criteria = new StoreCategoryQueryCriteria();
        criteria.setStoreId(storeId);
        List<StoreCategory> storeCategoryList = storeCategoryService.queryAll(criteria);
        List<StoreCategoryMerchantView> viewList = Optional.ofNullable(storeCategoryList).orElse(ListUtil.empty()).stream().map(i -> {
            StoreCategoryMerchantView view = new StoreCategoryMerchantView();
            BeanUtils.copyProperties(i, view);
            return view;
        }).collect(Collectors.toList());
        if (BooleanUtil.isFalse(recursive)) {
            return ResponseEntity.ok(R.success(viewList));
        }
        TreeNodeConfig config = new TreeNodeConfig();
        config.setIdKey("categoryId");
        config.setWeightKey("sortWeight");
        //config.setDeep(3);
        List<Tree<Long>> tree = TreeUtil.build(viewList, 0L, config, (c, treeNode) -> {
            treeNode.setId(c.getCategoryId());
            treeNode.setParentId(c.getParentId());
            treeNode.setName(c.getName());
            treeNode.setWeight(c.getSortWeight());
        });
        return ResponseEntity.ok(R.success(tree));
    }
    @GetMapping(value = "/{categoryId}")
    @ApiOperation("查询店铺类目")
    //@PreAuthorize("@el.check('merchant:storeCategory:list')" +
    //        " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> getById(@PathVariable Long categoryId,
                                     @RequestParam(value = "recursive", required = false) Boolean recursive) {
        StoreCategory storeCategory = storeCategoryService.getById(categoryId);
        StoreCategoryMerchantView view = new StoreCategoryMerchantView();
        BeanUtils.copyProperties(storeCategory, view);
        /*LambdaQueryWrapper<StoreCategory> wrapper = new LambdaQueryWrapper<StoreCategory>()
                .eq(StoreCategory::getParentId, categoryId);
        List<StoreCategory> subStoreCategoryList = storeCategoryService.list(wrapper);*/
        return ResponseEntity.ok(R.success(view));
    }
    @PostMapping
    @Log("新增店铺类目")
    @ApiOperation("新增店铺类目")
    //@PreAuthorize("@el.check('storeCategory:add')" +
    //        " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> createStoreCategory(@PathVariable Long storeId,
                                                 @Validated @RequestBody StoreCategoryMerchantCreateRequest request) {
        StoreCategory resources = new StoreCategory();
        BeanUtils.copyProperties(request, resources);
        resources.setStoreId(storeId);
        storeCategoryService.create(resources);
        return ResponseEntity.status(HttpStatus.CREATED).build();
    }
    @PutMapping(value = "/{categoryId}")
    @Log("修改店铺类目")
    @ApiOperation("修改店铺类目")
    //@PreAuthorize("@el.check('storeCategory:edit')" +
    //        " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateStoreCategory(@PathVariable Long storeId,
                                                 @PathVariable Long categoryId,
                                                 @Validated @RequestBody StoreCategoryMerchantUpdateRequest request) {
        StoreCategory resources = new StoreCategory();
        BeanUtils.copyProperties(request, resources);
        resources.setCategoryId(categoryId);
        resources.setStoreId(storeId);
        storeCategoryService.update(resources);
        return ResponseEntity.noContent().build();
    }
    @DeleteMapping
    @Log("删除店铺类目")
    @ApiOperation("删除店铺类目")
    @PreAuthorize("@el.check('storeCategory:del')" +
            " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> deleteStoreCategory(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
        storeCategoryService.deleteAll(ids);
        return ResponseEntity.noContent().build();
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java
New file
@@ -0,0 +1,68 @@
package com.oying.modules.pc.store.rest;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.common.id.StoreIdGenerator;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.dto.*;
import com.oying.modules.pc.store.service.StoreService;
import com.oying.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.time.ZonedDateTime;
/**
 * 店铺
 *
 * @author lzp
 * @date 2025-04-22
 */
@RestController
@RequestMapping("/api/pc/store")
@RequiredArgsConstructor
public class StoreController {
    private final StoreService storeService;
    @GetMapping(value = "/page")
    public R<?> getStoresByPage(@RequestBody StoreQueryCriteria criteria) {
        return R.success(storeService.queryByPage(criteria));
    }
    @GetMapping(value = "/list")
    public R<?> getStores(@RequestBody StoreQueryCriteria criteria) {
        return R.success(storeService.queryAll(criteria));
    }
    @GetMapping(value = "/{storeId}")
    public R<?> getStoreById(@PathVariable("storeId") Long storeId) {
        return R.success(storeService.getById(storeId));
    }
    @GetMapping(value = "/{storeId}/details")
    public R<?> getStoreDetailsById(@PathVariable("storeId") Long storeId) {
        return R.success(storeService.getById(storeId));
    }
    @PostMapping(value = "/createEmpty")
    public R<?> createEmpty(@RequestBody StoreCreateRequest request) {
        Store store = new Store();
        store.setStoreId(StoreIdGenerator.getId());
        store.setMerchantId(SecurityUtils.getCurrentUserId());
        store.setCreateBy(SecurityUtils.getCurrentUserId());
        store.setCreateTime(ZonedDateTime.now());
        storeService.save(store);
        return R.success();
    }
    /**
     * 修改店铺信息
     */
    @PostMapping(value = "/{storeId}")
    public R<?> update(@PathVariable("storeId") Long storeId, @RequestBody Store store) {
        store.setStoreId(storeId);
        storeService.updateById(store);
        return R.success();
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java
New file
@@ -0,0 +1,36 @@
package com.oying.modules.pc.store.rest;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.store.domain.dto.StoreCustomerDetailDto;
import com.oying.modules.pc.store.domain.dto.StoreCustomerQueryCriteria;
import com.oying.modules.pc.store.service.StoreQueryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
/**
 * 店铺
 *
 * @author lzp
 * @date 2025-04-22
 */
@Api(tags = "店铺(客户端)")
@RestController
@RequestMapping("/api/pc/customer/store")
@RequiredArgsConstructor
public class StoreCustomerController {
    private final StoreQueryService storeQueryService;
    @GetMapping(value = "/{storeId}")
    @ApiOperation("查询店铺")
    public ResponseEntity<?> getCustomerStoreById(@PathVariable("storeId") Long storeId) {
        StoreCustomerQueryCriteria criteria = new StoreCustomerQueryCriteria();
        criteria.setStoreId(storeId);
        StoreCustomerDetailDto detailDto = storeQueryService.getCustomerStoreDetail(criteria);
        return ResponseEntity.ok(R.success(detailDto));
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java
New file
@@ -0,0 +1,263 @@
package com.oying.modules.pc.store.rest;
import cn.hutool.core.collection.ListUtil;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
import com.oying.modules.pc.store.domain.dto.StoreFieldUpdateRequest;
import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
import com.oying.modules.pc.store.service.StoreCreateService;
import com.oying.modules.pc.store.service.StoreService;
import com.oying.modules.pc.store.view.StoreMerchantView;
import com.oying.modules.pc.store.view.StoreSimpleView;
import com.oying.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
 * 店铺
 *
 * @author lzp
 * @date 2025-04-22
 */
@Api(tags = "店铺(商户端)")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/pc/merchant/store")
public class StoreMerchantController {
    private final StoreService storeService;
    private final StoreCreateService storeCreateService;
    @GetMapping(value = "/list")
    @ApiOperation("查询所有店铺")
    //@PreAuthorize("@el.check('merchant:store:list')")
    public ResponseEntity<?> getList() {
        StoreQueryCriteria criteria = new StoreQueryCriteria();
        criteria.setMerchantId(SecurityUtils.getCurrentUserId());
        //criteria.setStatus();
        List<Store> storeList = Optional.ofNullable(storeService.queryAll(criteria)).orElse(ListUtil.empty());
        List<StoreSimpleView> storeViewList = storeList.stream().map(s -> {
            StoreSimpleView view = new StoreSimpleView();
            view.setId(s.getStoreId());
            view.setName(s.getStoreName());
            view.setLogoUrl("");
            view.setStatus(s.getStatus());
            return view;
        }).collect(Collectors.toList());
        return ResponseEntity.ok(R.success(storeViewList));
    }
    @GetMapping(value = "/{storeId}")
    @ApiOperation("查询店铺")
    //@PreAuthorize("@el.check('merchant:store:getById')" +
    //             " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> getById(@PathVariable Long storeId) {
        Store store = storeService.getById(storeId);
        StoreMerchantView view = new StoreMerchantView();
        BeanUtils.copyProperties(store, view);
        view.setLogoUrl("");
        return ResponseEntity.ok(R.success(view));
    }
    @PostMapping
    @ApiOperation("创建店铺")
    //@PreAuthorize("@el.check('merchant:store:create')")
    public ResponseEntity<?> create(@RequestBody StoreCreateRequest request) {
        storeCreateService.create(request);
        return ResponseEntity.status(HttpStatus.CREATED).build();
    }
    /**
     * 修改店铺信息
     */
    @PostMapping(value = "/{storeId}")
    @ApiOperation("修改店铺")
    //@PreAuthorize("@el.check('merchant:store:update')" +
    //        " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> update(@PathVariable("storeId") Long storeId,
                       @RequestBody Store store) {
        store.setStoreId(storeId);
        storeService.updateById(store);
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改店铺LOGO
     */
    @PatchMapping(value = "/{storeId}/logo")
    @ApiOperation("修改店铺LOGO")
    //@PreAuthorize("@el.check('merchant:store:list')" +
    //        " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateLogo(@PathVariable("storeId") Long storeId,
                           @Validated(value = StoreFieldUpdateRequest.UpdateStoreLogoImageGroup.class)
                           @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateLogo(storeId, request.getLogoImageUploadId());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改店铺名称
     */
    @PatchMapping(value = "/{storeId}/name")
    @ApiOperation("修改店铺名称")
    //@PreAuthorize("@el.check('merchant:store:name')" +
    //        " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateName(@PathVariable("storeId") Long storeId,
                           @Validated(value = StoreFieldUpdateRequest.UpdateStoreNameGroup.class)
                           @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateName(storeId, request.getStoreName());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改店铺简介
     */
    @PatchMapping(value = "/{storeId}/description")
    @ApiOperation("修改店铺简介")
    //@PreAuthorize("@el.check('merchant:store:description')" +
    //        " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateDescription(@PathVariable("storeId") Long storeId,
                                  @Validated(value = StoreFieldUpdateRequest.UpdateStoreDescriptionGroup.class)
                                  @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateDescription(storeId, request.getDescription());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改店铺联系电话
     */
    @PatchMapping(value = "/{storeId}/contactPhone")
    @ApiOperation("修改店铺联系电话")
    @PreAuthorize("@el.check('merchant:store:list')" +
            " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateContactPhone(@PathVariable("storeId") Long storeId,
                                   @Validated(value = StoreFieldUpdateRequest.UpdateStoreContactPhoneGroup.class)
                                   @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateContactPhone(storeId, request.getContactPhone());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改店铺地址
     */
    @PatchMapping(value = "/{storeId}/address")
    @ApiOperation("修改店铺地址")
    @PreAuthorize("@el.check('merchant:store:address')" +
            " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateAddress(@PathVariable("storeId") Long storeId,
                              @Validated(value = StoreFieldUpdateRequest.UpdateStoreAddressGroup.class)
                              @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateAddress(storeId, request.getAddress());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改店铺坐标
     */
    @PatchMapping(value = "/{storeId}/location")
    @ApiOperation("修改店铺坐标")
    @PreAuthorize("@el.check('merchant:store:location')" +
            " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateLocation(@PathVariable("storeId") Long storeId,
                               @Validated(value = StoreFieldUpdateRequest.UpdateStoreLocationGroup.class)
                               @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateLocation(storeId, request.getLongitude(), request.getLatitude());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改店铺配送范围
     */
    @PatchMapping(value = "/{storeId}/radius")
    @ApiOperation("修改店铺配送范围")
    @PreAuthorize("@el.check('merchant:store:radius')" +
            " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateRadius(@PathVariable("storeId") Long storeId,
                             @Validated(value = StoreFieldUpdateRequest.UpdateStoreRadiusGroup.class)
                             @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateRadius(storeId, request.getRadius());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改店铺绑定的经营类目
     */
    @PatchMapping(value = "/{storeId}/platformCategory")
    @ApiOperation("修改店铺绑定的经营类目")
    @PreAuthorize("@el.check('merchant:store:platformCategory')" +
            " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updatePlatformCategory(@PathVariable("storeId") Long storeId,
                                       @Validated(value = StoreFieldUpdateRequest.UpdateStorePlatformCategoryGroup.class)
                                       @RequestBody StoreFieldUpdateRequest request) {
        storeService.updatePlatformCategory(storeId, request.getPlatformCategoryId());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改店铺营业时间
     */
    @PatchMapping(value = "/{storeId}/businessHours")
    @ApiOperation("修改店铺营业时间")
    @PreAuthorize("@el.check('merchant:store:businessHours')" +
            " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateBusinessHours(@PathVariable("storeId") Long storeId,
                                    @Validated(value = StoreFieldUpdateRequest.UpdateStoreBusinessHoursGroup.class)
                                    @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateBusinessHours(storeId, request.getOpenTime(), request.getCloseTime());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改起送金额
     */
    @PatchMapping(value = "/{storeId}/deliveryMinimum")
    @ApiOperation("修改起送金额")
    @PreAuthorize("@el.check('merchant:store:deliveryMinimum')" +
            " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateDeliveryMinimum(@PathVariable("storeId") Long storeId,
                                      @Validated(value = StoreFieldUpdateRequest.UpdateStoreDeliveryMinimumGroup.class)
                                      @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateDeliveryMinimum(storeId, request.getDeliveryMinimum());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改配送费用
     */
    @PatchMapping(value = "/{storeId}/deliveryFee")
    @ApiOperation("修改配送费用")
    @PreAuthorize("@el.check('merchant:store:deliveryFee')" +
            " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> updateDeliveryFee(@PathVariable("storeId") Long storeId,
                                  @Validated(value = StoreFieldUpdateRequest.UpdateStoreDeliveryFeeGroup.class)
                                  @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateDeliveryFee(storeId, request.getDeliveryFee());
        return ResponseEntity.noContent().build();
    }
    /**
     * 修改状态
     */
    @PatchMapping(value = "/{storeId}/businessStatus")
    @ApiOperation("修改状态")
    @PreAuthorize("@el.check('merchant:store:businessStatus')" +
            " and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> businessStatus(@PathVariable("storeId") Long storeId,
                               @Validated(value = StoreFieldUpdateRequest.UpdateStoreBusinessStatusGroup.class)
                               @RequestBody StoreFieldUpdateRequest request) {
        storeService.updateStatus(storeId, request.getBusinessStatus());
        return ResponseEntity.noContent().build();
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationController.java
New file
@@ -0,0 +1,67 @@
package com.oying.modules.pc.store.rest;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.annotation.Log;
import com.oying.modules.pc.store.domain.StoreQualification;
import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
import com.oying.modules.pc.store.service.StoreQualificationService;
import com.oying.utils.PageResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author lzp
 * @date 2025-04-23
 **/
@RestController
@RequiredArgsConstructor
@Api(tags = "店铺资质")
@RequestMapping("/api/storeQualification")
public class StoreQualificationController {
    private final StoreQualificationService storeQualificationService;
    @GetMapping
    @ApiOperation("查询店铺资质")
    @PreAuthorize("@el.check('storeQualification:list')")
    public ResponseEntity<PageResult<StoreQualification>> queryStoreQualification(StoreQualificationQueryCriteria criteria) {
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        return new ResponseEntity<>(storeQualificationService.queryAll(criteria, page), HttpStatus.OK);
    }
    @PostMapping
    @Log("新增店铺资质")
    @ApiOperation("新增店铺资质")
    @PreAuthorize("@el.check('storeQualification:add')")
    public ResponseEntity<Object> createStoreQualification(@Validated @RequestBody StoreQualification resources) {
        storeQualificationService.create(resources);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }
    @PutMapping
    @Log("修改店铺资质")
    @ApiOperation("修改店铺资质")
    @PreAuthorize("@el.check('storeQualification:edit')")
    public ResponseEntity<Object> updateStoreQualification(@Validated @RequestBody StoreQualification resources) {
        storeQualificationService.update(resources);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }
    @DeleteMapping
    @Log("删除店铺资质")
    @ApiOperation("删除店铺资质")
    @PreAuthorize("@el.check('storeQualification:del')")
    public ResponseEntity<Object> deleteStoreQualification(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
        storeQualificationService.deleteAll(ids);
        return new ResponseEntity<>(HttpStatus.OK);
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java
New file
@@ -0,0 +1,55 @@
package com.oying.modules.pc.store.rest;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjUtil;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.store.domain.StoreQualification;
import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
import com.oying.modules.pc.store.service.StoreQualificationService;
import com.oying.modules.pc.store.view.CustomerStoreQualificationView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
 * @author lzp
 * @date 2025-04-23
 *
*/
@RestController
@RequiredArgsConstructor
@Api(tags = "店铺资质(客户端)")
@RequestMapping("/api/pc/customer/store/{storeId}/qualification")
public class StoreQualificationCustomerController {
    private final StoreQualificationService storeQualificationService;
    @GetMapping("/list")
    @ApiOperation("查询店铺资质")
    //@PreAuthorize("@el.check('customer:storeQualification:list')")
    public ResponseEntity<?> getList(@PathVariable Long storeId) {
        if (ObjUtil.isEmpty(storeId)) {
            return ResponseEntity.ok(R.success(ListUtil.empty()));
        }
        StoreQualificationQueryCriteria criteria = new StoreQualificationQueryCriteria();
        criteria.setStoreId(storeId);
        List<StoreQualification> qualificationList = storeQualificationService.queryAll(criteria);
        List<CustomerStoreQualificationView> viewList = Optional.ofNullable(qualificationList).orElse(ListUtil.empty()).stream().map(i -> {
            CustomerStoreQualificationView view = new CustomerStoreQualificationView();
            BeanUtils.copyProperties(i, view);
            view.setType(i.getQualificationType());
            view.setName(i.getQualificationName());
            view.setImageUrl("");
            return view;
        }).collect(Collectors.toList());
        return ResponseEntity.ok(R.success(viewList));
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationMerchantController.java
New file
@@ -0,0 +1,100 @@
package com.oying.modules.pc.store.rest;
import cn.hutool.core.collection.ListUtil;
import com.oying.annotation.Log;
import com.oying.modules.pc.common.core.domain.R;
import com.oying.modules.pc.store.domain.StoreQualification;
import com.oying.modules.pc.store.domain.dto.StoreQualificationCreateRequest;
import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
import com.oying.modules.pc.store.domain.dto.StoreQualificationUpdateRequest;
import com.oying.modules.pc.store.service.StoreQualificationService;
import com.oying.modules.pc.store.view.StoreQualificationMerchantView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
 * @author lzp
 * @date 2025-04-23
 **/
@RestController
@RequiredArgsConstructor
@Api(tags = "店铺资质(商户端)")
@RequestMapping("/api/pc/merchant/store/{storeId}/qualification")
public class StoreQualificationMerchantController {
    private final StoreQualificationService storeQualificationService;
    @GetMapping("/list")
    @ApiOperation("查询店铺资质")
    //@PreAuthorize("@el.check('merchant:storeQualification:list') " +
    //        "and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> getList(@PathVariable Long storeId) {
        StoreQualificationQueryCriteria criteria = new StoreQualificationQueryCriteria();
        criteria.setStoreId(storeId);
        List<StoreQualification> storeQualificationList = storeQualificationService.queryAll(criteria);
        List<StoreQualificationMerchantView> viewList = Optional.ofNullable(storeQualificationList).orElse(ListUtil.empty()).stream().map(i -> {
            StoreQualificationMerchantView view = new StoreQualificationMerchantView();
            view.setId(i.getQualificationId());
            view.setType(i.getQualificationType());
            view.setName(i.getQualificationName());
            view.setImageUrl("");
            return view;
        }).collect(Collectors.toList());
        return ResponseEntity.ok(R.success(viewList));
    }
    @PostMapping
    @Log("新增店铺资质")
    @ApiOperation("新增店铺资质")
    //@PreAuthorize("@el.check('merchant:storeQualification:add') " +
    //        "and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> create(@PathVariable Long storeId,
                                         @Validated @RequestBody StoreQualificationCreateRequest request) {
        StoreQualification resources = new StoreQualification();
        resources.setStoreId(storeId);
        resources.setQualificationType(request.getType());
        resources.setQualificationImageId(request.getImageUploadFileId());
        storeQualificationService.create(resources);
        return ResponseEntity.status(HttpStatus.CREATED).build();
    }
    @PutMapping("/{qualificationId}")
    @Log("修改店铺资质")
    @ApiOperation("修改店铺资质")
    //@PreAuthorize("@el.check('merchant:storeQualification:edit') " +
    //        "and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> update(@PathVariable Long storeId,
                                         @PathVariable Long qualificationId,
                                         @Validated @RequestBody StoreQualificationUpdateRequest request) {
        StoreQualification resources = new StoreQualification();
        resources.setQualificationId(qualificationId);
        resources.setStoreId(storeId);
        resources.setQualificationType(request.getType());
        resources.setQualificationImageId(request.getImageUploadFileId());
        storeQualificationService.update(resources);
        return ResponseEntity.noContent().build();
    }
    @DeleteMapping
    @Log("删除店铺资质")
    @ApiOperation("删除店铺资质")
    //@PreAuthorize("@el.check('merchant:storeQualification:batchDel') " +
    //        "and @storeMerchantOwnershipService.check(#storeId)")
    public ResponseEntity<?> batchDel(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
        storeQualificationService.deleteAll(ids);
        return ResponseEntity.noContent().build();
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCategoryService.java
New file
@@ -0,0 +1,52 @@
package com.oying.modules.pc.store.service;
import com.oying.modules.pc.store.domain.StoreCategory;
import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.utils.PageResult;
/**
* @description 服务接口
* @author lzp
* @date 2025-04-24
**/
public interface StoreCategoryService extends IService<StoreCategory> {
    /**
    * 查询数据分页
    * @param criteria 条件
    * @param page 分页参数
    * @return PageResult
    */
    PageResult<StoreCategory> queryAll(StoreCategoryQueryCriteria criteria, Page<Object> page);
    /**
    * 查询所有数据不分页
    * @param criteria 条件参数
    * @return List<StoreCategoryDto>
    */
    List<StoreCategory> queryAll(StoreCategoryQueryCriteria criteria);
    /**
    * 创建
    * @param resources /
    */
    void create(StoreCategory resources);
    /**
    * 编辑
    * @param resources /
    */
    void update(StoreCategory resources);
    /**
    * 多选删除
    * @param ids /
    */
    void deleteAll(List<Long> ids);
}
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreateService.java
New file
@@ -0,0 +1,7 @@
package com.oying.modules.pc.store.service;
import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
public interface StoreCreateService {
    void create(StoreCreateRequest request);
}
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreationCoordinator.java
New file
@@ -0,0 +1,31 @@
package com.oying.modules.pc.store.service;
import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class StoreCreationCoordinator {
    private final StoreService storeService;
    private final StoreQualificationService qualificationService;
    // 核心方法:支持可选 qualification
    /*@Transactional
    public StoreFullDTO createFullStore(StoreCreateRequest request) {
        // 1. 必选操作:store + location + staff
        Store store = storeService.create(request.getStore());
        StoreLocation location = locationService.create(store.getId(), request.getLocation());
        StoreStaff staff = staffService.create(store.getId(), request.getStaff());
        // 2. 可选操作:qualification(根据请求决定)
        StoreQualification qualification = null;
        if (request.hasQualification()) {
            qualification = qualificationService.create(store.getId(), request.getQualification());
        }
        // 3. 返回聚合结果
        return new StoreFullDTO(store, location, staff, qualification);
    }*/
}
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreMerchantOwnershipService.java
New file
@@ -0,0 +1,12 @@
package com.oying.modules.pc.store.service;
import com.oying.modules.pc.store.domain.Store;
public interface StoreMerchantOwnershipService {
    boolean isStoreOwnedByMerchant(Long storeId, Long merchantId);
    Store verifyAndGetStore(Long storeId, Long merchantId);
    void verifyStoreOwnership(Long storeId, Long merchantId);
    Boolean check(Long storeId);
}
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java
New file
@@ -0,0 +1,57 @@
package com.oying.modules.pc.store.service;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.modules.pc.store.domain.StoreQualification;
import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
import com.oying.utils.PageResult;
/**
* @description 服务接口
* @author lzp
* @date 2025-04-27
**/
public interface StoreQualificationService extends IService<StoreQualification> {
    /**
    * 查询数据分页
    * @param criteria 条件
    * @param page 分页参数
    * @return PageResult
    */
    PageResult<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria, Page<Object> page);
    /**
    * 查询所有数据不分页
    * @param criteria 条件参数
    * @return List<StoreQualificationDto>
    */
    List<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria);
    /**
    * 创建
    * @param resources /
    */
    void create(StoreQualification resources);
    /**
     * 批量创建
     * @param resources /
     */
    void batchCreate(List<StoreQualification> resources);
    /**
    * 编辑
    * @param resources /
    */
    void update(StoreQualification resources);
    /**
    * 多选删除
    * @param ids /
    */
    void deleteAll(List<Long> ids);
}
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQueryService.java
New file
@@ -0,0 +1,10 @@
package com.oying.modules.pc.store.service;
import com.oying.modules.pc.store.domain.dto.StoreCustomerDetailDto;
import com.oying.modules.pc.store.domain.dto.StoreCustomerQueryCriteria;
public interface StoreQueryService {
    StoreCustomerDetailDto getCustomerStoreDetail(StoreCustomerQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java
New file
@@ -0,0 +1,56 @@
package com.oying.modules.pc.store.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.StoreCategory;
import com.oying.modules.pc.store.domain.dto.StoreBusinessHoursRequest;
import com.oying.modules.pc.store.domain.dto.StoreLocationUpdateRequest;
import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
import com.oying.utils.PageResult;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.List;
/**
 * 店铺基础信息Service接口
 *
 * @author lzp
 * @date 2025-04-22
 */
public interface StoreService extends IService<Store> {
    PageResult<Store> queryByPage(StoreQueryCriteria criteria);
    List<Store> queryAll(StoreQueryCriteria criteria);
    Store getMerchantStore(Long merchantId);
    boolean create(Store store);
    boolean updateLogo(Long storeId, String logo);
    boolean updateName(Long storeId, String storeName);
    boolean updateDescription(Long storeId, String description);
    boolean updateContactPhone(Long storeId, String contactPhone);
    boolean updateAddress(Long storeId, String address);
    boolean updateLocation(Long storeId, Double longitude, Double latitude);
    boolean updateRadius(Long storeId, Integer radius);
    boolean updatePlatformCategory(Long storeId, Long platformCategory);
    boolean updateBusinessHours(Long storeId, LocalTime openTime, LocalTime endTime);
    boolean updateDeliveryMinimum(Long storeId, BigDecimal deliveryMinimum);
    boolean updateDeliveryFee(Long storeId, BigDecimal deliveryFee);
    boolean updateStatus(Long storeId, Integer status);
    boolean existsByIdAndMerchantId(Long storeId, Long merchantId);
}
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCategoryServiceImpl.java
New file
@@ -0,0 +1,96 @@
package com.oying.modules.pc.store.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oying.exception.EntityNotFoundException;
import com.oying.modules.pc.common.exception.LevelExceededException;
import com.oying.modules.pc.store.domain.StoreCategory;
import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
import com.oying.modules.pc.store.mapper.StoreCategoryMapper;
import com.oying.modules.pc.store.service.StoreCategoryService;
import com.oying.utils.FileUtil;
import com.oying.utils.PageResult;
import com.oying.utils.PageUtil;
import com.oying.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
/**
 * @author lzp
 * @date 2025-04-24
 **/
@Service
@RequiredArgsConstructor
public class StoreCategoryServiceImpl extends ServiceImpl<StoreCategoryMapper, StoreCategory> implements StoreCategoryService {
    private static final int MAX_LEVEL = 2;
    private final StoreCategoryMapper storeCategoryMapper;
    @Override
    public PageResult<StoreCategory> queryAll(StoreCategoryQueryCriteria criteria, Page<Object> page) {
        return PageUtil.toPage(storeCategoryMapper.findAll(criteria, page));
    }
    @Override
    public List<StoreCategory> queryAll(StoreCategoryQueryCriteria criteria) {
        return storeCategoryMapper.findAll(criteria);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(StoreCategory resources) {
        // 重名
        this.calculateAndSetLevel(resources);
        resources.setCreateBy(SecurityUtils.getCurrentUserId());
        storeCategoryMapper.insert(resources);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(StoreCategory resources) {
        StoreCategory storeCategory = getById(resources.getCategoryId());
        storeCategory.copy(resources);
        resources.setUpdateBy(SecurityUtils.getCurrentUserId());
        storeCategoryMapper.updateById(storeCategory);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        storeCategoryMapper.deleteBatchIds(ids);
    }
    /**
     * 计算并设置类目的层级
     */
    private void calculateAndSetLevel(StoreCategory category) {
        if (category == null) {
            throw new IllegalArgumentException("对象不能为null");
        }
        Long parentCategoryId = category.getParentId();
        if (parentCategoryId == null) {
            category.setParentId(0L);
            category.setLevel(1);
            return;
        }
        StoreCategory parentCategory = Optional.ofNullable(getById(parentCategoryId))
                .orElseThrow(() -> new EntityNotFoundException(StoreCategory.class, "parentId", parentCategoryId.toString()));
        int currentLevel = parentCategory.getLevel() + 1;
        if (currentLevel > MAX_LEVEL) {
            throw new LevelExceededException(category.getLevel(), MAX_LEVEL);
        }
        category.setLevel(currentLevel);
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java
New file
@@ -0,0 +1,51 @@
package com.oying.modules.pc.store.service.impl;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.StoreQualification;
import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
import com.oying.modules.pc.store.service.StoreCreateService;
import com.oying.modules.pc.store.service.StoreQualificationService;
import com.oying.modules.pc.store.service.StoreService;
import com.oying.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class StoreCreateServiceImpl implements StoreCreateService {
    private final StoreService storeService;
    private final StoreQualificationService storeQualificationService;
    @Transactional(rollbackFor = Exception.class)
    public void create(StoreCreateRequest request) {
        Store store = new Store();
        BeanUtils.copyProperties(request, store);
        store.setMerchantId(SecurityUtils.getCurrentUserId());
        store.setLogoImageId(request.getLogoUploadFileId());
        // store.setCoverImage(request.getCoverUploadFileId());
        storeService.create(store);
        if (request.hasQualificationList()) {
            List<StoreQualification> storeQualificationList = request.getQualificationList()
                    .stream()
                    .map(i -> {
                        StoreQualification qualification = new StoreQualification();
                        qualification.setStoreId(store.getStoreId());
                        qualification.setQualificationType(i.getType());
                        qualification.setQualificationName("");
                        qualification.setQualificationImageId(i.getImageUploadFileId());
                        return qualification;
                    })
                    .collect(Collectors.toList());
            storeQualificationList.forEach(i -> i.setStoreId(store.getStoreId()));
            storeQualificationService.batchCreate(storeQualificationList);
        }
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantOwnershipServiceImpl.java
New file
@@ -0,0 +1,59 @@
package com.oying.modules.pc.store.service.impl;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.service.StoreMerchantOwnershipService;
import com.oying.modules.pc.store.service.StoreService;
import com.oying.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service("smo")
@RequiredArgsConstructor
public class StoreMerchantOwnershipServiceImpl implements StoreMerchantOwnershipService {
    private final StoreService storeService;
    /**
     *  验证店铺是否属于商户
     */
    @Override
    public boolean isStoreOwnedByMerchant(Long storeId, Long merchantId) {
        /*if (storeId == null || merchantId == null) {
            return false;
        }
        Store store = storeService.getById(storeId);
        return Optional.ofNullable(store).map(i -> merchantId.equals(i.getMerchantId())).orElse(false);*/
        return true;
    }
    /**
     * 验证并获取店铺对象
     */
    @Override
    public Store verifyAndGetStore(Long storeId, Long merchantId) {
        Store store = storeService.getById(storeId);
        return Optional.ofNullable(store).orElseThrow(() -> new AccessDeniedException("无权访问此店铺"));
    }
    /**
     *  简单验证(不返回对象)
     */
    @Override
    public void verifyStoreOwnership(Long storeId, Long merchantId) {
        if (!isStoreOwnedByMerchant(storeId, merchantId)) {
            throw new AccessDeniedException("无权操作此店铺");
        }
    }
    /**
     * PreAuthorize验证
     */
    @Override
    public Boolean check(Long storeId) {
        Long merchantId = SecurityUtils.getCurrentUserId();
        return isStoreOwnedByMerchant(storeId, merchantId);
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java
New file
@@ -0,0 +1,79 @@
package com.oying.modules.pc.store.service.impl;
import cn.hutool.core.util.ObjUtil;
import com.oying.exception.EntityExistException;
import com.oying.modules.pc.common.id.StoreQualificationIdGenerator;
import com.oying.modules.pc.store.domain.StoreQualification;
import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
import com.oying.modules.pc.store.mapper.StoreQualificationMapper;
import com.oying.modules.pc.store.service.StoreQualificationService;
import com.oying.utils.*;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.ZonedDateTime;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
/**
* @description 服务实现
* @author lzp
* @date 2025-04-27
**/
@Service
@RequiredArgsConstructor
public class StoreQualificationServiceImpl extends ServiceImpl<StoreQualificationMapper, StoreQualification> implements StoreQualificationService {
    private final StoreQualificationMapper storeQualificationMapper;
    @Override
    public PageResult<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria, Page<Object> page){
        return PageUtil.toPage(storeQualificationMapper.findAll(criteria, page));
    }
    @Override
    public List<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria){
        return storeQualificationMapper.findAll(criteria);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(StoreQualification resources) {
        // resources.setQualificationId(StoreQualificationIdGenerator.getId());
        resources.setCreateBy(SecurityUtils.getCurrentUserId());
        resources.setCreateTime(ZonedDateTime.now());
        storeQualificationMapper.insert(resources);
    }
    @Override
    public void batchCreate(List<StoreQualification> resources) {
        resources.forEach(i-> {
            i.setCreateBy(SecurityUtils.getCurrentUserId());
            i.setCreateTime(ZonedDateTime.now());
        });
        this.saveBatch(resources);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(StoreQualification resources) {
        // resources.setUpdateBy();
        Long qualificationId = resources.getQualificationId();
        StoreQualification existingStoreQualification = this.getById(qualificationId);
        if (ObjUtil.isEmpty(existingStoreQualification)) {
            throw new EntityExistException(StoreQualification.class, "id", Optional.ofNullable(qualificationId).map(Object::toString).orElse("null"));
        }
        existingStoreQualification.copy(resources);
        storeQualificationMapper.updateById(existingStoreQualification);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        storeQualificationMapper.deleteBatchIds(ids);
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQueryServiceImpl.java
New file
@@ -0,0 +1,33 @@
package com.oying.modules.pc.store.service.impl;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.dto.StoreCustomerDetailDto;
import com.oying.modules.pc.store.domain.dto.StoreCustomerQueryCriteria;
import com.oying.modules.pc.store.service.StoreQueryService;
import com.oying.modules.pc.store.service.StoreService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class StoreQueryServiceImpl implements StoreQueryService {
    private final StoreService storeService;
    @Override
    public StoreCustomerDetailDto getCustomerStoreDetail(StoreCustomerQueryCriteria criteria) {
        Store store = storeService.getById(criteria.getStoreId());
        StoreCustomerDetailDto storeDto = new StoreCustomerDetailDto();
        BeanUtils.copyProperties(store, storeDto);
        storeDto.setName(store.getStoreName());
        storeDto.setLogoUrl("");
        storeDto.setBusinessHours("");
        storeDto.setDeliveryDuration(0);
        storeDto.setMonthlySales(0);
        storeDto.setScore(0);
        return storeDto;
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java
New file
@@ -0,0 +1,159 @@
package com.oying.modules.pc.store.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oying.modules.pc.store.domain.Store;
import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
import com.oying.modules.pc.store.mapper.StoreMapper;
import com.oying.modules.pc.store.service.StoreService;
import com.oying.utils.PageResult;
import com.oying.utils.PageUtil;
import com.oying.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Optional;
/**
 * 店铺Service业务层处理
 *
 * @author lzp
 * @date 2025-04-22
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StoreServiceImpl extends ServiceImpl<StoreMapper, Store> implements StoreService {
    private final StoreMapper storeMapper;
    @Override
    public PageResult<Store> queryByPage(StoreQueryCriteria criteria) {
        Page<Store> page = new Page<>(criteria.getPage(), criteria.getSize());
        return PageUtil.toPage(storeMapper.selectStoreList(criteria, page));
    }
    @Override
    public List<Store> queryAll(StoreQueryCriteria criteria) {
        return storeMapper.selectStoreList(criteria);
    }
    @Override
    public Store getMerchantStore(Long merchantId) {
        return storeMapper.selectStoreByMerchantId(merchantId);
    }
    @Override
    public boolean create(Store store) {
        // store.setStoreId(StoreIdGenerator.getId());
        store.setCreateBy(SecurityUtils.getCurrentUserId());
        store.setCreateTime(ZonedDateTime.now());
        return save(store);
    }
    @Override
    public boolean updateLogo(Long storeId, String logo) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId).set(Store::getLogoImageId, logo);
        return update(wrapper);
    }
    @Override
    public boolean updateName(Long storeId, String storeName) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getStoreName, storeName);
        return update(wrapper);
    }
    @Override
    public boolean updateDescription(Long storeId, String description) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getDescription, description);
        return update(wrapper);
    }
    @Override
    public boolean updateContactPhone(Long storeId, String contactPhone) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getContactPhone, contactPhone);
        return update(wrapper);
    }
    @Override
    public boolean updateAddress(Long storeId, String address) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getAddress, address);
        return update(wrapper);
    }
    @Override
    public boolean updateLocation(Long storeId, Double longitude, Double latitude) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getLongitude, longitude)
                .set(Store::getLatitude, latitude);
        return update(wrapper);
    }
    @Override
    public boolean updateRadius(Long storeId, Integer radius) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getRadius, radius);
        return update(wrapper);
    }
    @Override
    public boolean updatePlatformCategory(Long storeId, Long platformCategory) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getPlatformCategoryId, platformCategory);
        return update(wrapper);
    }
    @Override
    public boolean updateBusinessHours(Long storeId, LocalTime openTime, LocalTime endTime) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getOpenTime, openTime)
                .set(Store::getCloseTime, endTime);
        return update(wrapper);
    }
    @Override
    public boolean updateDeliveryMinimum(Long storeId, BigDecimal deliveryMinimum) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getDeliveryMinimum, deliveryMinimum);
        return update(wrapper);
    }
    @Override
    public boolean updateDeliveryFee(Long storeId, BigDecimal deliveryFee) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getDeliveryFee, deliveryFee);
        return update(wrapper);
    }
    @Override
    public boolean updateStatus(Long storeId, Integer status) {
        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
                .set(Store::getStatus, status);
        return update(wrapper);
    }
    @Override
    public boolean existsByIdAndMerchantId(Long storeId, Long merchantId) {
        if (storeId == null || merchantId == null) {
            return false;
        }
        Store store = getById(storeId);
        return Optional.ofNullable(store).map(i -> merchantId.equals(i.getMerchantId())).orElse(false);
    }
    private LambdaUpdateWrapper<Store> createLambdaUpdateWrapper(Long storeId) {
        return new LambdaUpdateWrapper<Store>()
                .eq(Store::getStoreId, storeId)
                .set(Store::getUpdateBy, SecurityUtils.getCurrentUserId());
    }
}
oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreCategoryView.java
New file
@@ -0,0 +1,25 @@
package com.oying.modules.pc.store.view;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
public class CustomerStoreCategoryView {
    @ApiModelProperty(value = "类目ID")
    private Long categoryId;
    @ApiModelProperty(value = "父ID")
    private Long parentId;
    @ApiModelProperty(value = "类目名称")
    private String name;
    @ApiModelProperty(value = "排序权重")
    private Integer sortWeight;
    private List<StoreCategoryMerchantView> children;
}
oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreQualificationView.java
New file
@@ -0,0 +1,21 @@
package com.oying.modules.pc.store.view;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class CustomerStoreQualificationView {
    @NotNull
    @ApiModelProperty(value = "资质类型")
    private Integer type;
    @ApiModelProperty(value = "资质名称")
    private String name;
    @ApiModelProperty(value = "资质图片")
    private String imageUrl;
}
oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreView.java
New file
@@ -0,0 +1,28 @@
package com.oying.modules.pc.store.view;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@Data
public class CustomerStoreView {
    private String name;
    private String logoUrl;
    private String description;
    private String address;
    private String businessHours;
    private String contactPhone;
    private Integer score;
    private Integer deliveryDuration;
    private Integer monthlySales;
}
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreCategoryMerchantView.java
New file
@@ -0,0 +1,23 @@
package com.oying.modules.pc.store.view;
import lombok.Data;
import java.util.List;
@Data
public class StoreCategoryMerchantView {
    private Long categoryId;
    private Long storeId;
    private Long parentId;
    private String name;
    private Integer sortWeight;
    private Integer active;
    private List<StoreCategoryMerchantView> children;
}
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreMerchantView.java
New file
@@ -0,0 +1,48 @@
package com.oying.modules.pc.store.view;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalTime;
@Data
public class StoreMerchantView {
    @ApiModelProperty(value = "ID")
    private Long storeId;
    @ApiModelProperty(value = "平台类目")
    private Long platformCategoryId;
    @ApiModelProperty(value = "店铺名称")
    private String storeName;
    private String logoUrl;
    @ApiModelProperty(value = "店铺描述")
    private String description;
    @ApiModelProperty(value = "联系电话")
    private String contactPhone;
    @ApiModelProperty(value = "营业开始时间")
    private LocalTime openTime;
    @ApiModelProperty(value = "营业结束时间")
    private LocalTime closeTime;
    @ApiModelProperty(value = "详细地址")
    private String address;
    @ApiModelProperty(value = "经度")
    private Double longitude;
    @ApiModelProperty(value = "纬度")
    private Double latitude;
    @ApiModelProperty(value = "营业半径(米)")
    private Integer radius;
    private Integer status;
}
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreQualificationMerchantView.java
New file
@@ -0,0 +1,24 @@
package com.oying.modules.pc.store.view;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class StoreQualificationMerchantView {
    @NotNull
    @ApiModelProperty(value = "资质ID")
    private Long id;
    @ApiModelProperty(value = "资质类型")
    private Integer type;
    @ApiModelProperty(value = "资质名称")
    private String name;
    @ApiModelProperty(value = "资质图片")
    private String imageUrl;
}
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreSimpleView.java
New file
@@ -0,0 +1,16 @@
package com.oying.modules.pc.store.view;
import lombok.Data;
@Data
public class StoreSimpleView {
    private Long id;
    private String name;
    private String logoUrl;
    private Integer status;
}
oying-system/src/main/java/com/oying/modules/pc/utils/WrapperUtils.java
New file
@@ -0,0 +1,18 @@
package com.oying.modules.pc.utils;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.oying.base.BaseEntity;
public class WrapperUtils {
    public static <T> UpdateWrapper<T> baseUpdateWrapper(Long id, Long updateBy) {
        return new UpdateWrapper<T>()
                .eq("id", id)
                .set("update_by", updateBy);
    }
    public static <T extends BaseEntity> LambdaUpdateWrapper<T> getBaseLambdaUpdateWrapper(Long id, Long updateBy) {
        return new LambdaUpdateWrapper<T>();
    }
}
oying-system/src/main/java/com/oying/modules/security/config/SwiftPassProperties.java
New file
@@ -0,0 +1,40 @@
package com.oying.modules.security.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
 * @author xin
 * @description
 * @date 2025/1/22 下午4:49
 */
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "swift-pass")
public class SwiftPassProperties {
    // 交易密钥1
    private String key;
    // 平台私钥
    private String mchPrivateKey;
    // 平台公钥
    private String platPublicKey;
    // 门店编号1
    private String mchId;
    // 签名方式
    private String signType;
    // 原生JS
    private String isRaw;
    // 是否小程序支付
    private String isMinipg;
    // AppID
    private String appId;
    // 请求url
    private String reqUrl;
    // 支付通知地址
    private String notifyUrl;
    // 退款通知地址
    private String refundUrl;
}
oying-system/src/main/java/com/oying/modules/security/config/WeiXinProperties.java
New file
@@ -0,0 +1,31 @@
package com.oying.modules.security.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "wx")
public class WeiXinProperties {
    // APPID
    private String appId;
    // APP密钥
    private String appSecret;
    // 跳转小程序类型
    private String miniProgramState;
    /*access_token的KEY*/
    private String tokenKey;
    /*access_token的失效时间间隔,微信是2小时,此处隔7200秒就重新获取*/
    private Long tokenTime;
    /*POST 获取稳定版接口调用凭据 获取小程序全局唯一后台接口调用凭据,token有效期为7200s,开发者需要进行妥善保存。*/
    private String getStableAccessToken;
    /*GET 小程序登录 登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程*/
    private String code2Session;
    /*POST 获取手机号 该接口用于将code换取用户手机号。 说明,每个code只能使用一次,code的有效期为5min。*/
    private String getPhoneNumber;
    /*POST 该接口用于发送订阅消息。*/
    private String sendMessage;
    /* 是否生成环境*/
    private boolean enabled;
}
oying-system/src/main/java/com/oying/modules/security/rest/AuthController.java
@@ -102,7 +102,7 @@
    }
    @ApiOperation("临时授权")
    @AnonymousPostMapping(value = "/token")
    @AnonymousGetMapping(value = "/token")
    public ResponseEntity<Object> loginTest(@RequestParam String username, HttpServletRequest request) {
        // 生成令牌与第三方系统获取令牌方式
        JwtUserDto jwtUser = userDetailsService.loadUserByUsername(username);
oying-system/src/main/java/com/oying/modules/security/rest/VerificationController.java
New file
@@ -0,0 +1,44 @@
package com.oying.modules.security.rest;
import cn.hutool.core.util.IdUtil;
import com.oying.annotation.rest.AnonymousGetMapping;
import com.oying.utils.RedisUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author xin
 * @description
 * @date 2025/5/29 00:54
 */
@Slf4j
@RestController
@RequestMapping("/auth/verification")
@RequiredArgsConstructor
@Api(tags = "系统:短信验证码")
public class VerificationController {
    private final RedisUtils redisUtils;
    @Value("${sms.key}")
    private String key;
    @Value("${sms.time}")
    private Long time;
    @AnonymousGetMapping
    @ApiOperation("短信验证码")
    public ResponseEntity<Object> toPayAsPc(@RequestParam String phone) {
        String uuid = key + IdUtil.simpleUUID();
        System.out.println(phone);
        //创建验证码
        String verification = (int) ((Math.random() * 9 + 1) * 100000) + "";
        redisUtils.set(uuid, verification, time);
        return ResponseEntity.ok(uuid);
    }
}
oying-system/src/main/java/com/oying/modules/security/service/WeiXinService.java
New file
@@ -0,0 +1,112 @@
package com.oying.modules.security.service;
import com.alibaba.fastjson2.JSONObject;
import com.oying.modules.security.config.WeiXinProperties;
import com.oying.utils.HttpRequest;
import com.oying.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@Service
@Slf4j
public class WeiXinService {
    @Resource
    private WeiXinProperties weiXinProperties;
    @Resource
    private RedisUtils redisUtils;
    @Value("${wx.enabled}")
    private Boolean wxEnabled;
    /**
     * POST 获取稳定版接口调用凭据 获取小程序全局唯一后台接口调用凭据,token有效期为7200s,开发者需要进行妥善保存。
     *
     * @return accessToken
     */
    public String getStableAccessToken() {
        String accessToken;
        if (redisUtils.isExpire(weiXinProperties.getTokenKey())) {
            // 获取接口调用凭据
            String url = weiXinProperties.getGetStableAccessToken();
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("grant_type", "client_credential");
            map.put("appid", weiXinProperties.getAppId());
            map.put("secret", weiXinProperties.getAppSecret());
            map.put("force_refresh", false);
            JSONObject jsonObject = HttpRequest.exchangeJsonObject(HttpMethod.POST, url, map);
            accessToken = jsonObject.getString("access_token");
            redisUtils.set(weiXinProperties.getTokenKey(), accessToken, weiXinProperties.getTokenTime());
        } else {
            // 查询接口调用凭据
            accessToken = (String) redisUtils.get(weiXinProperties.getTokenKey());
        }
        return accessToken;
    }
    /**
     * GET 小程序登录 登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程
     *
     * @param js_code 登录时获取的 code,可通过wx.login获取
     * @return JSONObject
     */
    public JSONObject code2Session(String js_code) {
        String url = weiXinProperties.getCode2Session();
        url = url.replace("{appid}", weiXinProperties.getAppId())
                .replace("{secret}", weiXinProperties.getAppSecret())
                .replace("{js_code}", js_code);
        return HttpRequest.exchangeJsonObject(HttpMethod.GET, url, null);
    }
    /**
     * POST 获取手机号 该接口用于将code换取用户手机号。 说明,每个code只能使用一次,code的有效期为5min。
     *
     * @param code 手机号获取凭证
     * @return JSONObject
     */
    public JSONObject getPhoneNumber(String code) {
        String url = weiXinProperties.getGetPhoneNumber();
        url = url.replace("{accessToken}", getStableAccessToken());
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("code", code);
        return HttpRequest.exchangeJsonObject(HttpMethod.POST, url, map);
    }
    /**
     * POST 该接口用于发送订阅消息。
     *
     * @param data 请求参数
     * @param openId 用户openId
     * @param templateId 订阅模板id
     * @param page 小程序跳转链接
     * @return JSONObject
     */
    public JSONObject sendMessage(Map<String, Object> data, String openId, String templateId, String page) {
        if (wxEnabled) {
            String url = weiXinProperties.getSendMessage();
            url = url.replace("{accessToken}", getStableAccessToken());
            Map<String, Object> map = getSendMessageDto(data, openId, templateId, page);
            return HttpRequest.exchangeJsonObject(HttpMethod.POST, url, map);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message", "测试环境");
        return jsonObject;
    }
    private Map<String, Object> getSendMessageDto(Map<String, Object> data, String openId, String templateId, String page) {
        Map<String, Object> map = new HashMap<>();
        map.put("touser", openId);
        map.put("template_id", templateId);
        map.put("page", page);
        map.put("miniprogram_state", weiXinProperties.getMiniProgramState());
        map.put("lang", "zh_CN");
        map.put("data", data);
        return map;
    }
}
oying-system/src/main/java/com/oying/modules/system/domain/Merchants.java
New file
@@ -0,0 +1,68 @@
package com.oying.modules.system.domain;
import com.oying.base.BaseEntity;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import java.sql.Timestamp;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
/**
* @description /
* @author lixin
* @date 2025-05-29
**/
@Getter
@Setter
@TableName("sys_merchants")
public class Merchants extends BaseEntity implements Serializable {
    @TableId(value = "merchants_id", type = IdType.AUTO)
    @ApiModelProperty(value = "ID")
    private Long merchantsId;
    @NotBlank
    @ApiModelProperty(value = "名称")
    private String merchantName;
    @NotBlank
    @ApiModelProperty(value = "商户编码")
    private String merchantCode;
    @NotBlank
    @ApiModelProperty(value = "营业执照号")
    private String businessLicense;
    @NotBlank
    @ApiModelProperty(value = "营业执照号路径")
    private String businessLicensePath;
    @NotBlank
    @ApiModelProperty(value = "联系手机")
    private String contactMobile;
    @ApiModelProperty(value = "排序")
    private Integer merchantsSort;
    @ApiModelProperty(value = "状态")
    private String enabled = "1";
    @ApiModelProperty(value = "审核人")
    private String authUser;
    @ApiModelProperty(value = "审核时间")
    private Timestamp authTime;
    @ApiModelProperty(value = "审核信息")
    private String authMessage;
    public void copy(Merchants source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
oying-system/src/main/java/com/oying/modules/system/domain/dto/MerchantsQueryCriteria.java
New file
@@ -0,0 +1,36 @@
package com.oying.modules.system.domain.dto;
import lombok.Data;
import java.sql.Timestamp;
import java.util.List;
import io.swagger.annotations.ApiModelProperty;
/**
* @author lixin
* @date 2025-05-29
**/
@Data
public class MerchantsQueryCriteria{
    @ApiModelProperty(value = "页码", example = "1")
    private Integer page = 1;
    @ApiModelProperty(value = "每页数据量", example = "10")
    private Integer size = 10;
    @ApiModelProperty(value = "名称")
    private String merchantName;
    @ApiModelProperty(value = "商户编码")
    private String merchantCode;
    @ApiModelProperty(value = "营业执照号")
    private String businessLicense;
    @ApiModelProperty(value = "联系手机")
    private String contactMobile;
    @ApiModelProperty(value = "状态")
    private String enabled;
    private List<Timestamp> createTime;
}
oying-system/src/main/java/com/oying/modules/system/mapper/MerchantsMapper.java
New file
@@ -0,0 +1,22 @@
package com.oying.modules.system.mapper;
import com.oying.modules.system.domain.Merchants;
import com.oying.modules.system.domain.dto.MerchantsQueryCriteria;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* @author lixin
* @date 2025-05-29
**/
@Mapper
public interface MerchantsMapper extends BaseMapper<Merchants> {
    IPage<Merchants> findAll(@Param("criteria") MerchantsQueryCriteria criteria, Page<Object> page);
    List<Merchants> findAll(@Param("criteria") MerchantsQueryCriteria criteria);
}
oying-system/src/main/java/com/oying/modules/system/rest/MerchantsController.java
New file
@@ -0,0 +1,73 @@
package com.oying.modules.system.rest;
import com.oying.annotation.Log;
import com.oying.modules.system.domain.Merchants;
import com.oying.modules.system.service.MerchantsService;
import com.oying.modules.system.domain.dto.MerchantsQueryCriteria;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.oying.utils.PageResult;
/**
* @author lixin
* @date 2025-05-29
**/
@RestController
@RequiredArgsConstructor
@Api(tags = "系统:商户信息")
@RequestMapping("/api/merchants")
public class MerchantsController {
    private final MerchantsService merchantsService;
    @ApiOperation("导出数据")
    @GetMapping(value = "/download")
    @PreAuthorize("@el.check('merchants:list')")
    public void exportMerchants(HttpServletResponse response, MerchantsQueryCriteria criteria) throws IOException {
        merchantsService.download(merchantsService.queryAll(criteria), response);
    }
    @GetMapping
    @ApiOperation("查询商户信息")
    @PreAuthorize("@el.check('merchants:list')")
    public ResponseEntity<PageResult<Merchants>> queryMerchants(MerchantsQueryCriteria criteria){
        Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
        return new ResponseEntity<>(merchantsService.queryAll(criteria,page),HttpStatus.OK);
    }
    @PostMapping
    @Log("新增商户信息")
    @ApiOperation("新增商户信息")
    @PreAuthorize("@el.check('merchants:add')")
    public ResponseEntity<Object> createMerchants(@Validated @RequestBody Merchants resources){
        merchantsService.create(resources);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }
    @PutMapping
    @Log("修改商户信息")
    @ApiOperation("修改商户信息")
    @PreAuthorize("@el.check('merchants:edit')")
    public ResponseEntity<Object> updateMerchants(@Validated @RequestBody Merchants resources){
        merchantsService.update(resources);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }
    @DeleteMapping
    @Log("删除商户信息")
    @ApiOperation("删除商户信息")
    @PreAuthorize("@el.check('merchants:del')")
    public ResponseEntity<Object> deleteMerchants(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
        merchantsService.deleteAll(ids);
        return new ResponseEntity<>(HttpStatus.OK);
    }
}
oying-system/src/main/java/com/oying/modules/system/service/MerchantsService.java
New file
@@ -0,0 +1,59 @@
package com.oying.modules.system.service;
import com.oying.modules.system.domain.Merchants;
import com.oying.modules.system.domain.dto.MerchantsQueryCriteria;
import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.oying.utils.PageResult;
/**
* @description 服务接口
* @author lixin
* @date 2025-05-29
**/
public interface MerchantsService extends IService<Merchants> {
    /**
    * 查询数据分页
    * @param criteria 条件
    * @param page 分页参数
    * @return PageResult
    */
    PageResult<Merchants> queryAll(MerchantsQueryCriteria criteria, Page<Object> page);
    /**
    * 查询所有数据不分页
    * @param criteria 条件参数
    * @return List<MerchantsDto>
    */
    List<Merchants> queryAll(MerchantsQueryCriteria criteria);
    /**
    * 创建
    * @param resources /
    */
    void create(Merchants resources);
    /**
    * 编辑
    * @param resources /
    */
    void update(Merchants resources);
    /**
    * 多选删除
    * @param ids /
    */
    void deleteAll(List<Long> ids);
    /**
    * 导出数据
    * @param all 待导出的数据
    * @param response /
    * @throws IOException /
    */
    void download(List<Merchants> all, HttpServletResponse response) throws IOException;
}
oying-system/src/main/java/com/oying/modules/system/service/impl/MerchantsServiceImpl.java
New file
@@ -0,0 +1,86 @@
package com.oying.modules.system.service.impl;
import com.oying.modules.system.domain.Merchants;
import com.oying.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.oying.modules.system.service.MerchantsService;
import com.oying.modules.system.domain.dto.MerchantsQueryCriteria;
import com.oying.modules.system.mapper.MerchantsMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.oying.utils.PageUtil;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import com.oying.utils.PageResult;
/**
* @description 服务实现
* @author lixin
* @date 2025-05-29
**/
@Service
@RequiredArgsConstructor
public class MerchantsServiceImpl extends ServiceImpl<MerchantsMapper, Merchants> implements MerchantsService {
    private final MerchantsMapper merchantsMapper;
    @Override
    public PageResult<Merchants> queryAll(MerchantsQueryCriteria criteria, Page<Object> page){
        return PageUtil.toPage(merchantsMapper.findAll(criteria, page));
    }
    @Override
    public List<Merchants> queryAll(MerchantsQueryCriteria criteria){
        return merchantsMapper.findAll(criteria);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Merchants resources) {
        merchantsMapper.insert(resources);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Merchants resources) {
        Merchants merchants = getById(resources.getMerchantsId());
        merchants.copy(resources);
        merchantsMapper.updateById(merchants);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        merchantsMapper.deleteBatchIds(ids);
    }
    @Override
    public void download(List<Merchants> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Merchants merchants : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("名称", merchants.getMerchantName());
            map.put("商户编码", merchants.getMerchantCode());
            map.put("营业执照号", merchants.getBusinessLicense());
            map.put("营业执照号路径", merchants.getBusinessLicensePath());
            map.put("联系手机", merchants.getContactMobile());
            map.put("排序", merchants.getMerchantsSort());
            map.put("状态", merchants.getEnabled());
            map.put("审核人", merchants.getAuthUser());
            map.put("审核时间", merchants.getAuthTime());
            map.put("审核信息", merchants.getAuthMessage());
            map.put("创建者", merchants.getCreateBy());
            map.put("更新者", merchants.getUpdateBy());
            map.put("创建日期", merchants.getCreateTime());
            map.put("更新时间", merchants.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}
oying-system/src/main/resources/config/application-dev.yml
@@ -111,8 +111,62 @@
    path: /opt/oying/file/
    avatar: /opt/oying/avatar/
  windows:
    path: C:\oying\file\
    avatar: C:\oying\avatar\
    path: d:\data\oying\file\
    avatar: d:\data\oying\avatar\
  # 文件大小 /M
  maxSize: 100
  avatarMaxSize: 5
  # 短信验证码key 时间
sms:
  key: oying-sms-key-
  time: 300
#微信配置
wx:
  # 测试环境
  enabled: false
  # AppID
  app-id: wx2273296a5569cbad
  # AppSecret
  app-secret: 4526d72d885be322b17d0694cd6d03f1
  # 跳转小程序类型 developer为开发版;trial为体验版;formal为正式版;默认为正式版
  mini-program-state: trial
  #  access_token的KEY
  token-key: wx_access_token
  #  access_token的失效时间间隔,微信是2小时,此处隔7200秒就重新获取
  token-time: 7200
  # 微信URL调用
  #  POST 获取稳定版接口调用凭据 获取小程序全局唯一后台接口调用凭据,token有效期为7200s,开发者需要进行妥善保存。
  get-stable-access-token: https://api.weixin.qq.com/cgi-bin/stable_token
  #  GET 小程序登录 登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程
  code2-session: https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={js_code}&grant_type=authorization_code
  #  POST 获取手机号 该接口用于将code换取用户手机号。 说明,每个code只能使用一次,code的有效期为5min。
  get-phone-number: https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={accessToken}
  #  POST 该接口用于发送订阅消息。
  send-message: https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={accessToken}
# 汇旺财
swift-pass:
  # 密钥
  key: qqqqqqqqqqqqqqqqqqqq
  # 私钥
  mch-private-key: qqqqqqqqqqqq
  # 公钥
  plat-public-key: qqqqq
  # 门店编号
  mch-id: 1111
  # 签名方式
  sign-type: MD5
  # 原生JS
  is-raw: 1
  # 是否小程序支付
  is-minipg: 1
  # AppID
  app-id: wx2273296a5569cbad
  # 请求url
  req-url: https://pay.hstypay.com/v2/pay/gateway
  # 支付通知地址
  notify-url: https://localhost/oying/api/swiftPass/alipayCallback
  # 退款通知地址
  refund-url: https://localhost/oying/api/swiftPass/returnNotify
oying-system/src/main/resources/config/application-prod.yml
@@ -127,3 +127,56 @@
  # 文件大小 /M
  maxSize: 100
  avatarMaxSize: 5
  # 短信验证码key 时间
sms:
  key: oying-sms-key-
  time: 300
#微信配置
wx:
  # 测试环境
  enabled: false
  # AppID
  app-id: wx2273296a5569cbad
  # AppSecret
  app-secret: 4526d72d885be322b17d0694cd6d03f1
  # 跳转小程序类型 developer为开发版;trial为体验版;formal为正式版;默认为正式版
  mini-program-state: trial
  #  access_token的KEY
  token-key: wx_access_token
  #  access_token的失效时间间隔,微信是2小时,此处隔7200秒就重新获取
  token-time: 7200
  # 微信URL调用
  #  POST 获取稳定版接口调用凭据 获取小程序全局唯一后台接口调用凭据,token有效期为7200s,开发者需要进行妥善保存。
  get-stable-access-token: https://api.weixin.qq.com/cgi-bin/stable_token
  #  GET 小程序登录 登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程
  code2-session: https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={js_code}&grant_type=authorization_code
  #  POST 获取手机号 该接口用于将code换取用户手机号。 说明,每个code只能使用一次,code的有效期为5min。
  get-phone-number: https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={accessToken}
  #  POST 该接口用于发送订阅消息。
  send-message: https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={accessToken}
# 汇旺财
swift-pass:
  # 密钥1
  key: qqqqqqqqqqqqqqqqqqqq
  # 私钥
  mch-private-key: qqqqqqqqqqqq
  # 公钥
  plat-public-key: qqqqq
  # 门店编号1
  mch-id: 1111
  # 签名方式
  sign-type: MD5
  # 原生JS
  is-raw: 1
  # 是否小程序支付
  is-minipg: 1
  # AppID
  app-id: wx2273296a5569cbad
  # 请求url
  req-url: https://pay.hstypay.com/v2/pay/gateway
  # 支付通知地址
  notify-url: https://localhost/oying/api/swiftPass/alipayCallback
  # 退款通知地址
  refund-url: https://localhost/oying/api/swiftPass/returnNotify
oying-system/src/main/resources/config/application.yml
@@ -33,10 +33,10 @@
  redis:
    #数据库索引
    database: ${REDIS_DB:1}
    host: ${REDIS_HOST:127.0.0.1}
    port: ${REDIS_PORT:6379}
    password: ${REDIS_PWD:}
    database: 0
    host: 127.0.0.1
    port: 6379
    password:
    #连接超时时间
    timeout: 5000
    # 连接池配置
oying-system/src/main/resources/mapper/message/MessageOrderBuyerMapper.xml
New file
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oying.modules.message.mapper.MessageOrderBuyerMapper">
    <resultMap id="BaseResultMap" type="com.oying.modules.message.domain.MessageOrderBuyer">
        <id column="id" property="id"/>
        <result column="order_id" property="orderId"/>
        <result column="message_type" property="messageType"/>
        <result column="message_content" property="messageContent"/>
        <result column="link" property="link"/>
        <result column="create_time" property="createTime"/>
    </resultMap>
    <sql id="Base_Column_List">
        id, order_id, message_type, message_content, link, create_time
    </sql>
    <select id="findAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from message_order_buyer
        <where>
        </where>
        order by id desc
    </select>
</mapper>
oying-system/src/main/resources/mapper/message/MessageOrderLeaveMapper.xml
New file
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oying.modules.message.mapper.MessageOrderLeaveMapper">
    <resultMap id="BaseResultMap" type="com.oying.modules.message.domain.MessageOrderLeave">
        <id column="id" property="id"/>
        <result column="order_id" property="orderId"/>
        <result column="customer_review" property="customerReview"/>
        <result column="seller_reply" property="sellerReply"/>
        <result column="link" property="link"/>
        <result column="create_time" property="createTime"/>
    </resultMap>
    <sql id="Base_Column_List">
        id, order_id, customer_review, seller_reply, link, create_time
    </sql>
    <select id="findAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from message_order_leave
        <where>
        </where>
        order by id desc
    </select>
</mapper>
oying-system/src/main/resources/mapper/message/MessageOrderSellerMapper.xml
New file
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oying.modules.message.mapper.MessageOrderSellerMapper">
    <resultMap id="BaseResultMap" type="com.oying.modules.message.domain.MessageOrderSeller">
        <id column="id" property="id"/>
        <result column="order_id" property="orderId"/>
        <result column="message_type" property="messageType"/>
        <result column="message_content" property="messageContent"/>
        <result column="link" property="link"/>
        <result column="create_time" property="createTime"/>
    </resultMap>
    <sql id="Base_Column_List">
        id, order_id, message_type, message_content, link, create_time
    </sql>
    <select id="findAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from message_order_seller
        <where>
        </where>
        order by id desc
    </select>
</mapper>
oying-system/src/main/resources/mapper/message/MessageSystemMapper.xml
New file
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oying.modules.message.mapper.MessageSystemMapper">
    <resultMap id="BaseResultMap" type="com.oying.modules.message.domain.MessageSystem">
        <id column="id" property="id"/>
        <result column="start_time" property="startTime"/>
        <result column="end_time" property="endTime"/>
    </resultMap>
    <sql id="Base_Column_List">
        id, start_time, end_time
    </sql>
    <select id="findAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from message_system
        <where>
        </where>
        order by id desc
    </select>
</mapper>
oying-system/src/main/resources/mapper/pc/category/PlatformCategoryMapper.xml
New file
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oying.modules.pc.category.mapper.PlatformCategoryMapper">
    <resultMap id="BaseResultMap" type="com.oying.modules.pc.category.domain.PlatformCategory">
        <id column="category_id" property="categoryId"/>
        <result column="parent_id" property="parentId"/>
        <result column="name" property="name"/>
        <result column="level" property="level"/>
        <result column="sort_weight" property="sortWeight"/>
        <result column="icon_id" property="iconId"/>
        <result column="status" property="status"/>
        <result column="active" property="active"/>
        <result column="create_by" property="createBy"/>
        <result column="create_time" property="createTime"/>
        <result column="update_by" property="updateBy"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>
    <sql id="Base_Column_List">
        category_id, parent_id, name, level, sort_weight, icon_id, status, active, create_by, create_time, update_by, update_time
    </sql>
    <select id="findAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from pc_platform_category
        <where>
            <if test="criteria.active != null">
                and active = #{criteria.active}
            </if>
        </where>
        order by category_id desc
    </select>
</mapper>
oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml
New file
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oying.modules.pc.product.mapper.ProductMapper">
    <resultMap id="BaseResultMap" type="com.oying.modules.pc.product.domain.Product">
        <id column="product_id" property="productId"/>
        <result column="store_id" property="storeId"/>
        <result column="code" property="code"/>
        <result column="barcode" property="barcode"/>
        <result column="name" property="name"/>
        <result column="title" property="title"/>
        <result column="category_id" property="categoryId"/>
        <result column="second_category_id" property="secondCategoryId"/>
        <result column="status" property="status"/>
        <result column="main_image" property="mainImage"/>
        <result column="detail_image" property="detailImage"/>
        <result column="description" property="description"/>
        <result column="price" property="price"/>
        <result column="stock_quantity" property="stockQuantity"/>
        <result column="min_purchase_quantity" property="minPurchaseQuantity"/>
        <result column="warn_stock" property="warnStock"/>
        <result column="weight" property="weight"/>
        <result column="width" property="width"/>
        <result column="length" property="length"/>
        <result column="height" property="height"/>
        <result column="deleted_flag" property="deletedFlag"/>
        <result column="version" property="version"/>
    </resultMap>
    <sql id="Base_Column_List">
        product_id, store_id, code, barcode, name, title, category_id, second_category_id, status, main_image, detail_image, description, price, stock_quantity, min_purchase_quantity, warn_stock, weight, width, length, height, deleted_flag, create_by, create_time, update_by, update_time, version
    </sql>
    <select id="findAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from pc_product
        <where>
            <if test="criteria.storeId != null">
                and store_id = #{criteria.storeId}
            </if>
            <if test="criteria.categoryId != null">
                and category_id = #{criteria.categoryId}
            </if>
            <if test="criteria.secondCategoryId != null">
                and second_category_id = #{criteria.secondCategoryId}
            </if>
            <if test="criteria.blurry != null and criteria.blurry != ''">
                and (name like concat('%',#{criteria.blurry},'%') or title like concat('%',#{criteria.blurry},'%'))
            </if>
            <if test="criteria.status != null">
                and status = #{criteria.status}
            </if>
            <if test="criteria.active != null">
                and active = #{criteria.active}
            </if>
        </where>
        order by product_id desc
    </select>
</mapper>
oying-system/src/main/resources/mapper/pc/search/SearchMapper.xml
New file
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.oying.modules.pc.store.mapper.StoreMapper">
<!--
    <resultMap id="storeWithProductResultMap" type="com.oying.modules.pc.store.domain.Store">
        <result property="storeId" column="store_id"/>
        <result property="merchantId" column="merchant_id"/>
        <result property="platformCategoryId" column="platform_category_id"/>
        <result property="storeName" column="store_name"/>
        <result property="description" column="description"/>
        <result property="deliveryFee" column="delivery_fee"/>
        <result property="deliveryMinimum" column="delivery_minimum"/>
        <result property="contactPhone" column="contact_phone"/>
        <collection property="products" ofType="Product">
            <id column="product_id" property="productId"/>
            <result column="store_id" property="storeId"/>
            <result column="title" property="title"/>
            <result column="status" property="status"/>
            <result column="description" property="description"/>
            <result column="price" property="price"/>
            <result column="stock_quantity" property="stockQuantity"/>
            <result column="min_purchase_quantity" property="minPurchaseQuantity"/>
            <result column="warn_stock" property="warnStock"/>
            <result column="weight" property="weight"/>
            <result column="version" property="version"/>
        </collection>
    </resultMap>
    <select id="queryNearStoreWithProduct" resultMap="storeWithProductResultMap">
        SELECT
        s.store_id AS storeId,
        s.store_name AS storeName,
        s.logo_image_id AS logoImageId,
        ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude, s.latitude)) AS distance,
        MATCH(s.store_name) AGAINST(#{criteria.blurry}) AS storeNameMatchScore
        FROM pc_store s inner join pc_product p ON s.store_id = p.product_id
        WHERE
        ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude, s.latitude)) &lt;= #{criteria.radius}
        AND ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude, s.latitude)) &lt;= s.radius
        AND s.status = 1000
        AND p.status in (1000, 1001, 1002)
        AND p.deleted_flag = 0
        AND CURRENT_TIME() BETWEEN s.open_time AND s.close_time
        <choose>
            <when test="criteria.blurry != null and criteria.blurry != ''">
                AND (MATCH(s.store_name) AGAINST(#{criteria.blurry} IN NATURAL LANGUAGE MODE) OR MATCH(p.title) AGAINST(#{criteria.blurry} IN NATURAL LANGUAGE MODE))
            </when>
            <otherwise>
            </otherwise>
        </choose>
    </select>-->
</mapper>
oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml
New file
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oying.modules.pc.store.mapper.StoreCategoryMapper">
    <resultMap id="BaseResultMap" type="com.oying.modules.pc.store.domain.StoreCategory">
        <id column="category_id" property="categoryId"/>
        <result column="parent_id" property="parentId"/>
        <result column="name" property="name"/>
        <result column="level" property="level"/>
        <result column="sort_weight" property="sortWeight"/>
        <result column="icon_id" property="iconId"/>
        <result column="status" property="status"/>
        <result column="active" property="active"/>
        <result column="create_by" property="createBy"/>
        <result column="create_time" property="createTime"/>
        <result column="update_by" property="updateBy"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>
    <sql id="Base_Column_List">
        category_id, parent_id, name, level, sort_weight, icon_id, status, active, create_by, create_time, update_by, update_time
    </sql>
    <select id="findAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from pc_store_category
        <where>
            <if test="criteria.storeId != null ">
                and store_id = #{criteria.storeId}
            </if>
            <if test="criteria.level != null ">
                and level = #{criteria.level}
            </if>
            <if test="criteria.active != null ">
                and active = #{criteria.active}
            </if>
        </where>
        order by category_id desc
    </select>
</mapper>
oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml
New file
@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.oying.modules.pc.store.mapper.StoreMapper">
    <resultMap id="StoreResult" type="com.oying.modules.pc.store.domain.Store">
        <result property="storeId" column="store_id"/>
        <result property="merchantId" column="merchant_id"/>
        <result property="platformCategoryId" column="platform_category_id"/>
        <result property="storeType" column="store_type"/>
        <result property="storeCode" column="store_code"/>
        <result property="storeName" column="store_name"/>
        <result property="businessScope" column="business_scope"/>
        <result property="status" column="status"/>
        <result property="logoImageId" column="logo_image_id"/>
        <result property="coverImageId" column="cover_image_id"/>
        <result property="description" column="description"/>
        <result property="tags" column="tags"/>
        <result property="deliveryFee" column="delivery_fee"/>
        <result property="deliveryMinimum" column="delivery_minimum"/>
        <result property="contactPhone" column="contact_phone"/>
        <result property="openTime" column="open_time"/>
        <result property="closeTime" column="close_time"/>
        <result property="address" column="address"/>
        <result property="longitude" column="longitude"/>
        <result property="latitude" column="latitude"/>
        <result property="geoHash" column="geo_hash"/>
        <result property="coordinateSystem" column="coordinate_system"/>
        <result property="radius" column="radius"/>
        <result property="createBy" column="create_by"/>
        <result property="createTime" column="create_time"/>
        <result property="updateBy" column="update_by"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>
    <sql id="store_column_list">
        store_id, merchant_id, platform_category_id, store_type, store_code, store_name, business_scope, status, logo_image_id,
        cover_image_id, description, tags, delivery_fee, delivery_minimum, contact_phone, open_time, close_time,
        address, longitude, latitude, geo_hash, geo_point, coordinate_system, radius, create_by, create_time, update_by, update_time
    </sql>
    <sql id="selectStoreVo">
        select
        store_id, merchant_id, platform_category_id, store_type, store_code, store_name, business_scope, status, logo_image_id,
        cover_image_id, description, tags, delivery_fee, delivery_minimum, contact_phone, open_time, close_time,
        address, longitude, latitude, geo_hash, geo_point, coordinate_system, radius, create_by, create_time, update_by, update_time from pc_store
    </sql>
    <select id="selectStoreList" resultMap="StoreResult">
        <include refid="selectStoreVo"/>
        <where>
            <if test="criteria.merchantId != null ">and merchant_id = #{criteria.merchantId}</if>
            <if test="criteria.storeName != null and criteria.storeName != ''">
                and store_name like concat('%', #{criteria.storeName}, '%')
            </if>
            <if test="criteria.status != null ">and status = #{criteria.status}</if>
        </where>
    </select>
    <select id="selectStoreByMerchantId" resultMap="StoreResult">
        <include refid="selectStoreVo"/>
        where merchant_id = #{merchantId}
    </select>
    <select id="queryNearStores" resultType="com.oying.modules.pc.search.domain.dto.StoreSearchDto">
        SELECT
        <trim prefix="" suffix="" suffixOverrides=",">
            s.store_id AS storeId,
            s.store_name AS storeName,
            s.logo_image AS logoImage,
            <!--<if test="criteria.longitude != null and criteria.latitude != null and criteria.radius != null">
                ST_Distance_Sphere(
                    POINT(#{criteria.longitude}, #{criteria.latitude}),
                    POINT(s.longitude, s.latitude)
                ) AS distance,</if>
            <if test="criteria.blurry != null and criteria.blurry != ''">
                MATCH(s.store_name) AGAINST(#{criteria.blurry}) AS matchScore
            </if>-->
        </trim>
        FROM pc_store s
        <where>
            <!-- 位置条件 -->
            <if test="criteria.longitude != null and criteria.latitude != null and criteria.radius != null">
                AND ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude,
                s.latitude)) &lt;= #{criteria.radius}
                AND ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude,
                s.latitude)) &lt;= s.radius
            </if>
            <!-- 店铺名称模糊查询 AND s.name LIKE CONCAT('%', #{criteria.blurry}, '%') -->
            <if test="criteria.blurry != null and criteria.blurry != ''">
                AND MATCH(s.store_name) AGAINST(#{criteria.blurry} IN NATURAL LANGUAGE MODE)
            </if>
            <!-- 营业状态 -->
            <if test="criteria.status != null">
                AND s.status = #{criteria.status}
            </if>
            <!-- 类目ID -->
            <if test="criteria.platformCategoryId != null">
                AND s.platform_category_id = #{criteria.platformCategoryId}
            </if>
        </where>
    </select>
</mapper>
oying-system/src/main/resources/mapper/pc/store/StoreQualificationMapper.xml
New file
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oying.modules.pc.store.mapper.StoreQualificationMapper">
    <resultMap id="BaseResultMap" type="com.oying.modules.pc.store.domain.StoreQualification">
        <id column="qualification_id" property="qualificationId"/>
        <result column="store_id" property="storeId"/>
        <result column="qualification_type" property="qualificationType"/>
        <result column="qualification_number" property="qualificationNumber"/>
        <result column="qualification_name" property="qualificationName"/>
        <result column="qualification_image_id" property="qualificationImageId"/>
        <result column="start_date" property="startDate"/>
        <result column="end_date" property="endDate"/>
        <result column="status" property="status"/>
        <result column="create_by" property="createBy"/>
        <result column="create_time" property="createTime"/>
        <result column="update_by" property="updateBy"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>
    <sql id="Base_Column_List">
        qualification_id, store_id, qualification_type, qualification_number, qualification_name, qualification_image_id, start_date, end_date, status,
        create_by, create_time, update_by, update_time
    </sql>
    <select id="findAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from pc_store_qualification
        <where>
            <if test="criteria.storeId != null">
                and store_id = #{criteria.storeId}
            </if>
        </where>
        order by qualification_id desc
    </select>
</mapper>
oying-system/src/main/resources/mapper/system/MerchantsMapper.xml
New file
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.oying.modules.system.mapper.MerchantsMapper">
    <resultMap id="BaseResultMap" type="com.oying.modules.system.domain.Merchants">
        <id column="merchants_id" property="merchantsId"/>
        <result column="merchant_name" property="merchantName"/>
        <result column="merchant_code" property="merchantCode"/>
        <result column="business_license" property="businessLicense"/>
        <result column="business_license_path" property="businessLicensePath"/>
        <result column="contact_mobile" property="contactMobile"/>
        <result column="merchants_sort" property="merchantsSort"/>
        <result column="enabled" property="enabled"/>
        <result column="create_by" property="createBy"/>
        <result column="update_by" property="updateBy"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
        <result column="auth_user" property="authUser"/>
        <result column="auth_time" property="authTime"/>
        <result column="auth_message" property="authMessage"/>
    </resultMap>
    <sql id="Base_Column_List">
        merchants_id, merchant_name, merchant_code, business_license, business_license_path, contact_mobile, merchants_sort, enabled, create_by, update_by, create_time, update_time, auth_user, auth_time, auth_message
    </sql>
    <select id="findAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from sys_merchants
        <where>
            <if test="criteria.blurry != null and criteria.blurry != ''">
                and (
                merchant_name like concat('%', #{criteria.blurry}, '%')
                or merchant_code like concat('%', #{criteria.blurry}, '%')
                or business_license like concat('%', #{criteria.blurry}, '%')
                or contact_mobile like concat('%', #{criteria.blurry}, '%')
                )
            </if>
            <if test="criteria.enabled != null">
                and enabled = #{criteria.enabled}
            </if>
            <if test="criteria.createTime != null and criteria.createTime.size() > 0">
                AND create_time BETWEEN #{criteria.createTime[0]} AND #{criteria.createTime[1]}
            </if>
        </where>
        order by merchants_sort desc
    </select>
</mapper>
pom.xml
@@ -210,6 +210,20 @@
            <version>${fastjson2.version}</version>
        </dependency>
        <!-- 请求跳过ssl证书验证 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
        </dependency>
        <!-- Java图形验证码 -->
        <dependency>
            <groupId>com.github.whvcse</groupId>