Quellcode durchsuchen

product 文件转移,商品详情页面完成

南鑫林 vor 6 Jahren
Ursprung
Commit
cbd45cc81d
33 geänderte Dateien mit 1231 neuen und 64 gelöschten Zeilen
  1. 132 40
      RainbowPlanet/RainbowPlanet.xcodeproj/project.pbxproj
  2. 5 5
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/FloorCell/ShoppingMallBarChart/ShoppingMallBarChartCollectionViewCell.swift
  3. 6 6
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/FloorCell/ShoppingMallRightSideleftPicture/ShoppingMallRightSideleftPictureCollectionViewCell.swift
  4. 6 6
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/FloorCell/ShoppingMallSlidingLeftRight/ShoppingMallSlidingLeftRightCollectionViewCell.swift
  5. 0 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/CollectionViewCell/ProductSlidingTopBottom/ProductSlidingTopBottomCollectionViewCell.swift
  6. 0 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorBannerView.swift
  7. 0 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorCenterHeaderCollectionReusableView.swift
  8. 0 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorCenterTitleView.swift
  9. 0 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorFullLeftHeaderCollectionReusableView.swift
  10. 0 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorLeftHeaderCollectionReusableView.swift
  11. 0 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorTitleView.swift
  12. 0 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/TableViewCell/ProductHBigTableViewCell.swift
  13. 0 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/TableViewCell/ProductHSmallTableViewCell.swift
  14. 60 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ProductDetail/View/ProductDetailFSPagerViewCell.swift
  15. 85 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ProductDetail/View/ProductDetailProductInfoTableViewCell.swift
  16. 113 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ProductDetail/View/ProductDetailTableViewHeaderView.swift
  17. 98 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ProductDetail/View/ProductDetailView.swift
  18. 52 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ProductDetail/ViewController/ProductDetailViewController.swift
  19. 8 2
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/Floor/ShoppingMallFloorTableViewCell.swift
  20. 1 1
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/FloorCell/ShoppingMallSlidingLeftRight/ShoppingMallSlidingLeftRightBgCollectionViewCell.swift
  21. 12 0
      RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/ViewController/ShoppingMallViewController.swift
  22. 201 0
      RainbowPlanet/RainbowPlanet/Service/Model/ProductModel/ProductDetailModel.swift
  23. 19 3
      RainbowPlanet/RainbowPlanet/Service/SwiftMoyaService/SwiftMoyaServiceApi/SwiftMoyaServiceProduct/SwiftMoyaNetWorkServiceProduct.swift
  24. 13 1
      RainbowPlanet/RainbowPlanet/Service/SwiftMoyaService/SwiftMoyaServiceApi/SwiftMoyaServiceProduct/SwiftMoyaServiceProductApi.swift
  25. 23 0
      RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/common_goods_pic_soldout.imageset/Contents.json
  26. BIN
      RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/common_goods_pic_soldout.imageset/common_goods_pic_soldout.png
  27. BIN
      RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/common_goods_pic_soldout.imageset/common_goods_pic_soldout@2x.png
  28. BIN
      RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/common_goods_pic_soldout.imageset/common_goods_pic_soldout@3x.png
  29. 0 0
      RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/pic_preload.imageset/Contents.json
  30. 0 0
      RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/pic_preload.imageset/pic_preload.png
  31. 0 0
      RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/pic_preload.imageset/pic_preload@2x.png
  32. 0 0
      RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/pic_preload.imageset/pic_preload@3x.png
  33. 397 0
      RainbowPlanet/RainbowPlanet/Tools/NXLPageControl/NXLPageControl.swift

+ 132 - 40
RainbowPlanet/RainbowPlanet.xcodeproj/project.pbxproj

@@ -10,6 +10,13 @@
 		0A110C4CD931995B8E8BF7C5 /* Pods_RainbowPlanet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D469F6C3768252BCB7001EDD /* Pods_RainbowPlanet.framework */; };
 		A70B2C042283D06B00B2449F /* ProductFloorFullLeftHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70B2C032283D06B00B2449F /* ProductFloorFullLeftHeaderCollectionReusableView.swift */; };
 		A70B2C072284305400B2449F /* ProductModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70B2C062284305400B2449F /* ProductModel.swift */; };
+		A70B2C102286A3BC00B2449F /* ProductDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70B2C0F2286A3BC00B2449F /* ProductDetailModel.swift */; };
+		A70B2C1D2286B52400B2449F /* ProductDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70B2C1B2286B52400B2449F /* ProductDetailViewController.swift */; };
+		A70B2C202286B54500B2449F /* ProductDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70B2C1F2286B54500B2449F /* ProductDetailView.swift */; };
+		A70B2C222286BF5900B2449F /* ProductDetailTableViewHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70B2C212286BF5900B2449F /* ProductDetailTableViewHeaderView.swift */; };
+		A70B2C252286C03800B2449F /* NXLPageControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70B2C242286C03800B2449F /* NXLPageControl.swift */; };
+		A70B2C272286C5D600B2449F /* ProductDetailFSPagerViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70B2C262286C5D600B2449F /* ProductDetailFSPagerViewCell.swift */; };
+		A70B2C292286D77200B2449F /* ProductDetailProductInfoTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70B2C282286D77200B2449F /* ProductDetailProductInfoTableViewCell.swift */; };
 		A70EBBC022561179000AD74F /* Extension+UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A70EBBBF22561179000AD74F /* Extension+UITableView.swift */; };
 		A7190167227543DB00104A50 /* baidu_cityid_rel.json in Resources */ = {isa = PBXBuildFile; fileRef = A7190166227543DB00104A50 /* baidu_cityid_rel.json */; };
 		A71901692275464000104A50 /* ProvinceCityAreaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A71901682275464000104A50 /* ProvinceCityAreaView.swift */; };
@@ -184,11 +191,11 @@
 		A7A98E41228046C5005306E9 /* ShoppingMallSepcialTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7A98E40228046C4005306E9 /* ShoppingMallSepcialTableViewCell.swift */; };
 		A7A98E4322804851005306E9 /* ShoppingMallSepcialFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7A98E4222804851005306E9 /* ShoppingMallSepcialFlowLayout.swift */; };
 		A7A98E4522804C63005306E9 /* ShoppingMallSepcialCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7A98E4422804C63005306E9 /* ShoppingMallSepcialCollectionViewCell.swift */; };
-		A7B4E71F228131720012914A /* ShoppingMallSlidingLeftRightCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E71E228131720012914A /* ShoppingMallSlidingLeftRightCollectionViewCell.swift */; };
+		A7B4E71F228131720012914A /* ProductSlidingLeftRightCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E71E228131720012914A /* ProductSlidingLeftRightCollectionViewCell.swift */; };
 		A7B4E721228151F40012914A /* ProductFloorTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E720228151F40012914A /* ProductFloorTitleView.swift */; };
 		A7B4E723228154750012914A /* ProductFloorBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E722228154750012914A /* ProductFloorBannerView.swift */; };
-		A7B4E728228160BA0012914A /* ShoppingMallRightSideleftPictureCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E727228160BA0012914A /* ShoppingMallRightSideleftPictureCollectionViewCell.swift */; };
-		A7B4E72D228176060012914A /* ShoppingMallBarChartCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E72C228176060012914A /* ShoppingMallBarChartCollectionViewCell.swift */; };
+		A7B4E728228160BA0012914A /* ProductRightSideleftPictureCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E727228160BA0012914A /* ProductRightSideleftPictureCollectionViewCell.swift */; };
+		A7B4E72D228176060012914A /* ProductMallBarChartCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E72C228176060012914A /* ProductMallBarChartCollectionViewCell.swift */; };
 		A7B4E72F2281773F0012914A /* ProductFloorCenterTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E72E2281773F0012914A /* ProductFloorCenterTitleView.swift */; };
 		A7B4E7352281907A0012914A /* CMSModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E7342281907A0012914A /* CMSModel.swift */; };
 		A7B4E738228191CC0012914A /* CommondModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7B4E737228191CC0012914A /* CommondModel.swift */; };
@@ -297,6 +304,13 @@
 		88DF1EFD2E202DA7C627E8A7 /* Pods_RainbowPlanetUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RainbowPlanetUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		A70B2C032283D06B00B2449F /* ProductFloorFullLeftHeaderCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductFloorFullLeftHeaderCollectionReusableView.swift; sourceTree = "<group>"; };
 		A70B2C062284305400B2449F /* ProductModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProductModel.swift; sourceTree = "<group>"; };
+		A70B2C0F2286A3BC00B2449F /* ProductDetailModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProductDetailModel.swift; sourceTree = "<group>"; };
+		A70B2C1B2286B52400B2449F /* ProductDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductDetailViewController.swift; sourceTree = "<group>"; };
+		A70B2C1F2286B54500B2449F /* ProductDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductDetailView.swift; sourceTree = "<group>"; };
+		A70B2C212286BF5900B2449F /* ProductDetailTableViewHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductDetailTableViewHeaderView.swift; sourceTree = "<group>"; };
+		A70B2C242286C03800B2449F /* NXLPageControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NXLPageControl.swift; sourceTree = "<group>"; };
+		A70B2C262286C5D600B2449F /* ProductDetailFSPagerViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductDetailFSPagerViewCell.swift; sourceTree = "<group>"; };
+		A70B2C282286D77200B2449F /* ProductDetailProductInfoTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductDetailProductInfoTableViewCell.swift; sourceTree = "<group>"; };
 		A70EBBBF22561179000AD74F /* Extension+UITableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extension+UITableView.swift"; sourceTree = "<group>"; };
 		A7190166227543DB00104A50 /* baidu_cityid_rel.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = baidu_cityid_rel.json; sourceTree = "<group>"; };
 		A71901682275464000104A50 /* ProvinceCityAreaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProvinceCityAreaView.swift; sourceTree = "<group>"; };
@@ -484,11 +498,11 @@
 		A7A98E40228046C4005306E9 /* ShoppingMallSepcialTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingMallSepcialTableViewCell.swift; sourceTree = "<group>"; };
 		A7A98E4222804851005306E9 /* ShoppingMallSepcialFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingMallSepcialFlowLayout.swift; sourceTree = "<group>"; };
 		A7A98E4422804C63005306E9 /* ShoppingMallSepcialCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingMallSepcialCollectionViewCell.swift; sourceTree = "<group>"; };
-		A7B4E71E228131720012914A /* ShoppingMallSlidingLeftRightCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingMallSlidingLeftRightCollectionViewCell.swift; sourceTree = "<group>"; };
+		A7B4E71E228131720012914A /* ProductSlidingLeftRightCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductSlidingLeftRightCollectionViewCell.swift; sourceTree = "<group>"; };
 		A7B4E720228151F40012914A /* ProductFloorTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductFloorTitleView.swift; sourceTree = "<group>"; };
 		A7B4E722228154750012914A /* ProductFloorBannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductFloorBannerView.swift; sourceTree = "<group>"; };
-		A7B4E727228160BA0012914A /* ShoppingMallRightSideleftPictureCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingMallRightSideleftPictureCollectionViewCell.swift; sourceTree = "<group>"; };
-		A7B4E72C228176060012914A /* ShoppingMallBarChartCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingMallBarChartCollectionViewCell.swift; sourceTree = "<group>"; };
+		A7B4E727228160BA0012914A /* ProductRightSideleftPictureCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductRightSideleftPictureCollectionViewCell.swift; sourceTree = "<group>"; };
+		A7B4E72C228176060012914A /* ProductMallBarChartCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductMallBarChartCollectionViewCell.swift; sourceTree = "<group>"; };
 		A7B4E72E2281773F0012914A /* ProductFloorCenterTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductFloorCenterTitleView.swift; sourceTree = "<group>"; };
 		A7B4E7342281907A0012914A /* CMSModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CMSModel.swift; sourceTree = "<group>"; };
 		A7B4E737228191CC0012914A /* CommondModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommondModel.swift; sourceTree = "<group>"; };
@@ -630,13 +644,109 @@
 		A70B2C0522841F1B00B2449F /* FloorCell */ = {
 			isa = PBXGroup;
 			children = (
-				A7B4E729228174E70012914A /* ShoppingMallBarChart */,
-				A7B4E72422815AFB0012914A /* ShoppingMallRightSideleftPicture */,
 				A7B4E71B22812D390012914A /* ShoppingMallSlidingLeftRight */,
 			);
 			path = FloorCell;
 			sourceTree = "<group>";
 		};
+		A70B2C112286B10000B2449F /* ProductDetail */ = {
+			isa = PBXGroup;
+			children = (
+				A70B2C1A2286B4F900B2449F /* ViewController */,
+				A70B2C192286B4ED00B2449F /* View */,
+			);
+			path = ProductDetail;
+			sourceTree = "<group>";
+		};
+		A70B2C122286B14C00B2449F /* Product */ = {
+			isa = PBXGroup;
+			children = (
+				A7B4E732228177BC0012914A /* ProductCollectionReusableView */,
+				A70B2C182286B48600B2449F /* TableViewCell */,
+				A70B2C132286B1C500B2449F /* CollectionViewCell */,
+			);
+			path = Product;
+			sourceTree = "<group>";
+		};
+		A70B2C132286B1C500B2449F /* CollectionViewCell */ = {
+			isa = PBXGroup;
+			children = (
+				A70B2C172286B47B00B2449F /* ProductSlidingTopBottom */,
+				A70B2C162286B44600B2449F /* ProductMallBarChart */,
+				A70B2C152286B44600B2449F /* ProductMallRightSideleftPicture */,
+				A70B2C142286B41000B2449F /* ProductMallSlidingLeftRight */,
+			);
+			path = CollectionViewCell;
+			sourceTree = "<group>";
+		};
+		A70B2C142286B41000B2449F /* ProductMallSlidingLeftRight */ = {
+			isa = PBXGroup;
+			children = (
+				A7B4E71E228131720012914A /* ProductSlidingLeftRightCollectionViewCell.swift */,
+			);
+			path = ProductMallSlidingLeftRight;
+			sourceTree = "<group>";
+		};
+		A70B2C152286B44600B2449F /* ProductMallRightSideleftPicture */ = {
+			isa = PBXGroup;
+			children = (
+				A7B4E727228160BA0012914A /* ProductRightSideleftPictureCollectionViewCell.swift */,
+			);
+			path = ProductMallRightSideleftPicture;
+			sourceTree = "<group>";
+		};
+		A70B2C162286B44600B2449F /* ProductMallBarChart */ = {
+			isa = PBXGroup;
+			children = (
+				A7B4E72C228176060012914A /* ProductMallBarChartCollectionViewCell.swift */,
+			);
+			path = ProductMallBarChart;
+			sourceTree = "<group>";
+		};
+		A70B2C172286B47B00B2449F /* ProductSlidingTopBottom */ = {
+			isa = PBXGroup;
+			children = (
+				BDF47D7D22827C3F00941AB9 /* ProductSlidingTopBottomCollectionViewCell.swift */,
+			);
+			path = ProductSlidingTopBottom;
+			sourceTree = "<group>";
+		};
+		A70B2C182286B48600B2449F /* TableViewCell */ = {
+			isa = PBXGroup;
+			children = (
+				A71AF0BB226F099B001730FE /* ProductHBigTableViewCell.swift */,
+				A7A98E0F227EC531005306E9 /* ProductHSmallTableViewCell.swift */,
+			);
+			path = TableViewCell;
+			sourceTree = "<group>";
+		};
+		A70B2C192286B4ED00B2449F /* View */ = {
+			isa = PBXGroup;
+			children = (
+				A70B2C1F2286B54500B2449F /* ProductDetailView.swift */,
+				A70B2C212286BF5900B2449F /* ProductDetailTableViewHeaderView.swift */,
+				A70B2C262286C5D600B2449F /* ProductDetailFSPagerViewCell.swift */,
+				A70B2C282286D77200B2449F /* ProductDetailProductInfoTableViewCell.swift */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		A70B2C1A2286B4F900B2449F /* ViewController */ = {
+			isa = PBXGroup;
+			children = (
+				A70B2C1B2286B52400B2449F /* ProductDetailViewController.swift */,
+			);
+			path = ViewController;
+			sourceTree = "<group>";
+		};
+		A70B2C232286C03800B2449F /* NXLPageControl */ = {
+			isa = PBXGroup;
+			children = (
+				A70B2C242286C03800B2449F /* NXLPageControl.swift */,
+			);
+			path = NXLPageControl;
+			sourceTree = "<group>";
+		};
 		A71901622275411C00104A50 /* ProvinceCityArea */ = {
 			isa = PBXGroup;
 			children = (
@@ -1522,6 +1632,8 @@
 		A77F2CA32232010F001BD3F6 /* ShoppingMallModule */ = {
 			isa = PBXGroup;
 			children = (
+				A70B2C122286B14C00B2449F /* Product */,
+				A70B2C112286B10000B2449F /* ProductDetail */,
 				A77F2CA42232010F001BD3F6 /* ShoppingMall */,
 				A7A98E03227EB7FD005306E9 /* Category */,
 				A7A98E15227EECEA005306E9 /* Special */,
@@ -1637,6 +1749,7 @@
 		A77F2CBC2232022A001BD3F6 /* Tools */ = {
 			isa = PBXGroup;
 			children = (
+				A70B2C232286C03800B2449F /* NXLPageControl */,
 				A7D4608C227616E600A5A54E /* FMDB */,
 				A71901712275F56C00104A50 /* BaiduToCityFactory */,
 				A719016E2275EF7A00104A50 /* NXLRealm */,
@@ -1730,6 +1843,7 @@
 				A7A98E01227E8900005306E9 /* ProductSearchListModel.swift */,
 				A7A98E11227ECA11005306E9 /* ProductSearchModel.swift */,
 				A70B2C062284305400B2449F /* ProductModel.swift */,
+				A70B2C0F2286A3BC00B2449F /* ProductDetailModel.swift */,
 				BDE3045C22851E4F001D050F /* ProductCartListModel.swift */,
 				BDE3045E228554CA001D050F /* ProductCartAmountModel.swift */,
 			);
@@ -1763,15 +1877,6 @@
 			path = View;
 			sourceTree = "<group>";
 		};
-		A7A98E0C227EBEE3005306E9 /* ProductView */ = {
-			isa = PBXGroup;
-			children = (
-				A71AF0BB226F099B001730FE /* ProductHBigTableViewCell.swift */,
-				A7A98E0F227EC531005306E9 /* ProductHSmallTableViewCell.swift */,
-			);
-			path = ProductView;
-			sourceTree = "<group>";
-		};
 		A7A98E15227EECEA005306E9 /* Special */ = {
 			isa = PBXGroup;
 			children = (
@@ -1839,34 +1944,15 @@
 			isa = PBXGroup;
 			children = (
 				A7B4E755228281620012914A /* ShoppingMallSlidingLeftRightBgCollectionViewCell.swift */,
-				A7B4E71E228131720012914A /* ShoppingMallSlidingLeftRightCollectionViewCell.swift */,
 			);
 			path = ShoppingMallSlidingLeftRight;
 			sourceTree = "<group>";
 		};
-		A7B4E72422815AFB0012914A /* ShoppingMallRightSideleftPicture */ = {
-			isa = PBXGroup;
-			children = (
-				A7B4E727228160BA0012914A /* ShoppingMallRightSideleftPictureCollectionViewCell.swift */,
-			);
-			path = ShoppingMallRightSideleftPicture;
-			sourceTree = "<group>";
-		};
-		A7B4E729228174E70012914A /* ShoppingMallBarChart */ = {
-			isa = PBXGroup;
-			children = (
-				A7B4E72C228176060012914A /* ShoppingMallBarChartCollectionViewCell.swift */,
-			);
-			path = ShoppingMallBarChart;
-			sourceTree = "<group>";
-		};
 		A7B4E730228177A90012914A /* ShoppingMallFloor */ = {
 			isa = PBXGroup;
 			children = (
 				A7B4E752228276270012914A /* Floor */,
 				A70B2C0522841F1B00B2449F /* FloorCell */,
-				A7B4E732228177BC0012914A /* ProductCollectionReusableView */,
-				A7A98E0C227EBEE3005306E9 /* ProductView */,
 			);
 			path = ShoppingMallFloor;
 			sourceTree = "<group>";
@@ -2277,7 +2363,6 @@
 			isa = PBXGroup;
 			children = (
 				BDF47D812282B3D100941AB9 /* ShoppingCartHotSaleTableViewCell.swift */,
-				BDF47D7D22827C3F00941AB9 /* ProductSlidingTopBottomCollectionViewCell.swift */,
 			);
 			path = ShoppingCartHotSale;
 			sourceTree = "<group>";
@@ -2633,11 +2718,13 @@
 				A72C01222275404A0065E0C3 /* ProvinceCityAreaModel.swift in Sources */,
 				A7C3DD1C226422D200FA262E /* SwiftMoyaNetWorkServiceSMS.swift in Sources */,
 				A72A7386223396CB00B21995 /* SwiftMoyaNetWorkManager.swift in Sources */,
+				A70B2C252286C03800B2449F /* NXLPageControl.swift in Sources */,
 				A7A98E12227ECA11005306E9 /* ProductSearchModel.swift in Sources */,
 				A71AF0B0226EF185001730FE /* SearchCollectionViewCell.swift in Sources */,
 				A7A98E1D227EF1CB005306E9 /* SpecialBannerView.swift in Sources */,
 				BDF47D852282C59F00941AB9 /* ShoppingCartListTableViewCell.swift in Sources */,
 				A77F2CCA223209F2001BD3F6 /* BaseTabbarViewController.swift in Sources */,
+				A70B2C1D2286B52400B2449F /* ProductDetailViewController.swift in Sources */,
 				A7CC75332271ABB0003C4F38 /* AddressManagerViewController.swift in Sources */,
 				A7CC750D227157DA003C4F38 /* MessageDetailesView.swift in Sources */,
 				BD7AB83622841A8B0030646A /* ShoppingCartPayOrderItemCell.swift in Sources */,
@@ -2646,6 +2733,7 @@
 				A729B5B022671310004AE098 /* MobileLoginView.swift in Sources */,
 				A71AA50C2272126A008FF1A5 /* EditAddressFooterView.swift in Sources */,
 				A7CC7528227196C4003C4F38 /* AccountSecuritySetTableViewCell.swift in Sources */,
+				A70B2C292286D77200B2449F /* ProductDetailProductInfoTableViewCell.swift in Sources */,
 				A72A726822321DBD00B21995 /* UMManager.swift in Sources */,
 				A70B2C042283D06B00B2449F /* ProductFloorFullLeftHeaderCollectionReusableView.swift in Sources */,
 				A7B4E721228151F40012914A /* ProductFloorTitleView.swift in Sources */,
@@ -2666,6 +2754,7 @@
 				A71AF0BA226F00F8001730FE /* SearchResultView.swift in Sources */,
 				A77F2CB52232010F001BD3F6 /* ShoppingMallViewController.swift in Sources */,
 				A71AA513227215B5008FF1A5 /* ExpressAddressListView.swift in Sources */,
+				A70B2C202286B54500B2449F /* ProductDetailView.swift in Sources */,
 				A7B4E723228154750012914A /* ProductFloorBannerView.swift in Sources */,
 				A7DC467F22783A47001F3EFC /* EditExpressAddressTableViewCell.swift in Sources */,
 				A7A98E4522804C63005306E9 /* ShoppingMallSepcialCollectionViewCell.swift in Sources */,
@@ -2690,7 +2779,7 @@
 				A72A72D622321E2700B21995 /* ThirdPartyMacro.swift in Sources */,
 				BDF47D80228288F900941AB9 /* ShoppingCartAccountView.swift in Sources */,
 				A7284401224DBB7700F82F30 /* SwiftMoyaNetWorkServiceUser.swift in Sources */,
-				A7B4E728228160BA0012914A /* ShoppingMallRightSideleftPictureCollectionViewCell.swift in Sources */,
+				A7B4E728228160BA0012914A /* ProductRightSideleftPictureCollectionViewCell.swift in Sources */,
 				BDEF7793228575A800ED0AC0 /* CommonPayCell.swift in Sources */,
 				A72843FC224DB6B800F82F30 /* SwiftMoyaServiceUserApi.swift in Sources */,
 				A7CC750622714306003C4F38 /* MessageNoticeHeaderCollectionReusableView.swift in Sources */,
@@ -2705,6 +2794,7 @@
 				A7CC753A2271B98B003C4F38 /* AddressManagerAddTableViewCell.swift in Sources */,
 				A71AF0AC226EDE37001730FE /* SearchNavigationbarView.swift in Sources */,
 				BDD4FB1422840954006FE833 /* ShoppingCartOrderPayView.swift in Sources */,
+				A70B2C222286BF5900B2449F /* ProductDetailTableViewHeaderView.swift in Sources */,
 				A7CC75432271E038003C4F38 /* SelfMentionContactsListViewController.swift in Sources */,
 				BDF47D872282C92200941AB9 /* ShoppingCartListTableViewHeader.swift in Sources */,
 				A7778CDF22461BAD00C7C47A /* PhoneCountryAreaSectionHeaderView.swift in Sources */,
@@ -2714,15 +2804,17 @@
 				BD20F1D32283D0ED00677D8E /* ShoppingCartPaySuccessCell.swift in Sources */,
 				A71AA52822732173008FF1A5 /* SwiftMoyaNetWorkServiceConfig.swift in Sources */,
 				A775CC0322377C6500EBDCF8 /* EmptyView.swift in Sources */,
+				A70B2C102286A3BC00B2449F /* ProductDetailModel.swift in Sources */,
 				A72A72A922321DE000B21995 /* NumberKeyboard.swift in Sources */,
 				A79057082276FEB00037F823 /* SelfMentionContactsModel.swift in Sources */,
+				A70B2C272286C5D600B2449F /* ProductDetailFSPagerViewCell.swift in Sources */,
 				A72A72AA22321DE000B21995 /* Log.swift in Sources */,
 				A72A72B622321DE000B21995 /* Extension+NSRange.swift in Sources */,
 				A75414FD224B5F28002480B5 /* MobileLoginViewController.swift in Sources */,
 				A771F07C226D4E1C007999DB /* AddressPOITableViewCell.swift in Sources */,
 				A72A72AE22321DE000B21995 /* CountdownButton.swift in Sources */,
 				A7A98E28227FD6C6005306E9 /* ShoppingMallListViewController.swift in Sources */,
-				A7B4E71F228131720012914A /* ShoppingMallSlidingLeftRightCollectionViewCell.swift in Sources */,
+				A7B4E71F228131720012914A /* ProductSlidingLeftRightCollectionViewCell.swift in Sources */,
 				A77F2CB72232010F001BD3F6 /* MineViewController.swift in Sources */,
 				A7778CA92244904500C7C47A /* Extension+Gifu.GIFImageView.swift in Sources */,
 				A7A98E02227E8900005306E9 /* ProductSearchListModel.swift in Sources */,
@@ -2757,7 +2849,7 @@
 				A72A72D122321E2700B21995 /* HTMLURLMacro.swift in Sources */,
 				A72A73162232481600B21995 /* WeChatpayManager.swift in Sources */,
 				A7CC750F22715AAC003C4F38 /* MessageDetailesTableViewCell.swift in Sources */,
-				A7B4E72D228176060012914A /* ShoppingMallBarChartCollectionViewCell.swift in Sources */,
+				A7B4E72D228176060012914A /* ProductMallBarChartCollectionViewCell.swift in Sources */,
 				A7CC7516227161D5003C4F38 /* SetViewController.swift in Sources */,
 				A7778CBA2244F14B00C7C47A /* Extension+UIViewController.swift in Sources */,
 				A7CC752C2271A1AE003C4F38 /* SetPasswordViewController.swift in Sources */,

+ 5 - 5
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/FloorCell/ShoppingMallBarChart/ShoppingMallBarChartCollectionViewCell.swift

@@ -9,7 +9,7 @@
 import UIKit
 import RxSwift
 
-class ShoppingMallBarChartCollectionViewCell: UICollectionViewCell {
+class ProductMallBarChartCollectionViewCell: UICollectionViewCell {
     
     let disposeBag = DisposeBag()
     
@@ -22,10 +22,10 @@ class ShoppingMallBarChartCollectionViewCell: UICollectionViewCell {
     typealias ReduceClosure = (_ productModel: ProductModel?,_ indexPath:IndexPath?) -> Void
     var reduceClosure : ReduceClosure?
     
-    class func cellWith(collectionView:UICollectionView,indexPath:IndexPath) -> ShoppingMallBarChartCollectionViewCell {
-        let ID = "ShoppingMallBarChartCollectionViewCell"
-        collectionView.register(ShoppingMallBarChartCollectionViewCell.self, forCellWithReuseIdentifier: ID)
-        let cell : ShoppingMallBarChartCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: ID, for: indexPath) as! ShoppingMallBarChartCollectionViewCell
+    class func cellWith(collectionView:UICollectionView,indexPath:IndexPath) -> ProductMallBarChartCollectionViewCell {
+        let ID = "ProductMallBarChartCollectionViewCell"
+        collectionView.register(ProductMallBarChartCollectionViewCell .self, forCellWithReuseIdentifier: ID)
+        let cell : ProductMallBarChartCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: ID, for: indexPath) as! ProductMallBarChartCollectionViewCell
         cell.indexPath = indexPath
         return cell
     }

+ 6 - 6
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/FloorCell/ShoppingMallRightSideleftPicture/ShoppingMallRightSideleftPictureCollectionViewCell.swift

@@ -1,5 +1,5 @@
 //
-//  ShoppingMallRightSideleftPictureCollectionViewCell.swift
+//  ProductRightSideleftPictureCollectionViewCell.swift
 //  RainbowPlanet
 //
 //  Created by 南鑫林 on 2019/5/7.
@@ -9,14 +9,14 @@
 import UIKit
 import RxSwift
 
-class ShoppingMallRightSideleftPictureCollectionViewCell: UICollectionViewCell {
+class ProductRightSideleftPictureCollectionViewCell: UICollectionViewCell {
     let disposeBag = DisposeBag()
     typealias PlusClosure = (_ productModel: ProductModel?,_ indexPath:IndexPath?) -> Void
     var plusClosure : PlusClosure?
-    class func cellWith(collectionView:UICollectionView,indexPath:IndexPath) -> ShoppingMallRightSideleftPictureCollectionViewCell {
-        let ID = "ShoppingMallRightSideleftPictureCollectionViewCell"
-        collectionView.register(ShoppingMallRightSideleftPictureCollectionViewCell.self, forCellWithReuseIdentifier: ID)
-        let cell : ShoppingMallRightSideleftPictureCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: ID, for: indexPath) as! ShoppingMallRightSideleftPictureCollectionViewCell
+    class func cellWith(collectionView:UICollectionView,indexPath:IndexPath) -> ProductRightSideleftPictureCollectionViewCell {
+        let ID = "ProductRightSideleftPictureCollectionViewCell"
+        collectionView.register(ProductRightSideleftPictureCollectionViewCell.self, forCellWithReuseIdentifier: ID)
+        let cell : ProductRightSideleftPictureCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: ID, for: indexPath) as! ProductRightSideleftPictureCollectionViewCell
         cell.indexPath = indexPath
         return cell
     }

+ 6 - 6
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/FloorCell/ShoppingMallSlidingLeftRight/ShoppingMallSlidingLeftRightCollectionViewCell.swift

@@ -1,5 +1,5 @@
 //
-//  ShoppingMallSlidingLeftRightCollectionViewCell.swift
+//  ProductSlidingLeftRightCollectionViewCell.swift
 //  RainbowPlanet
 //
 //  Created by 南鑫林 on 2019/5/7.
@@ -9,16 +9,16 @@
 import UIKit
 import RxSwift
 
-class ShoppingMallSlidingLeftRightCollectionViewCell: UICollectionViewCell {
+class ProductSlidingLeftRightCollectionViewCell: UICollectionViewCell {
     let disposeBag = DisposeBag()
     
     typealias PlusClosure = (_ productModel: ProductModel?,_ indexPath:IndexPath?) -> Void
     var plusClosure : PlusClosure?
     
-    class func cellWith(collectionView:UICollectionView,indexPath:IndexPath) -> ShoppingMallSlidingLeftRightCollectionViewCell {
-        let ID = "ShoppingMallSlidingLeftRightCollectionViewCell"
-        collectionView.register(ShoppingMallSlidingLeftRightCollectionViewCell.self, forCellWithReuseIdentifier: ID)
-        let cell : ShoppingMallSlidingLeftRightCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: ID, for: indexPath) as! ShoppingMallSlidingLeftRightCollectionViewCell
+    class func cellWith(collectionView:UICollectionView,indexPath:IndexPath) -> ProductSlidingLeftRightCollectionViewCell {
+        let ID = "ProductSlidingLeftRightCollectionViewCell"
+        collectionView.register(ProductSlidingLeftRightCollectionViewCell.self, forCellWithReuseIdentifier: ID)
+        let cell : ProductSlidingLeftRightCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: ID, for: indexPath) as! ProductSlidingLeftRightCollectionViewCell
         cell.indexPath = indexPath
         return cell
     }

RainbowPlanet/RainbowPlanet/Modules/ShoppingCartModule/ShoppingCart/View/ShoppingCartHotSale/ProductSlidingTopBottomCollectionViewCell.swift → RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/CollectionViewCell/ProductSlidingTopBottom/ProductSlidingTopBottomCollectionViewCell.swift


RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/ProductCollectionReusableView/ProductFloorBannerView.swift → RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorBannerView.swift


RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/ProductCollectionReusableView/ProductFloorCenterHeaderCollectionReusableView.swift → RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorCenterHeaderCollectionReusableView.swift


RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/ProductCollectionReusableView/ProductFloorCenterTitleView.swift → RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorCenterTitleView.swift


RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/ProductCollectionReusableView/ProductFloorFullLeftHeaderCollectionReusableView.swift → RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorFullLeftHeaderCollectionReusableView.swift


RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/ProductCollectionReusableView/ProductFloorLeftHeaderCollectionReusableView.swift → RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorLeftHeaderCollectionReusableView.swift


RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/ProductCollectionReusableView/ProductFloorTitleView.swift → RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/ProductCollectionReusableView/ProductFloorTitleView.swift


RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/ProductView/ProductHBigTableViewCell.swift → RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/TableViewCell/ProductHBigTableViewCell.swift


RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/ProductView/ProductHSmallTableViewCell.swift → RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/Product/TableViewCell/ProductHSmallTableViewCell.swift


+ 60 - 0
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ProductDetail/View/ProductDetailFSPagerViewCell.swift

@@ -0,0 +1,60 @@
+//
+//  ProductDetailFSPagerViewCell.swift
+//  RainbowPlanet
+//
+//  Created by 南鑫林 on 2019/5/11.
+//  Copyright © 2019 RainbowPlanet. All rights reserved.
+//
+
+import UIKit
+import FSPagerView
+class ProductDetailFSPagerViewCell: FSPagerViewCell {
+    class func cellWith(collectionView:FSPagerView,index:Int) -> ProductDetailFSPagerViewCell {
+        let ID = "ProductDetailFSPagerViewCell"
+        collectionView.register(ProductDetailFSPagerViewCell.self, forCellWithReuseIdentifier: ID)
+        let cell : ProductDetailFSPagerViewCell =
+            collectionView.dequeueReusableCell(withReuseIdentifier: ID, at: index) as! ProductDetailFSPagerViewCell
+        cell.index = index
+        return cell
+    }
+    //MARK: - indexPath
+    var index: Int?{
+        didSet {
+            
+        }
+    }
+    //MARK: - 初始化
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        setupViews()
+        setupLayouts()
+    }
+    
+    required init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    //MARK: - 设置view
+    private func setupViews() {
+        addSubview(productImageView)
+    }
+    
+    private func setupLayouts() {
+        productImageView.snp.makeConstraints { (make) in
+            make.center.equalToSuperview()
+            make.size.equalTo(172)
+        }
+
+    }
+    
+    private lazy var productImageView: UIImageView = {
+        let productImageView = UIImageView()
+        return productImageView
+    }()
+    
+    var imageNames: Array<String>?{
+        didSet {
+            productImageView.kf.setImage(with: kURLImage(name: imageNames?[index ?? 0] ?? "pic_preload"), placeholder: kImage(name: "pic_preload"))
+        }
+    }
+}

+ 85 - 0
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ProductDetail/View/ProductDetailProductInfoTableViewCell.swift

@@ -0,0 +1,85 @@
+//
+//  ProductDetailProductInfoTableViewCell.swift
+//  RainbowPlanet
+//
+//  Created by 南鑫林 on 2019/5/11.
+//  Copyright © 2019 RainbowPlanet. All rights reserved.
+//
+
+import UIKit
+
+class ProductDetailProductInfoTableViewCell: UITableViewCell {
+    
+    class func cellWith(tableView:UITableView,indexPath:IndexPath) -> ProductDetailProductInfoTableViewCell {
+        let ID = "ProductDetailProductInfoTableViewCell"
+        tableView.register(ProductDetailProductInfoTableViewCell.self, forCellReuseIdentifier: ID)
+        let cell : ProductDetailProductInfoTableViewCell = tableView.dequeueReusableCell(withIdentifier: ID, for: indexPath) as! ProductDetailProductInfoTableViewCell
+        cell.indexPath = indexPath
+        return cell
+    }
+    
+    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
+        super.init(style: style, reuseIdentifier: reuseIdentifier)
+        setupViews()
+        setupLayouts()
+    }
+    
+    required init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    var indexPath: IndexPath? {
+        didSet {
+            
+        }
+    }
+    //MRAK: - 设置View
+    private func setupViews() {
+        self.selectionStyle = .none
+    }
+    
+    private func setupLayouts() {
+        
+    }
+    
+    private lazy var topBgView: UIView = {
+        let topBgView = UIView()
+        topBgView.backgroundColor = kFFA42FColor
+        return topBgView
+    }()
+    
+    private lazy var sellPriceLabel : UILabel = {
+        let sellPriceLabel = UILabel()
+        sellPriceLabel.textColor = UIColor.white
+        sellPriceLabel.font = kMediumFont24
+        return sellPriceLabel
+    }()
+    
+    private lazy var markPriceLabel : UILabel = {
+        let markPriceLabel = UILabel()
+        markPriceLabel.textColor = UIColor.white
+        markPriceLabel.font = kRegularFont13
+        return markPriceLabel
+    }()
+    
+    private lazy var soldNumberLabel : UILabel = {
+        let soldNumberLabel = UILabel()
+        soldNumberLabel.textColor = UIColor.white
+        soldNumberLabel.font = kRegularFont13
+        return soldNumberLabel
+    }()
+    
+    private lazy var stockLabel : UILabel = {
+        let markPrice = UILabel()
+        markPrice.textColor = UIColor.white
+        markPrice.font = kRegularFont13
+        return markPrice
+    }()
+    
+    private lazy var bottomBgView: UIView = {
+        let bottomBgView = UIView()
+        bottomBgView.backgroundColor = UIColor.white
+        return bottomBgView
+    }()
+
+}

+ 113 - 0
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ProductDetail/View/ProductDetailTableViewHeaderView.swift

@@ -0,0 +1,113 @@
+//
+//  ProductDetailTableViewHeaderView.swift
+//  RainbowPlanet
+//
+//  Created by 南鑫林 on 2019/5/11.
+//  Copyright © 2019 RainbowPlanet. All rights reserved.
+//
+
+import UIKit
+import FSPagerView
+
+class ProductDetailTableViewHeaderView: BaseView {
+    
+    
+    var productDetailModel : ProductDetailModel? {
+        didSet {
+            if !(productDetailModel?.imgs?.isEmpty ?? true) {
+                let pageControlWidth = CGFloat((productDetailModel?.imgs!.count)!) * kScaleValue(value: 8) +  CGFloat((productDetailModel?.imgs!.count)! - 1) * kScaleValue(value: 8)
+                    pageControl.snp.remakeConstraints { (make) in
+                        make.bottom.equalTo(-12)
+                        make.height.equalTo(8)
+                        make.centerX.equalToSuperview()
+                        make.width.equalTo(pageControlWidth)
+                    }
+                pageControl.numberOfPages = (productDetailModel?.imgs!.count)!
+                if productDetailModel?.isConfirmSale == 0 {
+                    self.soldOutImageView.isHidden = true
+                }else {
+                    self.soldOutImageView.isHidden = false
+                }
+                pagerView.reloadData()
+            }
+        }
+    }
+    
+    
+    override func setupViews() {
+        backgroundColor = UIColor.white
+        addSubview(pagerView)
+        addSubview(pageControl)
+        pagerView.addSubview(soldOutImageView)
+    }
+    
+    override func setupLayouts() {
+        pagerView.snp.makeConstraints { (make) in
+            make.top.equalTo(kSafeStatusBarHeight)
+            make.left.right.bottom.equalToSuperview()
+        }
+        soldOutImageView.snp.makeConstraints { (make) in
+            make.center.equalToSuperview()
+            make.size.equalTo(91)
+        }
+    }
+    
+    private lazy var pagerView: FSPagerView = {
+        let pagerView = FSPagerView()
+        pagerView.delegate = self
+        pagerView.dataSource = self
+        pagerView.scrollDirection = .horizontal
+        pagerView.automaticSlidingInterval = 3.0
+        pagerView.isInfinite = true
+        pagerView.transformer = FSPagerViewTransformer(type: FSPagerViewTransformerType.coverFlow)
+        pagerView.itemSize = CGSize(width:kScreenWidth, height:251)
+        pagerView.decelerationDistance = FSPagerView.automaticDistance
+        
+        return pagerView
+    }()
+    
+    private lazy var pageControl: NXLPageControl = {
+        let pageControl = NXLPageControl()
+        pageControl.pointSize = CGSize.init(width: kScaleValue(value: 5), height: 5)
+        pageControl.currentWidthMultiple = 1//当前点的宽度为其他点的4倍
+        pageControl.localPointSpace = 8
+        pageControl.currentColor = kFFA42FColor
+        pageControl.otherColor = UIColor(white: 0, alpha: 0.2)
+        pageControl.clickPoint { [weak self] (index) in
+            
+        }
+        return pageControl
+    }()
+    
+    private lazy var soldOutImageView: UIImageView = {
+        let soldOutImageView = UIImageView()
+        soldOutImageView.image = kImage(name: "common_goods_pic_soldout")
+        return soldOutImageView
+    }()
+    
+}
+
+extension ProductDetailTableViewHeaderView: FSPagerViewDataSource,FSPagerViewDelegate {
+    func numberOfItems(in pagerView: FSPagerView) -> Int {
+        return productDetailModel?.imgs?.isEmpty ?? true ? 0 : productDetailModel?.imgs?.count ?? 0
+    }
+    func pagerView(_ pagerView: FSPagerView, cellForItemAt index: Int) -> FSPagerViewCell {
+        let cell  = ProductDetailFSPagerViewCell.cellWith(collectionView: pagerView, index: index)
+        cell.imageNames = productDetailModel?.imgs
+        return cell
+    }
+    
+    func pagerView(_ pagerView: FSPagerView, didSelectItemAt index: Int) {
+        pagerView.deselectItem(at: index, animated: true)
+        pagerView.scrollToItem(at: index, animated: true)
+    }
+    
+    func pagerViewWillEndDragging(_ pagerView: FSPagerView, targetIndex: Int) {
+        self.pageControl.currentPage = targetIndex
+    }
+    
+    func pagerViewDidEndScrollAnimation(_ pagerView: FSPagerView) {
+        self.pageControl.currentPage = pagerView.currentIndex
+    }
+    
+}

+ 98 - 0
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ProductDetail/View/ProductDetailView.swift

@@ -0,0 +1,98 @@
+//
+//  ProductDetailView.swift
+//  RainbowPlanet
+//
+//  Created by 南鑫林 on 2019/5/11.
+//  Copyright © 2019 RainbowPlanet. All rights reserved.
+//
+
+import UIKit
+
+class ProductDetailView: BaseView {
+    
+    var productDetailModel : ProductDetailModel? {
+        didSet {
+            tableView.ly_startLoading()
+            tableView.reloadData()
+            if productDetailModel?.imgs?.isEmpty ?? true {
+                tableView.tableHeaderView = nil
+            }else {
+                tableView.ly_hideEmpty()
+                tableView.tableHeaderView = productDetailTableViewHeaderView
+                productDetailTableViewHeaderView.productDetailModel = productDetailModel
+            }
+           
+        }
+    }
+    
+    override func setupViews() {
+        addSubview(tableView)
+        if #available(iOS 11.0, *) {
+            tableView.contentInsetAdjustmentBehavior = .never
+        }
+        let emptyView =  EmptyView.shared.diyCustomEmptyViewStyle2(iconStr: "page04", titleStr: "当前暂无数据")
+        emptyView.contentViewY = kScaleValue(value: 182)
+        tableView.ly_emptyView = emptyView
+    }
+    
+    override func setupLayouts() {
+        tableView.snp.makeConstraints { (make) in
+            make.edges.equalToSuperview()
+        }
+    }
+    
+    lazy var tableView: UITableView = {
+        let tableView = UITableView(frame: CGRect.zero, style: UITableView.Style.grouped)
+        tableView.separatorStyle = .none
+        tableView.backgroundColor = kf7f8faColor
+        tableView.dataSource = self
+        tableView.delegate = self
+        tableView.estimatedRowHeight = 0.000001
+        tableView.estimatedSectionFooterHeight = 0.000001
+        tableView.estimatedSectionHeaderHeight = 0.000001
+        return tableView
+    }()
+    
+    lazy var productDetailTableViewHeaderView: ProductDetailTableViewHeaderView = {
+        let productDetailTableViewHeaderView = ProductDetailTableViewHeaderView(frame: CGRect(x: 0, y: 0, width: kScreenWidth, height: 251+kSafeTabBarHeight))
+        return productDetailTableViewHeaderView
+    }()
+    
+}
+
+extension ProductDetailView : UITableViewDelegate, UITableViewDataSource {
+    func numberOfSections(in tableView: UITableView) -> Int {
+        return 0
+    }
+    
+    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return 1
+    }
+    
+    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        return UITableViewCell()
+    }
+    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+        return 0
+    }
+    
+    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
+        return 10
+    }
+    
+    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
+        return nil
+    }
+    
+    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
+        return 0.000001
+    }
+    
+    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
+        return nil
+    }
+    
+}
+
+
+

+ 52 - 0
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ProductDetail/ViewController/ProductDetailViewController.swift

@@ -0,0 +1,52 @@
+//
+//  ProductDetailViewController.swift
+//  RainbowPlanet
+//
+//  Created by 南鑫林 on 2019/5/11.
+//  Copyright © 2019 RainbowPlanet. All rights reserved.
+//
+
+import UIKit
+
+class ProductDetailViewController: BaseViewController {
+    
+    var productModel : ProductModel?
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        setupViews()
+        setupLayouts()
+        setupData()
+    }
+    
+    override func setupViews() {
+        navigationBar.wr_setBackgroundAlpha(alpha: 0)
+        view.addSubview(productDetailView)
+        view.insertSubview(navigationBar, aboveSubview: productDetailView)
+    }
+    
+    override func setupLayouts() {
+        productDetailView.snp.makeConstraints { (make) in
+            make.edges.equalToSuperview()
+        }
+    }
+    override func setupData() {
+        productDetailView.tableView.addHeaderWithHeader(withBeginRefresh: true, animation: false) {
+            [weak self] (page) in
+            self?.productDetailApi()
+        }
+    }
+    
+    private func productDetailApi() {
+        SwiftMoyaNetWorkServiceProduct.shared().productDetailApi(id: self.productModel?.id ?? 0) {
+            [weak self] (productDetailModel) -> (Void) in
+            self?.productDetailView.productDetailModel = productDetailModel as? ProductDetailModel
+        }
+    }
+    
+    lazy var productDetailView: ProductDetailView = {
+        let productDetailView = ProductDetailView()
+        return productDetailView
+    }()
+
+}

+ 8 - 2
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/Floor/ShoppingMallFloorTableViewCell.swift

@@ -165,7 +165,7 @@ extension ShoppingMallFloorTableViewCell: UICollectionViewDelegateFlowLayout,UIC
 
         switch cmsRuleModel?.showType {
         case 0: // 0:左图右字;
-            let cell = ShoppingMallRightSideleftPictureCollectionViewCell.cellWith(
+            let cell = ProductRightSideleftPictureCollectionViewCell.cellWith(
                 collectionView: collectionView, indexPath: indexPath)
             if !(productModelsArrays?.isEmpty ?? true) {
                 let productModels = productModelsArrays![indexPath.section]
@@ -188,7 +188,7 @@ extension ShoppingMallFloorTableViewCell: UICollectionViewDelegateFlowLayout,UIC
             
             return cell
         case 1: // 1:通栏大图
-            let cell = ShoppingMallBarChartCollectionViewCell.cellWith(
+            let cell = ProductMallBarChartCollectionViewCell.cellWith(
                 collectionView: collectionView, indexPath: indexPath)
             if !(productModelsArrays?.isEmpty ?? true) {
                 let productModels = productModelsArrays![indexPath.section]
@@ -219,6 +219,12 @@ extension ShoppingMallFloorTableViewCell: UICollectionViewDelegateFlowLayout,UIC
         }
     }
     
+    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        let productModels = productModelsArrays![indexPath.section]
+        let productModel = productModels[indexPath.row]
+        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ProductDetailVC"), object: productModel)
+    }
+    
     func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
         
         let cmsRuleModel = cmsRuleModels?[(indexPath.section)]

+ 1 - 1
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/View/ShoppingMallFloor/FloorCell/ShoppingMallSlidingLeftRight/ShoppingMallSlidingLeftRightBgCollectionViewCell.swift

@@ -105,7 +105,7 @@ extension ShoppingMallSlidingLeftRightBgCollectionViewCell: UICollectionViewDele
     }
     
     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-        let cell = ShoppingMallSlidingLeftRightCollectionViewCell.cellWith(collectionView: collectionView, indexPath: indexPath)
+        let cell = ProductSlidingLeftRightCollectionViewCell.cellWith(collectionView: collectionView, indexPath: indexPath)
         cell.productModel = productModels?[indexPath.row]
         cell.plusClosure = {
             [weak self] (productModel,indexPath) in

+ 12 - 0
RainbowPlanet/RainbowPlanet/Modules/ShoppingMallModule/ShoppingMall/ViewController/ShoppingMallViewController.swift

@@ -10,6 +10,11 @@ import UIKit
 
 class ShoppingMallViewController: BaseViewController {
     
+    deinit {
+        NotificationCenter.default.removeObserver(observe!)
+    }
+    weak var observe : NSObjectProtocol?
+    
     override func viewDidLoad() {
         super.viewDidLoad()
         setupViews()
@@ -35,6 +40,13 @@ class ShoppingMallViewController: BaseViewController {
     }
     
     override func setupData() {
+
+        observe = NotificationCenter.default.addObserver(forName: NSNotification.Name("ProductDetailVC"), object: nil, queue: OperationQueue.main) {[weak self] (notification) in
+            let productModel = notification.object as! ProductModel
+            let vc = ProductDetailViewController()
+            vc.productModel = productModel
+            self?.navigationController?.pushViewController(vc, animated: true)
+        }
         //搜索
         navigationBarView.searchBlock = {
             [weak self] in

+ 201 - 0
RainbowPlanet/RainbowPlanet/Service/Model/ProductModel/ProductDetailModel.swift

@@ -0,0 +1,201 @@
+//
+//	ProductDetailModel.swift
+//	Model file generated using JSONExport: https://github.com/Ahmed-Ali/JSONExport
+
+import Foundation 
+import ObjectMapper
+
+class ProductDetailModel : NSObject, Mappable{
+
+	var attributeCategoryId : Int?
+	var bigImg : String?
+	var categoryId1 : Int?
+	var categoryId2 : Int?
+	var categoryId3 : Int?
+	var city : [Int]?
+	var deliverType : Int?
+	var desc : String?
+	var id : Int?
+	var img : String?
+	var imgs : [String]?
+	var isConfirmSale : Int?
+	var label : [ProductDetailLabelModel]?
+	var limitNumber : Int?
+	var limitType : String?
+	var name : String?
+	var otherCode : String?
+	var parameter : [ProductDetailParameterModel]?
+	var receiveTime : String?
+	var receiveType : Int?
+	var report : [String]?
+	var saleName : String?
+	var shopId : Int?
+	var shopName : String?
+	var sku : [ProductDetailSkuModel]?
+	var spec : [ProductDetailSpecNameModel]?
+	var spuCode : String?
+	var storeTypeIds : String?
+	var subtitle : String?
+	var video : String?
+
+
+	class func newInstance(map: Map) -> Mappable?{
+		return ProductDetailModel()
+	}
+	required init?(map: Map){}
+	private override init(){}
+
+	func mapping(map: Map)
+	{
+		attributeCategoryId <- map["attribute_category_id"]
+		bigImg <- map["big_img"]
+		categoryId1 <- map["category_id1"]
+		categoryId2 <- map["category_id2"]
+		categoryId3 <- map["category_id3"]
+		city <- map["city"]
+		deliverType <- map["deliver_type"]
+		desc <- map["desc"]
+		id <- map["id"]
+		img <- map["img"]
+		imgs <- map["imgs"]
+		isConfirmSale <- map["is_confirm_sale"]
+		label <- map["label"]
+		limitNumber <- map["limit_number"]
+		limitType <- map["limit_type"]
+		name <- map["name"]
+		otherCode <- map["other_code"]
+		parameter <- map["parameter"]
+		receiveTime <- map["receive_time"]
+		receiveType <- map["receive_type"]
+		report <- map["report"]
+		saleName <- map["sale_name"]
+		shopId <- map["shop_id"]
+		shopName <- map["shop_name"]
+		sku <- map["sku"]
+		spec <- map["spec"]
+		spuCode <- map["spu_code"]
+		storeTypeIds <- map["store_type_ids"]
+		subtitle <- map["subtitle"]
+		video <- map["video"]
+		
+	}
+}
+
+class ProductDetailLabelModel : NSObject, Mappable{
+    
+    var isMain : Int?
+    var labelId : Int?
+    
+    
+    class func newInstance(map: Map) -> Mappable?{
+        return ProductDetailLabelModel()
+    }
+    required init?(map: Map){}
+    private override init(){}
+    
+    func mapping(map: Map)
+    {
+        isMain <- map["is_main"]
+        labelId <- map["label_id"]
+        
+    }
+    
+}
+
+class ProductDetailParameterModel : NSObject, Mappable{
+    
+    var id : Int?
+    var name : String?
+    var value : String?
+    
+    
+    class func newInstance(map: Map) -> Mappable?{
+        return ProductDetailParameterModel()
+    }
+    required init?(map: Map){}
+    private override init(){}
+    
+    func mapping(map: Map)
+    {
+        id <- map["id"]
+        name <- map["name"]
+        value <- map["value"]
+        
+    }
+}
+
+class ProductDetailSkuModel : NSObject, Mappable{
+    
+    var costPrice : Int?
+    var id : Int?
+    var isMain : Int?
+    var names : [ProductDetailSkuNameModel]?
+    var originPrice : Int?
+    var price : Int?
+    var stock : Int?
+    
+    
+    class func newInstance(map: Map) -> Mappable?{
+        return ProductDetailSkuModel()
+    }
+    required init?(map: Map){}
+    private override init(){}
+    
+    func mapping(map: Map)
+    {
+        costPrice <- map["cost_price"]
+        id <- map["id"]
+        isMain <- map["is_main"]
+        names <- map["names"]
+        originPrice <- map["origin_price"]
+        price <- map["price"]
+        stock <- map["stock"]
+        
+    }
+    
+}
+
+class ProductDetailSkuNameModel : NSObject, Mappable{
+    
+    var attributeItemId : Int?
+    var name : String?
+    var value : String?
+    
+    
+    class func newInstance(map: Map) -> Mappable?{
+        return ProductDetailSkuNameModel()
+    }
+    required init?(map: Map){}
+    private override init(){}
+    
+    func mapping(map: Map)
+    {
+        attributeItemId <- map["attribute_item_id"]
+        name <- map["name"]
+        value <- map["value"]
+        
+    }
+}
+
+class ProductDetailSpecNameModel : NSObject, Mappable{
+    
+    var attributeItemId : Int?
+    var name : String?
+    var value : [String]?
+    
+    
+    class func newInstance(map: Map) -> Mappable?{
+        return ProductDetailSpecNameModel()
+    }
+    required init?(map: Map){}
+    private override init(){}
+    
+    func mapping(map: Map)
+    {
+        attributeItemId <- map["attribute_item_id"]
+        name <- map["name"]
+        value <- map["value"]
+        
+    }
+    
+}

+ 19 - 3
RainbowPlanet/RainbowPlanet/Service/SwiftMoyaService/SwiftMoyaServiceApi/SwiftMoyaServiceProduct/SwiftMoyaNetWorkServiceProduct.swift

@@ -84,6 +84,22 @@ class SwiftMoyaNetWorkServiceProduct: NSObject {
         }
     }
     
+    // MARK: - 商品详情
+    /// 商品详情
+    ///
+    /// - Parameters:
+    ///   - ids:
+    ///   - completion: 回调
+    func productDetailApi(id:Int = 0,completion: @escaping apiCallBack) {
+        var parameters = Dictionary<String,Any>()
+        parameters.updateValue(id, forKey: "id")
+        SwiftProgressHUD.shared().showWait()
+        SwiftMoyaNetWorkManager.shared().request(ProductDetailModel.self, target: MultiTarget(SwiftMoyaServiceProductApi.productDetail(parameters: parameters))) { (productDetailModel) in
+            SwiftProgressHUD.shared().hide()
+            completion(productDetailModel)
+        }
+    }
+    
     // MARK: - 购物车列表
     /// 购物车列表
     ///
@@ -118,11 +134,11 @@ class SwiftMoyaNetWorkServiceProduct: NSObject {
         
         parameters.updateValue(productMdl.shopId ?? 0, forKey: "shop_id")
         parameters.updateValue(productMdl.shopName ?? "", forKey: "shop_name")
-        parameters.updateValue(productMdl.id    ?? 0, forKey: "product_id")
+        parameters.updateValue(productMdl.id ?? 0, forKey: "product_id")
         parameters.updateValue(productMdl.price ?? 0, forKey: "product_price")
         parameters.updateValue(productMdl.skuId ?? 0, forKey: "sku_id")
-        parameters.updateValue(productMdl.totalCount       ?? 0, forKey: "amount")
-        parameters.updateValue(productMdl.isSelect     ?? 0, forKey: "is_select")
+        parameters.updateValue(productMdl.totalCount ?? 0, forKey: "amount")
+        parameters.updateValue(productMdl.isSelect ?? 0, forKey: "is_select")
         parameters.updateValue(productMdl.name ?? "", forKey: "product_name")
         parameters.updateValue(productMdl.img  ?? "", forKey: "product_img")
         parameters.updateValue(productMdl.skuName  ?? "", forKey: "sku_name")

+ 13 - 1
RainbowPlanet/RainbowPlanet/Service/SwiftMoyaService/SwiftMoyaServiceApi/SwiftMoyaServiceProduct/SwiftMoyaServiceProductApi.swift

@@ -21,6 +21,10 @@ public let kProductCategoryApi = "/product/categoryList"
 /// 首页商品
 public let kProductHomeProductApi = "/product/honmeProduct"
 
+// MARK: - 商品详情
+/// 商品详情
+public let kProductDetailApi = "/product/detail"
+
 // MARK: - 购物车列表
 /// 购物车列表
 public let kProductCartListApi = "/product/cartList"
@@ -51,6 +55,7 @@ public let kProductCartAllSelApi = "/cart/isSelectAll"
 /// - productSearch: 搜索、列表、热销
 /// - productCategory: 商品分类
 /// - productHomeProduct: 首页商品
+/// - productDetail: 商品详情
 /// - productCartList: 购物车列表
 /// - productCartAdd: 购物车-添加
 /// - productCartDelete: 购物车-删除
@@ -61,6 +66,7 @@ public enum SwiftMoyaServiceProductApi {
     case productSearch(parameters:Dictionary<String, Any>)
     case productCategory(parameters:Dictionary<String, Any>)
     case productHomeProduct(parameters:Dictionary<String, Any>)
+    case productDetail(parameters:Dictionary<String, Any>)
     case productCartList(parameters:Dictionary<String, Any>)
     case productCartAdd(parameters:Dictionary<String, Any>)
     case productCartDelete(parameters:Dictionary<String, Any>)
@@ -76,6 +82,7 @@ extension SwiftMoyaServiceProductApi: TargetType {
         case .productSearch,
              .productCategory,
              .productHomeProduct,
+             .productDetail,
              .productCartList,
              .productCartAdd,
              .productCartDelete,
@@ -95,6 +102,8 @@ extension SwiftMoyaServiceProductApi: TargetType {
             return kProductCategoryApi
         case .productHomeProduct:
             return kProductHomeProductApi
+        case .productDetail:
+            return kProductDetailApi
         case .productCartList:
             return kProductCartListApi
         case .productCartAdd:
@@ -115,7 +124,8 @@ extension SwiftMoyaServiceProductApi: TargetType {
         case .productSearch,
              .productCategory,
              .productHomeProduct,
-             .productCartList
+             .productCartList,
+             .productDetail
             :
             return .post
         case .productCartAdd,
@@ -138,6 +148,7 @@ extension SwiftMoyaServiceProductApi: TargetType {
         case .productSearch(var parameters),
              .productCategory(var parameters),
              .productHomeProduct(var parameters),
+             .productDetail(var parameters),
              .productCartList(var parameters),
              .productCartAdd(var parameters),
              .productCartDelete(var parameters),
@@ -169,6 +180,7 @@ extension SwiftMoyaServiceProductApi: TargetType {
         case .productSearch,
              .productCategory,
              .productHomeProduct,
+             .productDetail,
              .productCartList,
              .productCartAdd,
              .productCartDelete,

+ 23 - 0
RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/common_goods_pic_soldout.imageset/Contents.json

@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "common_goods_pic_soldout.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "common_goods_pic_soldout@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "common_goods_pic_soldout@3x.png",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

BIN
RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/common_goods_pic_soldout.imageset/common_goods_pic_soldout.png


BIN
RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/common_goods_pic_soldout.imageset/common_goods_pic_soldout@2x.png


BIN
RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/common_goods_pic_soldout.imageset/common_goods_pic_soldout@3x.png


RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/DefaultPage/pic_preload.imageset/Contents.json → RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/pic_preload.imageset/Contents.json


RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/DefaultPage/pic_preload.imageset/pic_preload.png → RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/pic_preload.imageset/pic_preload.png


RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/DefaultPage/pic_preload.imageset/pic_preload@2x.png → RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/pic_preload.imageset/pic_preload@2x.png


RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/DefaultPage/pic_preload.imageset/pic_preload@3x.png → RainbowPlanet/RainbowPlanet/Supporting Files/Assets.xcassets/CommonIcon/pic_preload.imageset/pic_preload@3x.png


+ 397 - 0
RainbowPlanet/RainbowPlanet/Tools/NXLPageControl/NXLPageControl.swift

@@ -0,0 +1,397 @@
+//
+//  NXLPageControl.swift
+//  ReceptionHall
+//
+//  Created by 南鑫林 on 2019/4/11.
+//  Copyright © 2019 南鑫林. All rights reserved.
+//
+
+import UIKit
+
+class NXLPageControl: UIControl {
+
+    var localNumberOfPages = NSInteger()//分页数量
+    var localCurrentPage = NSInteger()//当前点所在下标
+    var localPointSize = CGSize()//点的大小
+    var localPointSpace = CGFloat()//点之间的间距
+    var localOtherColor = UIColor()//未选中点的颜色
+    var localCurrentColor = UIColor()//当前点的颜色
+    var localOtherImage: UIImage?//未选中点的图片
+    var localCurrentImage: UIImage?//当前点的图片
+    var localIsSquare = Bool()//是否是方形点
+    var localCurrentWidthMultiple = CGFloat()//当前选中点宽度与未选中点的宽度的倍数
+    var localOtherBorderColor: UIColor?//未选中点的layerColor
+    var localOtherBorderWidth: CGFloat?//未选中点的layer宽度
+    var localCurrentBorderColor: UIColor?//未选中点的layerColor
+    var localCurrentBorderWidth: CGFloat?//未选中点的layer宽度
+    var localStartX: CGFloat?
+    var localStartY: CGFloat?
+    var clickIndex: ((_ result: NSInteger?) -> ())?
+
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        initialize()
+    }
+
+    required init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    func initialize() {
+        self.backgroundColor = UIColor.clear
+        localNumberOfPages = 0//必须传入总页数
+        localCurrentPage = 0//默认当前页数为第一页
+        localPointSize = CGSize.init(width: 6, height: 6)//默认点的宽高分别为6
+        localPointSpace = 8//默认点的间距为8
+        localIsSquare = false//默认是圆点
+        localOtherColor = UIColor.init(white: 1, alpha: 0.5)//默认未选中点的颜色为白色,透明度50%
+        localCurrentColor = UIColor.white//默认选中点的颜色为白色
+        localCurrentWidthMultiple = 1//当前选中点宽度与未选中点的宽度的倍数,默认为1倍
+        localStartX = 0
+        localStartY = 0
+        creatPointView()//创建view
+    }
+
+    var numberOfPages: NSInteger {
+        set {
+            if localNumberOfPages == newValue {
+                return
+            }
+            localNumberOfPages = newValue
+            creatPointView()
+        }
+        get {
+            return self.localNumberOfPages
+        }
+    }
+
+    var currentPage: NSInteger {
+        set {
+            if localCurrentPage == newValue {
+                return
+            }
+            exchangeCurrentView(oldSelectedIndex: localCurrentPage, newSelectedIndex: newValue)
+            localCurrentPage = newValue
+        }
+        get {
+            return self.localCurrentPage
+        }
+    }
+
+    var pointSize: CGSize {
+        set {
+            if localPointSize != newValue {
+                localPointSize = newValue
+                creatPointView()
+            }
+        }
+        get {
+            return self.localPointSize
+        }
+    }
+
+    var pointSpace: CGFloat {
+        set {
+            if localPointSpace != newValue{
+                localPointSpace = newValue
+                creatPointView()
+            }
+        }
+        get {
+            return self.localPointSpace
+        }
+    }
+
+    var otherColor: UIColor {
+        set {
+            if localOtherColor != newValue {
+                localOtherColor = newValue
+                creatPointView()
+            }
+        }
+        get {
+            return self.localOtherColor
+        }
+    }
+
+    var currentColor: UIColor {
+        set {
+            if localCurrentColor != newValue {
+                localCurrentColor = newValue
+                creatPointView()
+            }
+        }
+        get {
+            return self.localCurrentColor
+        }
+    }
+
+    var otherImage: UIImage {
+        set {
+            if localOtherImage != newValue {
+                localOtherImage = newValue
+                creatPointView()
+            }
+        }
+        get {
+            return self.localOtherImage!
+        }
+    }
+
+    var currentImage: UIImage {
+        set{
+            if localCurrentImage != newValue {
+                localCurrentImage = newValue
+                creatPointView()
+            }
+        }
+        get {
+            return self.localCurrentImage!
+        }
+    }
+
+    var isSquare: Bool {
+        set {
+            if localIsSquare != newValue {
+                localIsSquare = newValue
+                creatPointView()
+            }
+        }
+        get {
+            return self.localIsSquare
+        }
+    }
+
+    var currentWidthMultiple: CGFloat {
+        set {
+            if localCurrentWidthMultiple != newValue {
+                localCurrentWidthMultiple = newValue
+                creatPointView()
+            }
+        }
+        get {
+            return self.localCurrentWidthMultiple
+        }
+    }
+
+    var otherBorderColor: UIColor {
+        set {
+            localOtherBorderColor = newValue
+            creatPointView()
+        }
+        get {
+            return self.localOtherBorderColor!
+        }
+    }
+
+    var otherBorderWidth: CGFloat {
+        set {
+            localOtherBorderWidth = newValue
+            creatPointView()
+        }
+        get {
+            return self.localOtherBorderWidth!
+        }
+    }
+
+    var currentBorderColor: UIColor {
+        set {
+            localCurrentBorderColor = newValue
+            creatPointView()
+        }
+        get {
+            return self.localCurrentBorderColor!
+        }
+    }
+
+    var currentBorderWidth: CGFloat {
+        set {
+            localCurrentBorderWidth = newValue
+            creatPointView()
+        }
+        get {
+            return self.localCurrentBorderWidth!
+        }
+    }
+    
+    var startX: CGFloat {
+        set {
+            localStartX = newValue
+            creatPointView()
+        }
+        get {
+            return self.localStartX!
+        }
+    }
+    
+    var startY: CGFloat {
+        set {
+            localStartY = newValue
+            creatPointView()
+        }
+        get {
+            return self.localStartX!
+        }
+    }
+
+    func creatPointView() {
+        for view in self.subviews {
+            view.removeFromSuperview()
+        }
+
+        if localNumberOfPages <= 0 {//必须传入总页数
+            return
+        }
+
+        var startX: CGFloat = localStartX!
+        var startY: CGFloat = localStartY!
+        let mainWidth = CGFloat(localNumberOfPages) * (localPointSize.width + localPointSpace)
+
+        if self.frame.size.width > mainWidth {
+            startX = (self.frame.size.width - mainWidth) / 2
+        }
+
+        if self.frame.size.height > localPointSize.height {
+            startY = (self.frame.size.height - localPointSize.height) / 2
+        }
+
+        //创建点
+        for index in 0 ..< numberOfPages {
+            if index == localCurrentPage {//是当前点
+                let currentPointView = UIView.init()
+                let currentPointViewWidth = localPointSize.width * localCurrentWidthMultiple
+                currentPointView.frame = CGRect.init(x: startX, y: startY, width: currentPointViewWidth, height: localPointSize.height)
+                currentPointView.backgroundColor = localCurrentColor
+                currentPointView.tag = index + 1000
+                currentPointView.layer.cornerRadius = localIsSquare ? 0 : localPointSize.height / 2
+                currentPointView.layer.masksToBounds = true
+                currentPointView.layer.borderColor = localCurrentBorderColor != nil ? localCurrentBorderColor?.cgColor : localCurrentColor.cgColor
+                currentPointView.layer.borderWidth = localCurrentBorderWidth != nil ? localCurrentBorderWidth! : 0
+                currentPointView.isUserInteractionEnabled = true
+                self.addSubview(currentPointView)
+                let tapGesture = UITapGestureRecognizer.init(target: self, action: #selector(clickAction(tapGesture:)))//添加小圆点点击手势
+                currentPointView.addGestureRecognizer(tapGesture)
+                startX = currentPointView.frame.maxX + localPointSpace
+
+                if localCurrentImage != nil {
+                    currentPointView.backgroundColor = UIColor.clear
+                    let localCurrentImageView = UIImageView.init()
+                    localCurrentImageView.tag = index + 2000
+                    localCurrentImageView.frame = currentPointView.bounds
+                    localCurrentImageView.image = localCurrentImage
+                    currentPointView.addSubview(localCurrentImageView)
+                }
+            } else {//其他点
+                let otherPointView = UIView.init()
+                otherPointView.frame = CGRect.init(x: startX, y: startY, width: localPointSize.width, height: localPointSize.height)
+                otherPointView.backgroundColor = localOtherColor
+                otherPointView.tag = index + 1000
+                otherPointView.layer.cornerRadius = localIsSquare ? 0 : localPointSize.height / 2;
+                otherPointView.layer.borderColor = localOtherBorderColor != nil ? localOtherBorderColor?.cgColor : localOtherColor.cgColor
+                otherPointView.layer.borderWidth = localOtherBorderWidth != nil ? localOtherBorderWidth! : 0
+                otherPointView.layer.masksToBounds = true
+                otherPointView.isUserInteractionEnabled = true
+                self.addSubview(otherPointView)
+                let tapGesture = UITapGestureRecognizer.init(target: self, action: #selector(clickAction(tapGesture:)))
+                otherPointView.addGestureRecognizer(tapGesture)
+                startX = otherPointView.frame.maxX + localPointSpace
+
+                if localOtherImage != nil {
+                    otherPointView.backgroundColor = UIColor.clear
+                    let localOtherImageView = UIImageView.init()
+                    localOtherImageView.tag = index + 2000
+                    localOtherImageView.frame = otherPointView.bounds
+                    localOtherImageView.image = localOtherImage
+                    otherPointView.addSubview(localOtherImageView)
+                }
+            }
+        }
+    }
+
+    func exchangeCurrentView(oldSelectedIndex: NSInteger, newSelectedIndex: NSInteger) {//切换当前点和其他点
+        let oldPointView = self.viewWithTag(1000 + oldSelectedIndex)
+        let newPointView = self.viewWithTag(1000 + newSelectedIndex)
+
+        oldPointView?.layer.borderColor = localOtherBorderColor != nil ? localOtherBorderColor?.cgColor : localOtherColor.cgColor
+        oldPointView?.layer.borderWidth = localOtherBorderWidth != nil ? localOtherBorderWidth! : 0
+
+        newPointView?.layer.borderColor = localCurrentBorderColor != nil ? localCurrentBorderColor?.cgColor : localCurrentColor.cgColor
+        newPointView?.layer.borderWidth = localCurrentBorderWidth != nil ? localCurrentBorderWidth! : 0
+
+        oldPointView?.backgroundColor = localOtherColor
+        newPointView?.backgroundColor = localCurrentColor
+
+        if localCurrentWidthMultiple != 1 {//如果当前选中点的宽度与未选中的点宽度不一样,则要改变选中前后两点的frame
+            UIView.animate(withDuration: 0.3, animations: {
+                var oldPointFrame = oldPointView?.frame
+                if newSelectedIndex < oldSelectedIndex {
+                    oldPointFrame?.origin.x += self.localPointSize.width * (self.localCurrentWidthMultiple - 1)
+                }
+                oldPointFrame?.size.width = self.localPointSize.width
+                oldPointView?.frame = oldPointFrame!
+
+                var newPointFrame = newPointView?.frame
+                if newSelectedIndex > oldSelectedIndex {
+                    newPointFrame?.origin.x -= self.localPointSize.width * (self.localCurrentWidthMultiple - 1)
+                }
+                newPointFrame?.size.width = self.localPointSize.width * self.localCurrentWidthMultiple
+                newPointView?.frame = newPointFrame!
+            })
+
+        }
+
+        if localCurrentImage != nil {//切换选中图片和未选中图片
+            let view = oldPointView?.viewWithTag(oldSelectedIndex + 2000)
+
+            if view != nil {
+                let oldlocalCurrentImageView = view as! UIImageView
+
+                oldlocalCurrentImageView.frame = CGRect.init(x: 0, y: 0, width: localPointSize.width, height: localPointSize.height)
+                oldlocalCurrentImageView.image = localOtherImage
+            }
+        }
+
+        if localOtherImage != nil {//切换选中图片和未选中图片
+            let view = newPointView?.viewWithTag(newSelectedIndex + 2000)
+            if view != nil {
+                let oldlocalOtherImageView = view as! UIImageView
+                let width = localPointSize.width * localCurrentWidthMultiple
+
+                oldlocalOtherImageView.frame = CGRect.init(x: 0, y: 0, width: width, height: localPointSize.height)
+                oldlocalOtherImageView.image = localCurrentImage
+
+            }
+        }
+
+        if newSelectedIndex - oldSelectedIndex > 1 {//点击圆点,中间有跳过的点
+            for index in oldSelectedIndex + 1 ..< newSelectedIndex {
+                let view = self.viewWithTag(1000 + index)
+                var frame = view?.frame
+                frame?.origin.x -= localPointSize.width * (localCurrentWidthMultiple - 1)
+                frame?.size.width = localPointSize.width
+                view?.frame = frame!
+            }
+        }
+
+        if newSelectedIndex - oldSelectedIndex < -1 {//点击圆点,中间有跳过的点
+            for index in newSelectedIndex + 1 ..< oldSelectedIndex {
+                let view = self.viewWithTag(1000 + index)
+                var frame = view?.frame
+                frame?.origin.x += localPointSize.width * (localCurrentWidthMultiple - 1)
+                frame?.size.width = localPointSize.width
+                view?.frame = frame!
+            }
+        }
+    }
+
+    @objc func clickAction(tapGesture: UITapGestureRecognizer) {//点击小圆点
+        let index = (tapGesture.view?.tag)! - 1000
+        self.clickIndex?(index)
+
+    }
+
+    func clickPoint(index: @escaping (_ result: NSInteger?) -> ()) {
+        self.clickIndex = index;
+    }
+
+}