From 289aa4cbe765dcfac5c540d10540c50d849c7702 Mon Sep 17 00:00:00 2001 From: Seany <17074267@qq.com> Date: Tue, 2 Dec 2025 13:10:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Atomx.Admin.Client.csproj | 28 + .../Components/AuthorizePermissionView.razor | 60 + .../Components/CultureSelector.razor | 29 + .../Components/LocalizedText.razor | 26 + .../Layout/EmptyLayout.razor | 9 + .../Layout/MainLayout.razor | 122 + .../Layout/MainLayout.razor.css | 98 + .../Atomx.Admin.Client/Layout/NavMenu.razor | 30 + .../Layout/NavMenu.razor.css | 105 + .../Atomx.Admin.Client/Models/AddressModel.cs | 85 + .../Atomx.Admin.Client/Models/AdminModel.cs | 50 + .../Atomx.Admin.Client/Models/AdminSearch.cs | 35 + .../Models/AppVersionModel.cs | 78 + .../Models/AppVersionSearch.cs | 20 + .../Atomx.Admin.Client/Models/BaseSearch.cs | 15 + .../Atomx.Admin.Client/Models/CategoryItem.cs | 11 + .../Models/CategoryModel.cs | 83 + .../Models/CategorySearch.cs | 10 + .../Models/CorporationModel.cs | 20 + .../Models/CorporationSearch.cs | 16 + .../Models/CorporationStaffModel.cs | 55 + .../Models/CorporationStaffSearch.cs | 40 + .../Models/CorporationUserModel.cs | 27 + .../Models/CorporationUserSearch.cs | 7 + .../Models/CurrencyModel.cs | 56 + .../Atomx.Admin.Client/Models/CurrentUser.cs | 9 + .../Models/LanguageModel.cs | 55 + .../Models/LanguageSearch.cs | 12 + .../Atomx.Admin.Client/Models/LinkItem.cs | 35 + .../Models/LocaleResourceModel.cs | 35 + .../Atomx.Admin.Client/Models/LoginModel.cs | 25 + .../Models/ManufacturerModel.cs | 58 + .../Models/ManufacturerProductItemSearch.cs | 13 + .../Models/ManufacturerSearch.cs | 16 + .../Models/MaterialSearch.cs | 20 + .../Atomx.Admin.Client/Models/MenuItem.cs | 9 + .../Atomx.Admin.Client/Models/MenuModel.cs | 70 + .../Atomx.Admin.Client/Models/MenuSearch.cs | 10 + .../Atomx.Admin.Client/Models/MenuTreeItem.cs | 19 + .../Models/MessageTemplateModel.cs | 40 + .../Models/MessageTemplateSearch.cs | 9 + .../Atomx.Admin.Client/Models/OrderSearch.cs | 12 + .../Models/PriceTrendSearch.cs | 12 + .../Models/ProductAddStockModel.cs | 50 + .../ProductAttributeCombinationModel.cs | 89 + .../Models/ProductAttributeItemModel.cs | 10 + .../Models/ProductAttributeModel.cs | 50 + .../Models/ProductAttributeOptionModel.cs | 40 + .../Models/ProductAttributeOptionSearch.cs | 12 + .../Models/ProductAttributeSearch.cs | 9 + .../Models/ProductAttributeValueModel.cs | 63 + .../Models/ProductDetailModel.cs | 6 + .../Atomx.Admin.Client/Models/ProductModel.cs | 241 + .../Models/ProductSKUPricesModel.cs | 23 + .../Models/ProductSaleAttributeModel.cs | 68 + .../ProductSaleSpecificationAttributeModel.cs | 6 + .../Models/ProductSearch.cs | 25 + .../Models/ProductSkuModel.cs | 77 + .../Models/ProductStockAttributeModel.cs | 75 + .../Models/ProductStockModel.cs | 32 + .../Models/ProductStockUnitModel.cs | 22 + .../Models/ProductStockUnitSearch.cs | 23 + .../Models/ProductTransferSearch.cs | 12 + .../Models/RawMaterialBatchSearch.cs | 27 + .../Models/RawMaterialRecordSearch.cs | 20 + .../Models/RawMaterialSearch.cs | 22 + .../Models/RawMaterialTransferSearch.cs | 25 + .../Atomx.Admin.Client/Models/RoleModel.cs | 47 + .../Models/RolePermissionGroup.cs | 11 + .../Models/RolePermissionItem.cs | 9 + .../Atomx.Admin.Client/Models/RoleSearch.cs | 7 + .../Atomx.Admin.Client/Models/SiteAppModel.cs | 26 + .../Models/SiteAppSearch.cs | 9 + .../Models/SpecificationAttributeItemModel.cs | 9 + .../Models/SpecificationAttributeModel.cs | 47 + .../SpecificationAttributeOptionModel.cs | 47 + .../SpecificationAttributeOptionSearch.cs | 15 + .../Models/SpecificationAttributeSearch.cs | 12 + .../Models/StoreProductItemSearch.cs | 12 + .../Atomx.Admin.Client/Models/StoreSearch.cs | 13 + .../Models/UploadFileModel.cs | 42 + .../Models/UploadFileSearch.cs | 20 + .../Atomx.Admin.Client/Models/UserSearch.cs | 41 + .../Models/WarehouseItemModel.cs | 12 + .../Models/WarehouseModel.cs | 28 + .../Models/WarehouseSearch.cs | 20 + .../Pages/Contents/ContentEdit.razor | 5 + .../Pages/Contents/ContentList.razor | 7 + .../Pages/Contents/PageEdit.razor | 5 + .../Pages/Contents/PageList.razor | 8 + .../Atomx.Admin.Client/Pages/Counter.razor | 18 + .../Atomx.Admin.Client/Pages/Home.razor | 24 + .../Atomx.Admin.Client/Pages/Login.razor | 140 + .../Atomx.Admin.Client/Pages/Logout.razor | 11 + .../Pages/Orders/OrderList.razor | 5 + .../Pages/Orders/OrderView.razor | 7 + .../Pages/Products/CategoryEdit.razor | 137 + .../Pages/Products/CategoryList.razor | 336 + .../Pages/Products/GoodsList.razor | 5 + .../Products/PredefinedAttributeList.razor | 290 + .../PredefinedSpecificationList.razor | 325 + .../Pages/Products/ProductAttributeList.razor | 339 + .../Pages/Products/ProductEdit.razor | 1201 ++ .../Pages/Products/ProductList.razor | 425 + .../Pages/Products/ProductStockList.razor | 258 + .../Pages/Products/SpecificationList.razor | 319 + .../Atomx.Admin.Client/Pages/Register.razor | 10 + .../Pages/Settings/MessageTemplateList.razor | 317 + .../Pages/Settings/Settings.razor | 7 + .../Pages/SiteApps/AppVersionList.razor | 10 + .../Pages/SiteApps/SiteAppList.razor | 7 + .../Pages/Storages/UploadList.razor | 291 + .../Pages/Systems/AdminList.razor | 347 + .../Pages/Systems/CurrencyList.razor | 7 + .../Pages/Systems/LanguageList.razor | 238 + .../Pages/Systems/LocaleResourceList.razor | 6 + .../Pages/Systems/MenuList.razor | 350 + .../Pages/Systems/PermissionEdit.razor | 186 + .../Pages/Systems/RoleList.razor | 259 + .../Pages/Users/UserList.razor | 5 + .../Atomx.Admin.Client/Pages/Weather.razor | 63 + Atomx.Admin/Atomx.Admin.Client/Program.cs | 24 + .../Atomx.Admin.Client/RedirectToLogin.razor | 8 + Atomx.Admin/Atomx.Admin.Client/Routes.razor | 13 + .../Services/ClientPermissionService.cs | 124 + .../Services/HttpService.cs | 67 + .../Services/LocalizationClientService.cs | 325 + .../Utils/AuthHeaderHandler.cs | 71 + .../Utils/HttpClientExtension.cs | 20 + .../Utils/IconsExtension.cs | 198 + .../PersistentAuthenticationStateProvider.cs | 141 + .../Atomx.Admin.Client/Utils/TokenProvider.cs | 40 + .../Validators/AddressModelValidator.cs | 14 + .../Validators/AdminModelValidator.cs | 17 + .../Validators/AppVersionModelValidator.cs | 38 + .../Validators/CategoryModelValidator.cs | 32 + .../Validators/CorporationModelValidator.cs | 21 + .../CorporationStaffModelValidator.cs | 19 + .../Validators/CurrencyModelValidator.cs | 13 + .../Validators/GeneralConfigValidator.cs | 13 + .../Validators/LanguageModelValidator.cs | 13 + .../LocaleResourceModelValidator.cs | 13 + .../Validators/LoginModelValidator.cs | 33 + .../Validators/ManufacturerModelValidator.cs | 21 + .../Validators/MaterialBatchValidator.cs | 13 + .../Validators/MaterialRecordValidator.cs | 13 + .../Validators/MaterialValidator.cs | 13 + .../Validators/MenuModelValidator.cs | 23 + .../MessageTemplateModelValidator.cs | 15 + .../ProductAddStockModelValidator.cs | 17 + .../ProductAttributeModelValidator.cs | 23 + .../ProductAttributeOptionModelValidator.cs | 22 + .../Validators/ProductModelValidator.cs | 21 + .../Validators/RoleModelValidator.cs | 13 + .../Validators/RoleValidator.cs | 13 + .../Validators/SiteAppModelValidator.cs | 13 + .../SpecificationAttributeModelValidator.cs | 22 + ...cificationAttributeOptionModelValidator.cs | 22 + .../Validators/UploadFileModelValidator.cs | 13 + .../Validators/UserValidator.cs | 13 + .../Validators/WarehouseModelValidator.cs | 13 + Atomx.Admin/Atomx.Admin.Client/_Imports.razor | 38 + .../wwwroot/appsettings.Development.json | 8 + .../wwwroot/appsettings.json | 12 + Atomx.Admin/Atomx.Admin/Atomx.Admin.csproj | 34 + Atomx.Admin/Atomx.Admin/Components/App.razor | 22 + .../Atomx.Admin/Components/Pages/Error.razor | 36 + .../Atomx.Admin/Components/_Imports.razor | 11 + .../Controllers/AddressController.cs | 163 + .../Controllers/AdminController.cs | 290 + .../Controllers/AppVersionController.cs | 232 + .../Atomx.Admin/Controllers/AreaController.cs | 47 + .../Controllers/CategoryController.cs | 307 + .../Controllers/CurrencyController.cs | 305 + .../Controllers/LanguageController.cs | 166 + .../Controllers/LocaleResourceController.cs | 191 + .../Atomx.Admin/Controllers/MenuController.cs | 303 + .../Controllers/MessageTemplateController.cs | 208 + .../Controllers/ProductAttributeController.cs | 245 + .../ProductAttributeOptionController.cs | 216 + .../Controllers/ProductController.cs | 1237 ++ .../Atomx.Admin/Controllers/RoleController.cs | 269 + .../Atomx.Admin/Controllers/SignController.cs | 139 + .../Controllers/SiteAppController.cs | 208 + .../SpecificationAttributeController.cs | 244 + .../SpecificationAttributeOptionController.cs | 225 + .../Controllers/UploadFileController.cs | 204 + .../Extensions/AuthorizationExtension.cs | 90 + .../Extensions/DataServiceExtension.cs | 72 + .../Extensions/DbMigrateExtension.cs | 574 + .../Extensions/FluentValidationExtension.cs | 61 + .../Middlewares/MonitoringMiddleware.cs | 123 + .../Atomx.Admin/Models/MonitoringOptions.cs | 12 + Atomx.Admin/Atomx.Admin/Models/PathFilter.cs | 8 + Atomx.Admin/Atomx.Admin/Program.cs | 130 + .../Properties/launchSettings.json | 15 + .../Atomx.Admin/Services/IdentityService.cs | 106 + .../Services/LocalizationFileService.cs | 147 + .../Services/LocalizationService.cs | 70 + .../Atomx.Admin/Services/PermissionService.cs | 95 + .../Utils/PermissionAuthorizationHandler.cs | 37 + ...RevalidatingAuthenticationStateProvider.cs | 108 + .../Atomx.Admin/Utils/ServerTokenProvider.cs | 27 + .../Atomx.Admin/appsettings.Development.json | 8 + Atomx.Admin/Atomx.Admin/appsettings.json | 77 + Atomx.Admin/Atomx.Admin/modify-config.csx | 53 + Atomx.Admin/Atomx.Admin/wwwroot/app.css | 77 + Atomx.Admin/Atomx.Admin/wwwroot/favicon.png | Bin 0 -> 1148 bytes .../lib/bootstrap/dist/css/bootstrap-grid.css | 4085 ++++++ .../bootstrap/dist/css/bootstrap-grid.css.map | 1 + .../bootstrap/dist/css/bootstrap-grid.min.css | 6 + .../dist/css/bootstrap-grid.min.css.map | 1 + .../bootstrap/dist/css/bootstrap-grid.rtl.css | 4084 ++++++ .../dist/css/bootstrap-grid.rtl.css.map | 1 + .../dist/css/bootstrap-grid.rtl.min.css | 6 + .../dist/css/bootstrap-grid.rtl.min.css.map | 1 + .../bootstrap/dist/css/bootstrap-reboot.css | 597 + .../dist/css/bootstrap-reboot.css.map | 1 + .../dist/css/bootstrap-reboot.min.css | 6 + .../dist/css/bootstrap-reboot.min.css.map | 1 + .../dist/css/bootstrap-reboot.rtl.css | 594 + .../dist/css/bootstrap-reboot.rtl.css.map | 1 + .../dist/css/bootstrap-reboot.rtl.min.css | 6 + .../dist/css/bootstrap-reboot.rtl.min.css.map | 1 + .../dist/css/bootstrap-utilities.css | 5402 +++++++ .../dist/css/bootstrap-utilities.css.map | 1 + .../dist/css/bootstrap-utilities.min.css | 6 + .../dist/css/bootstrap-utilities.min.css.map | 1 + .../dist/css/bootstrap-utilities.rtl.css | 5393 +++++++ .../dist/css/bootstrap-utilities.rtl.css.map | 1 + .../dist/css/bootstrap-utilities.rtl.min.css | 6 + .../css/bootstrap-utilities.rtl.min.css.map | 1 + .../lib/bootstrap/dist/css/bootstrap.css | 12057 ++++++++++++++++ .../lib/bootstrap/dist/css/bootstrap.css.map | 1 + .../lib/bootstrap/dist/css/bootstrap.min.css | 6 + .../bootstrap/dist/css/bootstrap.min.css.map | 1 + .../lib/bootstrap/dist/css/bootstrap.rtl.css | 12030 +++++++++++++++ .../bootstrap/dist/css/bootstrap.rtl.css.map | 1 + .../bootstrap/dist/css/bootstrap.rtl.min.css | 6 + .../dist/css/bootstrap.rtl.min.css.map | 1 + .../lib/bootstrap/dist/js/bootstrap.bundle.js | 6314 ++++++++ .../bootstrap/dist/js/bootstrap.bundle.js.map | 1 + .../bootstrap/dist/js/bootstrap.bundle.min.js | 7 + .../dist/js/bootstrap.bundle.min.js.map | 1 + .../lib/bootstrap/dist/js/bootstrap.esm.js | 4447 ++++++ .../bootstrap/dist/js/bootstrap.esm.js.map | 1 + .../bootstrap/dist/js/bootstrap.esm.min.js | 7 + .../dist/js/bootstrap.esm.min.js.map | 1 + .../lib/bootstrap/dist/js/bootstrap.js | 4494 ++++++ .../lib/bootstrap/dist/js/bootstrap.js.map | 1 + .../lib/bootstrap/dist/js/bootstrap.min.js | 7 + .../bootstrap/dist/js/bootstrap.min.js.map | 1 + Atomx.Common/Atomx.Common.csproj | 17 + Atomx.Common/Configuration/ConfigKeys.cs | 60 + Atomx.Common/Configuration/CurrencyNumber.cs | 50 + Atomx.Common/Configuration/GeneralConfig.cs | 60 + Atomx.Common/Configuration/StorageKeys.cs | 9 + Atomx.Common/Configuration/UploadConfig.cs | 40 + Atomx.Common/Constant/CacheKeys.cs | 220 + Atomx.Common/Constant/Permissions.cs | 67 + Atomx.Common/Entities/Address.cs | 149 + Atomx.Common/Entities/Admin.cs | 94 + Atomx.Common/Entities/AppVersion.cs | 99 + Atomx.Common/Entities/Area.cs | 69 + Atomx.Common/Entities/Category.cs | 119 + Atomx.Common/Entities/Comment.cs | 84 + Atomx.Common/Entities/Corporation.cs | 64 + .../CorporationManufacturerRelation.cs | 35 + Atomx.Common/Entities/CorporationStaff.cs | 96 + .../Entities/CorporationUserRelation.cs | 43 + Atomx.Common/Entities/Currency.cs | 94 + .../Entities/CurrencyChannelRelation.cs | 73 + Atomx.Common/Entities/Language.cs | 71 + Atomx.Common/Entities/LocaleResource.cs | 42 + Atomx.Common/Entities/LocalizedProperty.cs | 46 + Atomx.Common/Entities/Manufacturer.cs | 88 + .../Entities/ManufacturerProductRelation.cs | 43 + Atomx.Common/Entities/Material.cs | 45 + Atomx.Common/Entities/MaterialBatch.cs | 66 + Atomx.Common/Entities/MaterialRecord.cs | 81 + Atomx.Common/Entities/Menu.cs | 98 + Atomx.Common/Entities/MessageTemplate.cs | 65 + Atomx.Common/Entities/Order.cs | 363 + Atomx.Common/Entities/OrderItem.cs | 186 + Atomx.Common/Entities/OrderLog.cs | 54 + Atomx.Common/Entities/PaymentChannel.cs | 78 + Atomx.Common/Entities/Permission.cs | 34 + Atomx.Common/Entities/Picture.cs | 60 + Atomx.Common/Entities/Post.cs | 12 + Atomx.Common/Entities/PriceTrend.cs | 72 + Atomx.Common/Entities/Product.cs | 201 + Atomx.Common/Entities/ProductAttribute.cs | 84 + .../Entities/ProductAttributeCombination.cs | 127 + .../Entities/ProductAttributeOption.cs | 64 + .../Entities/ProductAttributeRelation.cs | 39 + .../Entities/ProductAttributeValue.cs | 67 + Atomx.Common/Entities/ProductChangeLog.cs | 66 + Atomx.Common/Entities/ProductInventory.cs | 56 + Atomx.Common/Entities/ProductInventoryLog.cs | 97 + Atomx.Common/Entities/ProductListing.cs | 224 + Atomx.Common/Entities/ProductPicture.cs | 42 + Atomx.Common/Entities/Role.cs | 68 + Atomx.Common/Entities/Setting.cs | 47 + Atomx.Common/Entities/SiteApp.cs | 47 + .../Entities/SpecificationAttribute.cs | 69 + .../Entities/SpecificationAttributeOption.cs | 59 + Atomx.Common/Entities/Store.cs | 59 + Atomx.Common/Entities/StoreProductItem.cs | 47 + Atomx.Common/Entities/UploadFile.cs | 84 + Atomx.Common/Entities/User.cs | 58 + Atomx.Common/Entities/UserAsset.cs | 51 + Atomx.Common/Entities/UserMeta.cs | 45 + Atomx.Common/Entities/UserStoreRelation.cs | 43 + Atomx.Common/Entities/Warehouse.cs | 47 + Atomx.Common/Entities/WarehouseStockRecord.cs | 41 + Atomx.Common/Enums/CategoryType.cs | 21 + Atomx.Common/Enums/ConfigType.cs | 15 + Atomx.Common/Enums/DataStatus.cs | 18 + Atomx.Common/Enums/LocalizedType.cs | 7 + Atomx.Common/Enums/MaterialType.cs | 10 + Atomx.Common/Enums/MenuType.cs | 18 + Atomx.Common/Enums/MessageTemplateType.cs | 28 + .../Enums/ProductInventoryChangeType.cs | 13 + Atomx.Common/Enums/ResultCode.cs | 17 + Atomx.Common/Models/ApiResult.cs | 51 + Atomx.Common/Models/BaseSearch.cs | 15 + Atomx.Common/Models/CategoryItemModel.cs | 12 + Atomx.Common/Models/JwtSetting.cs | 41 + Atomx.Common/Models/LocalizationFileFile.cs | 15 + Atomx.Common/Models/PagingList.cs | 45 + Atomx.Common/Models/ProductCategoryConfig.cs | 9 + Atomx.Common/Models/SelectItem.cs | 9 + Atomx.Common/Utils/ClaimKeys.cs | 13 + Atomx.Data/Atomx.Data.csproj | 21 + .../CacheServices/AgencyCacheService.cs | 63 + Atomx.Data/CacheServices/AreaCacheService.cs | 97 + .../CacheServices/AttributeCacheService.cs | 253 + Atomx.Data/CacheServices/BasicCacheService.cs | 46 + Atomx.Data/CacheServices/CacheService.cs | 176 + .../CacheServices/CategoryCacheService.cs | 300 + .../CacheServices/ConfigCacheService.cs | 320 + .../CacheServices/ContentCacheService.cs | 84 + .../CacheServices/CurrencyCacheService.cs | 189 + .../CacheServices/LanguageCacheService.cs | 103 + .../LocaleResourceCacheService.cs | 183 + .../CacheServices/LocalizationCacheService.cs | 30 + .../LocalizedPropertyCacheService.cs | 69 + .../CacheServices/ManufacturerCacheService.cs | 107 + .../PaymentChannelsCacheService.cs | 89 + .../ProductAttributeCacheService.cs | 16 + .../CacheServices/ProductCacheService.cs | 401 + Atomx.Data/CacheServices/RoleCacheService.cs | 110 + Atomx.Data/CacheServices/StoreCacheService.cs | 66 + .../CacheServices/StoreLevelCacheService.cs | 101 + Atomx.Data/CacheServices/UserCacheService.cs | 57 + Atomx.Data/DataContext.cs | 175 + .../Migrations/20251130091101_0.1.Designer.cs | 1374 ++ Atomx.Data/Migrations/20251130091101_0.1.cs | 743 + .../Migrations/DataContextModelSnapshot.cs | 1371 ++ Atomx.Data/Services/IdCreatorService.cs | 47 + Atomx.Storage/Atomx.Storage.csproj | 19 + Atomx.Storage/Atomx.Storage.http | 6 + Atomx.Storage/Controllers/UploadController.cs | 56 + .../Controllers/WeatherForecastController.cs | 33 + Atomx.Storage/Program.cs | 21 + Atomx.Storage/Properties/launchSettings.json | 14 + Atomx.Storage/Services/IIdentityService.cs | 84 + Atomx.Storage/WeatherForecast.cs | 13 + Atomx.Storage/appsettings.Development.json | 8 + Atomx.Storage/appsettings.json | 9 + Atomx.Utils/Atomx.Utils.csproj | 15 + Atomx.Utils/Extension/DateTimeExtension.cs | 188 + Atomx.Utils/Extension/IdCodeExtension.cs | 37 + Atomx.Utils/Extension/NumberExtension.cs | 81 + Atomx.Utils/Extension/ObjectExtension.cs | 46 + Atomx.Utils/Extension/PathExtension.cs | 86 + Atomx.Utils/Extension/RegexExtension.cs | 60 + Atomx.Utils/Extension/StringExtension.cs | 195 + Atomx.Utils/Extension/UploadExtension.cs | 189 + Atomx.Utils/Files/FileTypes.cs | 285 + Atomx.Utils/Images/ImageType.cs | 47 + Atomx.Utils/Json/Converts/ClaimConverter.cs | 36 + .../Json/Converts/DateTimeJsonConverter.cs | 33 + .../Json/Converts/LongJsonConverter.cs | 33 + Atomx.Utils/Json/JsonOptions.cs | 26 + Atomx.Utils/Json/JsonSerialize.cs | 30 + Atomx.Utils/Models/Result.cs | 25 + Atomx.Utils/Models/UploadResult.cs | 19 + Atomx.WebAPI/Atomx.WebAPI.csproj | 20 + Atomx.WebAPI/Atomx.WebAPI.http | 6 + Atomx.WebAPI/Controllers/AreaController.cs | 25 + Atomx.WebAPI/Controllers/SignController.cs | 33 + .../Controllers/WeatherForecastController.cs | 26 + Atomx.WebAPI/Grains/UserGrain.cs | 27 + Atomx.WebAPI/Program.cs | 21 + Atomx.WebAPI/Properties/launchSettings.json | 14 + Atomx.WebAPI/WeatherForecast.cs | 13 + Atomx.WebAPI/appsettings.Development.json | 8 + Atomx.WebAPI/appsettings.json | 9 + Atomx.sln | 61 + 400 files changed, 91177 insertions(+) create mode 100644 Atomx.Admin/Atomx.Admin.Client/Atomx.Admin.Client.csproj create mode 100644 Atomx.Admin/Atomx.Admin.Client/Components/AuthorizePermissionView.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Components/CultureSelector.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Components/LocalizedText.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Layout/EmptyLayout.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Layout/MainLayout.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Layout/MainLayout.razor.css create mode 100644 Atomx.Admin/Atomx.Admin.Client/Layout/NavMenu.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Layout/NavMenu.razor.css create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/AddressModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/AdminModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/AdminSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/AppVersionModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/AppVersionSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/BaseSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CategoryItem.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CategoryModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CategorySearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CorporationModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CorporationSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CorporationStaffModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CorporationStaffSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CorporationUserModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CorporationUserSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CurrencyModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/CurrentUser.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/LanguageModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/LanguageSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/LinkItem.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/LocaleResourceModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/LoginModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerProductItemSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/MaterialSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/MenuItem.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/MenuModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/MenuSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/MenuTreeItem.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/MessageTemplateModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/MessageTemplateSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/OrderSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/PriceTrendSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductAddStockModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeCombinationModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeItemModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeOptionModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeOptionSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeValueModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductDetailModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductSKUPricesModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductSaleAttributeModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductSaleSpecificationAttributeModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductSkuModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductStockAttributeModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductStockModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductStockUnitModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductStockUnitSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/ProductTransferSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialBatchSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialRecordSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialTransferSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/RoleModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/RolePermissionGroup.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/RolePermissionItem.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/RoleSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/SiteAppModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/SiteAppSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeItemModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeOptionModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeOptionSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/StoreProductItemSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/StoreSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/UploadFileModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/UploadFileSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/UserSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/WarehouseItemModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/WarehouseModel.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Models/WarehouseSearch.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Contents/ContentEdit.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Contents/ContentList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Contents/PageEdit.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Contents/PageList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Counter.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Home.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Login.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Logout.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Orders/OrderList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Orders/OrderView.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Products/CategoryEdit.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Products/CategoryList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Products/GoodsList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Products/PredefinedAttributeList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Products/PredefinedSpecificationList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductAttributeList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductEdit.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductStockList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Products/SpecificationList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Register.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Settings/MessageTemplateList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Settings/Settings.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/SiteApps/AppVersionList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/SiteApps/SiteAppList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Storages/UploadList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Systems/AdminList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Systems/CurrencyList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Systems/LanguageList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Systems/LocaleResourceList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Systems/MenuList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Systems/PermissionEdit.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Systems/RoleList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Users/UserList.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Pages/Weather.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Program.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/RedirectToLogin.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Routes.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/Services/ClientPermissionService.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Services/HttpService.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Services/LocalizationClientService.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Utils/AuthHeaderHandler.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Utils/HttpClientExtension.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Utils/IconsExtension.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Utils/PersistentAuthenticationStateProvider.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Utils/TokenProvider.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/AddressModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/AdminModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/AppVersionModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/CategoryModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/CorporationModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/CorporationStaffModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/CurrencyModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/GeneralConfigValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/LanguageModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/LocaleResourceModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/LoginModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/ManufacturerModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/MaterialBatchValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/MaterialRecordValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/MaterialValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/MenuModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/MessageTemplateModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/ProductAddStockModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/ProductAttributeModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/ProductAttributeOptionModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/ProductModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/RoleModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/RoleValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/SiteAppModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/SpecificationAttributeModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/SpecificationAttributeOptionModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/UploadFileModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/UserValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/Validators/WarehouseModelValidator.cs create mode 100644 Atomx.Admin/Atomx.Admin.Client/_Imports.razor create mode 100644 Atomx.Admin/Atomx.Admin.Client/wwwroot/appsettings.Development.json create mode 100644 Atomx.Admin/Atomx.Admin.Client/wwwroot/appsettings.json create mode 100644 Atomx.Admin/Atomx.Admin/Atomx.Admin.csproj create mode 100644 Atomx.Admin/Atomx.Admin/Components/App.razor create mode 100644 Atomx.Admin/Atomx.Admin/Components/Pages/Error.razor create mode 100644 Atomx.Admin/Atomx.Admin/Components/_Imports.razor create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/AddressController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/AdminController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/AppVersionController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/AreaController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/CategoryController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/CurrencyController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/LanguageController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/LocaleResourceController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/MenuController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/MessageTemplateController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/ProductAttributeController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/ProductAttributeOptionController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/ProductController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/RoleController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/SignController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/SiteAppController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/SpecificationAttributeController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/SpecificationAttributeOptionController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Controllers/UploadFileController.cs create mode 100644 Atomx.Admin/Atomx.Admin/Extensions/AuthorizationExtension.cs create mode 100644 Atomx.Admin/Atomx.Admin/Extensions/DataServiceExtension.cs create mode 100644 Atomx.Admin/Atomx.Admin/Extensions/DbMigrateExtension.cs create mode 100644 Atomx.Admin/Atomx.Admin/Extensions/FluentValidationExtension.cs create mode 100644 Atomx.Admin/Atomx.Admin/Middlewares/MonitoringMiddleware.cs create mode 100644 Atomx.Admin/Atomx.Admin/Models/MonitoringOptions.cs create mode 100644 Atomx.Admin/Atomx.Admin/Models/PathFilter.cs create mode 100644 Atomx.Admin/Atomx.Admin/Program.cs create mode 100644 Atomx.Admin/Atomx.Admin/Properties/launchSettings.json create mode 100644 Atomx.Admin/Atomx.Admin/Services/IdentityService.cs create mode 100644 Atomx.Admin/Atomx.Admin/Services/LocalizationFileService.cs create mode 100644 Atomx.Admin/Atomx.Admin/Services/LocalizationService.cs create mode 100644 Atomx.Admin/Atomx.Admin/Services/PermissionService.cs create mode 100644 Atomx.Admin/Atomx.Admin/Utils/PermissionAuthorizationHandler.cs create mode 100644 Atomx.Admin/Atomx.Admin/Utils/PersistingRevalidatingAuthenticationStateProvider.cs create mode 100644 Atomx.Admin/Atomx.Admin/Utils/ServerTokenProvider.cs create mode 100644 Atomx.Admin/Atomx.Admin/appsettings.Development.json create mode 100644 Atomx.Admin/Atomx.Admin/appsettings.json create mode 100644 Atomx.Admin/Atomx.Admin/modify-config.csx create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/app.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/favicon.png create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.js create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js create mode 100644 Atomx.Admin/Atomx.Admin/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map create mode 100644 Atomx.Common/Atomx.Common.csproj create mode 100644 Atomx.Common/Configuration/ConfigKeys.cs create mode 100644 Atomx.Common/Configuration/CurrencyNumber.cs create mode 100644 Atomx.Common/Configuration/GeneralConfig.cs create mode 100644 Atomx.Common/Configuration/StorageKeys.cs create mode 100644 Atomx.Common/Configuration/UploadConfig.cs create mode 100644 Atomx.Common/Constant/CacheKeys.cs create mode 100644 Atomx.Common/Constant/Permissions.cs create mode 100644 Atomx.Common/Entities/Address.cs create mode 100644 Atomx.Common/Entities/Admin.cs create mode 100644 Atomx.Common/Entities/AppVersion.cs create mode 100644 Atomx.Common/Entities/Area.cs create mode 100644 Atomx.Common/Entities/Category.cs create mode 100644 Atomx.Common/Entities/Comment.cs create mode 100644 Atomx.Common/Entities/Corporation.cs create mode 100644 Atomx.Common/Entities/CorporationManufacturerRelation.cs create mode 100644 Atomx.Common/Entities/CorporationStaff.cs create mode 100644 Atomx.Common/Entities/CorporationUserRelation.cs create mode 100644 Atomx.Common/Entities/Currency.cs create mode 100644 Atomx.Common/Entities/CurrencyChannelRelation.cs create mode 100644 Atomx.Common/Entities/Language.cs create mode 100644 Atomx.Common/Entities/LocaleResource.cs create mode 100644 Atomx.Common/Entities/LocalizedProperty.cs create mode 100644 Atomx.Common/Entities/Manufacturer.cs create mode 100644 Atomx.Common/Entities/ManufacturerProductRelation.cs create mode 100644 Atomx.Common/Entities/Material.cs create mode 100644 Atomx.Common/Entities/MaterialBatch.cs create mode 100644 Atomx.Common/Entities/MaterialRecord.cs create mode 100644 Atomx.Common/Entities/Menu.cs create mode 100644 Atomx.Common/Entities/MessageTemplate.cs create mode 100644 Atomx.Common/Entities/Order.cs create mode 100644 Atomx.Common/Entities/OrderItem.cs create mode 100644 Atomx.Common/Entities/OrderLog.cs create mode 100644 Atomx.Common/Entities/PaymentChannel.cs create mode 100644 Atomx.Common/Entities/Permission.cs create mode 100644 Atomx.Common/Entities/Picture.cs create mode 100644 Atomx.Common/Entities/Post.cs create mode 100644 Atomx.Common/Entities/PriceTrend.cs create mode 100644 Atomx.Common/Entities/Product.cs create mode 100644 Atomx.Common/Entities/ProductAttribute.cs create mode 100644 Atomx.Common/Entities/ProductAttributeCombination.cs create mode 100644 Atomx.Common/Entities/ProductAttributeOption.cs create mode 100644 Atomx.Common/Entities/ProductAttributeRelation.cs create mode 100644 Atomx.Common/Entities/ProductAttributeValue.cs create mode 100644 Atomx.Common/Entities/ProductChangeLog.cs create mode 100644 Atomx.Common/Entities/ProductInventory.cs create mode 100644 Atomx.Common/Entities/ProductInventoryLog.cs create mode 100644 Atomx.Common/Entities/ProductListing.cs create mode 100644 Atomx.Common/Entities/ProductPicture.cs create mode 100644 Atomx.Common/Entities/Role.cs create mode 100644 Atomx.Common/Entities/Setting.cs create mode 100644 Atomx.Common/Entities/SiteApp.cs create mode 100644 Atomx.Common/Entities/SpecificationAttribute.cs create mode 100644 Atomx.Common/Entities/SpecificationAttributeOption.cs create mode 100644 Atomx.Common/Entities/Store.cs create mode 100644 Atomx.Common/Entities/StoreProductItem.cs create mode 100644 Atomx.Common/Entities/UploadFile.cs create mode 100644 Atomx.Common/Entities/User.cs create mode 100644 Atomx.Common/Entities/UserAsset.cs create mode 100644 Atomx.Common/Entities/UserMeta.cs create mode 100644 Atomx.Common/Entities/UserStoreRelation.cs create mode 100644 Atomx.Common/Entities/Warehouse.cs create mode 100644 Atomx.Common/Entities/WarehouseStockRecord.cs create mode 100644 Atomx.Common/Enums/CategoryType.cs create mode 100644 Atomx.Common/Enums/ConfigType.cs create mode 100644 Atomx.Common/Enums/DataStatus.cs create mode 100644 Atomx.Common/Enums/LocalizedType.cs create mode 100644 Atomx.Common/Enums/MaterialType.cs create mode 100644 Atomx.Common/Enums/MenuType.cs create mode 100644 Atomx.Common/Enums/MessageTemplateType.cs create mode 100644 Atomx.Common/Enums/ProductInventoryChangeType.cs create mode 100644 Atomx.Common/Enums/ResultCode.cs create mode 100644 Atomx.Common/Models/ApiResult.cs create mode 100644 Atomx.Common/Models/BaseSearch.cs create mode 100644 Atomx.Common/Models/CategoryItemModel.cs create mode 100644 Atomx.Common/Models/JwtSetting.cs create mode 100644 Atomx.Common/Models/LocalizationFileFile.cs create mode 100644 Atomx.Common/Models/PagingList.cs create mode 100644 Atomx.Common/Models/ProductCategoryConfig.cs create mode 100644 Atomx.Common/Models/SelectItem.cs create mode 100644 Atomx.Common/Utils/ClaimKeys.cs create mode 100644 Atomx.Data/Atomx.Data.csproj create mode 100644 Atomx.Data/CacheServices/AgencyCacheService.cs create mode 100644 Atomx.Data/CacheServices/AreaCacheService.cs create mode 100644 Atomx.Data/CacheServices/AttributeCacheService.cs create mode 100644 Atomx.Data/CacheServices/BasicCacheService.cs create mode 100644 Atomx.Data/CacheServices/CacheService.cs create mode 100644 Atomx.Data/CacheServices/CategoryCacheService.cs create mode 100644 Atomx.Data/CacheServices/ConfigCacheService.cs create mode 100644 Atomx.Data/CacheServices/ContentCacheService.cs create mode 100644 Atomx.Data/CacheServices/CurrencyCacheService.cs create mode 100644 Atomx.Data/CacheServices/LanguageCacheService.cs create mode 100644 Atomx.Data/CacheServices/LocaleResourceCacheService.cs create mode 100644 Atomx.Data/CacheServices/LocalizationCacheService.cs create mode 100644 Atomx.Data/CacheServices/LocalizedPropertyCacheService.cs create mode 100644 Atomx.Data/CacheServices/ManufacturerCacheService.cs create mode 100644 Atomx.Data/CacheServices/PaymentChannelsCacheService.cs create mode 100644 Atomx.Data/CacheServices/ProductAttributeCacheService.cs create mode 100644 Atomx.Data/CacheServices/ProductCacheService.cs create mode 100644 Atomx.Data/CacheServices/RoleCacheService.cs create mode 100644 Atomx.Data/CacheServices/StoreCacheService.cs create mode 100644 Atomx.Data/CacheServices/StoreLevelCacheService.cs create mode 100644 Atomx.Data/CacheServices/UserCacheService.cs create mode 100644 Atomx.Data/DataContext.cs create mode 100644 Atomx.Data/Migrations/20251130091101_0.1.Designer.cs create mode 100644 Atomx.Data/Migrations/20251130091101_0.1.cs create mode 100644 Atomx.Data/Migrations/DataContextModelSnapshot.cs create mode 100644 Atomx.Data/Services/IdCreatorService.cs create mode 100644 Atomx.Storage/Atomx.Storage.csproj create mode 100644 Atomx.Storage/Atomx.Storage.http create mode 100644 Atomx.Storage/Controllers/UploadController.cs create mode 100644 Atomx.Storage/Controllers/WeatherForecastController.cs create mode 100644 Atomx.Storage/Program.cs create mode 100644 Atomx.Storage/Properties/launchSettings.json create mode 100644 Atomx.Storage/Services/IIdentityService.cs create mode 100644 Atomx.Storage/WeatherForecast.cs create mode 100644 Atomx.Storage/appsettings.Development.json create mode 100644 Atomx.Storage/appsettings.json create mode 100644 Atomx.Utils/Atomx.Utils.csproj create mode 100644 Atomx.Utils/Extension/DateTimeExtension.cs create mode 100644 Atomx.Utils/Extension/IdCodeExtension.cs create mode 100644 Atomx.Utils/Extension/NumberExtension.cs create mode 100644 Atomx.Utils/Extension/ObjectExtension.cs create mode 100644 Atomx.Utils/Extension/PathExtension.cs create mode 100644 Atomx.Utils/Extension/RegexExtension.cs create mode 100644 Atomx.Utils/Extension/StringExtension.cs create mode 100644 Atomx.Utils/Extension/UploadExtension.cs create mode 100644 Atomx.Utils/Files/FileTypes.cs create mode 100644 Atomx.Utils/Images/ImageType.cs create mode 100644 Atomx.Utils/Json/Converts/ClaimConverter.cs create mode 100644 Atomx.Utils/Json/Converts/DateTimeJsonConverter.cs create mode 100644 Atomx.Utils/Json/Converts/LongJsonConverter.cs create mode 100644 Atomx.Utils/Json/JsonOptions.cs create mode 100644 Atomx.Utils/Json/JsonSerialize.cs create mode 100644 Atomx.Utils/Models/Result.cs create mode 100644 Atomx.Utils/Models/UploadResult.cs create mode 100644 Atomx.WebAPI/Atomx.WebAPI.csproj create mode 100644 Atomx.WebAPI/Atomx.WebAPI.http create mode 100644 Atomx.WebAPI/Controllers/AreaController.cs create mode 100644 Atomx.WebAPI/Controllers/SignController.cs create mode 100644 Atomx.WebAPI/Controllers/WeatherForecastController.cs create mode 100644 Atomx.WebAPI/Grains/UserGrain.cs create mode 100644 Atomx.WebAPI/Program.cs create mode 100644 Atomx.WebAPI/Properties/launchSettings.json create mode 100644 Atomx.WebAPI/WeatherForecast.cs create mode 100644 Atomx.WebAPI/appsettings.Development.json create mode 100644 Atomx.WebAPI/appsettings.json create mode 100644 Atomx.sln diff --git a/Atomx.Admin/Atomx.Admin.Client/Atomx.Admin.Client.csproj b/Atomx.Admin/Atomx.Admin.Client/Atomx.Admin.Client.csproj new file mode 100644 index 0000000..1417e7b --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Atomx.Admin.Client.csproj @@ -0,0 +1,28 @@ + + + + net10.0 + enable + enable + true + Default + + + + + + + + + + + + + + + + + + + + diff --git a/Atomx.Admin/Atomx.Admin.Client/Components/AuthorizePermissionView.razor b/Atomx.Admin/Atomx.Admin.Client/Components/AuthorizePermissionView.razor new file mode 100644 index 0000000..8a5b8ce --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Components/AuthorizePermissionView.razor @@ -0,0 +1,60 @@ +@using Microsoft.AspNetCore.Authorization +@inject IPermissionService PermissionService +@inject IAuthorizationService AuthorizationService + + + + + @if (_hasPermission) + { + @ChildContent + } + else if (!string.IsNullOrEmpty(NotAuthorizedContent)) + { + @NotAuthorizedContent + } + + + @if (!string.IsNullOrEmpty(NotAuthenticatedContent)) + { + @NotAuthenticatedContent + } + + + + +@code { + [Parameter] public RenderFragment? ChildContent { get; set; } + [Parameter] public string? Permission { get; set; } + [Parameter] public string[]? Permissions { get; set; } + [Parameter] public bool RequireAll { get; set; } + [Parameter] public string? Policy { get; set; } + [Parameter] public string? NotAuthorizedContent { get; set; } + [Parameter] public string? NotAuthenticatedContent { get; set; } + + private bool _hasPermission; + + protected override async Task OnParametersSetAsync() + { + if (!string.IsNullOrEmpty(Policy)) + { + var authState = await AuthorizationService.AuthorizeAsync(null, Policy); + _hasPermission = authState.Succeeded; + } + else if (!string.IsNullOrEmpty(Permission)) + { + _hasPermission = await PermissionService.HasPermissionAsync(Permission); + } + else if (Permissions != null && Permissions.Length > 0) + { + if (RequireAll) + { + _hasPermission = await PermissionService.HasAllPermissionsAsync(Permissions); + } + else + { + _hasPermission = await PermissionService.HasAnyPermissionAsync(Permissions); + } + } + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Components/CultureSelector.razor b/Atomx.Admin/Atomx.Admin.Client/Components/CultureSelector.razor new file mode 100644 index 0000000..da084a0 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Components/CultureSelector.razor @@ -0,0 +1,29 @@ +@inject IJSRuntime JSRuntime +@inject ILocalizationService LocalizationService +@inject NavigationManager Navigation + +@* *@ + +@code { + private string _selectedCulture = "en-US"; + + protected override async Task OnInitializedAsync() + { + _selectedCulture = await JSRuntime.InvokeAsync("blazorCulture.get") ?? "en-US"; + } + + private async Task OnCultureChanged(ChangeEventArgs e) + { + var culture = e.Value?.ToString(); + if (!string.IsNullOrEmpty(culture)) + { + await JSRuntime.InvokeVoidAsync("blazorCulture.set", culture); + await LocalizationService.LoadResourcesAsync(culture); + Navigation.NavigateTo(Navigation.Uri, forceLoad: true); + } + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Components/LocalizedText.razor b/Atomx.Admin/Atomx.Admin.Client/Components/LocalizedText.razor new file mode 100644 index 0000000..7aaea5a --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Components/LocalizedText.razor @@ -0,0 +1,26 @@ +@inject ILocalizationService LocalizationService + +@Text + +@code { + private string? _text; + + [Parameter] + public string Key { get; set; } = string.Empty; + + [Parameter] + public string? Culture { get; set; } + + private string Text => _text ?? Key; + + protected override async Task OnParametersSetAsync() + { + await LoadText(); + } + + private async Task LoadText() + { + _text = await LocalizationService.GetStringAsync(Key, Culture) ?? Key; + StateHasChanged(); + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Layout/EmptyLayout.razor b/Atomx.Admin/Atomx.Admin.Client/Layout/EmptyLayout.razor new file mode 100644 index 0000000..e1953d3 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Layout/EmptyLayout.razor @@ -0,0 +1,9 @@ +@inherits LayoutComponentBase + +
+ @Body +
+ +@code { + +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Layout/MainLayout.razor b/Atomx.Admin/Atomx.Admin.Client/Layout/MainLayout.razor new file mode 100644 index 0000000..e40de20 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Layout/MainLayout.razor @@ -0,0 +1,122 @@ +@inherits LayoutComponentBase +@inject ILogger _logger + + + + + + + + + + + + + + @* + + *@ + + + + + + + + + + + + + @* + + *@ + + + + @Body + + + + +
+
+ 程序遇到了未知错误! + + +
+
+ @($"{ex.Message}{Environment.NewLine}{ex.StackTrace}") +
+
+
+
+ + + + +@code { + private ErrorBoundary? _errorBoundary; + + private void ResetError(Exception ex) + { + _logger.LogError(ex, "未处理的异常。"); + _errorBoundary?.Recover(); + } + + private bool _open = true; + + private void ToggleDrawer() + { + _open = !_open; + } + + private MenuDataItem[] MenuDatas; + + private AvatarMenuItem[] AvatarMenuItems => + [ + new() { Key = "center", IconType = "user", Option = "通知消息"}, + new() { Key = "setting", IconType = "setting", Option ="修改资料" }, + new() { IsDivider = true }, + new() { Key = "logout", IconType = "logout", Option = "退出登录"} + ]; + + public void HandleSelectUser(AntDesign.MenuItem item) + { + switch (item.Key) + { + case "center": + Navigation.NavigateTo("/account/center"); + break; + case "setting": + Navigation.NavigateTo("/account/settings"); + break; + case "logout": + Navigation.NavigateTo("/logout"); + break; + } + } + + protected async override Task OnInitializedAsync() + { + + var url = "/api/menu/tree"; + var apiResult = await HttpService.Get>>(url); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + MenuDatas = apiResult.Data.ToArray(); + StateHasChanged(); + } + } + } + + +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Layout/MainLayout.razor.css b/Atomx.Admin/Atomx.Admin.Client/Layout/MainLayout.razor.css new file mode 100644 index 0000000..38d1f25 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Layout/MainLayout.razor.css @@ -0,0 +1,98 @@ +.page { + position: relative; + display: flex; + flex-direction: column; +} + +main { + flex: 1; +} + +.sidebar { + background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); +} + +.top-row { + background-color: #f7f7f7; + border-bottom: 1px solid #d6d5d5; + justify-content: flex-end; + height: 3.5rem; + display: flex; + align-items: center; +} + + .top-row ::deep a, .top-row ::deep .btn-link { + white-space: nowrap; + margin-left: 1.5rem; + text-decoration: none; + } + + .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { + text-decoration: underline; + } + + .top-row ::deep a:first-child { + overflow: hidden; + text-overflow: ellipsis; + } + +@media (max-width: 640.98px) { + .top-row { + justify-content: space-between; + } + + .top-row ::deep a, .top-row ::deep .btn-link { + margin-left: 0; + } +} + +@media (min-width: 641px) { + .page { + flex-direction: row; + } + + .sidebar { + width: 250px; + height: 100vh; + position: sticky; + top: 0; + } + + .top-row { + position: sticky; + top: 0; + z-index: 1; + } + + .top-row.auth ::deep a:first-child { + flex: 1; + text-align: right; + width: 0; + } + + .top-row, article { + padding-left: 2rem !important; + padding-right: 1.5rem !important; + } +} + +#blazor-error-ui { + color-scheme: light only; + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + box-sizing: border-box; + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 1000; +} + + #blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; + } diff --git a/Atomx.Admin/Atomx.Admin.Client/Layout/NavMenu.razor b/Atomx.Admin/Atomx.Admin.Client/Layout/NavMenu.razor new file mode 100644 index 0000000..a835ded --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Layout/NavMenu.razor @@ -0,0 +1,30 @@ + + + + + + diff --git a/Atomx.Admin/Atomx.Admin.Client/Layout/NavMenu.razor.css b/Atomx.Admin/Atomx.Admin.Client/Layout/NavMenu.razor.css new file mode 100644 index 0000000..a2aeace --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Layout/NavMenu.razor.css @@ -0,0 +1,105 @@ +.navbar-toggler { + appearance: none; + cursor: pointer; + width: 3.5rem; + height: 2.5rem; + color: white; + position: absolute; + top: 0.5rem; + right: 1rem; + border: 1px solid rgba(255, 255, 255, 0.1); + background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1); +} + +.navbar-toggler:checked { + background-color: rgba(255, 255, 255, 0.5); +} + +.top-row { + min-height: 3.5rem; + background-color: rgba(0,0,0,0.4); +} + +.navbar-brand { + font-size: 1.1rem; +} + +.bi { + display: inline-block; + position: relative; + width: 1.25rem; + height: 1.25rem; + margin-right: 0.75rem; + top: -1px; + background-size: cover; +} + +.bi-house-door-fill-nav-menu { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E"); +} + +.bi-plus-square-fill-nav-menu { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E"); +} + +.bi-list-nested-nav-menu { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E"); +} + +.nav-item { + font-size: 0.9rem; + padding-bottom: 0.5rem; +} + + .nav-item:first-of-type { + padding-top: 1rem; + } + + .nav-item:last-of-type { + padding-bottom: 1rem; + } + + .nav-item ::deep .nav-link { + color: #d7d7d7; + background: none; + border: none; + border-radius: 4px; + height: 3rem; + display: flex; + align-items: center; + line-height: 3rem; + width: 100%; + } + +.nav-item ::deep a.active { + background-color: rgba(255,255,255,0.37); + color: white; +} + +.nav-item ::deep .nav-link:hover { + background-color: rgba(255,255,255,0.1); + color: white; +} + +.nav-scrollable { + display: none; +} + +.navbar-toggler:checked ~ .nav-scrollable { + display: block; +} + +@media (min-width: 641px) { + .navbar-toggler { + display: none; + } + + .nav-scrollable { + /* Never collapse the sidebar for wide screens */ + display: block; + + /* Allow sidebar to scroll for tall menus */ + height: calc(100vh - 3.5rem); + overflow-y: auto; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/AddressModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/AddressModel.cs new file mode 100644 index 0000000..f7db495 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/AddressModel.cs @@ -0,0 +1,85 @@ +namespace Atomx.Admin.Client.Models +{ + public class AddressModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 添加地址用户 + /// + public long UserId { get; set; } + + /// + /// 收件人姓名 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 邮件地址 + /// + public string Email { get; set; } = string.Empty; + + /// + /// 电话号码 + /// + public string Phone { get; set; } = string.Empty; + + /// + /// 公司 + /// + public string Company { get; set; } = string.Empty; + + /// + /// 国家 + /// + public long Country { get; set; } + + /// + /// 省份 + /// + public long Province { get; set; } + + /// + /// 城市 + /// + public long City { get; set; } + + /// + /// 地区 + /// + public long Region { get; set; } + + /// + /// 邮政编码 + /// + public string PostalCode { get; set; } = string.Empty; + + /// + /// 详细地址 + /// + public string FullAddress { get; set; } = string.Empty; + + /// + /// 地址所在经度 + /// + public decimal Longitude { get; set; } + + /// + /// 地址所在纬度 + /// + public decimal Latitude { get; set; } + + /// + /// 是否是虚拟地址 + /// + public bool IsVirtual { get; set; } + + /// + /// 是否编辑 + /// + public bool IsEdit { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/AdminModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/AdminModel.cs new file mode 100644 index 0000000..b5f22a1 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/AdminModel.cs @@ -0,0 +1,50 @@ +namespace Atomx.Admin.Client.Models +{ + public class AdminModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 管理员用户名 + /// + public string Username { get; set; } = string.Empty; + + /// + /// 注册手机号 + /// + public string Mobile { get; set; } = string.Empty; + + /// + /// 注册邮箱 + /// + public string Email { get; set; } = string.Empty; + + /// + /// 登录密码 + /// + public string Password { get; set; } = string.Empty; + + /// + /// 新密码 + /// + public string NewPassword { get; set; } = string.Empty; + + /// + /// 确认密码 + /// + public string RePassword { get; set; } = string.Empty; + + /// + /// 是否设置密码 + /// + public bool SetPassword { get; set; } + + /// + /// 状态 + /// + public int Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/AdminSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/AdminSearch.cs new file mode 100644 index 0000000..2789a93 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/AdminSearch.cs @@ -0,0 +1,35 @@ +namespace Atomx.Admin.Client.Models +{ + public class AdminSearch : BaseSearch + { + /// + /// 用户名或昵称 + /// + public string? Username { get; set; } + + /// + /// 邮件地址 + /// + public string? Email { get; set; } + + /// + /// 手机号码 + /// + public string? Mobile { get; set; } + + /// + /// 真实姓名 + /// + public string? RealName { get; set; } + + /// + /// 开始时间 + /// + public DateTime?[] RangeTime { get; set; } = new DateTime?[] { null, null }; + + /// + /// 状态 + /// + public string? Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/AppVersionModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/AppVersionModel.cs new file mode 100644 index 0000000..2f04c01 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/AppVersionModel.cs @@ -0,0 +1,78 @@ +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace Atomx.Admin.Client.Models +{ + public class AppVersionModel + { + /// + /// 数据ID + /// + [DatabaseGenerated(DatabaseGeneratedOption.None)] + [Key] + public long Id { get; set; } + + /// + /// 运行平台 + /// + public int Platform { get; set; } + + /// + /// 应用名称KEY + /// + [Column(TypeName = "varchar(64)")] + public string AppName { get; set; } = string.Empty; + + /// + /// 版本标题 + /// + [Column(TypeName = "varchar(64)")] + public string Title { get; set; } = string.Empty; + + /// + /// 版本 + /// + [Column(TypeName = "varchar(64)")] + public string Version { get; set; } = string.Empty; + + /// + /// 主版本号(major)无法向下兼容时,需要递增 + /// + [Column(TypeName = "varchar(64)")] + public int VersionX { get; set; } + + /// + /// 次版本号(minor)新增新的特性时,需要递增 + /// + [Column(TypeName = "varchar(64)")] + public int VersionY { get; set; } + + /// + /// 修订版本号(patch)修复问题时,需要递增 + /// + [Column(TypeName = "varchar(64)")] + public int VersionZ { get; set; } + + /// + /// 版本日期 + /// + [Column(TypeName = "varchar(64)")] + public int VersionDate { get; set; } + + /// + /// 版本状态 例如:b 表示bate版,即测试版 + /// + public int VersionState { get; set; } + + /// + /// 更新内容说明 + /// + [Column(TypeName = "text")] + public string Content { get; set; } = string.Empty; + + /// + /// 版本状态 + /// + public int Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/AppVersionSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/AppVersionSearch.cs new file mode 100644 index 0000000..9744577 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/AppVersionSearch.cs @@ -0,0 +1,20 @@ +namespace Atomx.Admin.Client.Models +{ + public class AppVersionSearch : BaseSearch + { + /// + /// 名称 + /// + public string? Name { get; set; } + + /// + /// 状态 + /// + public string Status { get; set; } = string.Empty; + + /// + /// 开始时间 + /// + public DateTime?[] RangeTime { get; set; } = new DateTime?[] { null, null }; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/BaseSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/BaseSearch.cs new file mode 100644 index 0000000..d040321 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/BaseSearch.cs @@ -0,0 +1,15 @@ +namespace Atomx.Admin.Client.Models +{ + public class BaseSearch + { + /// + /// 查询开始时间 + /// + public DateTime? StartTime { get; set; } + + /// + /// 查询结束时间 + /// + public DateTime? EndTime { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CategoryItem.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CategoryItem.cs new file mode 100644 index 0000000..352f346 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CategoryItem.cs @@ -0,0 +1,11 @@ +using Atomx.Common.Entities; + +namespace Atomx.Admin.Client.Models +{ + public class CategoryItem : Category + { + public List Children { get; set; } = new List(); + + public bool IsLast { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CategoryModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CategoryModel.cs new file mode 100644 index 0000000..b497973 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CategoryModel.cs @@ -0,0 +1,83 @@ +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace Atomx.Admin.Client.Models +{ + public class CategoryModel + { + /// + /// 分类ID + /// + [DatabaseGenerated(DatabaseGeneratedOption.None)] + [Key] + public long Id { get; set; } + + /// + /// 分类类型,1内容,2产品,3社区 + /// + public int Type { get; set; } + + /// + /// 上级分类ID + /// + public long ParentId { get; set; } + + /// + /// 分类名称 + /// + [Column(TypeName = "varchar(25)")] + public string Name { get; set; } = string.Empty; + + /// + /// 分类URL缩略名 + /// + [Column(TypeName = "varchar(50)")] + public string Slug { get; set; } = string.Empty; + + /// + /// Meta描述介绍 + /// + [Column(TypeName = "varchar(255)")] + public string MetaDescription { get; set; } = string.Empty; + + /// + /// Meta关键词 + /// + [Column(TypeName = "varchar(255)")] + public string MetaKeywords { get; set; } = string.Empty; + + /// + /// 过滤属性IDs + /// + [Column(TypeName = "varchar(255)")] + public string FilterAttributes { get; set; } = string.Empty; + + /// + /// 分类图片 + /// + [Column(TypeName = "varchar(255)")] + public string Image { get; set; } = string.Empty; + + /// + /// 分类页 banner + /// + [Column(TypeName = "varchar(255)")] + public string Banner { get; set; } = string.Empty; + + /// + /// 只是一个节点 + /// + public bool IsNode { get; set; } + + /// + /// 是否可用 + /// + + public bool Enabled { get; set; } + + /// + /// 排序 + /// + public int DisplayOrder { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CategorySearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CategorySearch.cs new file mode 100644 index 0000000..b4a93c2 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CategorySearch.cs @@ -0,0 +1,10 @@ +namespace Atomx.Admin.Client.Models +{ + public class CategorySearch : BaseSearch + { + /// + /// 分类名称 + /// + public string? Name { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CorporationModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationModel.cs new file mode 100644 index 0000000..9b68bdd --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationModel.cs @@ -0,0 +1,20 @@ +namespace Atomx.Admin.Client.Models +{ + public class CorporationModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 公司名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 数据状态 + /// + public int Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CorporationSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationSearch.cs new file mode 100644 index 0000000..18dd7ad --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationSearch.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Atomx.Admin.Client.Models +{ + public class CorporationSearch : BaseSearch + { + /// + /// 名称 + /// + public string? Name { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CorporationStaffModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationStaffModel.cs new file mode 100644 index 0000000..8806c1b --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationStaffModel.cs @@ -0,0 +1,55 @@ +namespace Atomx.Admin.Client.Models +{ + public class CorporationStaffModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 公司ID + /// + public long CorporationId { get; set; } + + /// + /// 管理员用户名 + /// + public string Username { get; set; } = string.Empty; + + /// + /// 注册手机号 + /// + public string Mobile { get; set; } = string.Empty; + + /// + /// 注册邮箱 + /// + public string Email { get; set; } = string.Empty; + + /// + /// 登录密码 + /// + public string Password { get; set; } = string.Empty; + + /// + /// 新密码 + /// + public string NewPassword { get; set; } = string.Empty; + + /// + /// 确认密码 + /// + public string RePassword { get; set; } = string.Empty; + + /// + /// 是否设置密码 + /// + public bool SetPassword { get; set; } + + /// + /// 状态 + /// + public int Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CorporationStaffSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationStaffSearch.cs new file mode 100644 index 0000000..c158704 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationStaffSearch.cs @@ -0,0 +1,40 @@ +namespace Atomx.Admin.Client.Models +{ + public class CorporationStaffSearch : BaseSearch + { + /// + /// 公司ID + /// + public long CorporationId { get; set; } + + /// + /// 用户名或昵称 + /// + public string? Username { get; set; } + + /// + /// 邮件地址 + /// + public string? Email { get; set; } + + /// + /// 手机号码 + /// + public string? Mobile { get; set; } + + /// + /// 真实姓名 + /// + public string? RealName { get; set; } + + /// + /// 开始时间 + /// + public DateTime?[] RangeTime { get; set; } = new DateTime?[] { null, null }; + + /// + /// 状态 + /// + public string? Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CorporationUserModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationUserModel.cs new file mode 100644 index 0000000..b8d0f41 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationUserModel.cs @@ -0,0 +1,27 @@ +using Atomx.Common.Entities; + +namespace Atomx.Admin.Client.Models +{ + public class CorporationUserModel:User + { + /// + /// 公司ID + /// + public long CorporationId { get; set; } + + /// + /// 用户ID + /// + public long UserId { get; set; } + + /// + /// 是否是管理员 + /// + public bool IsAdmin { get; set; } + + /// + /// 数据状态 + /// + public int Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CorporationUserSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationUserSearch.cs new file mode 100644 index 0000000..e01efc8 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CorporationUserSearch.cs @@ -0,0 +1,7 @@ +namespace Atomx.Admin.Client.Models +{ + public class CorporationUserSearch : BaseSearch + { + public string Name { get; set; } = string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CurrencyModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CurrencyModel.cs new file mode 100644 index 0000000..b6af7a4 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CurrencyModel.cs @@ -0,0 +1,56 @@ +namespace Atomx.Admin.Client.Models +{ + public class CurrencyModel + { + /// + /// 数据ID + /// + public int Id { get; set; } + + /// + /// 语言 + /// + public string Language { get; set; } = string.Empty; + + /// + /// 货币名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 货币单位代码 + /// + public string CurrencyCode { get; set; } = string.Empty; + + /// + /// 本地显示 + /// + public string DisplayLocale { get; set; } = string.Empty; + + /// + /// 数字自定义格式化 + /// + public string CustomFormatting { get; set; } = string.Empty; + + /// + /// 兑换汇率 + /// + public double Rate { get; set; } + + /// + /// 排序 + /// + public int DisplayOrder { get; set; } + + /// + /// 是否可用 + /// + + public bool Enabled { get; set; } + + /// + /// 是否编辑 + /// + public bool IsEdit { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/CurrentUser.cs b/Atomx.Admin/Atomx.Admin.Client/Models/CurrentUser.cs new file mode 100644 index 0000000..72d8e4c --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/CurrentUser.cs @@ -0,0 +1,9 @@ +namespace Atomx.Admin.Client.Models +{ + public class CurrentUser + { + public string Name { get; set; } = string.Empty; + public string Avatar { get; set; } = string.Empty; + public string UserId { get; set; } = string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/LanguageModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/LanguageModel.cs new file mode 100644 index 0000000..036bf28 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/LanguageModel.cs @@ -0,0 +1,55 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Atomx.Admin.Client.Models +{ + public class LanguageModel + { + /// + /// 数据ID + /// + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Key] + public int Id { get; set; } + + /// + /// 语言名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 语言标题 + /// + public string Title { get; set; } = string.Empty; + + /// + /// 语言名称 + /// + public string Culture { get; set; } = string.Empty; + + /// + /// 国旗 + /// + public string FlagImage { get; set; } = string.Empty; + + /// + /// 排序 + /// + public int DisplayOrder { get; set; } + + /// + /// 是否可用,系统面 + /// + public bool Enabled { get; set; } + + /// + /// 多语言资源的版本,可以是时间戳或哈希 + /// + public string ResourceVersion { get; set; } = string.Empty; + + /// + /// 是否编辑 + /// + public bool IsEdit { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/LanguageSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/LanguageSearch.cs new file mode 100644 index 0000000..46b7608 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/LanguageSearch.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace Atomx.Admin.Client.Models +{ + public class LanguageSearch : BaseSearch + { + /// + /// 语言名称 + /// + public string Name { get; set; } = string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/LinkItem.cs b/Atomx.Admin/Atomx.Admin.Client/Models/LinkItem.cs new file mode 100644 index 0000000..43a1ca7 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/LinkItem.cs @@ -0,0 +1,35 @@ +namespace Atomx.Common.Models +{ + public class LinkItem + { + /// + /// 链接标识 + /// + public string Key { get; set; } = string.Empty; + + /// + /// 链接名字 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 标题 + /// + public string Title { get; set; } = string.Empty; + + /// + /// 图标 + /// + public string Image { get; set; } = string.Empty; + + /// + /// 链接URL + /// + public string Url { get; set; } = string.Empty; + + /// + /// 是否可用 + /// + public bool Enabled { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/LocaleResourceModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/LocaleResourceModel.cs new file mode 100644 index 0000000..a2843a4 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/LocaleResourceModel.cs @@ -0,0 +1,35 @@ +namespace Atomx.Admin.Client.Models +{ + public class LocaleResourceModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 语言编码 + /// + public int LanguageId { get; set; } + + /// + /// 语言名称 + /// + public string Culture { get; set; } = string.Empty; + + /// + /// 资源名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 资源内容值 + /// + public string Value { get; set; } = string.Empty; + + /// + /// 是否编辑 + /// + public bool IsEdit { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/LoginModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/LoginModel.cs new file mode 100644 index 0000000..1f51a6d --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/LoginModel.cs @@ -0,0 +1,25 @@ +namespace Atomx.Admin.Client.Models +{ + public class LoginModel + { + /// + /// 登录账号 + /// + public string Account { get; set; } = string.Empty; + + /// + /// 登录密码 + /// + public string Password { get; set; } = string.Empty; + + /// + /// 地区代码,同时用来识别是否手机登录 + /// + public string AreaCode { get; set; } = string.Empty; + + /// + /// 是否记住我 + /// + public bool SaveMe { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerModel.cs new file mode 100644 index 0000000..59a9bdb --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerModel.cs @@ -0,0 +1,58 @@ +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace Atomx.Admin.Client.Models +{ + public class ManufacturerModel + { + /// + /// 制造商ID + /// + public long Id { get; set; } + + /// + /// 制造商名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 是否是供应商 + /// + public bool IsVendor { get; set; } + + /// + /// 品牌LOGO + /// + public string Logo { get; set; } = string.Empty; + + /// + /// 品牌制造商描述 + /// + public string Description { get; set; } = string.Empty; + + /// + /// Meta标题 + /// + public string MetaTitle { get; set; } = string.Empty; + + /// + /// Meta标题 + /// + public string MetaKeywords { get; set; } = string.Empty; + + /// + /// Meta标题 + /// + public string MetaDescription { get; set; } = string.Empty; + + /// + /// 是否启用 + /// + public bool Enabled { get; set; } + + /// + /// 显示排序 + /// + public int DisplayOrder { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerProductItemSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerProductItemSearch.cs new file mode 100644 index 0000000..026227c --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerProductItemSearch.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Atomx.Admin.Client.Models +{ + public class ManufacturerProductItemSearch : BaseSearch + { + + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerSearch.cs new file mode 100644 index 0000000..fd85166 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ManufacturerSearch.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Atomx.Admin.Client.Models +{ + public class ManufacturerSearch:BaseSearch + { + /// + /// 名称 + /// + public string Name { get; set; }=string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/MaterialSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/MaterialSearch.cs new file mode 100644 index 0000000..5b5630c --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/MaterialSearch.cs @@ -0,0 +1,20 @@ +namespace Atomx.Admin.Client.Models +{ + public class MaterialSearch : BaseSearch + { + /// + /// 类型 + /// + public int? Type { get; set; } + + /// + /// 原料归属公司ID + /// + public long CorporationId { get; set; } + + /// + /// 原料归属店铺网点ID + /// + public long StoreId { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/MenuItem.cs b/Atomx.Admin/Atomx.Admin.Client/Models/MenuItem.cs new file mode 100644 index 0000000..67e159c --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/MenuItem.cs @@ -0,0 +1,9 @@ +using Atomx.Common.Entities; + +namespace Atomx.Admin.Client.Models +{ + public class MenuItem : Menu + { + public List? Children { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/MenuModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/MenuModel.cs new file mode 100644 index 0000000..7eab037 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/MenuModel.cs @@ -0,0 +1,70 @@ +namespace Atomx.Admin.Client.Models +{ + public class MenuModel + { + /// + /// 分类ID + /// + public long Id { get; set; } + + /// + /// 分类类型,1-管理后台系统 + /// + public int Type { get; set; } + + /// + /// 上级分类ID + /// + public long ParentId { get; set; } + + /// + /// 分类名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 分类图片 + /// + public string Icon { get; set; } = string.Empty; + + /// + /// 菜单分组,针对折叠菜单效果 + /// + public string Key { get; set; } = string.Empty; + + /// + /// 菜单链接的URL + /// + public string Url { get; set; } = string.Empty; + + /// + /// 权限代码 + /// + public string Code { get; set; } = string.Empty; + + /// + /// 是否外链接 + /// + public bool IsLink { get; set; } + + /// + /// 是否可用 + /// + public bool Enabled { get; set; } + + /// + /// 层级深度 + /// + public int Depth { get; set; } + + /// + /// 层级路径 + /// + public string Path { get; set; } = string.Empty; + + /// + /// 排序 + /// + public int DisplayOrder { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/MenuSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/MenuSearch.cs new file mode 100644 index 0000000..4452779 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/MenuSearch.cs @@ -0,0 +1,10 @@ +namespace Atomx.Admin.Client.Models +{ + public class MenuSearch + { + /// + /// 名称 + /// + public string Name { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/MenuTreeItem.cs b/Atomx.Admin/Atomx.Admin.Client/Models/MenuTreeItem.cs new file mode 100644 index 0000000..175f1fe --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/MenuTreeItem.cs @@ -0,0 +1,19 @@ +namespace Atomx.Admin.Client.Models +{ + public class MenuTreeItem + { + public string Icon { get; set; } = string.Empty; + + public string IconFont { get; set; } = string.Empty; + + public string Locale { get; set; } = string.Empty; + + public string Name { get; set; } = string.Empty; + + public string Key { get; set; } = string.Empty; + + public string Path { get; set; } = string.Empty; + + public List Children { get; set; } = new List(); + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/MessageTemplateModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/MessageTemplateModel.cs new file mode 100644 index 0000000..94095d5 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/MessageTemplateModel.cs @@ -0,0 +1,40 @@ +namespace Atomx.Admin.Client.Models +{ + public class MessageTemplateModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 消息模板类型 + /// + public string Type { get; set; } = string.Empty; + + /// + /// 信息模板KEY + /// + public string Key { get; set; } = string.Empty; + + /// + /// 消息模板名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 消息标题 + /// + public string Title { get; set; } = string.Empty; + + /// + /// 消息内容 + /// + public string Body { get; set; } = string.Empty; + + /// + /// 是否可用 + /// + public bool Enabled { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/MessageTemplateSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/MessageTemplateSearch.cs new file mode 100644 index 0000000..a906ad2 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/MessageTemplateSearch.cs @@ -0,0 +1,9 @@ +namespace Atomx.Admin.Client.Models +{ + public class MessageTemplateSearch : BaseSearch + { + public int? Type { get; set; } + + public string Key { get; set; } = string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/OrderSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/OrderSearch.cs new file mode 100644 index 0000000..6bc611c --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/OrderSearch.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Atomx.Admin.Client.Models +{ + public class OrderSearch : BaseSearch + { + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/PriceTrendSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/PriceTrendSearch.cs new file mode 100644 index 0000000..93c37d3 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/PriceTrendSearch.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Atomx.Admin.Client.Models +{ + public class PriceTrendSearch : BaseSearch + { + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductAddStockModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAddStockModel.cs new file mode 100644 index 0000000..12fbd13 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAddStockModel.cs @@ -0,0 +1,50 @@ +namespace Atomx.Admin.Client.Models +{ + public class ProductAddStockModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 产品ID + /// + public long ProductId { get; set; } + + /// + /// 产品标题 + /// + public string Title { get; set; } = string.Empty; + + /// + /// 产品属性 + /// + public List ProductStockAttributes { get; set; } = new(); + + /// + /// SKU信息 + /// + public ProductAttributeCombinationModel ProductAttributeCombination { get; set; } = new(); + + /// + /// 归属公司ID + /// + public long CorporationId { get; set; } + + /// + /// 仓库ID + /// + public string WarehouseId { get; set; } = string.Empty; + + /// + /// 是否新增属性 + /// + public bool AddAttribute { get; set; } + + /// + /// 添加库存 + /// + public int AddStockQuantity { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeCombinationModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeCombinationModel.cs new file mode 100644 index 0000000..f518b2d --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeCombinationModel.cs @@ -0,0 +1,89 @@ +namespace Atomx.Admin.Client.Models +{ + /// + /// 产品SKU属性组合模型 + /// + public class ProductAttributeCombinationModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 产品ID + /// + public long ProductId { get; set; } + + /// + /// 供应制造商ID + /// + public long ManufacturerId { get; set; } + + /// + /// 属性JSON + /// + public List SkuAttributes { get; set; } = new List(); + + /// + /// 库存数量 + /// + public int StockQuantity { get; set; } + + /// + /// 销售数量 + /// + public int SalesQuantity { get; set; } + + /// + /// SKU编码 + /// + public string SkuNumber { get; set; } = string.Empty; + + /// + /// 销售加工费 + /// + public decimal ProcessCharge { get; set; } + + /// + /// 加工费成本 + /// + public decimal ProcessCost { get; set; } + + /// + /// 销售附加费 + /// + public decimal Surcharge { get; set; } + + /// + /// 附加费成本 + /// + public decimal SurchargeCost { get; set; } + + /// + /// SKU的市场价,划线价 + /// + public decimal MarketPrice { get; set; } + + /// + /// SKU的销售价格 + /// + + public decimal Price { get; set; } + + /// + /// 重量 + /// + public decimal Weight { get; set; } + + /// + /// 重量单位,1克,2千克,3磅,4盎司 + /// + public int WeightUnit { get; set; } + + /// + /// 是否上架销售 + /// + public bool Enabled { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeItemModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeItemModel.cs new file mode 100644 index 0000000..08dce14 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeItemModel.cs @@ -0,0 +1,10 @@ +using Atomx.Common.Entities; + +namespace Atomx.Admin.Client.Models +{ + public class ProductAttributeItemModel : ProductAttribute + { + + public string CategoryName { get; set; } = string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeModel.cs new file mode 100644 index 0000000..3ac3f25 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeModel.cs @@ -0,0 +1,50 @@ +namespace Atomx.Admin.Client.Models +{ + public class ProductAttributeModel + { + /// + /// 属性ID + /// + public long Id { get; set; } + + /// + /// 上级属性,用于规格属性做分组 + /// + public long ParentId { get; set; } + + /// + /// 分类ID + /// + public long CategoryId { get; set; } + + /// + /// 属性名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 属性控件类型,1选项,0文本 + /// + public int ControlType { get; set; } + + /// + /// 必须填写重量 + /// + public bool WeightIsRequired { get; set; } + + /// + /// 是否是必须的属性 + /// + public bool IsRequired { get; set; } + + /// + /// 展示排序 + /// + public int DisplayOrder { get; set; } + + /// + /// 数据状态 + /// + public int Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeOptionModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeOptionModel.cs new file mode 100644 index 0000000..780946c --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeOptionModel.cs @@ -0,0 +1,40 @@ +namespace Atomx.Admin.Client.Models +{ + public class ProductAttributeOptionModel + { + /// + /// 预设值ID + /// + public long Id { get; set; } + + /// + /// 供应商自定义值 + /// + public long VendorId { get; set; } + + /// + /// 产品属性ID + /// + public long AttributeId { get; set; } + + /// + /// 预设值名称 + /// + public string Value { get; set; } = string.Empty; + + /// + /// 展示排序 + /// + public int DisplayOrder { get; set; } + + /// + /// 是否通用的 + /// + public bool Standard { get; set; } + + /// + /// 数据状态 + /// + public int Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeOptionSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeOptionSearch.cs new file mode 100644 index 0000000..82065af --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeOptionSearch.cs @@ -0,0 +1,12 @@ +namespace Atomx.Admin.Client.Models +{ + public class ProductAttributeOptionSearch : BaseSearch + { + /// + /// 值 + /// + public string? Value { get; set; } + + public long AttributeId { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeSearch.cs new file mode 100644 index 0000000..7d5531e --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeSearch.cs @@ -0,0 +1,9 @@ +namespace Atomx.Admin.Client.Models +{ + public class ProductAttributeSearch : BaseSearch + { + public string Name { get; set; }=string.Empty; + + public long CategoryId { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeValueModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeValueModel.cs new file mode 100644 index 0000000..b513822 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductAttributeValueModel.cs @@ -0,0 +1,63 @@ +namespace Atomx.Admin.Client.Models +{ + /// + /// 产品属性值模型 + /// + public class ProductAttributeValueModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 产品ID + /// + public long ProductId { get; set; } + + /// + /// 预设值ID + /// + public long OptionId { get; set; } + + /// + /// 产品属性关系数据ID + /// + public long ProductAttributeRelationId { get; set; } + + /// + /// 属性值名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 属性图片 + /// + public string Image { get; set; } = string.Empty; + + /// + /// 重量 + /// + public decimal Weight { get; set; } + + /// + /// 重量单位,1克,2千克,3磅,4盎司 + /// + public int WeightUnit { get; set; } + + /// + /// 是否是加重的 + /// + public bool IsAddWeight { get; set; } = false; + + /// + /// 展示排序 + /// + public int DisplayOrder { get; set; } + + /// + /// 是否在编辑 + /// + public bool IsEdit { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductDetailModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductDetailModel.cs new file mode 100644 index 0000000..fef5d6f --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductDetailModel.cs @@ -0,0 +1,6 @@ +namespace Atomx.Admin.Client.Models +{ + public class ProductDetailModel + { + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductModel.cs new file mode 100644 index 0000000..e6f9c3e --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductModel.cs @@ -0,0 +1,241 @@ +using Atomx.Common.Entities; + +namespace Atomx.Admin.Client.Models +{ + public class ProductModel + { + /// + /// 产品ID + /// + public long Id { get; set; } + + /// + /// 父产品ID + /// + public long ParentProductId { get; set; } + + /// + /// 发布用户ID + /// + + public long UserId { get; set; } + + /// + /// 归属公司ID + /// + + public long CorporationId { get; set; } + + /// + /// 卖家店铺ID + /// + public long StoreId { get; set; } + + /// + /// 产品类型ID + /// + public long ProductTypeId { get; set; } + + /// + /// 分类路径 + /// + public string? CategoryPath { get; set; } = string.Empty; + + /// + /// 分类ID + /// + public long CategoryId { get; set; } + + /// + /// 制造商ID + /// + public long ManufacturerId { get; set; } + + /// + /// SEO Title + /// + public string MetaTitle { get; set; } = string.Empty; + + /// + /// SEO Description + /// + public string MetaDescription { get; set; } = string.Empty; + + /// + /// 产品Slug + /// + public string Slug { get; set; } = string.Empty; + + /// + /// 产品名称 + /// + public string Title { get; set; } = string.Empty; + + /// + /// 产品唯一编码 + /// + public string? SIN { get; set; } = string.Empty; + + /// + /// 封面图片 + /// + public string? Image { get; set; } = string.Empty; + + /// + /// 产品图片,JSON + /// + public string? Photos { get; set; } = string.Empty; + + /// + /// 产品卖点 + /// + public string? Feature { get; set; } = string.Empty; + + /// + /// 产品简介 + /// + public string? Description { get; set; } = string.Empty; + + /// + /// 产品特点标签 + /// + public string? Tags { get; set; } = string.Empty; + + /// + /// 产品详细介绍 + /// + public string Body { get; set; } = string.Empty; + + /// + /// 规格信息Json + /// + public string? Specification { get; set; } = string.Empty; + + /// + /// 商品库存 + /// + public int StockQuantity { get; set; } + + /// + /// 重量 + /// + public decimal? Weight { get; set; } + + /// + /// 市场价,划线价 + /// + public decimal MarketPrice { get; set; } + + /// + /// 销售标价 + /// + public decimal Price { get; set; } + + /// + /// SKU组合的产品价格信息 + /// + public string? SkuPrices { get; set; } = string.Empty; + + /// + /// 商品扩展信息 + /// + public string Extended { get; set; } = string.Empty; + + /// + /// 订单最小数量 + /// + public int OrderMinimumQuantity { get; set; } + + /// + /// 订单最多数量 + /// + public int OrderMaximumQuantity { get; set; } + + /// + /// 是否允许退货 + /// + public bool AllowReturn { get; set; } + + /// + /// 是否允许换货 + /// + public bool AllowExchange { get; set; } + + /// + /// 是否独立发货 + /// + public bool SingleShip { get; set; } + + /// + /// 预计运输天数 + /// + public int ShippingDays { get; set; } + + /// + /// 运费模板ID + /// + public long ShippingId { get; set; } + + /// + /// 精选 + /// + public bool IsFeatured { get; set; } + + /// + /// 是否 best + /// + public bool IsBest { get; set; } + + /// + /// 是否标注新品 + /// + public bool IsNew { get; set; } + + /// + /// 排序 + /// + public int DisplayOrder { get; set; } + + /// + /// 暂停销售,前台处理成已售罄 + /// + public bool StopSales { get; set; } + + /// + /// 产品状态,0未上架,1上架 + /// + + public int Status { get; set; } + + /// + /// 产品信息审核状态 + /// + public int ReviewStatus { get; set; } + + /// + /// 禁用优惠券 + /// + public bool DisableCoupons { get; set; } + + /// + /// 产品属性 + /// + public List ProductSaleAttributes { get; set; } = new(); + + /// + /// 产品属性组合信息 + /// + public List ProductAttributeCombinations { get; set; } = new(); + + /// + /// 用来设置SKU属性图片的数据源 + /// + public List PhotoSalesAttribute { get; set; } = new(); + + /// + /// 是否编辑 + /// + public bool IsEdit { get; set; } = false; + + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductSKUPricesModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductSKUPricesModel.cs new file mode 100644 index 0000000..f19ea38 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductSKUPricesModel.cs @@ -0,0 +1,23 @@ +namespace Atomx.Admin.Client.Models +{ + /// + /// SKU价格 + /// + public class ProductSKUPricesModel + { + /// + /// SKU组合ID + /// + public long Id { get; set; } + + /// + /// 市场价 + /// + public decimal? MarketPrice { get; set; } + + /// + /// 销售价 + /// + public decimal? Price { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductSaleAttributeModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductSaleAttributeModel.cs new file mode 100644 index 0000000..1b7c8d4 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductSaleAttributeModel.cs @@ -0,0 +1,68 @@ +namespace Atomx.Admin.Client.Models +{ + /// + /// 产品销售属性模型 + /// + public class ProductSaleAttributeModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 属性ID + /// + public long AttributeId { get; set; } + + /// + /// 控件的类型 + /// + public int ControlType { get; set; } + + /// + /// 必须填重量 + /// + public bool WeightIsRequired { get; set; } + + /// + /// 属性名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 是否拥有规格图片 + /// + public bool Image { get; set; } + + /// + /// 属性排序 + /// + public int DisplayOrder { get; set; } + + /// + /// 产品属性值 + /// + public List ProductAttributeValues { get; set; } = new List(); + + /// + /// + /// + public string SelectOption { get; set; } = string.Empty; + + /// + /// 输入的新属性值 + /// + public string InputText { get; set; } = string.Empty; + + /// + /// 是否编辑状态 + /// + public bool AddAttribute { get; set; } + + /// + /// 是否是必须的属性 + /// + public bool IsRequired { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductSaleSpecificationAttributeModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductSaleSpecificationAttributeModel.cs new file mode 100644 index 0000000..b17ccd3 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductSaleSpecificationAttributeModel.cs @@ -0,0 +1,6 @@ +namespace Atomx.Admin.Client.Models +{ + public class ProductSaleSpecificationAttributeModel + { + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductSearch.cs new file mode 100644 index 0000000..ef8d2c3 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductSearch.cs @@ -0,0 +1,25 @@ +namespace Atomx.Admin.Client.Models +{ + public class ProductSearch : BaseSearch + { + /// + /// 产品标题 + /// + public string Title { get; set; } = string.Empty; + + /// + /// 分类ID + /// + public string CategoryId { get; set; } = string.Empty; + + /// + /// 产品状态 + /// + public string Status { get; set; } = string.Empty; + + /// + /// 开始时间 + /// + public DateTime?[] RangeTime { get; set; } = new DateTime?[] { null, null }; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductSkuModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductSkuModel.cs new file mode 100644 index 0000000..114e32d --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductSkuModel.cs @@ -0,0 +1,77 @@ +using Atomx.Utils.Extension; + +namespace Atomx.Admin.Client.Models +{ + /// + /// 产品SKU信息模型 + /// + public class ProductSkuModel : IEquatable + { + /// + /// 属性ID + /// + public long AttributeId { get; set; } + + /// + /// 属性名称 + /// + public string AttributeName { get; set; } = string.Empty; + + /// + /// 属性值ID + /// + public long ValueId { get; set; } + + /// + /// 属性值 Name + /// + public string ValueName { get; set; } = string.Empty; + + /// + /// 重量 + /// + public decimal Weight { get; set; } + + /// + /// 重量单位,1毫克mg,2克g,3千克kg,4吨t,5磅lb,6盎司oz + /// + public int WeightUnit { get; set; } + + public bool Equals(ProductSkuModel? other) + { + if (other is null) return false; + if (ValueId != other.ValueId) + { + return AttributeId == other.AttributeId && + ValueId == other.ValueId && + Weight.RemoveTrailingZeros() == other.Weight.RemoveTrailingZeros() && + WeightUnit == other.WeightUnit && + AttributeName == other.AttributeName && + ValueName == other.ValueName; + } + else + { + return AttributeId == other.AttributeId && + ValueId == other.ValueId && + AttributeName == other.AttributeName; + } + } + + public override bool Equals(object obj) => Equals(obj as ProductSkuModel); + + public override int GetHashCode() + { + unchecked + { + int hash = 17; + hash = hash * 23 + AttributeId.GetHashCode(); + hash = hash * 23 + ValueId.GetHashCode(); + hash = hash * 23 + Weight.GetHashCode(); + hash = hash * 23 + WeightUnit.GetHashCode(); + hash = hash * 23 + (AttributeName?.GetHashCode() ?? 0); + hash = hash * 23 + (ValueName?.GetHashCode() ?? 0); + return hash; + } + } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockAttributeModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockAttributeModel.cs new file mode 100644 index 0000000..db22f47 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockAttributeModel.cs @@ -0,0 +1,75 @@ +namespace Atomx.Admin.Client.Models +{ + public class ProductStockAttributeModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 属性ID + /// + public long AttributeId { get; set; } + + /// + /// 控件的类型 + /// + public int ControlType { get; set; } + + /// + /// 必须填重量 + /// + public bool WeightIsRequired { get; set; } + + /// + /// 重量单位,1毫克mg,2克g,3千克kg,4吨t,5磅lb,6盎司oz + /// + public int WeightUnit { get; set; } + + /// + /// 属性名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 是否拥有规格图片 + /// + public bool Image { get; set; } + + /// + /// 属性排序 + /// + public int DisplayOrder { get; set; } + + /// + /// 产品属性值 + /// + public List ProductAttributeValues { get; set; } = new List(); + + /// + /// 新产品属性值 + /// + public ProductAttributeValueModel AttributeValue { get; set; } = new ProductAttributeValueModel(); + + /// + /// + /// + public string SelectOption { get; set; } = string.Empty; + + /// + /// 输入的新属性值 + /// + public string InputText { get; set; } = string.Empty; + + /// + /// 是否编辑状态 + /// + public bool AddAttribute { get; set; } + + /// + /// 是否是必须的属性 + /// + public bool IsRequired { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockModel.cs new file mode 100644 index 0000000..0384179 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockModel.cs @@ -0,0 +1,32 @@ +using Atomx.Common.Entities; + +namespace Atomx.Admin.Client.Models +{ + public class ProductStockModel: ProductAttributeCombination + { + /// + /// 产品名称 + /// + public string Title { get; set; } = string.Empty; + + /// + /// 封面图片 + /// + public string? Image { get; set; } = string.Empty; + + /// + /// 产品SKU信息 + /// + public List Sku { get; set; } = new(); + + /// + /// 仓库ID + /// + public long WarehouseId { get; set; } + + /// + /// 添加库存 + /// + public int AddStockQuantity { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockUnitModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockUnitModel.cs new file mode 100644 index 0000000..be12c38 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockUnitModel.cs @@ -0,0 +1,22 @@ +using Atomx.Common.Entities; + +namespace Atomx.Admin.Client.Models +{ + /// + /// 产品SKU库存量模型 + /// + public class ProductStockUnitModel : ProductAttributeCombination + { + /// + /// 产品名称 + /// + public string Title { get; set; } = string.Empty; + + /// + /// 封面图片 + /// + public string? Image { get; set; } = string.Empty; + + public List Sku { get; set; } = new(); + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockUnitSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockUnitSearch.cs new file mode 100644 index 0000000..3f83b6e --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductStockUnitSearch.cs @@ -0,0 +1,23 @@ +namespace Atomx.Admin.Client.Models +{ + /// + /// 产品SKU库存量搜索模型 + /// + public class ProductStockUnitSearch : BaseSearch + { + /// + /// 产品ID + /// + public int Type { get; set; } + + /// + /// 产品名称 + /// + public string Key { get; set; } = string.Empty; + + /// + /// 重量 + /// + public decimal Weight { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/ProductTransferSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/ProductTransferSearch.cs new file mode 100644 index 0000000..9dd9503 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/ProductTransferSearch.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Atomx.Admin.Client.Models +{ + public class ProductTransferSearch : BaseSearch + { + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialBatchSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialBatchSearch.cs new file mode 100644 index 0000000..3313f07 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialBatchSearch.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Atomx.Admin.Client.Models +{ + public class RawMaterialBatchSearch : BaseSearch + { + /// + /// 原料类型ID + /// + public long MaterialId { get; set; } + + /// + /// 原料归属公司ID + /// + public long CorporationId { get; set; } + + /// + /// 原料归属店铺网点ID + /// + public long StoreId { get; set; } + } +} + \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialRecordSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialRecordSearch.cs new file mode 100644 index 0000000..091c882 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialRecordSearch.cs @@ -0,0 +1,20 @@ +namespace Atomx.Admin.Client.Models +{ + public class RawMaterialRecordSearch : BaseSearch + { + /// + /// 原料类型ID + /// + public long MaterialId { get; set; } + + /// + /// 原料归属公司ID + /// + public long CorporationId { get; set; } + + /// + /// 原料归属店铺网点ID + /// + public long StoreId { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialSearch.cs new file mode 100644 index 0000000..50ee780 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialSearch.cs @@ -0,0 +1,22 @@ +namespace Atomx.Admin.Client.Models +{ + public class RawMaterialSearch : BaseSearch + { + /// + /// 原料类型ID + /// + public long MaterialId { get; set; } + + /// + /// 原料归属公司ID + /// + public long CorporationId { get; set; } + + /// + /// 原料归属店铺网点ID + /// + public long StoreId { get; set; } + + + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialTransferSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialTransferSearch.cs new file mode 100644 index 0000000..0bbddcd --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/RawMaterialTransferSearch.cs @@ -0,0 +1,25 @@ +namespace Atomx.Admin.Client.Models +{ + public class RawMaterialTransferSearch : BaseSearch + { + /// + /// 原料类型ID + /// + public long MaterialId { get; set; } + + /// + /// 原料归属公司ID + /// + public long CorporationId { get; set; } + + /// + /// 原料归属店铺网点ID + /// + public long FromStoreId { get; set; } + + /// + /// 原料归属店铺网点ID + /// + public long ToStoreId { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/RoleModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/RoleModel.cs new file mode 100644 index 0000000..8e63892 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/RoleModel.cs @@ -0,0 +1,47 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace Atomx.Admin.Client.Models +{ + public class RoleModel + { + /// + /// 数据ID + /// + public int Id { get; set; } + + /// + /// 角色类型 + /// + public int Type { get; set; } + + /// + /// 角色名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 说明 + /// + public string Description { get; set; } = string.Empty; + + /// + /// 权限 + /// + public string Permission { get; set; } = string.Empty; + + /// + /// 是否系统角色 + /// + public bool IsSystemRole { get; set; } + + /// + /// 是否可用 + /// + public bool Enabled { get; set; } + + /// + /// 是否是编辑 + /// + public bool IsEdit { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/RolePermissionGroup.cs b/Atomx.Admin/Atomx.Admin.Client/Models/RolePermissionGroup.cs new file mode 100644 index 0000000..cbf593d --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/RolePermissionGroup.cs @@ -0,0 +1,11 @@ +namespace Atomx.Admin.Client.Models +{ + public class RolePermissionGroup + { + public string Category { get; set; } + + public string CategoryName { get; set; } + + public List PermissionItems { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/RolePermissionItem.cs b/Atomx.Admin/Atomx.Admin.Client/Models/RolePermissionItem.cs new file mode 100644 index 0000000..b91b11f --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/RolePermissionItem.cs @@ -0,0 +1,9 @@ +namespace Atomx.Admin.Client.Models +{ + public class RolePermissionItem + { + public string Name { get; set; } + public string Description { get; set; } + public bool IsSelected { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/RoleSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/RoleSearch.cs new file mode 100644 index 0000000..7e02acb --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/RoleSearch.cs @@ -0,0 +1,7 @@ +namespace Atomx.Admin.Client.Models +{ + public class RoleSearch + { + public string? Name { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/SiteAppModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/SiteAppModel.cs new file mode 100644 index 0000000..ac11c6a --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/SiteAppModel.cs @@ -0,0 +1,26 @@ +namespace Atomx.Admin.Client.Models +{ + public class SiteAppModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 网站应用类型 + /// + public int Type { get; set; } + + + /// + /// 网站应用名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 是否可用 + /// + public bool Enabled { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/SiteAppSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/SiteAppSearch.cs new file mode 100644 index 0000000..f671236 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/SiteAppSearch.cs @@ -0,0 +1,9 @@ +namespace Atomx.Admin.Client.Models +{ + public class SiteAppSearch : BaseSearch + { + public int? Type { get; set; } + + public string Name { get; set; } = string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeItemModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeItemModel.cs new file mode 100644 index 0000000..8fbe647 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeItemModel.cs @@ -0,0 +1,9 @@ +using Atomx.Common.Entities; + +namespace Atomx.Admin.Client.Models +{ + public class SpecificationAttributeItemModel:SpecificationAttribute + { + public string CategoryName { get; set; } = string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeModel.cs new file mode 100644 index 0000000..65c9d07 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeModel.cs @@ -0,0 +1,47 @@ +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace Atomx.Admin.Client.Models +{ + public class SpecificationAttributeModel + { + /// + /// 属性ID + /// + [DatabaseGenerated(DatabaseGeneratedOption.None)] + [Key] + public long Id { get; set; } + + /// + /// 上级属性,用于规格属性做分组 + /// + public long ParentId { get; set; } + + /// + /// 分类ID + /// + public long CategoryId { get; set; } + + /// + /// 属性名称 + /// + [Column(TypeName = "varchar(50)")] + + public string Name { get; set; } = string.Empty; + + /// + /// 属性控件类型,1选项,2文本 + /// + public int ControlType { get; set; } + + /// + /// 展示排序 + /// + public int DisplayOrder { get; set; } + + /// + /// 数据状态 + /// + public int Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeOptionModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeOptionModel.cs new file mode 100644 index 0000000..df1fef5 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeOptionModel.cs @@ -0,0 +1,47 @@ +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace Atomx.Admin.Client.Models +{ + public class SpecificationAttributeOptionModel + { + /// + /// 预设值ID + /// + [DatabaseGenerated(DatabaseGeneratedOption.None)] + [Key] + + public long Id { get; set; } + + /// + /// 供应商自定义值 + /// + public long VendorId { get; set; } + + /// + /// 产品属性ID + /// + public long SpecificationId { get; set; } + + /// + /// 预设值名称 + /// + [Column(TypeName = "varchar(50)")] + public string Value { get; set; } = string.Empty; + + /// + /// 展示排序 + /// + public int DisplayOrder { get; set; } + + /// + /// 是否通用的 + /// + public bool Standard { get; set; } + + /// + /// 数据状态 + /// + public int Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeOptionSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeOptionSearch.cs new file mode 100644 index 0000000..65b4d75 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeOptionSearch.cs @@ -0,0 +1,15 @@ +namespace Atomx.Admin.Client.Models +{ + public class SpecificationAttributeOptionSearch:BaseSearch + { + /// + /// 值 + /// + public string? Value { get; set; } + + /// + /// 规格ID + /// + public long SpecificationId { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeSearch.cs new file mode 100644 index 0000000..9f5a654 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/SpecificationAttributeSearch.cs @@ -0,0 +1,12 @@ +namespace Atomx.Admin.Client.Models +{ + public class SpecificationAttributeSearch : BaseSearch + { + /// + /// 名称 + /// + public string? Name { get; set; } + + public long CategoryId { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/StoreProductItemSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/StoreProductItemSearch.cs new file mode 100644 index 0000000..3e66944 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/StoreProductItemSearch.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Atomx.Admin.Client.Models +{ + public class StoreProductItemSearch + { + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/StoreSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/StoreSearch.cs new file mode 100644 index 0000000..ec9e56a --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/StoreSearch.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Atomx.Admin.Client.Models +{ + public class StoreSearch : BaseSearch + { + + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/UploadFileModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/UploadFileModel.cs new file mode 100644 index 0000000..4fee5b6 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/UploadFileModel.cs @@ -0,0 +1,42 @@ +namespace Atomx.Admin.Client.Models +{ + public class UploadFileModel + { + public long Id { get; set; } + + /// + /// 文件类型 + /// + public int Type { get; set; } + + /// + /// 文件名 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 存放路径 + /// + public string Path { get; set; } = string.Empty; + + /// + /// 文件扩展 + /// + public string Extension { get; set; } = string.Empty; + + /// + /// 文件扩展 + /// + public string ContentType { get; set; } = string.Empty; + + /// + /// 创建用户ID + /// + public long CreateUid { get; set; } + + /// + /// 创建用户名 + /// + public string CreateBy { get; set; } = string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/UploadFileSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/UploadFileSearch.cs new file mode 100644 index 0000000..b43651d --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/UploadFileSearch.cs @@ -0,0 +1,20 @@ +namespace Atomx.Admin.Client.Models +{ + public class UploadFileSearch : BaseSearch + { + /// + /// 文件类型 + /// + public int? Type { get; set; } + + /// + /// 名称 + /// + public string? Name { get; set; } + + /// + /// 开始时间 + /// + public DateTime?[] RangeTime { get; set; } = new DateTime?[] { null, null }; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/UserSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/UserSearch.cs new file mode 100644 index 0000000..415f3ab --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/UserSearch.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Atomx.Admin.Client.Models +{ + public class UserSearch : BaseSearch + { + /// + /// 用户名或昵称 + /// + public string? Username { get; set; } + + /// + /// 邮件地址 + /// + public string? Email { get; set; } + + /// + /// 手机号码 + /// + public string? Mobile { get; set; } + + /// + /// 真实姓名 + /// + public string? RealName { get; set; } + + /// + /// 开始时间 + /// + public DateTime?[] RangeTime { get; set; } = new DateTime?[] { null, null }; + + /// + /// 状态 + /// + public string? Status { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/WarehouseItemModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/WarehouseItemModel.cs new file mode 100644 index 0000000..012de5c --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/WarehouseItemModel.cs @@ -0,0 +1,12 @@ +using Atomx.Common.Entities; + +namespace Atomx.Admin.Client.Models +{ + public class WarehouseItemModel:Warehouse + { + /// + /// 公司名称 + /// + public string CorporationName { get; set; } = string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/WarehouseModel.cs b/Atomx.Admin/Atomx.Admin.Client/Models/WarehouseModel.cs new file mode 100644 index 0000000..8ee100c --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/WarehouseModel.cs @@ -0,0 +1,28 @@ +namespace Atomx.Admin.Client.Models +{ + /// + /// 仓库模型 + /// + public class WarehouseModel + { + /// + /// 数据ID + /// + public long Id { get; set; } + + /// + /// 归属公司ID + /// + public long CorporationId { get; set; } + + /// + /// 分类名称 + /// + public string Name { get; set; } = string.Empty; + + /// + /// 是否可用 + /// + public bool Enabled { get; set; } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Models/WarehouseSearch.cs b/Atomx.Admin/Atomx.Admin.Client/Models/WarehouseSearch.cs new file mode 100644 index 0000000..7fcd66c --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Models/WarehouseSearch.cs @@ -0,0 +1,20 @@ +namespace Atomx.Admin.Client.Models +{ + public class WarehouseSearch : BaseSearch + { + /// + /// 仓库名称 + /// + public string? Name { get; set; } = string.Empty; + + /// + /// 企业ID + /// + public long CorporationId { get; set; } = 0; + + /// + /// 企业名称 + /// + public string CorporationName { get; set; } = string.Empty; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/ContentEdit.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/ContentEdit.razor new file mode 100644 index 0000000..9d66945 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/ContentEdit.razor @@ -0,0 +1,5 @@ +

ContentEdit

+ +@code { + +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/ContentList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/ContentList.razor new file mode 100644 index 0000000..071d3be --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/ContentList.razor @@ -0,0 +1,7 @@ +@page "/content/list" + +

ContentList

+ +@code { + +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/PageEdit.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/PageEdit.razor new file mode 100644 index 0000000..18a25c3 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/PageEdit.razor @@ -0,0 +1,5 @@ +

PageEdit

+ +@code { + +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/PageList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/PageList.razor new file mode 100644 index 0000000..d2addaa --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Contents/PageList.razor @@ -0,0 +1,8 @@ +@page "/content/page/list" + + +

PageList

+ +@code { + +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Counter.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Counter.razor new file mode 100644 index 0000000..ef23cb3 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Counter.razor @@ -0,0 +1,18 @@ +@page "/counter" + +Counter + +

Counter

+ +

Current count: @currentCount

+ + + +@code { + private int currentCount = 0; + + private void IncrementCount() + { + currentCount++; + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Home.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Home.razor new file mode 100644 index 0000000..3a8532b --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Home.razor @@ -0,0 +1,24 @@ +@page "/" +@attribute [Authorize] + +Home + +

Hello, world!

+ +Welcome to your new app. + +
  • + 产品分类 +
  • +
  • + 产品分类编辑 +
  • +
  • + 多语言设置 +
  • +
  • + 多语言资源设置 +
  • +
  • + 角色管理 +
  • \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Login.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Login.razor new file mode 100644 index 0000000..64a6bbd --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Login.razor @@ -0,0 +1,140 @@ +@page "/account/login" +@layout EmptyLayout +@inject ILogger Logger + + +登录 + +@if (!dataLoaded) +{ + +} +else +{ + + + + +
    + + + + + + + + + + + + + + 忘记密码 + + + 马上注册 + + + + + + +
    +
    +
    + + Copyright © 2025-@DateTime.Now.Year Atomx.cn All rights reserved. + runing as @handler + +
    +} + + +@code { + string handler = "Server"; + + [Parameter] + [SupplyParameterFromQuery(Name = "ReturnUrl")] + public string? ReturnUrl { get; set; } + + [SupplyParameterFromForm] + public LoginModel login { get; set; } = new(); + private Form form = null!; + + bool dataLoaded = false; + + string message { get; set; } = string.Empty; + + private bool _isLoading = false; + + + protected override void OnInitialized() + { + if (OperatingSystem.IsBrowser()) + { + handler = "Wasm"; + } + else + { + handler = "Server"; + } + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + var authState = await AuthStateProvider.GetAuthenticationStateAsync(); + if (authState.User.Identity != null) + { + if (authState.User.Identity.IsAuthenticated) + { + Navigation.NavigateTo(ReturnUrl ?? "/"); + } + } + } + if (!dataLoaded) + { + dataLoaded = true; + StateHasChanged(); + } + } + + private async Task LoginAsync() + { + if (form.Validate()) + { + var api = "/api/sign/in"; + var result = await HttpService.Post>(api, login); + if (result.Success) + { + Console.WriteLine("请求api成功"); + if (!string.IsNullOrEmpty(result.Data)) + { + await localStorage.SetItemAsStringAsync(StorageKeys.JWTTokenKeyName, result.Data); + await localStorage.SetItemAsStringAsync("refreshToken", result.Data); + var authState = (AuthStateProvider as PersistentAuthenticationStateProvider); + if (authState != null) + { + authState.UpdateAuthenticationState(result.Data); + } + Logger.LogInformation($"登录成功跳转目标,{ReturnUrl}"); + Navigation.NavigateTo(ReturnUrl ?? "/"); + } + } + else + { + ModalService.Error(new ConfirmOptions() { Title = "提示", Content = result.Message }); + } + } + + } + + private async Task OnPasswordKeyDown(KeyboardEventArgs value) + { + if (value.Key == "Enter") + { + await LoginAsync(); + } + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Logout.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Logout.razor new file mode 100644 index 0000000..fc075be --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Logout.razor @@ -0,0 +1,11 @@ +@page "/logout" +@layout EmptyLayout + +@code { + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await ((PersistentAuthenticationStateProvider)AuthStateProvider).MarkUserAsLoggedOut(); + Navigation.NavigateTo("/account/login"); + await base.OnAfterRenderAsync(firstRender); + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Orders/OrderList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Orders/OrderList.razor new file mode 100644 index 0000000..4a7cfe9 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Orders/OrderList.razor @@ -0,0 +1,5 @@ +

    OrderList

    + +@code { + +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Orders/OrderView.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Orders/OrderView.razor new file mode 100644 index 0000000..d6b7f09 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Orders/OrderView.razor @@ -0,0 +1,7 @@ +@page "/orders/view/{OrderId:long}" + +

    OrderView

    + +@code { + +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Products/CategoryEdit.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/CategoryEdit.razor new file mode 100644 index 0000000..b9e96bf --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/CategoryEdit.razor @@ -0,0 +1,137 @@ +@page "/product/category/edit" +@page "/product/category/edit/{Id:long?}" + +@inject ILogger Logger +@* @attribute [Authorize] *@ + +分类编辑 +分类信息 + + + +
    + @* @if (languages.Count > 1 && Id > 0) + { + + + + 标准 + + + @foreach (var item in languages) + { + + + @item.Name @item.Id.ToString() + + + } + + } + + + + + @foreach (var item in categories) + { + + } + + + + + + + + + + + + *@ + + + + + + + + + + + 启用 + + + + +
    +
    +
    + +@code { + [SupplyParameterFromQuery] + int? Lang { get; set; } + + [Parameter] + public long? Id { get; set; } + + [SupplyParameterFromForm] + CategoryModel model { get; set; } = new(); + Form editform = null!; + + bool pageLoading = true; + List Categories = new(); + + protected override void OnInitialized() + { + base.OnInitialized(); + } + + protected override async Task OnParametersSetAsync() + { + pageLoading = true; + // await LoadCategories(); + // if (Id > 0) + // { + // await LoadData(); + // await SearchAttribute(string.Empty); + // } + // else + // { + // editCategory = true; + // CategoryPath = string.Empty; + // } + // if (Categories.Any()) + // { + // BindCategory(); + // } + pageLoading = false; + base.OnParametersSet(); + } + + async Task LoadCategories() + { + var url = $"/api/category/items"; + var apiResult = await HttpService.Get>>(url); + if (apiResult.Success) + { + Categories = apiResult.Data ?? new(); + } + } + + async void OnFormFinishAsync() + { + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Products/CategoryList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/CategoryList.razor new file mode 100644 index 0000000..f169d83 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/CategoryList.razor @@ -0,0 +1,336 @@ +@page "/category/list" + +@inject ILogger Logger +@attribute [Authorize] + +分类管理 +菜单管理 + +
    + + + + + + + + +
    + + +
    + +
    +
    +
    + + + + + 菜单列表 +
    + +
    + +
    +
    + + + @GetName(context) + + + + + + + @if (context.Enabled) + { + + + } + else + { + + } + + + + + @if (context.IsLast) + { + + 属性 + + + + 规格 + + + } + + + + + + + + 编辑 + + + + + 删除 + + + + + + + + + + + + + + +
    +
    + + +
    + + + + + + + + + + + + + + + 启用 + + + + + +
    + +@code { + + + + [SupplyParameterFromQuery] + int? Page { get; set; } + + [SupplyParameterFromForm] + CategorySearch search { get; set; } = new(); + Form searchForm = null!; + + [SupplyParameterFromForm] + CategoryModel model { get; set; } = new(); + Form editform = null!; + + List categories = new(); + + bool drawerVisible; + + protected override void OnParametersSet() + { + loadQueryString(); + LoadList(); + + base.OnParametersSet(); + } + + void loadQueryString() + { + var uri = new Uri(Navigation.Uri); + var query = uri.Query; + search.Name = query.GetQueryString("Name"); + } + + private async void LoadList() + { + var url = "/api/category/list"; + var apiResult = await HttpService.Get>>(url); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + categories = apiResult.Data; + StateHasChanged(); + } + } + } + + void OnSearchFinish() + { + Page = Page.GetValueOrDefault(1) - 1; + + OnSearch(Page.Value); + } + + void OnSearchReset() + { + search = new(); + searchForm?.Reset(); + OnSearchFinish(); + } + + private void OnReset() + { + search = new(); + LoadList(); + + } + + private void OnSearch(int page) + { + var queryString = search.BuildQueryString(); + if (string.IsNullOrEmpty(queryString)) + { + if (page > 1) + { + Navigation.NavigateTo($"/category/list?page={page}"); + } + else + { + Navigation.NavigateTo($"/category/list"); + } + } + else + { + if (page > 1) + { + Navigation.NavigateTo($"/category/list?page={page}&{queryString}"); + } + else + { + Navigation.NavigateTo($"/category/list?{queryString}"); + } + } + LoadList(); + } + + + async Task HandleDeleteConfirmAsync(MouseEventArgs e, long id) + { + + var url = $"/api/category/delete/{id}"; + var apiResult = await HttpService.Post>(url, new()); + if (apiResult.Success) + { + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" }); + } + } + + void OnEditClick(CategoryItem item) + { + this.model = item.Adapt(); + drawerVisible = true; + } + + async Task OnFormFinish() + { + if (editform.Validate()) + { + var result = new ApiResult(); + var data = model.Adapt(); + if (model.Id > 0) + { + var url = $"api/category/edit"; + result = await HttpService.Post>(url, data); + } + else + { + var url = $"api/category/add"; + result = await HttpService.Post>(url, data); + } + + if (result.Code == (int)ResultCode.Success) + { + + CloseDrawer(); + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "服务异常", Content = result.Message }); + } + } + } + + private string GetPath(string path) + { + var array = path.Split(",").ToList(); + var pathText = string.Empty; + foreach (var item in array) + { + var name = categories.Where(p => p.Id == item.ToLong()).Select(p => p.Name).SingleOrDefault(); + if (string.IsNullOrEmpty(pathText)) + { + pathText = name; + } + else + { + pathText = $"{pathText}>{name}"; + } + } + return pathText; + } + + private string GetName(CategoryItem menu) + { + string name = string.Empty; + if (menu.Depth > 0) + { + var symbol = " "; + for (var i = 0; i < menu.Depth; i++) + { + symbol = $"{symbol}{symbol}"; + } + name = $"{symbol}├ {menu.Name}"; + } + else + { + name = menu.Name; + } + return name; + } + + void OnCreateClick() + { + model = new CategoryModel(); + drawerVisible = true; + } + + void CloseDrawer() + { + drawerVisible = false; + editform.Reset(); + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Products/GoodsList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/GoodsList.razor new file mode 100644 index 0000000..6e162c2 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/GoodsList.razor @@ -0,0 +1,5 @@ +

    GoodsList

    + +@code { + +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Products/PredefinedAttributeList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/PredefinedAttributeList.razor new file mode 100644 index 0000000..1633a9b --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/PredefinedAttributeList.razor @@ -0,0 +1,290 @@ +@page "/attribute/predefined/list/{AttributeId:long}" + +@inject ILogger Logger +@attribute [Authorize] + + +产品属性管理 +属性列表 + +
    + + + + + + + + +
    + + +
    + +
    +
    +
    + + + + + + @productAttribute.Name 属性预设值列表 +
    + +
    +
    +
    + + + + + @if (context.Status == 1) + { + + + } + else + { + + } + + + + + + 编辑 + + + + 删除 + + + + + +
    +
    + + + +
    + + +
    + + + + + + + + + + 启用 + 禁用 + + + + + + +
    + +@code { + [Parameter] + public long AttributeId { get; set; } + + [SupplyParameterFromQuery] + int? Page { get; set; } + + [SupplyParameterFromQuery(Name = "size")] + int? PageSize { get; set; } + + [SupplyParameterFromForm] + ProductAttributeOptionSearch search { get; set; } = new(); + Form searchForm = null!; + + [SupplyParameterFromForm] + ProductAttributeOptionModel model { get; set; } = new(); + Form editform = null!; + + ProductAttribute productAttribute = new(); + PagingList PagingList = new(); + bool loading { get; set; } = true; + bool searchExpand { get; set; } = false; + + + bool drawerVisible; + + protected override void OnInitialized() + { + base.OnInitialized(); + } + + protected override void OnParametersSet() + { + + loadQueryString(); + LoadList(); + LoadAttribute(); + base.OnParametersSet(); + } + + void loadQueryString() + { + var uri = new Uri(Navigation.Uri); + var query = uri.Query; + search.Value = query.GetQueryString("Value"); + } + + private async void LoadAttribute() + { + var url = $"/api/productattribute/{AttributeId}"; + var apiResult = await HttpService.Get>(url); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + productAttribute = apiResult.Data; + } + } + } + + + private async void LoadList() + { + + loading = true; + var url = "/api/productattributeoption/search"; + var apiResult = await HttpService.GetPagingList(url, search, Page.GetValueOrDefault(1), PageSize.GetValueOrDefault(20)); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + PagingList = apiResult.Data; + } + } + loading = false; + StateHasChanged(); + } + + + void OnSearchFinish() + { + Page = Page.GetValueOrDefault(1) - 1; + + OnSearch(Page.Value); + } + + + private void OnSearchReset() + { + search = new(); + LoadList(); + } + + private void OnSearch(int page) + { + var queryString = search.BuildQueryString(); + if (string.IsNullOrEmpty(queryString)) + { + if (page > 1) + { + Navigation.NavigateTo($"/attribute/predefined/list/{AttributeId}?page={page}"); + } + else + { + Navigation.NavigateTo($"/attribute/predefined/list/{AttributeId}"); + } + } + else + { + if (page > 1) + { + Navigation.NavigateTo($"/attribute/predefined/list/{AttributeId}?page={page}&{queryString}"); + } + else + { + Navigation.NavigateTo($"/attribute/predefined/list/{AttributeId}?{queryString}"); + } + } + } + + void OnPageChanged(PaginationEventArgs args) + { + OnSearch(args.Page); + } + + + + + async Task HandleDeleteConfirmAsync(MouseEventArgs e, long id) + { + + var url = $"/api/productattributeoption/delete/{model.Id}"; + var apiResult = await HttpService.Post>(url, new()); + if (apiResult.Success) + { + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" }); + } + } + + async Task OnFormFinish() + { + if (editform.Validate()) + { + + var result = new ApiResult(); + if (model.Id > 0) + { + var url = $"api/productattributeoption/edit"; + result = await HttpService.Post>(url, model); + } + else + { + var url = $"api/productattributeoption/add"; + result = await HttpService.Post>(url, model); + } + + if (result.Code == (int)ResultCode.Success) + { + + CloseDrawer(); + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "服务异常", Content = result.Message }); + } + } + } + + + void OnEditClick(ProductAttributeOption option) + { + this.model = option.Adapt(); + drawerVisible = true; + } + + void OnCreateClick() + { + model = new(); + drawerVisible = true; + } + + private void CloseDrawer() + { + drawerVisible = false; + editform.Reset(); + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Products/PredefinedSpecificationList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/PredefinedSpecificationList.razor new file mode 100644 index 0000000..5c2c0f1 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/PredefinedSpecificationList.razor @@ -0,0 +1,325 @@ +@page "/specification/predefined/list/{SpecificationId:long}" + +@inject ILogger Logger +@attribute [Authorize] + + +产品规格管理 + +属性列表 + +
    + + + + + + + + +
    + + +
    + +
    +
    +
    + + + + + + @specificationAttribute.Name 属性列表 +
    + +
    +
    +
    + + + + + @if (context.Status == 1) + { + + + } + else + { + + } + + + + + + 编辑 + + + + 删除 + + + + + +
    +
    + + + +
    + + +
    + + + + + + + + + + + 启用 + 禁用 + + + + + + +
    + +@code { + [Parameter] + public long SpecificationId { get; set; } + + [SupplyParameterFromQuery] + int? Page { get; set; } + + [SupplyParameterFromQuery(Name = "size")] + int? PageSize { get; set; } + + [SupplyParameterFromForm] + SpecificationAttributeOptionSearch search { get; set; } = new(); + Form searchForm = null!; + + [SupplyParameterFromForm] + SpecificationAttributeOptionModel model { get; set; } = new(); + Form editform = null!; + + SpecificationAttribute specificationAttribute = new(); + PagingList PagingList = new(); + bool loading { get; set; } = true; + bool searchExpand { get; set; } = false; + private bool drawerVisible; + + SpecificationAttributeOptionModelValidator validator = new(); + + protected override void OnInitialized() + { + base.OnInitialized(); + } + + protected override void OnParametersSet() + { + + loadQueryString(); + LoadList(); + LoadSpecification(); + base.OnParametersSet(); + } + + void loadQueryString() + { + var uri = new Uri(Navigation.Uri); + var query = uri.Query; + search.Value = query.GetQueryString("Value"); + } + + + private async void LoadList() + { + + loading = true; + var url = "/api/specificationattributeoption/search"; + var apiResult = await HttpService.GetPagingList(url, search, Page.GetValueOrDefault(1), PageSize.GetValueOrDefault(20)); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + PagingList = apiResult.Data; + } + } + loading = false; + StateHasChanged(); + } + + private async void LoadSpecification() + { + var url = $"/api/specificationattribute/{SpecificationId}"; + var apiResult = await HttpService.Get>(url); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + specificationAttribute = apiResult.Data; + } + } + } + + + void OnSearchFinish() + { + Page = Page.GetValueOrDefault(1) - 1; + + OnSearch(Page.Value); + } + + + private void OnSearchReset() + { + search = new(); + LoadList(); + } + + private void OnSearch(int page) + { + var queryString = search.BuildQueryString(); + if (string.IsNullOrEmpty(queryString)) + { + if (page > 1) + { + Navigation.NavigateTo($"/specification/predefined/list/{SpecificationId}?page={page}"); + } + else + { + Navigation.NavigateTo($"/specification/predefined/list/{SpecificationId}"); + } + } + else + { + if (page > 1) + { + Navigation.NavigateTo($"/specification/predefined/list/{SpecificationId}?page={page}&{queryString}"); + } + else + { + Navigation.NavigateTo($"/specification/predefined/list/{SpecificationId}?{queryString}"); + } + } + // LoadList(); + } + + void OnPageChanged(PaginationEventArgs args) + { + + var queryString = search.BuildQueryString(); + if (string.IsNullOrEmpty(queryString)) + { + Navigation.NavigateTo($"/attribute/list?page={args.Page}"); + } + else + { + Navigation.NavigateTo($"/attribute/list?page={Page}&{queryString}"); + } + } + + + + + + async Task HandleDeleteConfirmAsync(MouseEventArgs e, long id) + { + + var url = $"/api/specificationattributeoption/delete/{model.Id}"; + var apiResult = await HttpService.Post>(url, new()); + if (apiResult.Success) + { + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" }); + } + } + + async Task OnFormFinish() + { + model.SpecificationId = SpecificationId; + if (editform.Validate()) + { + + + var result = new ApiResult(); + if (model.Id > 0) + { + var url = $"api/specificationattributeoption/edit"; + result = await HttpService.Post>(url, model); + } + else + { + var url = $"api/specificationattributeoption/add"; + result = await HttpService.Post>(url, model); + } + + if (result.Code == (int)ResultCode.Success) + { + + CloseDrawer(); + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "服务异常", Content = result.Message }); + } + } + } + + private void OnPageChanged(int args) + { + OnSearch(args); + } + + private bool _editDrawerOpen; + + private void OpenDrawer() + { + model = new(); + _editDrawerOpen = true; + } + + void OnEditClick(SpecificationAttributeOption item) + { + this.model = item.Adapt(); + drawerVisible = true; + } + + void OnDrawerOverlayClick(bool state) + { + if (!state) + { + model = new(); + _editDrawerOpen = state; + } + } + + void OnCreateClick() + { + drawerVisible = true; + } + + void CloseDrawer() + { + drawerVisible = false; + editform.Reset(); + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductAttributeList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductAttributeList.razor new file mode 100644 index 0000000..ae00267 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductAttributeList.razor @@ -0,0 +1,339 @@ +@page "/attribute/list" + +@rendermode InteractiveAuto +@inject ILogger Logger +@inject HttpService HttpService +@attribute [Authorize] + + +产品属性管理 + +属性列表 + +
    + + + + + + + + +
    + + +
    + +
    +
    +
    + + + + + + 属性列表 +
    + +
    +
    +
    + + + + @if (context.ControlType == 1) + { + 选项 + } + else + { + 文本框 + } + + + + @if (context.WeightIsRequired) + { + 必填 + } + + + @if (context.IsRequired) + { + 必选 + } + + + + @if (context.Status == 1) + { + + + } + else + { + + } + + + + + + 预设值 + + + 编辑 + + + + 删除 + + + + + +
    +
    + + + +
    + + +
    + + + + + + + + 默认(文本) + 选项 + + + + 必填 + + + 默认属性 + + + + 启用 + 禁用 + + + + + + +
    + +@code { + [SupplyParameterFromQuery] + int? Page { get; set; } + + [SupplyParameterFromQuery] + long CategoryId { get; set; } + + [SupplyParameterFromQuery(Name = "size")] + int? PageSize { get; set; } + + [SupplyParameterFromForm] + ProductAttributeSearch search { get; set; } = new(); + Form searchForm = null!; + + [SupplyParameterFromForm] + ProductAttributeModel model { get; set; } = new(); + Form editform = null!; + + PagingList PagingList = new(); + bool loading { get; set; } = true; + bool searchExpand { get; set; } = false; + private bool drawerVisible; + + protected override void OnInitialized() + { + base.OnInitialized(); + } + + protected override void OnParametersSet() + { + + loadQueryString(); + LoadList(); + model.CategoryId = CategoryId; + base.OnParametersSet(); + } + + void loadQueryString() + { + var uri = new Uri(Navigation.Uri); + var query = uri.Query; + search.Name = query.GetQueryString("Name"); + search.CategoryId = CategoryId; + } + + + private async void LoadList() + { + + loading = true; + var url = "/api/productattribute/search"; + var apiResult = await HttpService.GetPagingList(url, search, Page.GetValueOrDefault(1), PageSize.GetValueOrDefault(20)); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + PagingList = apiResult.Data; + } + } + loading = false; + StateHasChanged(); + } + + void OnSearchFinish() + { + Page = Page.GetValueOrDefault(1) - 1; + + OnSearch(Page.Value); + } + + + private void OnSearchReset() + { + search = new(); + LoadList(); + } + + private void OnReset() + { + search = new(); + LoadList(); + } + + private void OnSearch(int page) + { + var queryString = search.BuildQueryString(); + if (string.IsNullOrEmpty(queryString)) + { + if (page > 1) + { + Navigation.NavigateTo($"/attribute/list?page={page}"); + } + else + { + Navigation.NavigateTo($"/attribute/list"); + } + } + else + { + if (page > 1) + { + Navigation.NavigateTo($"/attribute/list?page={page}&{queryString}"); + } + else + { + Navigation.NavigateTo($"/attribute/list?{queryString}"); + } + } + } + + void OnPageChanged(PaginationEventArgs args) + { + + var queryString = search.BuildQueryString(); + if (string.IsNullOrEmpty(queryString)) + { + Navigation.NavigateTo($"/attribute/list?page={args.Page}"); + } + else + { + Navigation.NavigateTo($"/attribute/list?page={Page}&{queryString}"); + } + } + + + void OnEditClick(ProductAttribute productAttribute) + { + this.model = productAttribute.Adapt(); + drawerVisible = true; + } + + async Task HandleDeleteConfirmAsync(MouseEventArgs e, long id) + { + var url = $"/api/productattribute/delete/{id}"; + var apiResult = await HttpService.Post>(url, new()); + if (apiResult.Success) + { + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" }); + } + } + + async Task OnFormFinish() + { + Console.WriteLine("run on from finish "); + if (CategoryId > 0) + { + model.CategoryId = CategoryId; + } + + if (editform.Validate()) + { + var result = new ApiResult(); + if (model.Id > 0) + { + var url = $"api/productattribute/edit"; + result = await HttpService.Post>(url, model); + } + else + { + var url = $"api/productattribute/add"; + result = await HttpService.Post>(url, model); + } + + if (result.Code == (int)ResultCode.Success) + { + + CloseDrawer(); + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "服务异常", Content = result.Message }); + } + } + } + + private void OnPageChanged(int args) + { + OnSearch(args); + } + + + void OnCreateClick() + { + drawerVisible = true; + } + + void CloseDrawer() + { + drawerVisible = false; + editform.Reset(); + } + + void OnViewPredefinedListClick(long id) + { + Navigation.NavigateTo($"/attribute/Predefined/list/{id}"); + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductEdit.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductEdit.razor new file mode 100644 index 0000000..46c40a5 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductEdit.razor @@ -0,0 +1,1201 @@ +@page "/product/create" +@page "/product/edit/{id:long?}" + +@inject ILogger Logger +@attribute [Authorize] + +编辑产品 + + 编辑产品信息 + +
    + + + 商品类目 + + + 标题内容需包含商品名称,建议添加材质、功能、特征或商品描述 + + + + + + @if (editCategory) + { + + + + @if (showLevel2Category) + { + + } + @if (showLevel3Category) + { + + } + @if (showLevel4Category) + { + + } + + + + + + } + else + { + + @CategoryPath + + + + + + + + + + + + + + @if (model.ProductSaleAttributes.Count > 0) + { + + @foreach (var item in model.ProductSaleAttributes) + { + if (item.AttributeId > 0) + { + + + + + @item.Name@item.DisplayOrder + + + + + @if (!item.IsRequired) + { + + } + + + + @foreach (var value in item.ProductAttributeValues) + { + @if (item.ControlType == 0) + { + @if (value.IsEdit) + { + + + @if (CurrentProductAttribute.WeightIsRequired) + { + + @GetWeightUnit(CurrentProductAttribute.WeightUnit) + + } + + + + } + else + { + + + @if (item.WeightIsRequired) + { + + + + } + @value.DisplayOrder + + + + + + + + } + } + else + { + + } + } + @if (item.AddAttribute) + { + + + @if (CurrentProductAttribute.WeightIsRequired) + { + + @GetWeightUnit(CurrentProductAttribute.WeightUnit) + + } + + + + } + else + { + + + + } + + + + } + else + { + + + + + + + + + + + + + + + + + + + + } + } + + } + @if (model.ProductSaleAttributes.Count < 3) + { + + + + } + + @if (ProductAttributeCombinationsForEdit.Count() > 0) + { + +
    + + + @foreach (var item in model.ProductSaleAttributes) + { + + } + + + + + + + + + @foreach (var item in model.ProductSaleAttributes) + { + if (item.ProductAttributeValues.Any()) + { + + } + } + + + + + + + + + + @foreach (var item in ProductAttributeCombinationsForEdit) + { + + @foreach (var sku in item.SkuAttributes) + { + + + } + + + + + + + + } + +
    + @item.Name + 上架市场价销售价库存规格编码
    + @sku.ValueName + @if (sku.Weight > 0) + { + (@($"{sku.Weight}{@GetWeightUnit(sku.WeightUnit)}")) + } + + + + + + + + + + +
    +
    +
    + } + + + + + + 发布 + 保存草稿 + + + + + + } + + +
    +
    + +@code { + [Parameter] + public long Id { get; set; } + + /// + /// 产品表单model + /// + [SupplyParameterFromForm] + ProductModel model { get; set; } = new(); + Form editForm = null!; + + /// + /// 分类下可用的产品属性集 + /// + List productAttributes = new(); + /// + /// 当前编辑中的产品属性 + /// + ProductAttribute CurrentProductAttribute = new(); + + bool editCategory; + bool loading = false; + + /// + /// 当前编辑中的属性值对象 + /// + ProductAttributeValueModel editAttributeValue = new(); + + /// + /// 分类信息 + /// + List Categories = new(); + CategoryItem? Category = new(); + List Level1Categories = new(); + long level1CategoryId; + List Level2Categories = new(); + long level2CategoryId; + bool showLevel2Category; + List Level3Categories = new(); + long level3CategoryId; + bool showLevel3Category; + List Level4Categories = new(); + long level4CategoryId; + bool showLevel4Category; + + + string CategoryPath = string.Empty; + + ProductSaleAttributeModel editAttribute = new(); + List attributeOptions = new(); + + List SpecificationAttributes = new(); //分类规则属性 + + /// + /// 编辑的属性组合SKU信息 + /// + List ProductAttributeCombinationsForEdit = new(); + + + protected override void OnInitialized() + { + base.OnInitialized(); + } + + protected override async Task OnParametersSetAsync() + { + loading = true; + await LoadCategories(); + if (Id > 0) + { + await LoadData(); + await SearchAttribute(string.Empty); + } + else + { + editCategory = true; + CategoryPath = string.Empty; + } + if (Categories.Any()) + { + BindCategory(); + } + loading = false; + base.OnParametersSet(); + } + + + + async Task LoadData() + { + var url = $"/api/product/detail/{Id}"; + var apiResult = await HttpService.Get>(url); + if (apiResult.Success) + { + if (apiResult.Data == null) + { + Navigation.NavigateTo($"/product/list"); + } + else + { + model = apiResult.Data.Adapt(); + model.IsEdit = true; + RebuildSkuCombinations(); + } + } + else + { + Navigation.NavigateTo($"/product/list"); + } + + StateHasChanged(); + } + + + async void OnFormFinish() + { + if (editForm.Validate()) + { + + var result = new ApiResult(); + model.ProductAttributeCombinations = ProductAttributeCombinationsForEdit; + + Console.WriteLine("提交数据:"); + Console.WriteLine(model.ToJson()); + + if (model.Id > 0) + { + var url = $"api/product/edit"; + result = await HttpService.Post>(url, model); + } + else + { + var url = $"api/product/add"; + result = await HttpService.Post>(url, model); + } + + if (result.Code == (int)ResultCode.Success) + { + await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "数据提交成功" }); + Navigation.NavigateTo($"/product/list"); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = result.Message }); + } + } + } + + void OnClickEditCategory() + { + ModalService.Confirm(new ConfirmOptions() + { + + Title = "操作提示", + Content = "修改类目可能会导致部分内容丢失,确认修改?", + OkText = "修改类目", + OnOk = (e) => { editCategory = true; CategoryPath = string.Empty; StateHasChanged(); return Task.CompletedTask; }, + CancelText = "取消" + }); + } + + void OnAddAttributeClick() + { + int count = model.ProductSaleAttributes.Count(); + model.ProductSaleAttributes.Add(new ProductSaleAttributeModel() { DisplayOrder = count + 1 }); + } + + async Task SearchAttribute(string value) + { + ProductAttributeSearch attributeSearch = new() + { + Name = value, + CategoryId = model.CategoryId + }; + + var url = $"/api/productattribute/search"; + var apiResult = await HttpService.GetPagingList(url, attributeSearch, 1, 50); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + productAttributes = apiResult.Data.Items; + + if (Id == 0) + { + + var requiredAttributes = productAttributes.Where(p => p.IsRequired).ToList(); + foreach (var item in requiredAttributes) + { + + var attribute = new ProductSaleAttributeModel() + { + AttributeId = item.Id, + Name = item.Name, + ControlType = item.ControlType, + WeightIsRequired = item.WeightIsRequired, + IsRequired = item.IsRequired + }; + + model.ProductSaleAttributes.Add(attribute); + } + } + return; + } + } + productAttributes = new List(); + } + + /// + /// 在Select中选中了要添加的属性对象 + /// + /// + /// + void ProductAttributeChanged(AutoCompleteOption item, ProductSaleAttributeModel saleAttributeModel) + { + Console.WriteLine($"选中了{item.Value}"); + var id = (long)item.Value; + var attribute = productAttributes.FirstOrDefault(x => x.Id == id); + if (attribute != null) + { + if (model.ProductSaleAttributes.Any(x => x.AttributeId == attribute.Id)) + { + ModalService.Info(new ConfirmOptions() { Title = "提示", Content = "该属性已经添加过了" }); + return; + } + + saleAttributeModel.AttributeId = attribute.Id; + saleAttributeModel.Name = attribute.Name; + saleAttributeModel.ControlType = attribute.ControlType; + saleAttributeModel.WeightIsRequired = attribute.WeightIsRequired; + saleAttributeModel.IsRequired = attribute.IsRequired; + } + StateHasChanged(); + } + + /// + /// 点击添加属性值按钮 + /// + /// + void OnClickAddAttributeValue(ProductSaleAttributeModel attribute) + { + foreach (var item in model.ProductSaleAttributes) + { + Console.WriteLine(item.ToJson()); + Console.WriteLine(attribute.ToJson()); + if (item.AttributeId == attribute.AttributeId) + { + attribute.AddAttribute = true; + editAttribute = attribute; + CurrentProductAttribute = productAttributes.FirstOrDefault(x => x.Id == attribute.AttributeId); + } + else + { + item.AddAttribute = false; + } + } + StateHasChanged(); + } + + void OnClickEditAttributeValue(ProductSaleAttributeModel attribute, ProductAttributeValueModel value) + { + value.IsEdit = true; + attribute.AddAttribute = false; + CurrentProductAttribute = productAttributes.FirstOrDefault(x => x.Id == attribute.AttributeId); + editAttributeValue = value; + Console.WriteLine($"编辑属性值:{value.ToJson()}"); + Console.WriteLine($"编辑属性值:{editAttributeValue.ToJson()}"); + } + + /// + /// 保存新的属性值 + /// + /// + /// + void OnClickEditAttributeValueForSave(ProductSaleAttributeModel attribute, ProductAttributeValueModel value) + { + + if (CurrentProductAttribute.ControlType == 0) + { + if (string.IsNullOrEmpty(value.Name)) + { + MessageService.Error("请输入规格值"); + return; + } + } + if (CurrentProductAttribute.WeightIsRequired) + { + if (value.Weight <= 0) + { + MessageService.Error("请输入重量"); + return; + } + } + var attributeValue = attribute.ProductAttributeValues.Where(p => p.Name == value.Name && p.Weight == value.Weight && p.DisplayOrder != value.DisplayOrder).SingleOrDefault(); + if (attributeValue != null) + { + MessageService.Error("已经设置了一个相同的属性值"); + return; + } + Console.WriteLine($"编辑属性值之后:{value.ToJson()}"); + value.IsEdit = false; + RebuildSkuCombinations(); + } + + void OnClickEditAttributeValueForCancel(ProductSaleAttributeModel attribute, ProductAttributeValueModel value) + { + value.IsEdit = false; + attribute.AddAttribute = false; + CurrentProductAttribute = new(); + } + + /// + /// 保存新的属性值 + /// + /// + /// + void HandleSaveAttributeValueAsync(long id) + { + var data = model.ProductSaleAttributes.SingleOrDefault(p => p.AttributeId == id); + if (data != null) + { + if (CurrentProductAttribute.ControlType == 0) + { + if (string.IsNullOrEmpty(editAttributeValue.Name)) + { + MessageService.Error("请输入规格值"); + return; + } + } + if (CurrentProductAttribute.WeightIsRequired) + { + if (editAttributeValue.Weight <= 0) + { + MessageService.Error("请输入重量"); + return; + } + } + var attributeValue = data.ProductAttributeValues.Where(p => p.Name == editAttributeValue.Name && p.Weight == editAttributeValue.Weight).SingleOrDefault(); + if (attributeValue != null) + { + MessageService.Error("已经设置了一个相同的属性值"); + return; + } + data.ProductAttributeValues.Add(new ProductAttributeValueModel() { Id = editAttributeValue.Id, Name = editAttributeValue.Name, Weight = editAttributeValue.Weight, WeightUnit = editAttributeValue.WeightUnit, DisplayOrder = data.ProductAttributeValues.Count }); + editAttributeValue = new(); + RebuildSkuCombinations(); + } + } + + void HandleCancelAttribute(long id) + { + var data = model.ProductSaleAttributes.SingleOrDefault(p => p.AttributeId == id); + if (data != null) + { + data.AddAttribute = false; + } + } + + void HandleRemoveAttributeValue(long attributeId, ProductAttributeValueModel value) + { + var data = model.ProductSaleAttributes.SingleOrDefault(p => p.AttributeId == attributeId); + data.ProductAttributeValues.Remove(value); + if (data.ProductAttributeValues.Count == 0) + { + + var attribute = model.PhotoSalesAttribute.SingleOrDefault(p => p.Id == data.AttributeId); + if (attribute != null) + { + model.PhotoSalesAttribute.Remove(attribute); + } + } + RebuildSkuCombinations(); + UpdateSkuPrices(); + } + + bool DisableMoveUpState(ProductSaleAttributeModel saleAttributeModel) + { + var index = saleAttributeModel.DisplayOrder; + if (index > 1) + { + if (model.ProductSaleAttributes.Count > 1) + { + return false; + } + } + return true; + } + + bool DisableMoveDownState(ProductSaleAttributeModel saleAttributeModel) + { + var index = saleAttributeModel.DisplayOrder; + if (index < 3 && index != model.ProductSaleAttributes.Count) + { + if (model.ProductSaleAttributes.Count > 1) + { + return false; + } + } + return true; + } + + void OnClickAttributeDisplayMoveUp(ProductSaleAttributeModel saleAttributeModel) + { + var index = saleAttributeModel.DisplayOrder; + if (index != 1) + { + var prev = model.ProductSaleAttributes.SingleOrDefault(p => p.DisplayOrder == index - 1); + if (prev == null) + { + return; + } + prev.DisplayOrder = prev.DisplayOrder + 1; + saleAttributeModel.DisplayOrder = saleAttributeModel.DisplayOrder - 1; + model.ProductSaleAttributes = model.ProductSaleAttributes.OrderBy(p => p.DisplayOrder).ToList(); + StateHasChanged(); + } + RebuildSkuCombinations(); + } + + void OnClickAttributeDisplayMoveDown(ProductSaleAttributeModel saleAttributeModel) + { + var index = saleAttributeModel.DisplayOrder; + if (index < 3 && index != model.ProductSaleAttributes.Count) + { + var next = model.ProductSaleAttributes.SingleOrDefault(p => p.DisplayOrder == index + 1); + if (next == null) + { + return; + } + next.DisplayOrder--; + saleAttributeModel.DisplayOrder++; + model.ProductSaleAttributes = model.ProductSaleAttributes.OrderBy(p => p.DisplayOrder).ToList(); + StateHasChanged(); + } + RebuildSkuCombinations(); + } + + void OnClickDeleteSaleAttribute(ProductSaleAttributeModel saleAttributeModel) + { + model.ProductSaleAttributes.Remove(saleAttributeModel); + var index = 1; + foreach (var item in model.ProductSaleAttributes) + { + item.DisplayOrder = index; + index++; + } + RebuildSkuCombinations(); + } + + void UploadFiles(IReadOnlyList files) + { + + } + + #region 分类相关 + + void BindCategory() + { + Category = Categories.SingleOrDefault(p => p.Id == model.CategoryId); + var path = Category?.Path.Split(",") ?? []; + if (path.Length > 0) + { + for (var i = 0; i < path.Length; i++) + { + if (i == 0) + { + level1CategoryId = path[i].ToLong(); + } + else if (i == 1) + { + level2CategoryId = path[i].ToLong(); + } + else if (i == 2) + { + level3CategoryId = path[i].ToLong(); + } + else + { + level4CategoryId = path[i].ToLong(); + } + } + } + Level1Categories = Categories.Where(p => p.ParentId == 0).ToList(); + + if (level1CategoryId > 0) + { + Level2Categories = Categories.Where(p => p.ParentId == level1CategoryId).ToList(); + } + if (level2CategoryId > 0) + { + Level3Categories = Categories.Where(p => p.ParentId == level2CategoryId).ToList(); + } + if (level3CategoryId > 0) + { + Level4Categories = Categories.Where(p => p.ParentId == level3CategoryId).ToList(); + } + + if (Category != null) + { + BuildCategoryPath(Category); + } + } + + async Task LoadCategories() + { + var url = $"/api/category/items"; + var apiResult = await HttpService.Get>>(url); + if (apiResult.Success) + { + Categories = apiResult.Data ?? new(); + } + } + + private void Level1CategoryValueChanged(long id) + { + level1CategoryId = id; + if (level1CategoryId > 0) + { + level2CategoryId = 0; + Level2Categories = Categories.Where(p => p.ParentId == id).ToList(); + } + else + { + Level2Categories = new(); + } + if (Level2Categories.Any()) + { + model.CategoryId = 0; + showLevel2Category = true; + showLevel3Category = false; + showLevel4Category = false; + level3CategoryId = 0; + level4CategoryId = 0; + Level3Categories = new(); + Level4Categories = new(); + } + else + { + model.CategoryId = level1CategoryId; + showLevel2Category = false; + showLevel3Category = false; + showLevel4Category = false; + level2CategoryId = 0; + level3CategoryId = 0; + level4CategoryId = 0; + Level3Categories = new(); + Level4Categories = new(); + } + } + + private void Level2CategoryValueChanged(long id) + { + level2CategoryId = id; + Level3Categories = Categories.Where(p => p.ParentId == id).ToList(); + if (Level3Categories.Any()) + { + model.CategoryId = 0; + showLevel3Category = true; + showLevel4Category = false; + level4CategoryId = 0; + Level4Categories = new(); + } + else + { + model.CategoryId = level2CategoryId; + showLevel3Category = false; + showLevel4Category = false; + level3CategoryId = 0; + level4CategoryId = 0; + Level4Categories = new(); + } + + } + + private void Level3CategoryValueChanged(long id) + { + level3CategoryId = id; + Level4Categories = Categories.Where(p => p.ParentId == id).ToList(); + if (Level4Categories.Any()) + { + model.CategoryId = 0; + showLevel4Category = true; + level4CategoryId = 0; + } + else + { + model.CategoryId = level3CategoryId; + showLevel4Category = false; + level4CategoryId = 0; + } + + } + + private void Level4CategoryValueChanged(long id) + { + level4CategoryId = id; + model.CategoryId = level4CategoryId; + } + + async Task OnClickNext() + { + if (model.CategoryId == 0) + { + ModalService.Info(new ConfirmOptions() { Title = "操作提示", Content = "请确认产品归属分类" }); + return; + } + var category = Categories.Where(p => p.Id == model.CategoryId).SingleOrDefault(); + if (category == null) + { + ModalService.Info(new ConfirmOptions() { Title = "操作提示", Content = "请设置正确的产品归属分类" }); + return; + } + BuildCategoryPath(category); + + editCategory = false; + await SearchAttribute(string.Empty); + } + #endregion + + void BuildCategoryPath(Category category) + { + Console.WriteLine(category.Name); + Console.WriteLine(category.Path); + var ids = category.Path.Split(","); + foreach (var id in ids) + { + var item = Categories.Where(p => p.Id == id.ToLong()).SingleOrDefault(); + if (item != null) + { + if (string.IsNullOrEmpty(CategoryPath)) + { + CategoryPath = item.Name; + } + else + { + CategoryPath = $"{CategoryPath} > {item.Name}"; + } + } + } + } + + int runNumber = 0; + + /// + /// 根据卡迪尔乘积构建UI表单 + /// + void RebuildSkuCombinations() + { + List> result = new List>(); + List TempSkuCombinations = new List(); + if (model.ProductSaleAttributes.Count > 0) + { + var list = model.ProductSaleAttributes.Where(p => p.ProductAttributeValues.Count > 0).ToList(); + Descartes(list, 0, result, new List()); + //int count = result.Count(); + + + foreach (var item in result) + { + + bool state = false; + foreach (var comb in model.ProductAttributeCombinations) + { + + if (comb.SkuAttributes.SequenceEqual(item)) + { + //新的SKU组合信息,原始SKU组合信息不能改动 + var combinationModel = new ProductAttributeCombinationModel() + { + Enabled = comb.Enabled, + Id = comb.Id, + MarketPrice = comb.MarketPrice, + Price = comb.Price, + ProductId = comb.ProductId, + SalesQuantity = comb.SalesQuantity, + SkuNumber = comb.SkuNumber, + SkuAttributes = item, + StockQuantity = comb.StockQuantity, + Weight = comb.Weight, + ManufacturerId = comb.ManufacturerId, + ProcessCharge = comb.ProcessCharge, + ProcessCost = comb.ProcessCost, + Surcharge = comb.Surcharge, + SurchargeCost = comb.SurchargeCost + }; + + TempSkuCombinations.Add(combinationModel); + state = true; + break; + } + } + + if (!state) + { + var combinationModel = new ProductAttributeCombinationModel() + { + Enabled = false, + Id = 0, + MarketPrice = 0, + Price = 0, + ProductId = model.Id, + SalesQuantity = 0, + SkuNumber = "", + SkuAttributes = item, + StockQuantity = 0, + Weight = 0, + }; + foreach (var sku in item) + { + if (sku.Weight > 0) + { + combinationModel.Weight = sku.Weight; + } + } + TempSkuCombinations.Add(combinationModel); + } + } + } + ProductAttributeCombinationsForEdit = TempSkuCombinations; + + Console.WriteLine($"执行步骤:{runNumber},RebuildSkuCombinations,数据:{model.ProductSaleAttributes.ToJson()}"); + runNumber++; + } + + /// + /// 笛卡尔乘积处理 + /// + /// + /// + /// + /// + /// + List Descartes(List list, int count, List> result, List data) + { + List tempData = data.Clone(); + if (list.Count() > 0) + { + ProductSaleAttributeModel saleAttribute = list[count]; + List attributeValues = saleAttribute.ProductAttributeValues; + foreach (var item in attributeValues) + { + if (count + 1 < list.Count()) + { + var copy2 = data.Clone(); + copy2.Add(new ProductSkuModel { AttributeId = saleAttribute.AttributeId, AttributeName = saleAttribute.Name, ValueId = item.Id, ValueName = item.Name, Weight = item.Weight.RemoveTrailingZeros().ToDecimal() }); + + var productSKu = Descartes(list, count + 1, result, copy2); + tempData.AddRange(productSKu); + } + else + { + var copy = data.Clone(); + var sku = new ProductSkuModel { AttributeId = saleAttribute.AttributeId, AttributeName = saleAttribute.Name, ValueId = item.Id, ValueName = item.Name, Weight = item.Weight.RemoveTrailingZeros().ToDecimal() }; + copy.Add(sku); + + result.Add(copy); + } + } + } + return tempData; + } + + string PriceFormat(decimal value) + { + return value.ToString("F2"); + } + + /// + /// 根据SKU规格变化更新产品信息中的价格 + /// + void UpdateSkuPrices() + { + if (ProductAttributeCombinationsForEdit.Any()) + { + model.MarketPrice = ProductAttributeCombinationsForEdit.Max(p => p.MarketPrice); + model.Price = ProductAttributeCombinationsForEdit.Max(p => p.Price); + model.StockQuantity = ProductAttributeCombinationsForEdit.Sum(p => p.StockQuantity); + } + else + { + model.MarketPrice = 0; + model.Price = 0; + model.StockQuantity = 0; + } + } + + /// + /// SKU市场价变化后更新商品市场价 + /// + void UpdateMarketPrice(ProductAttributeCombinationModel data, decimal price) + { + var marketPrice = price; + foreach (var item in ProductAttributeCombinationsForEdit) + { + if (item.SkuAttributes.SequenceEqual(data.SkuAttributes)) + { + item.MarketPrice = price; + } + if (item.MarketPrice > marketPrice) + { + marketPrice = item.Price; + } + } + model.MarketPrice = marketPrice; + + } + + /// + /// SKU销售价格变化后更新商品销售价格 + /// + void UpdatePrice(ProductAttributeCombinationModel data, decimal price) + { + var salePrice = price; + + foreach (var item in ProductAttributeCombinationsForEdit) + { + if (item.SkuAttributes.SequenceEqual(data.SkuAttributes)) + { + item.Price = price; + } + if (item.Price > salePrice) + { + salePrice = item.Price; + } + } + model.Price = salePrice; + } + + /// + /// SKU库存变化后更新库存 + /// + void UpdateStockQuantity(ProductAttributeCombinationModel data, int num) + { + int quantity = 0; + foreach (var item in ProductAttributeCombinationsForEdit) + { + if (item.SkuAttributes.SequenceEqual(data.SkuAttributes)) + { + item.StockQuantity = num; + } + quantity = quantity + item.StockQuantity; + } + model.StockQuantity = quantity; + StateHasChanged(); + } + + string GetWeightAndUnit(ProductSkuModel skuModel) + { + + switch (skuModel.WeightUnit) + { + case 1: + return $"{skuModel.Weight}mg"; + case 3: + return $"{skuModel.Weight}kg"; + case 4: + return $"{skuModel.Weight}t"; + case 5: + return $"{skuModel.Weight}lb"; + case 6: + return $"{skuModel.Weight}oz"; + default: + return $"{skuModel.Weight}g"; + } + } + + string GetWeightUnit(int weightUnit) + { + + switch (weightUnit) + { + case 1: + return $"mg"; + case 3: + return $"kg"; + case 4: + return $"t"; + case 5: + return $"lb"; + case 6: + return $"oz"; + default: + return $"g"; + } + } +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductList.razor new file mode 100644 index 0000000..22747e5 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductList.razor @@ -0,0 +1,425 @@ +@page "/product/list" +@inject ILogger Logger +@attribute [Authorize] + +产品管理 + +产品列表 + +
    + + + + + + + + +
    + + +
    + +
    +
    +
    + + + + + + 产品列表 +
    + +
    +
    +
    + + +
    @context.Title
    + @context.Id +
    + + + + @if (context.Status == 1) + { + + + } + else + { + + } + + + + + + 入库 + + + 编辑 + + + + 删除 + + + + +
    +
    +
    + + + +
    + + +
    + + + @stockModel.Title + + @if (!stockModel.AddAttribute) + { + @foreach (var item in stockModel.ProductStockAttributes) + { + + + + } + + } + + + 设置新规格 + + + @if (stockModel.AddAttribute) + { + @foreach (var item in stockModel.ProductStockAttributes) + { + + + @if (item.WeightIsRequired) + { + + @GetWeightUnit(item.WeightUnit) + + } + + } + } + + + + + + + + + + + + + + + + + + +
    + +@code { + [SupplyParameterFromQuery] + int? Page { get; set; } + + [SupplyParameterFromQuery(Name = "size")] + int? PageSize { get; set; } + + [SupplyParameterFromForm] + ProductSearch search { get; set; } = new(); + Form searchForm = null!; + + PagingList PagingList = new(); + bool loading { get; set; } = true; + bool searchExpand { get; set; } = false; + + [SupplyParameterFromForm] + ProductAddStockModel stockModel { get; set; } = new(); + Form stockForm = null!; + bool drawerVisible; + string WarehouseName = string.Empty; + List warehouseSelectItems = new(); + + public TypographyCopyableConfig CopyHint { get; set; } = null!; + + protected override void OnInitialized() + { + CopyHint = new() { OnCopy = () => MessageService.Success("复制成功") }; + base.OnInitialized(); + } + + protected override void OnParametersSet() + { + + loadQueryString(); + LoadList(); + + base.OnParametersSet(); + } + + void loadQueryString() + { + var uri = new Uri(Navigation.Uri); + var query = uri.Query; + search.Title = query.GetQueryString("Title"); + search.CategoryId = query.GetQueryString("CategoryId"); + + var data = query.GetQueryString("RangeTime"); + if (!string.IsNullOrEmpty(data)) + { + var rangetime = data.Split("-"); + if (rangetime != null && rangetime.Length > 0) + { + searchExpand = true; + search.RangeTime[0] = rangetime[0].NumberToDateTime(); + search.RangeTime[1] = rangetime[1].NumberToDateTime(); + StateHasChanged(); + } + } + + } + + void OnSearchFinish() + { + Page = Page.GetValueOrDefault(1) - 1; + MessageService.Info("正在查询数据..."); + OnSearch(Page.Value); + } + + + private void OnSearchReset() + { + search = new(); + LoadList(); + } + + private async void LoadList() + { + + loading = true; + var url = "/api/product/search"; + var apiResult = await HttpService.GetPagingList(url, search, Page.GetValueOrDefault(1), PageSize.GetValueOrDefault(20)); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + PagingList = apiResult.Data; + } + } + loading = false; + StateHasChanged(); + } + + + private void OnReset() + { + search = new(); + LoadList(); + } + + private void OnSearch(int page) + { + var queryString = search.BuildQueryString(); + if (string.IsNullOrEmpty(queryString)) + { + if (page > 1) + { + Navigation.NavigateTo($"/product/list?page={page}"); + } + else + { + Navigation.NavigateTo($"/product/list"); + } + } + else + { + if (page > 1) + { + Navigation.NavigateTo($"/product/list?page={page}&{queryString}"); + } + else + { + Navigation.NavigateTo($"/product/list?{queryString}"); + } + } + } + + async Task HandleDeleteConfirmAsync(MouseEventArgs e, long id) + { + var url = $"/api/product/delete/{id}"; + var apiResult = await HttpService.Post>(url, new()); + if (apiResult.Success) + { + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" }); + } + } + + + + void OnPageChanged(PaginationEventArgs args) + { + OnSearch(args.Page); + } + + + + + void OnCreateClick() + { + Navigation.NavigateTo($"/product/create"); + } + + void OnEditClick(long id) + { + Navigation.NavigateTo($"/product/edit/{id}"); + } + + async Task OnClickAddStock(Product product) + { + drawerVisible = true; + stockModel = product.Adapt(); + stockModel.ProductId = product.Id; + + var url = $"/api/product/attributes/{product.Id}"; + var apiResult = await HttpService.Post>>(url, new()); + if (apiResult.Success) + { + stockModel.ProductStockAttributes = apiResult.Data ?? new(); + } + + WarehouseSearch warehouseSearch = new() + { + CorporationId = product.CorporationId + }; + url = $"/api/warehouse/select"; + var selectResult = await HttpService.Post>>(url, warehouseSearch); + if (selectResult.Success) + { + warehouseSelectItems = selectResult.Data ?? new(); + } + } + + async void OnWarehouseInput(ChangeEventArgs e) + { + WarehouseSearch warehouseSearch = new() + { + CorporationId = stockModel.CorporationId, + Name = e.Value?.ToString() + }; + var url = $"/api/warehouse/select"; + var selectResult = await HttpService.Post>>(url, warehouseSearch); + if (selectResult.Success) + { + warehouseSelectItems = selectResult.Data ?? new(); + } + } + + Func CompareWith = (a, b) => + { + if (a is SelectItem o1 && b is SelectItem o2) + { + return o1.Name == o2.Name; + } + else + { + return false; + } + }; + + void CloseDrawer() + { + drawerVisible = false; + stockForm.Reset(); + } + + async Task OnStockFormFinish() + { + if (stockForm.Validate()) + { + var result = new ApiResult(); + + Console.WriteLine(stockModel.ToJson()); + + var url = $"api/product/stock/add"; + result = await HttpService.Post>(url, stockModel); + + + if (result.Code == (int)ResultCode.Success) + { + + CloseDrawer(); + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "服务异常", Content = result.Message }); + } + } + } + + string GetAttributeValue(ProductAttributeValueModel value) + { + + if (value.Weight > 0) + { + return $"{value.Name}({value.Weight.RemoveTrailingZeros()}{GetWeightUnit(value.WeightUnit)})"; + } + else + { + return value.Name; + } + } + + string GetWeightUnit(int weightUnit) + { + + switch (weightUnit) + { + case 1: + return $"mg"; + case 3: + return $"kg"; + case 4: + return $"t"; + case 5: + return $"lb"; + case 6: + return $"oz"; + default: + return $"g"; + } + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductStockList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductStockList.razor new file mode 100644 index 0000000..3df4f45 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/ProductStockList.razor @@ -0,0 +1,258 @@ +@page "/product/stock/list" + +@inject ILogger Logger +@attribute [Authorize] + +产品库存列表 + + + + + 产品库存列表 + + + + + + @foreach (var item in context.Sku) + { + + @item.ValueName + @if (item.Weight > 0) + { + (@($"{item.Weight}{@GetWeightUnit(item.WeightUnit)}")) + } + + } + + + @context.Weight.RemoveTrailingZeros() + + + + + + + + 入库 + + + + +
    +
    + + + +
    + + + +
    + + + @model.Title + + + @if (model.Sku != null) + { + @foreach (var item in model.Sku) + { + + @item.AttributeName + + @item.ValueName + @if (item.Weight > 0) + { + (@($"{item.Weight}{@GetWeightUnit(item.WeightUnit)}")) + } + + + } + } + + + + + + + + +
    + +@code { + [SupplyParameterFromQuery] + int? Page { get; set; } + + [SupplyParameterFromQuery(Name = "size")] + int? PageSize { get; set; } + + [SupplyParameterFromForm] + ProductStockUnitSearch search { get; set; } = new(); + Form searchForm = null!; + + PagingList PagingList = new(); + + [SupplyParameterFromForm] + ProductStockModel model { get; set; } = new(); + Form editform = null!; + + bool loading { get; set; } = true; + bool searchExpand { get; set; } = false; + private bool drawerVisible; + + protected override void OnInitialized() + { + base.OnInitialized(); + } + + protected override void OnParametersSet() + { + + loadQueryString(); + LoadList(); + + base.OnParametersSet(); + } + + void loadQueryString() + { + var uri = new Uri(Navigation.Uri); + var query = uri.Query; + search.Key = query.GetQueryString("Key"); + search.Type = query.GetQueryString("Type").ToInt(); + } + + void OnSearchFinish() + { + Page = Page.GetValueOrDefault(1) - 1; + + OnSearch(Page.Value); + } + + + private void OnSearchReset() + { + search = new(); + LoadList(); + } + + private async void LoadList() + { + + loading = true; + var url = "/api/product/stock/search"; + var apiResult = await HttpService.GetPagingList(url, search, Page.GetValueOrDefault(1), PageSize.GetValueOrDefault(20)); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + PagingList = apiResult.Data; + } + } + loading = false; + StateHasChanged(); + } + + + private void OnReset() + { + search = new(); + LoadList(); + } + + private void OnSearch(int page) + { + var queryString = search.BuildQueryString(); + if (string.IsNullOrEmpty(queryString)) + { + if (page > 1) + { + Navigation.NavigateTo($"/product/stock/list?page={page}"); + } + else + { + Navigation.NavigateTo($"/product/stock/list"); + } + } + else + { + if (page > 1) + { + Navigation.NavigateTo($"/product/stock/list?page={page}&{queryString}"); + } + else + { + Navigation.NavigateTo($"/product/stock/list?{queryString}"); + } + } + } + + + + void OnPageChanged(PaginationEventArgs args) + { + OnSearch(args.Page); + } + + string PriceFormat(decimal value) + { + return value.ToString("G"); + } + + void CloseDrawer() + { + drawerVisible = false; + editform.Reset(); + } + + void OnClickAddStock(ProductStockUnitModel item) + { + model = item.Adapt(); + drawerVisible = true; + } + + async Task OnFormFinish() + { + if (editform.Validate()) + { + var result = new ApiResult(); + + + + var url = $"api/product/skustock/add"; + result = await HttpService.Post>(url, model); + if (result.Code == (int)ResultCode.Success) + { + + CloseDrawer(); + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "服务异常", Content = result.Message }); + } + } + } + + string GetWeightUnit(int weightUnit) + { + + switch (weightUnit) + { + case 1: + return $"mg"; + case 3: + return $"kg"; + case 4: + return $"t"; + case 5: + return $"lb"; + case 6: + return $"oz"; + default: + return $"g"; + } + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Products/SpecificationList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/SpecificationList.razor new file mode 100644 index 0000000..0c9600d --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Products/SpecificationList.razor @@ -0,0 +1,319 @@ +@page "/specification/list" + +@inject ILogger Logger +@attribute [Authorize] + + +产品规格管理 + +属性列表 + +
    + + + + + + + + +
    + + +
    + +
    +
    +
    + + + + + + 属性列表 +
    + +
    +
    +
    + + + + @if (context.ControlType == 1) + { + 选项 + } + else + { + 文本框 + } + + + + + @if (context.Status == 1) + { + + + } + else + { + + } + + + + + + 预设值 + + + 编辑 + + + + 删除 + + + + + +
    +
    + + + +
    + + +
    + + + + + + + + 默认(文本) + 选项 + + + + + 启用 + 禁用 + + + + + + +
    + + +@code { + [SupplyParameterFromQuery] + int? Page { get; set; } + + [SupplyParameterFromQuery] + long CategoryId { get; set; } + + [SupplyParameterFromQuery(Name = "size")] + int? PageSize { get; set; } + + [SupplyParameterFromForm] + SpecificationAttributeSearch search { get; set; } = new(); + Form searchForm = null!; + + [SupplyParameterFromForm] + SpecificationAttributeModel model { get; set; } = new(); + Form editform = null!; + + PagingList PagingList = new(); + bool loading { get; set; } = true; + bool searchExpand { get; set; } = false; + private bool drawerVisible; + + protected override void OnInitialized() + { + base.OnInitialized(); + } + + protected override void OnParametersSet() + { + + loadQueryString(); + LoadList(); + + base.OnParametersSet(); + } + + void loadQueryString() + { + var uri = new Uri(Navigation.Uri); + var query = uri.Query; + search.Name = query.GetQueryString("Name"); + search.CategoryId = CategoryId; + } + + + private async void LoadList() + { + + loading = true; + var url = "/api/specificationattribute/search"; + var apiResult = await HttpService.GetPagingList(url, search, Page.GetValueOrDefault(1), PageSize.GetValueOrDefault(20)); + if (apiResult.Success) + { + if (apiResult.Data != null) + { + PagingList = apiResult.Data; + } + } + loading = false; + StateHasChanged(); + } + + + void OnSearchFinish() + { + Page = Page.GetValueOrDefault(1) - 1; + + OnSearch(Page.Value); + } + + + private void OnSearchReset() + { + search = new(); + LoadList(); + } + + private void OnReset() + { + search = new(); + LoadList(); + } + + private void OnSearch(int page) + { + var queryString = search.BuildQueryString(); + if (string.IsNullOrEmpty(queryString)) + { + if (page > 1) + { + Navigation.NavigateTo($"/specification/list?page={page}"); + } + else + { + Navigation.NavigateTo($"/specification/list"); + } + } + else + { + if (page > 1) + { + Navigation.NavigateTo($"/specification/list?page={page}&{queryString}"); + } + else + { + Navigation.NavigateTo($"/specification/list?{queryString}"); + } + } + } + + + void OnEditClick(SpecificationAttribute attribute) + { + this.model = attribute.Adapt(); + drawerVisible = true; + } + + async Task HandleDeleteConfirmAsync(MouseEventArgs e, long id) + { + + var url = $"/api/specificationattribute/delete/{model.Id}"; + var apiResult = await HttpService.Post>(url, new()); + if (apiResult.Success) + { + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "操作提示", Content = "删除数据成功" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "操作提示", Content = $"数据删除失败.{apiResult.Message}" }); + } + } + + async Task OnFormFinish() + { + if (CategoryId > 0) + { + model.CategoryId = CategoryId; + } + + if (editform.Validate()) + { + var result = new ApiResult(); + + + if (model.Id > 0) + { + var url = $"api/specificationattribute/edit"; + result = await HttpService.Post>(url, model); + } + else + { + var url = $"api/specificationattribute/add"; + result = await HttpService.Post>(url, model); + } + + if (result.Code == (int)ResultCode.Success) + { + + CloseDrawer(); + LoadList(); + await ModalService.InfoAsync(new ConfirmOptions() { Title = "提示", Content = "数据提交成功!" }); + } + else + { + await ModalService.ErrorAsync(new ConfirmOptions() { Title = "服务异常", Content = result.Message }); + } + } + } + + + void OnPageChanged(PaginationEventArgs args) + { + + var queryString = search.BuildQueryString(); + if (string.IsNullOrEmpty(queryString)) + { + Navigation.NavigateTo($"/specification/list?page={args.Page}"); + } + else + { + Navigation.NavigateTo($"/specification/list?page={Page}&{queryString}"); + } + } + + + void OnCreateClick() + { + drawerVisible = true; + } + + void CloseDrawer() + { + drawerVisible = false; + editform.Reset(); + } + + void OnViewPredefinedListClick(long id) + { + Navigation.NavigateTo($"/specification/Predefined/list/{id}"); + } +} \ No newline at end of file diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Register.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Register.razor new file mode 100644 index 0000000..0081d77 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Register.razor @@ -0,0 +1,10 @@ +@page "/account/register" +@inject ILogger Logger + +注册账号 + +

    Register

    + +@code { + +} diff --git a/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/MessageTemplateList.razor b/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/MessageTemplateList.razor new file mode 100644 index 0000000..c4d8936 --- /dev/null +++ b/Atomx.Admin/Atomx.Admin.Client/Pages/Settings/MessageTemplateList.razor @@ -0,0 +1,317 @@ +@page "/setting/messagetemplate/list" + +@inject ILogger Logger +@* @attribute [Authorize] *@ + +消息模板 +消息模版管理 + +
    + + + + + + + +
    + + +
    + +
    +
    +
    + + + + + + 菜单列表 +
    + +
    +
    +
    + + + @if (context.Type == (int)MessageTemplateType.Message) + { + 站内信 + } + else if (context.Type == (int)MessageTemplateType.Email) + { + 邮件 + } + else if (context.Type == (int)MessageTemplateType.Sms) + { + 短信 + } + + + + + + @if (context.Enabled) + { + + + } + else + { + + } + + + + + + + + + + + 编辑 + + + + + 删除 + + + + + + + + + + + + + + +
    + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +