暂无描述

FKProDetailController.m 56KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374
  1. //
  2. // FKProDetailController.m
  3. // FirstLink
  4. //
  5. // Created by jack on 16/8/11.
  6. // Copyright © 2016年 FirstLink. All rights reserved.
  7. //
  8. #import "FKProDetailController.h"
  9. #import "FKPullPageTopView.h"
  10. #import "FKPullPageBottomView.h"
  11. #import "FKLadderTableView.h"
  12. #import "FKProSegmentView.h"
  13. #import "FKProServeDetailView.h"
  14. #import "FKProBottomView.h"
  15. #import "FKProHeaderView.h"
  16. #import "FKProductNavigationBar.h"
  17. #import "FKProductSelectSpecView.h"
  18. #import "GuideView.h"
  19. #import "XHImageViewer.h"
  20. #import "FKShareView.h"
  21. #import "FLShareHelper.h"
  22. #import "FLImageHelper.h"
  23. #import "FKAddBasketAnimTool.h"
  24. #import "FKCollectAnimationTool.h"
  25. #import "FKProDetailViewModel.h"
  26. #import "FKProDetailRequest.h"
  27. #import "FKProductDetailReform.h"
  28. #import "FKSubmitOrderController.h"
  29. #import "WebViewController.h"
  30. #import "FLControllerHelper.h"
  31. #import "ChatViewController.h"
  32. #import "FKProductAdviseController.h"
  33. #import "FKBasketController.h"
  34. #import "FKExploreListController.h"
  35. #import "FKPriceWarnEditController.h"
  36. #import "SchemaManager.h"
  37. #import "SDWebImageDownloader.h"
  38. #define CONTENT_OFFSET_KEYPATH @"contentOffset"
  39. typedef NS_ENUM(NSUInteger, kSpecActionTag) {
  40. kSpecActionTagBuy = 0,
  41. kSpecActionTagAddBasket,
  42. kSpecActionTagSelect,
  43. };
  44. static NSString *PRODUCT_HAS_SHOW_GUIDE_KEY = @"PRODUCT_HAS_SHOW_GUIDE_KEY";
  45. @interface FKProDetailController ()
  46. <UITableViewDataSource,
  47. UITableViewDelegate,
  48. RefreshControlDelegate,
  49. FLNetworkDelegate,
  50. FKCollectAnimationToolDelegate,
  51. PdProductShowCellDelegate,
  52. FKProductSelectSpecViewDelegate,
  53. FKProRecommendListCellDelegate>
  54. @property (nonatomic, strong) FKLadderTableView *ladderView;
  55. @property (nonatomic, strong) FKProSegmentView *segmentView;
  56. @property (nonatomic, strong) FKProServeDetailView *featureView;
  57. @property (nonatomic, strong) FKProBottomView *bottomView;
  58. @property (nonatomic, strong) FKProductNavigationBar *navBar;
  59. @property (nonatomic, strong) FKProductSelectSpecView *buySpecView;
  60. @property (nonatomic, strong) FKProductSelectSpecView *priceWarnSpecView;
  61. @property (nonatomic, strong) XHImageViewer *imageBrowser; // 图片查看器
  62. @property (nonatomic, strong) FKAddBasketAnimTool *addBasketAnimTool;
  63. @property (nonatomic, strong) FKCollectAnimationTool *collectAnimTool; // 收藏动画管理
  64. @property (nonatomic, strong) UITableView *upTableView;
  65. @property (nonatomic, strong) UITableView *downTableView;
  66. @property (nonatomic, strong) FKProDetailViewModel *viewModel;
  67. @end
  68. @implementation FKProDetailController
  69. - (instancetype)initWithProductID:(NSString *)productID{
  70. return [self initWithProductID:productID selectSpecId:nil];
  71. }
  72. - (instancetype)initWithProductID:(NSString *)productID selectSpecId:(NSString *)selectSpecId; {
  73. self = [super init];
  74. if (self) {
  75. self.viewModel.productID = productID;
  76. self.viewModel.selectSpecId = selectSpecId;
  77. }
  78. return self;
  79. }
  80. - (void)viewDidLoad {
  81. [super viewDidLoad];
  82. self.edgesForExtendedLayout = UIRectEdgeAll;
  83. self.automaticallyAdjustsScrollViewInsets = NO;
  84. [[NSNotificationCenter defaultCenter] addObserver:self
  85. selector:@selector(timeCountZeroCallback)
  86. name:PRODUCT_DETAIL_COUNT_TIME_ZERO
  87. object:nil];
  88. if (self.openURLPara) {
  89. self.viewModel.productID = self.openURLPara[@"id"];
  90. self.viewModel.refer = self.openURLPara[REFER_KEY];
  91. [self savePageRefer:self.openURLPara];
  92. }
  93. [self addAllSubviews];
  94. [self reqAllLookList];
  95. }
  96. - (void)viewWillAppear:(BOOL)animated{
  97. [super viewWillAppear:animated];
  98. [UIApplication sharedApplication].statusBarHidden = NO;
  99. [self.navigationController setNavigationBarHidden:YES animated:YES];
  100. [self reqAllWithHud:YES];
  101. if (!self.viewModel.relativeProArray.count){
  102. [self requestForRelativeProduct];
  103. }
  104. }
  105. - (void)viewDidAppear:(BOOL)animated {
  106. [super viewDidAppear:animated];
  107. [self.tabBarController.tabBar setHidden:YES];
  108. }
  109. - (void)viewWillDisappear:(BOOL)animated {
  110. [super viewWillDisappear:animated];
  111. [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
  112. [self.navigationController.view bringSubviewToFront:self.navigationController.navigationBar];
  113. [self hiddenSpecView];
  114. }
  115. - (void)viewDidDisappear:(BOOL)animated {
  116. [super viewDidDisappear:animated];
  117. [self.viewModel setNotShowWeightDetailDefault];
  118. }
  119. - (void)addAllSubviews{
  120. [self.view addSubview:self.ladderView];
  121. [self.view addSubview:self.bottomView];
  122. [self.view addSubview:self.navBar];
  123. [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
  124. make.left.bottom.right.equalTo(self.view);
  125. make.height.mas_equalTo(IS_IPHONE_X ? 90 : 56);
  126. }];
  127. [self.ladderView mas_makeConstraints:^(MASConstraintMaker *make) {
  128. make.left.top.right.equalTo(self.view);
  129. make.bottom.equalTo(self.bottomView.mas_top);
  130. }];
  131. [self.navBar mas_makeConstraints:^(MASConstraintMaker *make) {
  132. make.left.right.top.equalTo(self.view);
  133. make.height.equalTo(IS_IPHONE_X ? @88 : @64);
  134. }];
  135. }
  136. - (void)dealloc {
  137. [self.upTableView removeObserver:self.navBar forKeyPath:CONTENT_OFFSET_KEYPATH];
  138. [self.ladderView.bgScrollView removeObserver:self.navBar forKeyPath:CONTENT_OFFSET_KEYPATH];
  139. [[NSNotificationCenter defaultCenter] removeObserver:self];
  140. }
  141. #pragma mark - response
  142. - (void)networkDidSuccessResponse:(NSDictionary*)response identify:(int)identify header:(MSGHeader*)header {
  143. [self.ladderView.upControl finishRefreshingDirection:RefreshDirectionTop];
  144. [self.ladderView.downControl finishRefreshingDirection:RefreshDirectionBottom];
  145. if (header.code.intValue == RESPONSE_MSG_NORMAL) {
  146. if (identify == kProductReqTypeDetail) {
  147. WeakSelf(weakSelf);
  148. dispatch_async(dispatch_get_main_queue(), ^{
  149. [weakSelf.hudView hide:YES];
  150. [weakSelf.hudView removeFromSuperview];
  151. weakSelf.hudView = nil;
  152. });
  153. self.viewModel.dataItem = [FKProductDetailReform parserDataItemWithDict:response];
  154. [self.viewModel checkSpecImgArray];
  155. [self refreshContent];
  156. [self showShareGuide];
  157. [self reqBrandRecommendList];
  158. }else if (identify == kProductReqTypeAddCollect){
  159. self.viewModel.dataItem.currentUser.hasCollect = YES;
  160. self.bottomView.collected = YES;
  161. }else if (identify == kProductReqTypeRemoveCollect){
  162. self.viewModel.dataItem.currentUser.hasCollect = NO;
  163. self.bottomView.collected = NO;
  164. }else if (identify == kProductReqTypeSpec){
  165. [self handleSpecResponse:response];
  166. [self.upTableView reloadData];
  167. }else if (identify == kProductReqTypeAddToBasket){
  168. // 执行动画
  169. self.addBasketAnimTool.image = [self.buySpecView getCurrentShowImg];
  170. self.addBasketAnimTool.picUrl = [self.buySpecView.dataCenter currentPicUrlToShow];
  171. [self.addBasketAnimTool showInView:self.view targetView:self.bottomView.goToBasketBtn];
  172. [[NSNotificationCenter defaultCenter] postNotificationName:BASKET_NEED_TO_REFRESH object:nil];
  173. }else if (identify == kProductReqTypeBrandRecommend) {
  174. self.viewModel.brandRecItem = [FKProductDetailReform parserBrandRecItemWithDict:response];
  175. [self.upTableView reloadData];
  176. }else if (identify == kProductReqTypeAllLookList) {
  177. self.viewModel.allLookItem = [FKProductDetailReform parserAllLookItemWithDict:response];
  178. [self.upTableView reloadData];
  179. }else if (identify == kProductReqTypeRelativePro){
  180. self.viewModel.relativeProArray = [FKProductDetailReform parserRelativeProItemArrayWithDict:response];
  181. self.viewModel.totalRelativeCount = [FKProductDetailReform parserTotalRelativeWihtDict:response];
  182. [self refreshBottomState];
  183. [self.downTableView reloadData];
  184. }else if (identify == kProductReqTypeMoreRelativePro){
  185. [self.viewModel appendMoreRelativePro:[FKProductDetailReform parserRelativeProItemArrayWithDict:response]];
  186. self.viewModel.totalRelativeCount = [FKProductDetailReform parserTotalRelativeWihtDict:response];
  187. [self refreshBottomState];
  188. [self.downTableView reloadData];
  189. } else if (identify == kProductReqTypeTagList) {
  190. self.viewModel.tagArray = [FKProductDetailReform parserFeatureListWithDict:response];
  191. [self.upTableView reloadData];
  192. } else if (identify == kProductReqTypeActivity) {
  193. self.viewModel.activityArray = [FKProductDetailReform parserAcitvityArrayWithDict:response];
  194. [self.upTableView reloadData];
  195. } else if (identify == kProductReqTypeTips) {
  196. self.viewModel.tipsItem = [FKProductDetailReform parserTipsItemWithDict:response];
  197. if (self.segmentView.currentIndex == 1) [self.downTableView reloadData];
  198. } else if (identify == kProductReqTypeVipDiscountItem) {
  199. self.viewModel.discountItem = [FKProductDetailReform parserVipDiscountItem:response];
  200. [self.upTableView reloadData];
  201. }
  202. }else{
  203. [FLProgressHUDHelper showText:header.msg inView:self.view];
  204. }
  205. }
  206. - (void)networkDidReceiveError:(NSError*)error identify:(int)identify header:(MSGHeader*)header{
  207. if (identify == kProductReqTypeDetail) {
  208. WeakSelf(weakSelf);
  209. dispatch_async(dispatch_get_main_queue(), ^{
  210. [weakSelf.hudView hide:YES];
  211. [weakSelf.hudView removeFromSuperview];
  212. weakSelf.hudView = nil;
  213. });
  214. }
  215. [self.ladderView.upControl finishRefreshingDirection:RefreshDirectionTop];
  216. [self.ladderView.upControl finishRefreshingDirection:RefreshDirectionBottom];
  217. [FLProgressHUDHelper showText:header.msg inView:self.view];
  218. }
  219. - (void)handleSpecResponse:(NSDictionary *)response{
  220. NSArray *productItemArray = [FKProductDetailReform parserSpecProductItemArrayWithDict:response];
  221. [self.viewModel setSelectProductItemWithProductArray:productItemArray];
  222. FKProductSpecDataCenter *dataCenter = [self dataCenterWithType:kSpecTypeNormal response:response];
  223. [dataCenter configWithViewModel:self.viewModel];
  224. self.buySpecView.dataCenter = dataCenter;
  225. FKProductSpecDataCenter *priceWarnDataCenter = [self dataCenterWithType:kSpecTypePriceWarn response:response];
  226. [priceWarnDataCenter configWithViewModel:self.viewModel];
  227. self.priceWarnSpecView.dataCenter = priceWarnDataCenter;
  228. if (productItemArray.count > 0) {
  229. self.viewModel.specPicArray = [dataCenter specImgUrlArray:productItemArray];
  230. } else {
  231. [self.viewModel checkSpecImgArray];
  232. }
  233. self.viewModel.selectSpecId = nil; // 只做第一次默认选中
  234. [self.bottomView resetContentWithDataModel:self.viewModel.dataItem specDataCenter:dataCenter];
  235. }
  236. #pragma mark - request
  237. - (void)reqAllWithHud:(BOOL)hud{
  238. [self requestForSpecData];
  239. [self reqInitialDataWithHud:hud];
  240. [self reqTagList];
  241. [self reqActivity];
  242. [self reqWenxinTips];
  243. [self requestDiscountItem];
  244. }
  245. - (void)requestForSpecData{
  246. [FKProDetailRequest requestWithType:kProductReqTypeSpec
  247. info:@{PRODUCT_ID_KEY : self.viewModel.productID}
  248. delegate:self];
  249. }
  250. - (void)reqInitialDataWithHud:(BOOL)hud {
  251. // 请求初始化数据
  252. if (hud) [self.hudView show:YES];
  253. if (!self.viewModel.productID.length){
  254. [self.hudView hide:YES];
  255. return;
  256. }
  257. [FKProDetailRequest requestWithType:kProductReqTypeDetail
  258. info:@{PRODUCT_ID_KEY : self.viewModel.productID,
  259. REFER_KEY : [FLStringHelper replaceNilWithEmpty:self.viewModel.refer]}
  260. delegate:self];
  261. }
  262. - (void)requestForRelativeProduct{
  263. [FKProDetailRequest requestWithType:kProductReqTypeRelativePro
  264. info:@{PRODUCT_ID_KEY : self.viewModel.productID,
  265. PRODUCT_RELATIVE_START_ROW_KEY : @(0)}
  266. delegate:self];
  267. }
  268. - (void)requestForMoreRelative{
  269. [FKProDetailRequest requestWithType:kProductReqTypeMoreRelativePro
  270. info:@{PRODUCT_ID_KEY : self.viewModel.productID,
  271. PRODUCT_RELATIVE_START_ROW_KEY : @(self.viewModel.relativeProArray.count)}
  272. delegate:self];
  273. }
  274. - (void)reqBrandRecommendList{
  275. // 一次请求,从其他页面回来不请求
  276. if (!self.viewModel.brandRecItem) {
  277. NSString *brandID = self.viewModel.dataItem.productInfo.brandId;
  278. if ([FLStringHelper isValidString:brandID]) {
  279. [FKProDetailRequest requestWithType:kProductReqTypeBrandRecommend
  280. info:@{BRAND_ID_KEY : brandID}
  281. delegate:self];
  282. }
  283. }
  284. }
  285. - (void)reqAllLookList{
  286. if ([FLStringHelper isValidString:self.viewModel.productID]) {
  287. [FKProDetailRequest requestWithType:kProductReqTypeAllLookList
  288. info:@{PRODUCT_ID_KEY : self.viewModel.productID}
  289. delegate:self];
  290. }
  291. }
  292. - (void)reqTagList{
  293. [FKProDetailRequest reqTagList:self.viewModel.productID
  294. identify:kProductReqTypeTagList
  295. delegate:self];
  296. }
  297. - (void)reqActivity{
  298. [FKProDetailRequest reqAcitvity:self.viewModel.productID
  299. identify:kProductReqTypeActivity
  300. delegate:self];
  301. }
  302. - (void)reqWenxinTips {
  303. [FKProDetailRequest reqTipListWithIdentify:kProductReqTypeTips delegate:self];
  304. }
  305. - (void)requestDiscountItem {
  306. [FKProDetailRequest reqVipDiscountWithIdentify:kProductReqTypeVipDiscountItem delegate:self];
  307. }
  308. #pragma mark - refresh delegate
  309. - (void)refreshControl:(FKRefreshControl *)refreshControl didEngageRefreshDirection:(RefreshDirection)direction{
  310. if (direction == RefreshDirectionTop) {
  311. [self reqAllWithHud:NO];
  312. [self requestForRelativeProduct];
  313. }else if (direction == RefreshDirectionBottom){
  314. [self requestForMoreRelative];
  315. }
  316. }
  317. #pragma mark - tableView dataSource
  318. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
  319. kProTableType tableType = [self tableTypeForTable:tableView];
  320. return [self.viewModel numberOfSectionsInTableType:tableType];
  321. }
  322. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
  323. kProTableType tableType = [self tableTypeForTable:tableView];
  324. return [self.viewModel numberOfRowsInSection:section tableType:tableType];
  325. }
  326. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
  327. kProTableType tableType = [self tableTypeForTable:tableView];
  328. kProCellType cellType = [self.viewModel cellTypeForIndexPath:indexPath tableType:tableType];
  329. if (cellType == kProCellTypeBCChannelFee) {
  330. NSString *countryId = self.viewModel.dataItem.countryInfoItem.countryId;
  331. NSString *urlString = [NSString stringWithFormat:@"%@/detail/income-tax.html?country=%@", [[FKServerUtil sharedInstance] webServer], countryId];
  332. [self showFeatureDetail:urlString];
  333. } else if (cellType == kProCellTypeFeature) {
  334. NSString *countryId = self.viewModel.dataItem.countryInfoItem.countryId;
  335. NSString *prodId = self.viewModel.productID;
  336. NSString *channel = self.viewModel.dataItem.productInfo.isBCChannel ? @"&channel=bc" : @"";
  337. if (countryId && prodId) {
  338. NSString *urlString = [NSString stringWithFormat:@"%@/detail/service_desc.html?country=%@&id=%@%@",
  339. [[FKServerUtil sharedInstance] webServer],
  340. countryId,
  341. prodId,
  342. channel];
  343. [self showFeatureDetail:urlString];
  344. }
  345. } else if (cellType == kProCellTypeSelectSpec) {
  346. self.buySpecView.tag = kSpecActionTagSelect;
  347. [self.buySpecView showInView:self.navigationController.view animated:YES];
  348. } else if (cellType == kProCellTypeActivityScroll) {
  349. FKPromotionActivityItem *item = [self.viewModel activityItemAtIndex:indexPath.row];
  350. if ([FLStringHelper isValidString:item.targetUrl]) {
  351. [self parseURLSchema:item.targetUrl];
  352. }
  353. } else if (cellType == kProCellTypeSource) {
  354. [self clickSourceMoreAction:nil];
  355. } else if (cellType == kProCellTypeSeek) {
  356. [self pushAdviceController];
  357. }
  358. }
  359. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  360. kProTableType tableType = [self tableTypeForTable:tableView];
  361. kProCellType cellType = [self.viewModel cellTypeForIndexPath:indexPath tableType:tableType];
  362. NSString *reuseIdentify = [self.viewModel cellIdentifyForIndexPath:indexPath tableType:tableType];
  363. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentify];
  364. switch (cellType) {
  365. case kProCellTypeTopImgList:{
  366. FKProBannerCell *bannerCell = (FKProBannerCell *)cell;
  367. [bannerCell.goToDetailBtn addTarget:self
  368. action:@selector(clickGoToDetailBtn:)
  369. forControlEvents:UIControlEventTouchUpInside];
  370. WeakSelf(weakSelf);
  371. bannerCell.clickAction = ^(NSInteger index, FKProBannerCell * cell) {
  372. [weakSelf clickBannerCellAtIndex:index bannerCell:cell];
  373. };
  374. }
  375. break;
  376. case kProCellTypeTitle:{
  377. FKProTitleCell *titleCell = (FKProTitleCell *)cell;
  378. [titleCell.priceWarnActBtn addTarget:self
  379. action:@selector(clickPriceWarnBtn:)
  380. forControlEvents:UIControlEventTouchUpInside];
  381. }
  382. break;
  383. case kProCellTypeAmazonScore: {
  384. break;
  385. }
  386. case kProCellTypeProudctShow:{
  387. PdProductShowCell *showCell = (PdProductShowCell *)cell;
  388. [showCell configWithShowItem:[self.viewModel.dataItem productShowItemForIndex:indexPath.row]];
  389. showCell.delegate = self;
  390. }
  391. break;
  392. case kProCellTypeWeight:{
  393. FKProductWeightCell *weightCell = (FKProductWeightCell *)cell;
  394. [weightCell.infoBtn addTarget:self
  395. action:@selector(clickWeightInfo:)
  396. forControlEvents:UIControlEventTouchUpInside];
  397. }
  398. break;
  399. case kProCellTypeRelative:{
  400. FKProductRelativeCell *relativieCell = (FKProductRelativeCell *)cell;
  401. WeakSelf(weakSelf);
  402. relativieCell.clickRelative = ^(NSInteger index){
  403. [weakSelf clickRelativeAtIndex:index];
  404. };
  405. }
  406. break;
  407. case kProCellTypeBrand:{
  408. FKProBrandCell *brandCell = (FKProBrandCell *)cell;
  409. [brandCell.bookButton addTarget:self
  410. action:@selector(clickBookBtn:)
  411. forControlEvents:UIControlEventTouchUpInside];
  412. [brandCell.brandButton addTarget:self
  413. action:@selector(clickBrandBtn:)
  414. forControlEvents:UIControlEventTouchUpInside];
  415. [brandCell.arrowBtn addTarget:self
  416. action:@selector(clickBrandArrowBtn:)
  417. forControlEvents:UIControlEventTouchUpInside];
  418. }
  419. break;
  420. case kProCellTypeBrandList:
  421. case kProCellTypeAllLook:{
  422. FKProRecommendListCell *listCell = (FKProRecommendListCell *)cell;
  423. listCell.delegate = self;
  424. }
  425. break;
  426. case kProCellTypeInfo:{
  427. FKProInfoCell *infoCell = (FKProInfoCell *)cell;
  428. [infoCell.actionBtn addTarget:self
  429. action:@selector(clickTranslateBtn:)
  430. forControlEvents:UIControlEventTouchUpInside];
  431. [infoCell.linkBtn addTarget:self
  432. action:@selector(clickSourceLinkBtn:)
  433. forControlEvents:UIControlEventTouchUpInside];
  434. }
  435. break;
  436. case kProCellTypeWeightError:{
  437. FKProWeightErrorCell *errorCell = (FKProWeightErrorCell *)cell;
  438. [errorCell.connenctBtn addTarget:self
  439. action:@selector(clickWeithErrorConnect:)
  440. forControlEvents:UIControlEventTouchUpInside];
  441. }
  442. default:
  443. break;
  444. }
  445. if (cell) {
  446. cell.selectionStyle = UITableViewCellSelectionStyleNone;
  447. [cell fk_configWithViewModel:self.viewModel indexPath:indexPath];
  448. } else {
  449. return [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
  450. }
  451. return cell;
  452. }
  453. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
  454. kProTableType tableType = [self tableTypeForTable:tableView];
  455. NSIndexPath *targetIndex = [NSIndexPath indexPathForRow:0 inSection:section];
  456. kProCellType cellType = [self.viewModel cellTypeForIndexPath:targetIndex tableType:tableType];
  457. if (cellType == kProCellTypeAllLook) {
  458. FKProHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:NSStringFromClass([FKProHeaderView class])];
  459. headerView.titleLabel.text = self.viewModel.allLookItem.title;
  460. return headerView;
  461. } else if (cellType == kProCellTypeProudctShow) {
  462. FKProHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:NSStringFromClass([FKProHeaderView class])];
  463. headerView.titleLabel.text = @"商品图片";
  464. return headerView;
  465. } else if (cellType == kProCellTypeRelative) {
  466. FKProHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:NSStringFromClass([FKProHeaderView class])];
  467. headerView.titleLabel.text = @"为你推荐";
  468. return headerView;
  469. }
  470. return nil;
  471. }
  472. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
  473. kProTableType tableType = [self tableTypeForTable:tableView];
  474. return [self.viewModel cellHeightForIndexPath:indexPath tableType:tableType];
  475. }
  476. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
  477. NSInteger topTableNumOfSection = [self.viewModel numberOfSectionsInTableType:kProTableTypeUp];
  478. if (section == (topTableNumOfSection - 1)) {
  479. return (10.0f + 50.0f);
  480. }
  481. return 10.0f;
  482. }
  483. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
  484. kProTableType tableType = [self tableTypeForTable:tableView];
  485. NSIndexPath *targetIndex = [NSIndexPath indexPathForRow:0 inSection:section];
  486. kProCellType cellType = [self.viewModel cellTypeForIndexPath:targetIndex tableType:tableType];
  487. if (cellType == kProCellTypeAllLook || cellType == kProCellTypeProudctShow) return 35;
  488. if (tableView == self.downTableView) {
  489. if (section == 0) return 10.0f;
  490. if (cellType == kProCellTypeRelative) return 45.0f;
  491. }
  492. return CGFLOAT_MIN;
  493. }
  494. #pragma mark - select specView delegate
  495. - (void)didClickHeaderImgBoxView:(FKProductImgBoxView *)imageBoxView showPicUrl:(NSString *)showPicUrl{
  496. if (!imageBoxView || !showPicUrl.length) return;
  497. UIImageView *newImgView = [[UIImageView alloc]initWithFrame:imageBoxView.imageView.bounds];
  498. [newImgView fl_setImageWithURL:[NSURL URLWithString:showPicUrl]];
  499. [imageBoxView.imageView addSubview:newImgView];
  500. [self.imageBrowser showWithImageViews:@[newImgView] selectedView:newImgView];
  501. }
  502. - (void)specViewSelectDone:(FKProductSelectSpecView *)specView selectedProductItem:(FKProductItem *)productItem{
  503. if (specView.dataCenter.type == kSpecTypeNormal){
  504. if (productItem) {
  505. self.viewModel.selectBuyItem = productItem;
  506. self.viewModel.hasSelectedSKU = YES;
  507. [self.upTableView reloadData];
  508. }
  509. if (specView.tag == kSpecActionTagBuy){
  510. // 购买
  511. [self pushSubmitOrderController:productItem];
  512. } else if (specView.tag == kSpecActionTagAddBasket){
  513. // 加入购物车
  514. [self addProductToBasket:productItem];
  515. } else if (specView.tag == kSpecActionTagSelect) {
  516. // 规格选择
  517. self.viewModel.selectBuyItem = productItem;
  518. [self.upTableView reloadData];
  519. }
  520. }else if (specView.dataCenter.type == kSpecTypePriceWarn){
  521. // 降价提醒
  522. FKPriceWarnEditController *priceWarn = [[FKPriceWarnEditController alloc]initWithPriceWarnItem:[productItem createPriceWarnItem]];
  523. [priceWarn setHidesBottomBarWhenPushed:YES];
  524. [self.navigationController pushViewController:priceWarn animated:YES];
  525. }
  526. }
  527. - (void)didClickShowSizeBtn{
  528. // 展示尺码表
  529. ProductShowItem *sizeItem = [self.viewModel.dataItem getSizePicItem];
  530. if (sizeItem){
  531. UIImageView *newImgView = [[UIImageView alloc]init];
  532. [self.viewModel configWithSizeImgView:newImgView];
  533. [self.imageBrowser showWithImageViews:@[newImgView] selectedView:newImgView];
  534. }
  535. }
  536. - (void)didClickShowSizeLinkBtn {
  537. [self pushWebViewController:@"https://m.fine3q.com/event/chima/chimabiao.html"];
  538. }
  539. #pragma mark - Recommendlist delegate
  540. - (void)listCell:(FKProRecommendListCell *)cell selectAtIndex:(NSIndexPath *)indexpath{
  541. NSIndexPath *targetIndex = [self.upTableView indexPathForCell:cell];
  542. if (targetIndex) {
  543. kProCellType cellType = [self.viewModel cellTypeForIndexPath:targetIndex tableType:kProTableTypeUp];
  544. NSString *pageRefer = nil;
  545. FKProRecommendItem *item = nil;
  546. if (cellType == kProCellTypeAllLook) {
  547. pageRefer = PRPageDetailEngineRecommend;
  548. item = [self.viewModel allLookItemAtIndex:indexpath.row];
  549. } else if (cellType == kProCellTypeBrandList) {
  550. pageRefer = PRPageDetailBrandRecommend;
  551. item = [self.viewModel brandRecItemAtIndex:indexpath.row];
  552. }
  553. if (item.itemId) {
  554. FKProDetailController *detail = [[FKProDetailController alloc]initWithProductID:item.itemId];
  555. [self.navigationController pushViewController:detail animated:YES];
  556. [[FKPageRouterUtil sharedInstance] pushPageRefer:pageRefer
  557. itemID:item.itemId
  558. value:item.name];
  559. }
  560. }
  561. }
  562. #pragma mark - FKCollectAnimationToolDelegate
  563. - (void)allCollectAnimationFinish:(FKCollectAnimationTool *)tool{
  564. kProductReqType type = tool.collectSelected ? kProductReqTypeAddCollect : kProductReqTypeRemoveCollect;
  565. NSDictionary *infoDict = [self.viewModel infoForRequestType:type];
  566. if (!infoDict)return;
  567. [FKProDetailRequest requestWithType:type info:infoDict delegate:self];
  568. }
  569. #pragma mark - Time Count Down Zero Callback
  570. - (void)timeCountZeroCallback {
  571. [self reqAllWithHud:YES];
  572. }
  573. #pragma mark - Method
  574. - (void)refreshContent {
  575. [self.buySpecView.dataCenter configWithViewModel:self.viewModel];
  576. [self.buySpecView resetContent];
  577. [self.priceWarnSpecView.dataCenter configWithViewModel:self.viewModel];
  578. [self.priceWarnSpecView resetContent];
  579. [self.upTableView reloadData];
  580. [self.downTableView reloadData];
  581. [self.bottomView resetContentWithDataModel:self.viewModel.dataItem specDataCenter:self.buySpecView.dataCenter];
  582. }
  583. - (FKProductSpecDataCenter *)dataCenterWithType:(kSpecType)type response:(NSDictionary *)response{
  584. FKProductSpecDataCenter *dataCenter = [[FKProductSpecDataCenter alloc]init];
  585. dataCenter.type = type;
  586. if (type == kSpecTypeNormal) {
  587. dataCenter.selectedProductItem = self.viewModel.selectBuyItem;
  588. } else if (type == kSpecTypePriceWarn) {
  589. dataCenter.selectedProductItem = self.viewModel.selectPriceWarnItem;
  590. }
  591. dataCenter.specItemArray = [FKProductDetailReform parserSpecItemArrayWithDict:response];
  592. dataCenter.productItemArray = [FKProductDetailReform parserSpecProductItemArrayWithDict:response];
  593. return dataCenter;
  594. }
  595. - (void)parseURLSchema:(NSString *)urlString {
  596. if (urlString.length > 0) {
  597. NSURL *url = [NSURL URLWithString:urlString];
  598. if ([url.scheme rangeOfString:@"HTTP" options:NSCaseInsensitiveSearch].length > 0) {
  599. [self pushWebViewController:urlString];
  600. } else {
  601. [[SchemaManager sharedManager] parserURL:url shouldCache:NO];
  602. }
  603. }
  604. }
  605. - (void)pushWebViewController:(NSString *)urlString {
  606. WebViewController *newViewController = [[FLControllerHelper currentStoryBoard] instantiateViewControllerWithIdentifier:@"WebViewController"];
  607. newViewController.url = urlString;
  608. [self.navigationController pushViewController:newViewController animated:YES];
  609. }
  610. - (void)hiddenSpecView{
  611. [self.buySpecView dismissAnimated];
  612. [self.priceWarnSpecView dismissAnimated];
  613. }
  614. - (void)savePageRefer:(NSDictionary *)para {
  615. NSString *pk = self.openURLPara[@"p_k"];
  616. NSString *pr = self.openURLPara[@"p_r"];
  617. if (pr.length > 0) {
  618. NSArray *values = [[pk stringByRemovingPercentEncoding] componentsSeparatedByString:@"|"];
  619. [[FKPageRouterUtil sharedInstance] pushPageRefer:pr values:values];
  620. }
  621. }
  622. - (void)showShareGuide{
  623. BOOL res = [[[NSUserDefaults standardUserDefaults] objectForKey:PRODUCT_HAS_SHOW_GUIDE_KEY] boolValue];
  624. if (!res) {
  625. GuideView *guideView = [[GuideView alloc] init];
  626. [guideView addMaskView:@"product_share_img" withImageRect:CGRectMake((UISCREENWIDTH-285)/2, 63, 285, 247) andBtnRect:CGRectMake(UISCREENWIDTH/2-80, 310-45, 160, 45)];
  627. [[NSUserDefaults standardUserDefaults] setBool:YES forKey:PRODUCT_HAS_SHOW_GUIDE_KEY];
  628. [[NSUserDefaults standardUserDefaults] synchronize];
  629. }
  630. }
  631. - (void)refreshBottomState{
  632. if (self.viewModel.showWarn) {
  633. [self.ladderView.downControl setBottomEnabled:NO];
  634. } else {
  635. if (self.viewModel.relativeProArray.count < self.viewModel.totalRelativeCount){
  636. [self.ladderView.downControl setBottomEnabled:YES];
  637. }else{
  638. [self.ladderView.downControl setBottomEnabled:NO];
  639. }
  640. }
  641. }
  642. - (void)showFeatureDetail:(NSString *)urlString {
  643. if (urlString) {
  644. [self.featureView requestWithURL:[NSURL URLWithString:urlString]];
  645. [self.featureView showInView:self.view animated:YES];
  646. }
  647. }
  648. - (kProTableType)tableTypeForTable:(UITableView *)tableView{
  649. if (tableView == self.downTableView) {
  650. return kProTableTypeDown;
  651. } else if (tableView == self.upTableView) {
  652. return kProTableTypeUp;
  653. }
  654. return kProTableTypeUnknow;
  655. }
  656. - (void)handleBottomAction:(kProBottomAction)actionType{
  657. if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) {
  658. [FLControllerHelper presentLoginViewController];
  659. return;
  660. }
  661. switch (actionType) {
  662. case kProBottomActionServer:{
  663. [self pushChatViewController:@"用户正在看商品:"];
  664. }
  665. break;
  666. case kProBottomActionCollect:{
  667. [self resetCollectState:self.bottomView.collected];
  668. [self.collectAnimTool showAnimationWithCollect:self.bottomView.collected inView:self.view];
  669. }
  670. break;
  671. case kProBottomActionGoToBasket:{
  672. // go to basket
  673. self.bottomView.redPoint.hidden = YES;
  674. FKBasketController *basket = [[FKBasketController alloc]init];
  675. [self.navigationController pushViewController:basket animated:YES];
  676. }
  677. break;
  678. case kProBottomActionAddBasket:{
  679. // add to basket
  680. NSError *error;
  681. if ([self productCanBeBuyWithError:&error]){
  682. if ([self.buySpecView.dataCenter isOnlyOneSku] || (self.viewModel.selectBuyItem && self.viewModel.hasSelectedSKU)) {
  683. [self addProductToBasket:self.viewModel.selectBuyItem];
  684. } else {
  685. self.buySpecView.tag = kSpecActionTagAddBasket;
  686. [self.buySpecView showInView:self.navigationController.view animated:YES];
  687. }
  688. } else {
  689. [FLProgressHUDHelper showText:error.localizedDescription inView:self.view];
  690. }
  691. }
  692. break;
  693. case kProBottomActionBuy:{
  694. NSError *error;
  695. if ([self productCanBeBuyWithError:&error]){
  696. if ([self.buySpecView.dataCenter isOnlyOneSku] || (self.viewModel.selectBuyItem && self.viewModel.hasSelectedSKU)) {
  697. [self pushSubmitOrderController:self.viewModel.selectBuyItem];
  698. } else {
  699. self.buySpecView.tag = kSpecActionTagBuy;
  700. [self.buySpecView showInView:self.navigationController.view animated:YES];
  701. }
  702. };
  703. }
  704. default:
  705. break;
  706. }
  707. }
  708. - (void)resetCollectState:(BOOL)collected{
  709. self.bottomView.collected = collected;
  710. }
  711. - (NSDictionary *)chatViewControllerExtData:(NSString *)title {
  712. return @{EXT_MSG_TYPE_V2: @{EXT_MSG_TYPE_TRACK_V2: @{EXT_MSG_TITLE_V2 : title,
  713. EXT_MSG_PRICE_V2 : [self.viewModel.dataItem getTotalPrice],
  714. EXT_MSG_DESC_V2 : [FLStringHelper replaceNilWithEmpty:self.viewModel.dataItem.productInfo.title],
  715. EXT_MSG_PIC_URL_V2 : [FLStringHelper replaceNilWithEmpty:self.viewModel.dataItem.productInfo.firstPicUrl],
  716. EXT_MSG_ITEM_URL_V2 : [FLStringHelper replaceNilWithEmpty:self.viewModel.dataItem.webUrl],
  717. EXT_MSG_USER_ID_V2 : @"",
  718. EXT_MSG_POST_ID_V2 : self.viewModel.productID
  719. }},
  720. EXT_MSG_ORDER_TITLE: [FLStringHelper replaceNilWithEmpty:[FLStringHelper replaceNilWithEmpty:self.viewModel.dataItem.productInfo.title]],
  721. EXT_QUEUE_NAME : QueueNameShouqian};
  722. }
  723. #pragma mark - click action
  724. - (void)navBackBtnClick{
  725. [self.navigationController popViewControllerAnimated:YES];
  726. }
  727. - (void)clickTranslateBtn:(UIButton *)sender{
  728. self.viewModel.showTranslate = !self.viewModel.showTranslate;
  729. [self.downTableView reloadData];
  730. }
  731. - (void)navShareBtnClick{
  732. FKShareView *shareView = [[FKShareView alloc] initWithLogin:[FKUserManager isUserLogin]];
  733. WeakSelf(weakSelf);
  734. [shareView showInView:self.view actionBlock:^(kShareViewActionType type, FKShareView *shareView) {
  735. [weakSelf clickShareForType:type];
  736. }];
  737. }
  738. - (void)clickGoToDetailBtn:(UIButton *)sender{
  739. [self.ladderView goToDown];
  740. }
  741. - (void)clickSourceLinkBtn:(UIButton *)sender{
  742. NSString *buyChannel = self.viewModel.dataItem.productInfo.linkUrl;
  743. if ([FLStringHelper isUrlString:buyChannel]){
  744. [self pushWebViewControllerWithUrl:buyChannel];
  745. }
  746. }
  747. - (void)clickSourceMoreAction:(UIButton *)sender {
  748. NSString *keyword = self.viewModel.dataItem.supplier.name;
  749. NSString *itemID = self.viewModel.dataItem.supplier.supplyID;
  750. if (![FLStringHelper isValidString:keyword]) return;
  751. FKExploreListController *controller = [[FKExploreListController alloc] initWithSource:FKExploreListSourceSupplier];
  752. [controller.conditionManager addConditionWithType:FKExploreConditionTypeSupplier
  753. itemID:itemID
  754. value:keyword];
  755. [self.navigationController pushViewController:controller animated:YES];
  756. [[FKPageRouterUtil sharedInstance] pushPageRefer:PRPageSearchSupplier itemID:itemID value:keyword];
  757. }
  758. #pragma mark - Brand Cell Action
  759. - (void)clickBookBtn:(UIButton *)sender{
  760. if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) {
  761. [self showLoginActionMenu];
  762. return;
  763. }
  764. NSString *brandId = self.viewModel.brandRecItem.brandInfo.itemID;
  765. [FKProDetailRequest reqBookBrand:brandId
  766. isCancel:sender.selected ? YES : NO
  767. identify:kProductReqTypeBookBrand
  768. delegate:self];
  769. sender.selected = !sender.selected;
  770. }
  771. - (void)clickBrandBtn:(UIButton *)sender{
  772. // 跳转品牌搜索
  773. NSString *keyword = self.viewModel.brandRecItem.brandInfo.brandName;
  774. NSString *itemID = self.viewModel.brandRecItem.brandInfo.itemID;
  775. if (![FLStringHelper isValidString:keyword]) return;
  776. FKExploreListController *controller = [[FKExploreListController alloc] initWithSource:FKExploreListSourceBrand];
  777. [controller.conditionManager addConditionWithType:FKExploreConditionTypeBrand
  778. itemID:itemID
  779. value:keyword];
  780. [self.navigationController pushViewController:controller animated:YES];
  781. }
  782. - (void)clickBrandArrowBtn:(UIButton *)sender {
  783. self.viewModel.isBrandDescClose = !self.viewModel.isBrandDescClose;
  784. [self.upTableView reloadData];
  785. }
  786. - (void)clickPriceWarnBtn:(UIButton *)sender {
  787. if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) {
  788. [self showLoginActionMenu];
  789. return;
  790. }
  791. // 降价通知
  792. [self.priceWarnSpecView showInView:self.navigationController.view animated:YES];
  793. }
  794. - (void)clickRelativeAtIndex:(NSInteger)index{
  795. FKProductRelativeItem *item = [self.viewModel relativeItemAtIndex:index];
  796. if ([FLStringHelper isValidString:item.itemId]){
  797. FKProDetailController *detail = [[FKProDetailController alloc]initWithProductID:item.itemId];
  798. [self.navigationController pushViewController:detail animated:YES];
  799. [[FKPageRouterUtil sharedInstance] pushPageRefer:PRPageDetailRecommend
  800. itemID:self.viewModel.productID
  801. value:self.viewModel.dataItem.productInfo.name];
  802. }
  803. }
  804. - (void)clickBannerCellAtIndex:(NSInteger)index bannerCell:(FKProBannerCell *)cell{
  805. [self showBannerImgListWithSelectIndex:index sourceCell:cell];
  806. }
  807. - (void)clickProductImg:(PdProductShowCell *)cell{
  808. NSIndexPath *indexPath = [self.downTableView indexPathForCell:cell];
  809. if (indexPath){
  810. [self showImgBrowerWithSelectIndex:indexPath.row sourceCell:cell];
  811. }
  812. }
  813. - (void)clickWeightInfo:(UIButton *)sender{
  814. self.viewModel.showWeightDetail = !self.viewModel.showWeightDetail;
  815. [self.upTableView reloadData];
  816. }
  817. - (void)clickWeithErrorConnect:(UIButton *)sender{
  818. if ([FKUserManager sharedManager].applicationMode == ApplicationModeVisitor) {
  819. [FLControllerHelper presentLoginViewController];
  820. return;
  821. }
  822. [self pushChatViewController:@"重量有疑问:"];
  823. }
  824. - (void)showImgBrowerWithSelectIndex:(NSUInteger)index sourceCell:(UITableViewCell *)sourceCell{
  825. NSArray *imgUrlArray = [self.viewModel.dataItem allProductImgUrlArray];
  826. if (!imgUrlArray.count) return;
  827. NSMutableArray *imgArrayM = [NSMutableArray arrayWithCapacity:imgUrlArray.count];
  828. for (int i = 0; i < imgUrlArray.count; i++) {
  829. UIImageView *newImgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, UISCREENWIDTH, UISCREENWIDTH)];
  830. ProductShowItem *showItem = [self.viewModel.dataItem productShowItemForIndex:i];
  831. if (showItem) newImgView.frame = CGRectMake(0, 0, UISCREENWIDTH, [showItem realImgHeightForRealWidth:UISCREENWIDTH]);
  832. [newImgView sd_setImageWithURL:[NSURL URLWithString:imgUrlArray[i]]];
  833. if (i == index) [sourceCell.contentView addSubview:newImgView];
  834. [imgArrayM addObject:newImgView];
  835. }
  836. [self.imageBrowser showWithImageViews:imgArrayM selectedView:(UIImageView *)imgArrayM[index]];
  837. }
  838. - (void)showBannerImgListWithSelectIndex:(NSUInteger)index sourceCell:(UITableViewCell *)sourceCell{
  839. NSArray *imgUrlArray = self.viewModel.specPicArray;
  840. if (!imgUrlArray.count) return;
  841. NSMutableArray *imgArrayM = [NSMutableArray arrayWithCapacity:imgUrlArray.count];
  842. for (int i = 0; i < imgUrlArray.count; i++) {
  843. UIImageView *newImgView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, UISCREENWIDTH, UISCREENWIDTH)];
  844. [newImgView sd_setImageWithURL:[NSURL URLWithString:imgUrlArray[i]]];
  845. if (i == index) [sourceCell.contentView addSubview:newImgView];
  846. [imgArrayM addObject:newImgView];
  847. }
  848. [self.imageBrowser showWithImageViews:imgArrayM selectedView:(UIImageView *)imgArrayM[index]];
  849. }
  850. - (BOOL)productCanBeBuyWithError:(NSError **)error{
  851. if (self.buySpecView.dataCenter && [self.buySpecView.dataCenter getTotalStock] <= 0){
  852. // 抢光
  853. *error = [NSError errorWithDomain:@"FirstLinkErrorDomain"
  854. code:0
  855. userInfo:@{NSLocalizedDescriptionKey : @"该商品已抢光"}];
  856. return NO;
  857. }else if (!self.viewModel.dataItem.productInfo.productOnLine) {
  858. // 产品下线
  859. NSString *errorStr = @"该商品";
  860. NSString *offLineStr = [self.viewModel.dataItem.productInfo offLineStr];
  861. if (offLineStr) {
  862. errorStr = [errorStr stringByAppendingString:offLineStr];
  863. }else{
  864. errorStr = @"该商品已失效";
  865. }
  866. *error = [NSError errorWithDomain:@"FirstLinkErrorDomain"
  867. code:0
  868. userInfo:@{NSLocalizedDescriptionKey : errorStr}];
  869. return NO;
  870. }else if (self.viewModel.dataItem.saleRule.isOnlyNew && self.viewModel.dataItem.currentUser.hasEverBuy){
  871. // 新用户专享
  872. *error = [NSError errorWithDomain:@"FirstLinkErrorDomain"
  873. code:0
  874. userInfo:@{NSLocalizedDescriptionKey : @"该商品为新用户专享"}];
  875. return NO;
  876. }
  877. *error = nil;
  878. return YES;
  879. }
  880. - (void)clickShareForType:(kShareViewActionType)type{
  881. if (type == kShareViewActionTypeNone) return;
  882. if (type == kShareViewActionTypeQuestion){
  883. NSString *qsURL = [NSString stringWithFormat:@"%@/support/about-points.html", [[FKServerUtil sharedInstance] webServer]];
  884. [self pushWebViewControllerWithUrl:qsURL];
  885. return;
  886. }
  887. NSString *tagId = self.viewModel.productID;
  888. NSString *title = self.viewModel.dataItem.shareTargetItem.title;
  889. NSString *desc = self.viewModel.dataItem.shareTargetItem.shareDesc;
  890. NSString *url = self.viewModel.dataItem.shareTargetItem.shareUrl;
  891. NSString *imgUrl = self.viewModel.dataItem.shareTargetItem.picUrl;
  892. NSString *firstImgUrl = [self.viewModel specPicArray].firstObject;
  893. CGSize size = CGSizeMake(SHARE_IMAGE_LENGTH, SHARE_IMAGE_LENGTH);
  894. if (type == kShareViewActionTypeWeibo) size = CGSizeMake(SHARE_IMAGE_LENGTH_WEIBO, SHARE_IMAGE_LENGTH_WEIBO);
  895. [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:firstImgUrl] options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
  896. if (image) {
  897. image = [FLImageHelper generateThumbnailFromCenter:image frame:size];
  898. } else {
  899. image = [FLImageHelper generateThumbnailFromCenter:[FLImageHelper getAppIcon] frame:size];
  900. }
  901. dispatch_async(dispatch_get_main_queue(), ^{
  902. switch (type) {
  903. case kShareViewActionTypeFriend:
  904. [FLShareHelper shareToWeixin:desc description:title thumbImage:image webURL:url scene:WeixinSceneFriend];
  905. break;
  906. case kShareViewActionTypeCircle:
  907. [FLShareHelper shareToWeixin:desc description:title thumbImage:image webURL:url scene:WeixinSceneCicle];
  908. break;
  909. case kShareViewActionTypeWeibo:{
  910. [FLShareHelper shareToWeiboWithTitle:desc content:title image:image urlString:url tagID:tagId];
  911. }
  912. break;
  913. case kShareViewActionTypeQQzone:
  914. [FLShareHelper shareToQQZoneWithTitle:title content:desc imgUrl:imgUrl urlString:url];
  915. break;
  916. case kShareViewActionTypeURLCopy: {
  917. if (url.length > 0) {
  918. UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
  919. pasteboard.persistent = YES;
  920. [pasteboard setString:url];
  921. [FLProgressHUDHelper showText:@"拷贝成功" inView:self.view];
  922. } else {
  923. [FLProgressHUDHelper showText:@"无可拷贝内容" inView:self.view];
  924. }
  925. break;
  926. }
  927. default:
  928. break;
  929. }
  930. });
  931. }];
  932. }
  933. #pragma mark - Push Controller
  934. - (void)pushWebViewControllerWithUrl:(NSString *)url {
  935. WebViewController *newViewController = [[FLControllerHelper currentStoryBoard] instantiateViewControllerWithIdentifier:@"WebViewController"];
  936. newViewController.url = url;
  937. newViewController.hidesBottomBarWhenPushed = YES;
  938. newViewController.naviBarHidden = NO;
  939. [self.navigationController pushViewController:newViewController animated:YES];
  940. }
  941. - (void)pushSubmitOrderController:(FKProductItem *)productItem {
  942. if (!productItem) return;
  943. FKSubmitUnitItem *unitItem = [self.viewModel createSubmitUnitItemWithProductItem:productItem];
  944. FKSubmitOrderController *submitCtrl = [[FKSubmitOrderController alloc] initWithUnitItemArray:@[unitItem]
  945. userLevel:[self.viewModel.dataItem.currentUser getCurrentUserLevel]
  946. entranSouce:kSubmitEnterSourceDetail];
  947. [self.navigationController pushViewController:submitCtrl animated:YES];
  948. }
  949. - (void)pushChatViewController:(NSString *)title {
  950. if (!self.viewModel.dataItem) return;
  951. ChatViewController *chatController = [[ChatViewController alloc] initWithChatter:self.viewModel.dataItem.serveUser.serveId
  952. isGroup:NO];
  953. chatController.naviTitle = self.viewModel.dataItem.serveUser.nickName;
  954. chatController.receiverHeadURL = self.viewModel.dataItem.serveUser.headerPicUrl;
  955. chatController.msgExtData = [self chatViewControllerExtData:title];
  956. [self.navigationController pushViewController:chatController animated:YES];
  957. }
  958. - (void)pushAdviceController{
  959. FKProductAdviseController *advise = [[FKProductAdviseController alloc]initWithItemID:self.viewModel.productID];
  960. [self.navigationController pushViewController:advise animated:YES];
  961. }
  962. - (void)addProductToBasket:(FKProductItem *)productItem{
  963. if (productItem.selectedAmount <= 0 || !productItem.goodsID.length) return;
  964. NSDictionary *infoDict = @{PRODUCT_ID_KEY : productItem.goodsID,
  965. PRODUCT_AMOUNT_KEY : @(productItem.selectedAmount)};
  966. [FKProDetailRequest requestWithType:kProductReqTypeAddToBasket
  967. info:infoDict
  968. delegate:self];
  969. }
  970. #pragma mark - property
  971. - (FKLadderTableView *)ladderView{
  972. if (_ladderView == nil) {
  973. _ladderView = [[FKLadderTableView alloc]initWithUpTableView:self.upTableView
  974. downTableView:self.downTableView
  975. downSegmentView:self.segmentView
  976. delegate:self];
  977. [_ladderView.bgScrollView addObserver:self.navBar forKeyPath:CONTENT_OFFSET_KEYPATH options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
  978. }
  979. return _ladderView;
  980. }
  981. - (UITableView *)upTableView{
  982. if (_upTableView == nil) {
  983. _upTableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped];
  984. _upTableView.delegate = self;
  985. _upTableView.dataSource = self;
  986. _upTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  987. _upTableView.backgroundColor = UIColorFromRGB(0xf4f4f4);
  988. [_upTableView addObserver:self.navBar forKeyPath:CONTENT_OFFSET_KEYPATH options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
  989. if (@available(iOS 11.0, *)) {
  990. _upTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  991. }
  992. [_upTableView registerClass:[FKProBannerCell class] forCellReuseIdentifier:NSStringFromClass([FKProBannerCell class])];
  993. [_upTableView registerClass:[FKProActivityInProgressCell class] forCellReuseIdentifier:NSStringFromClass([FKProActivityInProgressCell class])];
  994. [_upTableView registerClass:[FKProActivityForeshowCell class] forCellReuseIdentifier:NSStringFromClass([FKProActivityForeshowCell class])];
  995. [_upTableView registerClass:[FKProActivityThemeCell class] forCellReuseIdentifier:NSStringFromClass([FKProActivityThemeCell class])];
  996. [_upTableView registerClass:[FKProTitleCell class] forCellReuseIdentifier:NSStringFromClass([FKProTitleCell class])];
  997. [_upTableView registerClass:[FKProAmazonScoreCell class] forCellReuseIdentifier:NSStringFromClass([FKProAmazonScoreCell class])];
  998. [_upTableView registerClass:[FKProTagListCell class] forCellReuseIdentifier:NSStringFromClass([FKProTagListCell class])];
  999. [_upTableView registerClass:[FKProPriceDetailCell class] forCellReuseIdentifier:NSStringFromClass([FKProPriceDetailCell class])];
  1000. [_upTableView registerClass:[FKProductWeightCell class] forCellReuseIdentifier:NSStringFromClass([FKProductWeightCell class])];
  1001. [_upTableView registerClass:[FKProWeightErrorCell class] forCellReuseIdentifier:NSStringFromClass([FKProWeightErrorCell class])];
  1002. [_upTableView registerClass:[FKProSpecResCell class] forCellReuseIdentifier:NSStringFromClass([FKProSpecResCell class])];
  1003. [_upTableView registerClass:[FKProBCChannelFeeCell class] forCellReuseIdentifier:NSStringFromClass([FKProBCChannelFeeCell class])];
  1004. [_upTableView registerClass:[FKProActivityCell class] forCellReuseIdentifier:NSStringFromClass([FKProActivityCell class])];
  1005. [_upTableView registerClass:[FKProFeatureCell class] forCellReuseIdentifier:NSStringFromClass([FKProFeatureCell class])];
  1006. [_upTableView registerClass:[FKProSourceCell class] forCellReuseIdentifier:NSStringFromClass([FKProSourceCell class])];
  1007. [_upTableView registerClass:[FKProSeekCell class] forCellReuseIdentifier:NSStringFromClass([FKProSeekCell class])];
  1008. [_upTableView registerClass:[FKProAskAnswerCell class] forCellReuseIdentifier:NSStringFromClass([FKProAskAnswerCell class])];
  1009. [_upTableView registerClass:[FKProRecommendListCell class] forCellReuseIdentifier:NSStringFromClass([FKProRecommendListCell class])];
  1010. [_upTableView registerClass:[FKProBrandCell class] forCellReuseIdentifier:NSStringFromClass([FKProBrandCell class])];
  1011. [_upTableView registerClass:[FKProRecommendListCell class] forCellReuseIdentifier:NSStringFromClass([FKProRecommendListCell class])];
  1012. [_upTableView registerClass:[FKProHeaderView class] forHeaderFooterViewReuseIdentifier:NSStringFromClass([FKProHeaderView class])];
  1013. }
  1014. return _upTableView;
  1015. }
  1016. - (UITableView *)downTableView{
  1017. if (_downTableView == nil) {
  1018. _downTableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped];
  1019. _downTableView.delegate = self;
  1020. _downTableView.dataSource = self;
  1021. _downTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  1022. _downTableView.backgroundColor = UIColorFromRGB(0xf4f4f4);
  1023. _downTableView.contentInset = UIEdgeInsetsMake(10, 0, 0, 0);
  1024. _downTableView.scrollsToTop = NO;
  1025. if (@available(iOS 11.0, *)) {
  1026. _downTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  1027. }
  1028. [_downTableView registerClass:[FKProRecommendListCell class] forCellReuseIdentifier:NSStringFromClass([FKProRecommendListCell class])];
  1029. [_downTableView registerClass:[FKProductRecommendCell class] forCellReuseIdentifier:NSStringFromClass([FKProductRecommendCell class])];
  1030. [_downTableView registerClass:[FKProInfoCell class] forCellReuseIdentifier:NSStringFromClass([FKProInfoCell class])];
  1031. [_downTableView registerClass:[PdProductShowCell class] forCellReuseIdentifier:NSStringFromClass([PdProductShowCell class])];
  1032. [_downTableView registerClass:[FKProductRelativeCell class] forCellReuseIdentifier:NSStringFromClass([FKProductRelativeCell class])];
  1033. [_downTableView registerClass:[FKProWarnTitleCell class] forCellReuseIdentifier:NSStringFromClass([FKProWarnTitleCell class])];
  1034. [_downTableView registerClass:[FKProProcessCell class] forCellReuseIdentifier:NSStringFromClass([FKProProcessCell class])];
  1035. [_downTableView registerClass:[FKProWarnHeaderCell class] forCellReuseIdentifier:NSStringFromClass([FKProWarnHeaderCell class])];
  1036. [_downTableView registerClass:[FKProHeaderView class] forHeaderFooterViewReuseIdentifier:NSStringFromClass([FKProHeaderView class])];
  1037. }
  1038. return _downTableView;
  1039. }
  1040. - (FKProSegmentView *)segmentView{
  1041. if (_segmentView == nil) {
  1042. WeakSelf(weakSelf);
  1043. _segmentView = [[FKProSegmentView alloc]initWithIndexChange:^(NSInteger index) {
  1044. weakSelf.viewModel.showWarn = (index == 0 ? NO : YES);
  1045. [weakSelf refreshBottomState];
  1046. [weakSelf.downTableView reloadData];
  1047. }];
  1048. }
  1049. return _segmentView;
  1050. }
  1051. - (FKProServeDetailView *)featureView{
  1052. if (_featureView == nil) {
  1053. _featureView = [[FKProServeDetailView alloc]init];
  1054. }
  1055. return _featureView;
  1056. }
  1057. - (FKProDetailViewModel *)viewModel{
  1058. if (_viewModel == nil) {
  1059. _viewModel = [[FKProDetailViewModel alloc]init];
  1060. }
  1061. return _viewModel;
  1062. }
  1063. - (FKProBottomView *)bottomView{
  1064. if (_bottomView == nil) {
  1065. WeakSelf(weakSelf);
  1066. _bottomView = [[FKProBottomView alloc]initWithAction:^(kProBottomAction actionType) {
  1067. [weakSelf handleBottomAction:actionType];
  1068. }];
  1069. }
  1070. return _bottomView;
  1071. }
  1072. - (FKProductSelectSpecView *)buySpecView{
  1073. if (_buySpecView == nil) {
  1074. _buySpecView = [[FKProductSelectSpecView alloc]init];
  1075. _buySpecView.delegate = self;
  1076. }
  1077. return _buySpecView;
  1078. }
  1079. - (FKProductSelectSpecView *)priceWarnSpecView{
  1080. if (_priceWarnSpecView == nil) {
  1081. _priceWarnSpecView = [[FKProductSelectSpecView alloc]init];
  1082. _priceWarnSpecView.delegate = self;
  1083. }
  1084. return _priceWarnSpecView;
  1085. }
  1086. - (FKProductNavigationBar *)navBar{
  1087. if (_navBar == nil) {
  1088. _navBar = [[FKProductNavigationBar alloc]init];
  1089. [_navBar.backBtn addTarget:self action:@selector(navBackBtnClick) forControlEvents:UIControlEventTouchUpInside];
  1090. [_navBar.shareBtn addTarget:self action:@selector(navShareBtnClick) forControlEvents:UIControlEventTouchUpInside];
  1091. }
  1092. return _navBar;
  1093. }
  1094. - (FKAddBasketAnimTool *)addBasketAnimTool{
  1095. if (_addBasketAnimTool == nil) {
  1096. _addBasketAnimTool = [[FKAddBasketAnimTool alloc]init];
  1097. WeakSelf(weakSelf);
  1098. _addBasketAnimTool.finishBlock = ^(void){
  1099. weakSelf.bottomView.redPoint.hidden = NO;
  1100. [FLProgressHUDHelper showText:@"成功添加到购物车" inView:weakSelf.view];
  1101. };
  1102. }
  1103. return _addBasketAnimTool;
  1104. }
  1105. - (XHImageViewer *)imageBrowser{
  1106. if (_imageBrowser == nil) {
  1107. _imageBrowser = [[XHImageViewer alloc] init];
  1108. _imageBrowser.dismissInCenter = YES;
  1109. }
  1110. return _imageBrowser;
  1111. }
  1112. - (FKCollectAnimationTool *)collectAnimTool{
  1113. if (_collectAnimTool == nil) {
  1114. _collectAnimTool = [[FKCollectAnimationTool alloc]init];
  1115. _collectAnimTool.delegate = self;
  1116. }
  1117. return _collectAnimTool;
  1118. }
  1119. @end