添加注销账号

This commit is contained in:
2026-02-28 14:50:27 +08:00
parent 4269fde923
commit 40ef964b8c
9 changed files with 242 additions and 56 deletions

View File

@@ -0,0 +1,19 @@
//
// KBCancelAccountVC.h
// keyBoard
//
// 注销账户页面
//
#import "BaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface KBCancelAccountVC : BaseViewController
/// 注销协议 HTML 内容(由外部传入或内部请求)
@property (nonatomic, copy, nullable) NSString *htmlContent;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,142 @@
//
// KBCancelAccountVC.m
// keyBoard
//
// + HTML +
//
#import "KBCancelAccountVC.h"
#import <WebKit/WebKit.h>
#import <Masonry/Masonry.h>
#import "KBMyVM.h"
#import "KBAlert.h"
@interface KBCancelAccountVC ()
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) UIButton *cancelAccountBtn;
@property (nonatomic, strong) KBMyVM *myVM;
@end
@implementation KBCancelAccountVC
- (void)viewDidLoad {
[super viewDidLoad];
self.kb_titleLabel.text = KBLocalized(@"Cancel Account");
self.view.backgroundColor = [UIColor colorWithHex:0xFFFFFF];
[self.view addSubview:self.titleLabel];
[self.view addSubview:self.webView];
[self.view addSubview:self.cancelAccountBtn];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT + 20);
make.left.equalTo(self.view).offset(16);
make.right.equalTo(self.view).offset(-16);
}];
[self.cancelAccountBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(16);
make.right.equalTo(self.view).offset(-16);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-12);
make.height.mas_equalTo(56);
}];
[self.webView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.titleLabel.mas_bottom).offset(16);
make.left.equalTo(self.view).offset(16);
make.right.equalTo(self.view).offset(-16);
make.bottom.equalTo(self.cancelAccountBtn.mas_top).offset(-16);
}];
[self fetchAgreement];
}
- (void)fetchAgreement {
__weak typeof(self) weakSelf = self;
[self.myVM fetchCancelAccountWarningWithCompletion:^(NSString * _Nullable html, NSError * _Nullable error) {
if (html.length > 0) {
weakSelf.htmlContent = html;
}
[weakSelf loadHTMLContent];
}];
}
- (void)loadHTMLContent {
NSString *html = self.htmlContent ?: @"";
//
NSString *wrappedHTML = [NSString stringWithFormat:
@"<html><head>"
"<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'>"
"<style>"
"body { font-family: -apple-system, sans-serif; font-size: 15px; color: #333; "
"line-height: 1.6; padding: 0; margin: 0; word-wrap: break-word; }"
"</style></head><body>%@</body></html>", html];
[self.webView loadHTMLString:wrappedHTML baseURL:nil];
}
#pragma mark - Actions
- (void)onTapCancelAccount {
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_cancel_account_confirm_btn"
pageId:@"cancel_account"
elementId:@"cancel_account_confirm_btn"
extra:nil
completion:nil];
KBWeakSelf;
[KBAlert confirmTitle:KBLocalized(@"Cancel Account") message:KBLocalized(@"After cancellation, your account will be deactivated and local login data will be cleared. Continue?") ok:KBLocalized(@"Confirm") cancel:KBLocalized(@"Cancel") completion:^(BOOL ok) {
if (!ok) { return; }
[weakSelf.myVM cancelAccountWithCompletion:nil];
}];
}
#pragma mark - Lazy
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [UILabel new];
_titleLabel.text = KBLocalized(@"Cancel Account Notice");
_titleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
_titleLabel.font = [KBFont bold:20];
_titleLabel.numberOfLines = 0;
}
return _titleLabel;
}
- (WKWebView *)webView {
if (!_webView) {
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
_webView.backgroundColor = UIColor.whiteColor;
_webView.scrollView.showsVerticalScrollIndicator = YES;
_webView.layer.cornerRadius = 12;
_webView.layer.masksToBounds = YES;
}
return _webView;
}
- (UIButton *)cancelAccountBtn {
if (!_cancelAccountBtn) {
_cancelAccountBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[_cancelAccountBtn setTitle:KBLocalized(@"Confirm Cancel Account") forState:UIControlStateNormal];
[_cancelAccountBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
_cancelAccountBtn.titleLabel.font = [KBFont medium:16];
_cancelAccountBtn.backgroundColor = [UIColor colorWithHex:0xFF0000];
_cancelAccountBtn.layer.cornerRadius = 12;
_cancelAccountBtn.layer.masksToBounds = YES;
[_cancelAccountBtn addTarget:self action:@selector(onTapCancelAccount) forControlEvents:UIControlEventTouchUpInside];
}
return _cancelAccountBtn;
}
- (KBMyVM *)myVM {
if (!_myVM) {
_myVM = [[KBMyVM alloc] init];
}
return _myVM;
}
@end

View File

@@ -15,6 +15,7 @@
#import "KBGenderPickerPopView.h"
#import "KBMyVM.h"
#import "KBAlert.h"
#import "KBCancelAccountVC.h"
@interface KBPersonInfoVC () <UITableViewDelegate, UITableViewDataSource, PHPickerViewControllerDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
//
@@ -28,8 +29,6 @@
// 退
@property (nonatomic, strong) UIButton *logoutBtn;
//
@property (nonatomic, strong) UIButton *cancelBtn;
//
@property (nonatomic, copy) NSArray<NSDictionary *> *items; // {title,value,arrow,copy}
@@ -70,15 +69,6 @@
// 退
[self.view addSubview:self.logoutBtn];
[self.logoutBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(16);
make.right.equalTo(self.view).offset(-16);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-(12 + 56 + 10));
make.height.mas_equalTo(56);
}];
//
[self.view addSubview:self.cancelBtn];
[self.cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(16);
make.right.equalTo(self.view).offset(-16);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-12);
@@ -87,7 +77,7 @@
//
UIEdgeInsets inset = self.tableView.contentInset;
inset.bottom = 56 + 10 + 56 + 24; // + +
inset.bottom = 56 + 24; // +
self.tableView.contentInset = inset;
self.viewModel = [[KBMyVM alloc] init];
__weak typeof(self) weakSelf = self;
@@ -128,14 +118,18 @@
#pragma mark - UITableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.items.count; }
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return section == 0 ? self.items.count : 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 56.0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 12.0; }
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return section == 0 ? 12.0 : 15.0;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { return [UIView new]; }
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 0.01; }
@@ -143,19 +137,34 @@
static NSString *cid = @"KBPersonInfoItemCell";
KBPersonInfoItemCell *cell = [tableView dequeueReusableCellWithIdentifier:cid];
if (!cell) { cell = [[KBPersonInfoItemCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cid]; }
NSDictionary *it = self.items[indexPath.row];
BOOL isTop = (indexPath.row == 0);
BOOL isBottom = (indexPath.row == self.items.count - 1);
[cell configWithTitle:it[@"title"]
value:it[@"value"]
showArrow:[it[@"arrow"] boolValue]
showCopy:[it[@"copy"] boolValue]
isTop:isTop
isBottom:isBottom];
if (indexPath.section == 0) {
NSDictionary *it = self.items[indexPath.row];
BOOL isTop = (indexPath.row == 0);
BOOL isBottom = (indexPath.row == self.items.count - 1);
[cell configWithTitle:it[@"title"]
value:it[@"value"]
showArrow:[it[@"arrow"] boolValue]
showCopy:[it[@"copy"] boolValue]
isTop:isTop
isBottom:isBottom];
} else {
[cell configWithTitle:KBLocalized(@"Cancel Account")
value:@""
showArrow:YES
showCopy:NO
isTop:YES
isBottom:YES];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 1) {
KBCancelAccountVC *vc = [[KBCancelAccountVC alloc] init];
[self.navigationController pushViewController:vc animated:YES];
return;
}
if (indexPath.row == 0) {
// ->
CGFloat width = KB_SCREEN_WIDTH;
@@ -287,25 +296,6 @@
[self.myVM logout];
}
- (void)onTapCancelAccount {
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_person_cancel_account_btn"
pageId:@"person_info"
elementId:@"cancel_account_btn"
extra:nil
completion:nil];
KBWeakSelf;
[KBAlert confirmTitle:KBLocalized(@"Cancel Account")
message:KBLocalized(@"After cancellation, your account will be deactivated and local login data will be cleared. Continue?")
ok:KBLocalized(@"Confirm")
cancel:KBLocalized(@"Cancel")
okColor:[UIColor colorWithHex:0xFF0000]
cancelColor:nil
completion:^(BOOL ok) {
if (!ok) { return; }
[weakSelf.myVM cancelAccountWithCompletion:nil];
}];
}
#pragma mark - Lazy UI
- (UITableView *)tableView {
@@ -409,19 +399,6 @@
return _logoutBtn;
}
- (UIButton *)cancelBtn {
if (!_cancelBtn) {
_cancelBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[_cancelBtn setTitle:KBLocalized(@"Cancel Account") forState:UIControlStateNormal];
[_cancelBtn setTitleColor:[UIColor colorWithHex:0xFF0000] forState:UIControlStateNormal];
_cancelBtn.titleLabel.font = [KBFont medium:16];
_cancelBtn.backgroundColor = UIColor.whiteColor;
_cancelBtn.layer.cornerRadius = 12; _cancelBtn.layer.masksToBounds = YES;
[_cancelBtn addTarget:self action:@selector(onTapCancelAccount) forControlEvents:UIControlEventTouchUpInside];
}
return _cancelBtn;
}
#pragma mark - Image Picker
- (void)presentImagePicker {