MerchantEnrollGuideView.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. //
  2. // MerchantEnrollGuideView.m
  3. // BuguLive
  4. //
  5. // Created by qitewei on 2025/8/11.
  6. // Copyright © 2025 xfg. All rights reserved.
  7. //
  8. #import "MerchantEnrollGuideView.h"
  9. #import "UIView+Extention.h"
  10. @implementation MerchantEnrollGuideView
  11. - (instancetype)initWithFrame:(CGRect)frame
  12. {
  13. self = [super initWithFrame:frame];
  14. if (self) {
  15. [self setupUI];
  16. [self setupConstraints];
  17. [self updateSubmitButtonState];
  18. }
  19. return self;
  20. }
  21. - (void)setupUI {
  22. // 添加头部背景和内容
  23. [self addSubview:self.headerImageView];
  24. [self.headerImageView addSubview:self.headerIconImageView];
  25. [self.headerImageView addSubview:self.textLabel];
  26. [self.headerImageView addSubview:self.subtitleLabel];
  27. // 添加scrollView
  28. [self addSubview:self.scrollView];
  29. [self.scrollView addSubview:self.contentView];
  30. // 添加步骤容器
  31. [self.contentView addSubview:self.stepsContainerView];
  32. [self setupStepsViews];
  33. // 添加协议和按钮
  34. [self setupAgreementViews];
  35. }
  36. - (void)setupStepsViews {
  37. [self.stepsContainerView addSubview:self.step1View];
  38. [self.stepsContainerView addSubview:self.step2View];
  39. [self.stepsContainerView addSubview:self.step3View];
  40. // 步骤1
  41. [self setupStepView:self.step1View
  42. stepIcon:@"store_01"
  43. stepNumber:@"01"
  44. stepTitle:ASLocalizedString(@"提交材料")
  45. stepDuration:ASLocalizedString(@"约30分钟")
  46. stepDesc:ASLocalizedString(@"上传营业执照、法定代表人身份证等\n相关资质资料")
  47. actionText:ASLocalizedString(@"查询材料")
  48. action:@selector(checkMaterialsClicked:)];
  49. // 步骤2
  50. [self setupStepView:self.step2View
  51. stepIcon:@"store_02"
  52. stepNumber:@"02"
  53. stepTitle:ASLocalizedString(@"平台审核")
  54. stepDuration:ASLocalizedString(@"约1-3个工作日")
  55. stepDesc:ASLocalizedString(@"平台进行资质审核")
  56. actionText:ASLocalizedString(@"查询结果")
  57. action:@selector(checkResultClicked:)];
  58. // 步骤3
  59. [self setupStepView:self.step3View
  60. stepIcon:@"store_03"
  61. stepNumber:@"03"
  62. stepTitle:ASLocalizedString(@"完成入驻")
  63. stepDuration:nil
  64. stepDesc:ASLocalizedString(@"可以去发布产品和视频/直播带货了")
  65. actionText:nil
  66. action:nil];
  67. }
  68. - (void)setupAgreementViews {
  69. [self addSubview:self.agreementCheckBox];
  70. [self addSubview:self.agreementLabel];
  71. }
  72. - (void)setupStepView:(UIView *)stepView
  73. stepIcon:(NSString *)iconName
  74. stepNumber:(NSString *)stepNumber
  75. stepTitle:(NSString *)stepTitle
  76. stepDuration:(NSString *)stepDuration
  77. stepDesc:(NSString *)stepDesc
  78. actionText:(NSString *)actionText
  79. action:(SEL)action {
  80. // 步骤图标
  81. UIImageView *iconImageView = [[UIImageView alloc] init];
  82. iconImageView.image = [UIImage imageNamed:iconName];
  83. [stepView addSubview:iconImageView];
  84. // // 步骤编号
  85. // UILabel *numberLabel = [[UILabel alloc] init];
  86. // numberLabel.text = stepNumber;
  87. // numberLabel.font = [UIFont boldSystemFontOfSize:24];
  88. // numberLabel.textColor = [UIColor colorWithRed:0.26 green:0.46 blue:1.0 alpha:1.0];
  89. // [stepView addSubview:numberLabel];
  90. // 步骤标题
  91. UILabel *titleLabel = [[UILabel alloc] init];
  92. titleLabel.text = stepTitle;
  93. titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
  94. titleLabel.textColor = [UIColor blackColor];
  95. [stepView addSubview:titleLabel];
  96. // 步骤时长(如果有)
  97. UILabel *durationLabel = nil;
  98. if (stepDuration) {
  99. durationLabel = [[UILabel alloc] init];
  100. durationLabel.text = stepDuration;
  101. durationLabel.font = [UIFont systemFontOfSize:14];
  102. durationLabel.textColor = [UIColor colorWithRed:0.26 green:0.46 blue:1.0 alpha:1.0];
  103. [stepView addSubview:durationLabel];
  104. }
  105. // 连接线
  106. UIImageView *lineImageView = [[UIImageView alloc] init];
  107. lineImageView.contentMode = UIViewContentModeScaleAspectFit;
  108. if ([stepNumber isEqualToString:@"03"]) {
  109. // 第三步不需要连接线
  110. lineImageView.hidden = YES;
  111. } else {
  112. lineImageView.image = [UIImage imageNamed:@"store_01_line"];
  113. }
  114. [stepView addSubview:lineImageView];
  115. // 步骤描述
  116. UILabel *descLabel = [[UILabel alloc] init];
  117. descLabel.text = stepDesc;
  118. descLabel.font = [UIFont systemFontOfSize:14];
  119. descLabel.textColor = [UIColor grayColor];
  120. descLabel.numberOfLines = 0;
  121. [stepView addSubview:descLabel];
  122. // 操作按钮(如果有)
  123. UIButton *actionButton = nil;
  124. if (actionText && action) {
  125. actionButton = [UIButton buttonWithType:UIButtonTypeCustom];
  126. [actionButton setTitle:actionText forState:UIControlStateNormal];
  127. [actionButton setTitleColor:[UIColor colorWithRed:0.26 green:0.46 blue:1.0 alpha:1.0] forState:UIControlStateNormal];
  128. actionButton.titleLabel.font = [UIFont systemFontOfSize:14];
  129. [actionButton addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
  130. [stepView addSubview:actionButton];
  131. }
  132. // 设置约束
  133. [iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
  134. make.left.equalTo(stepView).offset(kRealValue(24));
  135. make.top.equalTo(stepView).offset(kRealValue(20));
  136. make.size.mas_equalTo(CGSizeMake(kRealValue(28), kRealValue(24)));
  137. }];
  138. // [numberLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  139. // make.left.equalTo(iconImageView.mas_right).offset(kRealValue(16));
  140. // make.top.equalTo(stepView).offset(kRealValue(20));
  141. // }];
  142. [titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  143. make.left.equalTo(iconImageView.mas_right).offset(kRealValue(12));
  144. make.centerY.equalTo(iconImageView);
  145. }];
  146. if (durationLabel) {
  147. [durationLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  148. make.left.equalTo(titleLabel.mas_right).offset(kRealValue(12));
  149. make.centerY.equalTo(titleLabel);
  150. }];
  151. }
  152. if (!lineImageView.hidden) {
  153. [lineImageView mas_makeConstraints:^(MASConstraintMaker *make) {
  154. make.left.equalTo(iconImageView).offset(kRealValue(20));
  155. make.top.equalTo(iconImageView.mas_bottom).offset(kRealValue(8));
  156. make.width.equalTo(@(kRealValue(8)));
  157. make.height.equalTo(@(kRealValue(70)));
  158. }];
  159. }
  160. [descLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  161. make.left.equalTo(titleLabel);
  162. make.right.equalTo(stepView).offset(-kRealValue(24));
  163. make.top.equalTo(titleLabel.mas_bottom).offset(kRealValue(8));
  164. }];
  165. if (actionButton) {
  166. [actionButton mas_makeConstraints:^(MASConstraintMaker *make) {
  167. make.left.equalTo(titleLabel);
  168. make.top.equalTo(descLabel.mas_bottom).offset(kRealValue(8));
  169. make.bottom.equalTo(stepView).offset(-kRealValue(20));
  170. }];
  171. } else {
  172. [descLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  173. make.bottom.equalTo(stepView).offset(-kRealValue(20));
  174. }];
  175. }
  176. }
  177. - (void)setupConstraints {
  178. [self.headerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
  179. make.height.mas_equalTo(kRealValue(90));
  180. make.left.right.equalTo(self).inset(12);
  181. make.top.mas_offset(0);
  182. }];
  183. [self.scrollView mas_remakeConstraints:^(MASConstraintMaker *make) {
  184. make.left.right.equalTo(self).inset(12);
  185. make.bottom.equalTo(self.agreementCheckBox.mas_top).mas_offset(-kRealValue(10));
  186. make.top.equalTo(self.headerImageView.mas_bottom).offset(kRealValue(10));
  187. }];
  188. // 头部图标
  189. [self.headerIconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
  190. make.left.mas_offset(0);
  191. make.top.mas_offset(kRealValue(-50));
  192. make.width.height.equalTo(@(kRealValue(160)));
  193. }];
  194. // 标题
  195. [self.textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  196. make.left.equalTo(self.headerIconImageView.mas_right);
  197. make.top.mas_offset(kRealValue(21));
  198. }];
  199. // 副标题
  200. [self.subtitleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  201. make.left.equalTo(self.textLabel);
  202. make.right.mas_offset(-8);
  203. make.top.equalTo(self.textLabel.mas_bottom).offset(kRealValue(10));
  204. }];
  205. // 步骤容器
  206. [self.stepsContainerView mas_makeConstraints:^(MASConstraintMaker *make) {
  207. make.left.right.equalTo(self.contentView);
  208. make.top.mas_offset(0);
  209. make.bottom.mas_offset(0);
  210. }];
  211. // 步骤视图
  212. [self.step1View mas_makeConstraints:^(MASConstraintMaker *make) {
  213. make.left.right.top.equalTo(self.stepsContainerView);
  214. }];
  215. [self.step2View mas_makeConstraints:^(MASConstraintMaker *make) {
  216. make.left.right.equalTo(self.stepsContainerView);
  217. make.top.equalTo(self.step1View.mas_bottom);
  218. }];
  219. [self.step3View mas_makeConstraints:^(MASConstraintMaker *make) {
  220. make.left.right.equalTo(self.stepsContainerView);
  221. make.top.equalTo(self.step2View.mas_bottom);
  222. make.bottom.equalTo(self.stepsContainerView);
  223. }];
  224. // 协议复选框
  225. [self.agreementCheckBox mas_makeConstraints:^(MASConstraintMaker *make) {
  226. make.left.equalTo(self.nextButton).offset(kRealValue(24));
  227. make.bottom.equalTo(self.nextButton.mas_top).offset(kRealValue(-20));
  228. make.width.height.equalTo(@(kRealValue(20)));
  229. }];
  230. // 协议标签
  231. [self.agreementLabel mas_makeConstraints:^(MASConstraintMaker *make) {
  232. make.left.equalTo(self.agreementCheckBox.mas_right).offset(kRealValue(8));
  233. make.right.mas_offset(-kRealValue(24));
  234. make.centerY.equalTo(self.agreementCheckBox);
  235. }];
  236. }
  237. #pragma mark - Actions
  238. - (void)checkMaterialsClicked:(UIButton *)sender {
  239. // TODO: 查看材料详情
  240. NSLog(@"Check materials clicked");
  241. }
  242. - (void)checkResultClicked:(UIButton *)sender {
  243. // TODO: 查看审核结果
  244. NSLog(@"Check result clicked");
  245. }
  246. - (void)agreementCheckBoxClicked:(UIButton *)sender {
  247. self.isAgreementChecked = !self.isAgreementChecked;
  248. [self updateAgreementCheckBox];
  249. [self updateSubmitButtonState];
  250. }
  251. - (void)goNext {
  252. if (!self.isAgreementChecked) {
  253. // TODO: 显示提示信息
  254. NSLog(@"Please agree to the agreement first");
  255. return;
  256. }
  257. [super goNext];
  258. }
  259. - (void)agreementLabelTapped:(UITapGestureRecognizer *)gesture {
  260. // TODO: 显示协议详情
  261. NSLog(@"Agreement tapped");
  262. }
  263. #pragma mark - Private Methods
  264. - (void)updateAgreementCheckBox {
  265. NSString *imageName = self.isAgreementChecked ? @"store_check" : @"store_uncheck";
  266. [self.agreementCheckBox setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
  267. }
  268. - (void)updateSubmitButtonState {
  269. self.nextButton.enabled = self.isAgreementChecked;
  270. self.nextButton.alpha = self.isAgreementChecked ? 1.0 : 0.5;
  271. }
  272. #pragma mark - Lazy Loading
  273. - (UIImageView *)headerIconImageView {
  274. if (!_headerIconImageView) {
  275. UIImageView *headerIconImageView = [[UIImageView alloc] init];
  276. headerIconImageView.image = [UIImage imageNamed:@"store_header_icon"];
  277. headerIconImageView.contentMode = UIViewContentModeScaleAspectFit;
  278. _headerIconImageView = headerIconImageView;
  279. }
  280. return _headerIconImageView;
  281. }
  282. - (UIImageView *)headerImageView {
  283. if (!_headerImageView) {
  284. _headerImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"store_header"]];
  285. _headerImageView.contentMode = UIViewContentModeScaleAspectFill;
  286. }
  287. return _headerImageView;
  288. }
  289. - (UILabel *)textLabel {
  290. if (!_textLabel) {
  291. UILabel *titleLabel = [[UILabel alloc] init];
  292. titleLabel.text = ASLocalizedString(@"商家入驻");
  293. titleLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightMedium];
  294. titleLabel.textColor = [UIColor whiteColor];
  295. _textLabel = titleLabel;
  296. }
  297. return _textLabel;
  298. }
  299. - (UILabel *)subtitleLabel {
  300. if (!_subtitleLabel) {
  301. UILabel *subtitleLabel = [[UILabel alloc] init];
  302. subtitleLabel.text = ASLocalizedString(@"以下是商家入驻流程,请仔细阅读");
  303. subtitleLabel.font = [UIFont systemFontOfSize:12 weight:UIFontWeightRegular];
  304. subtitleLabel.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
  305. subtitleLabel.numberOfLines = 2;
  306. _subtitleLabel = subtitleLabel;
  307. }
  308. return _subtitleLabel;
  309. }
  310. - (UIView *)stepsContainerView {
  311. if (!_stepsContainerView) {
  312. UIView *stepsContainerView = [[UIView alloc] init];
  313. stepsContainerView.backgroundColor = [UIColor clearColor];
  314. _stepsContainerView = stepsContainerView;
  315. }
  316. return _stepsContainerView;
  317. }
  318. - (UIView *)step1View {
  319. if (!_step1View) {
  320. UIView *step1View = [[UIView alloc] init];
  321. step1View.backgroundColor = [UIColor clearColor];
  322. _step1View = step1View;
  323. }
  324. return _step1View;
  325. }
  326. - (UIView *)step2View {
  327. if (!_step2View) {
  328. UIView *step2View = [[UIView alloc] init];
  329. step2View.backgroundColor = [UIColor clearColor];
  330. _step2View = step2View;
  331. }
  332. return _step2View;
  333. }
  334. - (UIView *)step3View {
  335. if (!_step3View) {
  336. UIView *step3View = [[UIView alloc] init];
  337. step3View.backgroundColor = [UIColor clearColor];
  338. _step3View = step3View;
  339. }
  340. return _step3View;
  341. }
  342. - (UIButton *)agreementCheckBox {
  343. if (!_agreementCheckBox) {
  344. UIButton *agreementCheckBox = [UIButton buttonWithType:UIButtonTypeCustom];
  345. [agreementCheckBox setImage:[UIImage imageNamed:@"store_uncheck"] forState:UIControlStateNormal];
  346. [agreementCheckBox addTarget:self action:@selector(agreementCheckBoxClicked:) forControlEvents:UIControlEventTouchUpInside];
  347. _agreementCheckBox = agreementCheckBox;
  348. }
  349. return _agreementCheckBox;
  350. }
  351. - (UILabel *)agreementLabel {
  352. if (!_agreementLabel) {
  353. UILabel *agreementLabel = [[UILabel alloc] init];
  354. NSString *text = [NSString stringWithFormat:@"%@ %@",
  355. ASLocalizedString(@"已阅读并同意签署"),
  356. ASLocalizedString(@"《入驻开店服务协议》")];
  357. NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:text];
  358. // 设置整体样式
  359. [attributedText addAttribute:NSFontAttributeName
  360. value:[UIFont systemFontOfSize:14]
  361. range:NSMakeRange(0, text.length)];
  362. [attributedText addAttribute:NSForegroundColorAttributeName
  363. value:[UIColor grayColor]
  364. range:NSMakeRange(0, text.length)];
  365. // 设置协议链接样式
  366. NSRange linkRange = [text rangeOfString:ASLocalizedString(@"《入驻开店服务协议》")];
  367. if (linkRange.location != NSNotFound) {
  368. [attributedText addAttribute:NSForegroundColorAttributeName
  369. value:[UIColor colorWithRed:0.26 green:0.46 blue:1.0 alpha:1.0]
  370. range:linkRange];
  371. }
  372. agreementLabel.attributedText = attributedText;
  373. agreementLabel.userInteractionEnabled = YES;
  374. agreementLabel.numberOfLines = 2;
  375. // 添加点击手势
  376. UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(agreementLabelTapped:)];
  377. [agreementLabel addGestureRecognizer:tapGesture];
  378. _agreementLabel = agreementLabel;
  379. }
  380. return _agreementLabel;
  381. }
  382. @end