Skip to content

Commit c8d193d

Browse files
committed
添加项目转让功能
1 parent 4fc0d63 commit c8d193d

8 files changed

+448
-36
lines changed

Coding_iOS.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
4E2DB34B1BA6AEB4002F27C4 /* coding_emoji_gif_06@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB3441BA6AEB4002F27C4 /* coding_emoji_gif_06@2x.png */; };
143143
4E2DB34C1BA6AEB4002F27C4 /* coding_emoji_gif_07@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB3451BA6AEB4002F27C4 /* coding_emoji_gif_07@2x.png */; };
144144
4E2DB34D1BA6AEB4002F27C4 /* coding_emoji_gif_01@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4E2DB3461BA6AEB4002F27C4 /* coding_emoji_gif_01@2x.png */; };
145+
4E2ECEAD1BD4D51000CB6EC9 /* ProjectTransferSettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E2ECEAC1BD4D51000CB6EC9 /* ProjectTransferSettingViewController.m */; settings = {ASSET_TAGS = (); }; };
145146
4E35A99F1A3EC47E00CE35F1 /* FileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E35A99E1A3EC47E00CE35F1 /* FileViewController.m */; };
146147
4E38CF5F1A7A28AF005536C0 /* CodeBranchTagButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E38CF5E1A7A28AF005536C0 /* CodeBranchTagButton.m */; };
147148
4E38CF621A7B7C99005536C0 /* CodeBranchOrTag.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E38CF611A7B7C99005536C0 /* CodeBranchOrTag.m */; };
@@ -1120,6 +1121,8 @@
11201121
4E2DB3441BA6AEB4002F27C4 /* coding_emoji_gif_06@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "coding_emoji_gif_06@2x.png"; sourceTree = "<group>"; };
11211122
4E2DB3451BA6AEB4002F27C4 /* coding_emoji_gif_07@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "coding_emoji_gif_07@2x.png"; sourceTree = "<group>"; };
11221123
4E2DB3461BA6AEB4002F27C4 /* coding_emoji_gif_01@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "coding_emoji_gif_01@2x.png"; sourceTree = "<group>"; };
1124+
4E2ECEAB1BD4D51000CB6EC9 /* ProjectTransferSettingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProjectTransferSettingViewController.h; sourceTree = "<group>"; };
1125+
4E2ECEAC1BD4D51000CB6EC9 /* ProjectTransferSettingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProjectTransferSettingViewController.m; sourceTree = "<group>"; };
11231126
4E35A99D1A3EC47E00CE35F1 /* FileViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileViewController.h; sourceTree = "<group>"; };
11241127
4E35A99E1A3EC47E00CE35F1 /* FileViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileViewController.m; sourceTree = "<group>"; };
11251128
4E38CF5D1A7A28AF005536C0 /* CodeBranchTagButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeBranchTagButton.h; sourceTree = "<group>"; };
@@ -4682,6 +4685,8 @@
46824685
B9A00D811ACA3A17008BA008 /* ProjectSettingViewController.m */,
46834686
B9A00D831ACA3A55008BA008 /* ProjectAdvancedSettingViewController.h */,
46844687
B9A00D841ACA3A55008BA008 /* ProjectAdvancedSettingViewController.m */,
4688+
4E2ECEAB1BD4D51000CB6EC9 /* ProjectTransferSettingViewController.h */,
4689+
4E2ECEAC1BD4D51000CB6EC9 /* ProjectTransferSettingViewController.m */,
46854690
B93D90491ACBA3110057A6EE /* ProjectDeleteAlertControllerVisualStyle.h */,
46864691
B93D904A1ACBA3110057A6EE /* ProjectDeleteAlertControllerVisualStyle.m */,
46874692
);
@@ -5285,6 +5290,7 @@
52855290
8EA6D1B219E240C40076D59C /* Depot.m in Sources */,
52865291
4ED6731E1A8DD38C00DF2D1A /* ReportIllegalViewController.m in Sources */,
52875292
8EF643CE19FF7E2900F7EEB0 /* TweetDetailCell.m in Sources */,
5293+
4E2ECEAD1BD4D51000CB6EC9 /* ProjectTransferSettingViewController.m in Sources */,
52885294
4EABD2571AD3CAAC005E515F /* UIMessageInputView_Add.m in Sources */,
52895295
7EB02FCE1B6CF5D500D2166C /* UIMessageInputView_Voice.m in Sources */,
52905296
8E59F0E21A0098BA009A905F /* UIScrollView+SVInfiniteScrolling.m in Sources */,

Coding_iOS/Controllers/ProjectSetting/ProjectAdvancedSettingViewController.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ @implementation ProjectAdvancedSettingViewController
2424

2525
- (void)viewDidLoad {
2626
[super viewDidLoad];
27+
self.title = @"删除项目";
2728

2829
for (NSLayoutConstraint *cons in self.lines) {
2930
cons.constant = 0.5;
3031
}
3132

32-
self.title = @"高级设置";
3333
self.tableView.tableFooterView = [UIView new];
3434
[self.tableView setSeparatorColor:[UIColor colorWithRGBHex:0xe5e5e5]];
3535
}

Coding_iOS/Controllers/ProjectSetting/ProjectSetting.storyboard

Lines changed: 199 additions & 23 deletions
Large diffs are not rendered by default.

Coding_iOS/Controllers/ProjectSetting/ProjectSettingViewController.m

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,18 +162,10 @@ -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)
162162

163163
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
164164
{
165-
//
166-
if (indexPath.section == 0 && indexPath.row == 0) {
167-
return;
168-
}
169-
if (indexPath.section == 1 && indexPath.row == 0) {
165+
if (indexPath.row == 0) {
166+
cell.separatorInset = UIEdgeInsetsMake(0.f, 13, 0.f, 0.f);
167+
}else{
170168
cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.f);
171-
return;
172-
}
173-
174-
// Remove seperator inset
175-
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
176-
[cell setSeparatorInset:UIEdgeInsetsZero];
177169
}
178170

179171
// Prevent the cell from inheriting the Table View's margin settings
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// ProjectTransferSettingViewController.h
3+
// Coding_iOS
4+
//
5+
// Created by Ease on 15/10/19.
6+
// Copyright © 2015年 Coding. All rights reserved.
7+
//
8+
9+
#import <UIKit/UIKit.h>
10+
@class Project;
11+
12+
@interface ProjectTransferSettingViewController : UITableViewController
13+
@property (nonatomic, strong) Project *project;
14+
@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *lines;
15+
@end
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
//
2+
// ProjectTransferSettingViewController.m
3+
// Coding_iOS
4+
//
5+
// Created by Ease on 15/10/19.
6+
// Copyright © 2015年 Coding. All rights reserved.
7+
//
8+
9+
#import "ProjectTransferSettingViewController.h"
10+
#import "Coding_NetAPIManager.h"
11+
12+
#import <SDCAlertController.h>
13+
#import <SDCAlertView.h>
14+
#import <UIView+SDCAutoLayout.h>
15+
#import "ProjectDeleteAlertControllerVisualStyle.h"
16+
#import "Ease_2FA.h"
17+
#import "ProjectMemberListViewController.h"
18+
19+
@interface ProjectTransferSettingViewController ()<UITextFieldDelegate>
20+
@property (strong, nonatomic) User *selectedUser;
21+
22+
@property (strong, nonatomic) SDCAlertController *alert;
23+
@property (weak, nonatomic) IBOutlet UIImageView *userIconView;
24+
@property (weak, nonatomic) IBOutlet UILabel *userNameLabel;
25+
@property (weak, nonatomic) IBOutlet UIButton *transferBtn;
26+
@end
27+
28+
@implementation ProjectTransferSettingViewController
29+
- (void)viewDidLoad {
30+
[super viewDidLoad];
31+
self.title = @"转让项目";
32+
33+
for (NSLayoutConstraint *cons in self.lines) {
34+
cons.constant = 0.5;
35+
}
36+
37+
[self.tableView setSeparatorColor:[UIColor colorWithRGBHex:0xe5e5e5]];
38+
[_userIconView doCircleFrame];
39+
[_transferBtn successStyle];
40+
_transferBtn.enabled = NO;
41+
}
42+
- (void)setSelectedUser:(User *)selectedUser{
43+
if ([selectedUser.global_key isEqualToString:[Login curLoginUser].global_key]) {
44+
[NSObject showHudTipStr:@"项目不能转让给自己!"];
45+
return;
46+
}
47+
_selectedUser = selectedUser;
48+
[_userIconView sd_setImageWithURL:[_selectedUser.avatar urlImageWithCodePathResizeToView:_userIconView] placeholderImage:[UIImage imageNamed:@"taskOwner"]];
49+
_userNameLabel.text = selectedUser.name;
50+
_transferBtn.enabled = _selectedUser.global_key.length > 0;
51+
}
52+
#pragma mark UITableView
53+
54+
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
55+
return [UIView new];
56+
}
57+
58+
//-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
59+
//{
60+
// if (indexPath.section == 1 && indexPath.row == 0) {
61+
// cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.f);
62+
// return;
63+
// }
64+
//
65+
// // Remove seperator inset
66+
// if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
67+
// [cell setSeparatorInset:UIEdgeInsetsZero];
68+
// }
69+
//
70+
// // Prevent the cell from inheriting the Table View's margin settings
71+
// if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
72+
// [cell setPreservesSuperviewLayoutMargins:NO];
73+
// }
74+
//
75+
// // Explictly set your cell's layout margins
76+
// if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
77+
// [cell setLayoutMargins:UIEdgeInsetsZero];
78+
// }
79+
//}
80+
81+
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
82+
[tableView deselectRowAtIndexPath:indexPath animated:YES];
83+
if (indexPath.section == 1) {
84+
__weak typeof(self) weakSelf = self;
85+
ProjectMemberListViewController *vc = [[ProjectMemberListViewController alloc] init];
86+
[vc setFrame:self.view.bounds project:_project type:ProMemTypeTaskOwner refreshBlock:nil selectBlock:^(ProjectMember *member) {
87+
weakSelf.selectedUser = member.user;
88+
} cellBtnBlock:nil];
89+
[self.navigationController pushViewController:vc animated:YES];
90+
}
91+
}
92+
93+
94+
#pragma mark Btn
95+
96+
- (IBAction)transferBtnClicked:(id)sender {
97+
[[Coding_NetAPIManager sharedManager] request_VerifyTypeWithBlock:^(VerifyType type, NSError *error) {
98+
if (!error) {
99+
[self showDeleteAlertWithType:type];
100+
}
101+
}];
102+
}
103+
104+
- (void)showDeleteAlertWithType:(VerifyType)type{
105+
106+
if (self.alert) {//正在显示
107+
return;
108+
}
109+
110+
NSString *title, *message, *placeHolder;
111+
if (type == VerifyTypePassword) {
112+
title = @"需要验证密码";
113+
message = @"这是一个危险的操作,请提供登录密码确认!";
114+
placeHolder = @"请输入密码";
115+
}else if (type == VerifyTypeTotp){
116+
title = @"需要动态验证码";
117+
message = @"这是一个危险操作,需要进行身份验证!";
118+
placeHolder = @"请输入动态验证码";
119+
}else{//不知道啥类型,不处理
120+
return;
121+
}
122+
123+
_alert = [SDCAlertController alertControllerWithTitle:title message:message preferredStyle:SDCAlertControllerStyleAlert];
124+
125+
UITextField *passwordTextField = [[UITextField alloc] initWithFrame:CGRectMake(15, 0, 240.0, 30.0)];
126+
passwordTextField.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 30)];
127+
passwordTextField.leftViewMode = UITextFieldViewModeAlways;
128+
passwordTextField.layer.borderColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.6].CGColor;
129+
passwordTextField.layer.borderWidth = 1;
130+
passwordTextField.secureTextEntry = (type == VerifyTypePassword);
131+
passwordTextField.backgroundColor = [UIColor whiteColor];
132+
passwordTextField.placeholder = placeHolder;
133+
if (type == VerifyTypeTotp) {
134+
passwordTextField.text = [OTPListViewController otpCodeWithGK:[Login curLoginUser].global_key];
135+
}
136+
passwordTextField.delegate = self;
137+
138+
[_alert.contentView addSubview:passwordTextField];
139+
140+
NSDictionary* passwordViews = NSDictionaryOfVariableBindings(passwordTextField);
141+
142+
[_alert.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[passwordTextField]-(>=14)-|" options:0 metrics:nil views:passwordViews]];
143+
144+
// Style
145+
_alert.visualStyle = [ProjectDeleteAlertControllerVisualStyle new];
146+
147+
// 添加密码框
148+
// [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
149+
// textField.secureTextEntry = YES;
150+
// }];
151+
152+
// 添加按钮
153+
@weakify(self);
154+
_alert.actionLayout = SDCAlertControllerActionLayoutHorizontal;
155+
[_alert addAction:[SDCAlertAction actionWithTitle:@"取消" style:SDCAlertActionStyleDefault handler:^(SDCAlertAction *action) {
156+
@strongify(self);
157+
self.alert = nil;
158+
}]];
159+
[_alert addAction:[SDCAlertAction actionWithTitle:@"确定" style:SDCAlertActionStyleDefault handler:^(SDCAlertAction *action) {
160+
@strongify(self);
161+
self.alert = nil;
162+
NSString *passCode = passwordTextField.text;
163+
if ([passCode length] > 0) {
164+
// 转让项目
165+
[[Coding_NetAPIManager sharedManager] request_TransferProject:self.project toUser:self.selectedUser passCode:passCode type:type andBlock:^(Project *data, NSError *error) {
166+
if (!error) {
167+
[self.navigationController popToRootViewControllerAnimated:YES];
168+
}
169+
}];
170+
}
171+
}]];
172+
173+
[_alert presentWithCompletion:^{
174+
[passwordTextField becomeFirstResponder];
175+
}];
176+
}
177+
178+
179+
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
180+
[textField resignFirstResponder];
181+
return YES;
182+
}
183+
184+
#pragma mark - Orientations
185+
- (BOOL)shouldAutorotate{
186+
return UIInterfaceOrientationIsLandscape(self.interfaceOrientation);
187+
}
188+
189+
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
190+
return UIInterfaceOrientationPortrait;
191+
}
192+
193+
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
194+
return UIInterfaceOrientationMaskPortrait;
195+
}
196+
@end

Coding_iOS/Util/Manager/Coding_NetAPIManager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ typedef NS_ENUM(NSUInteger, VerifyType){
7575
- (void)request_UpdateProject_WithObj:(Project *)project andBlock:(void (^)(Project *data, NSError *error))block;
7676
- (void)request_UpdateProject_WithObj:(Project *)project icon:(UIImage *)icon andBlock:(void (^)(id data, NSError *error))block progerssBlock:(void (^)(CGFloat progressValue))progress;;
7777
- (void)request_DeleteProject_WithObj:(Project *)project passCode:(NSString *)passCode type:(VerifyType)type andBlock:(void (^)(Project *data, NSError *error))block;
78-
78+
- (void)request_TransferProject:(Project *)project toUser:(User *)user passCode:(NSString *)passCode type:(VerifyType)type andBlock:(void (^)(Project *data, NSError *error))block;
7979
//MRPR
8080
- (void)request_MRPRS_WithObj:(MRPRS *)curMRPRS andBlock:(void (^)(MRPRS *data, NSError *error))block;
8181
- (void)request_MRPRBaseInfo_WithObj:(MRPR *)curMRPR andBlock:(void (^)(MRPRBaseInfo *data, NSError *error))block;

Coding_iOS/Util/Manager/Coding_NetAPIManager.m

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,33 @@ - (void)request_DeleteProject_WithObj:(Project *)project passCode:(NSString *)pa
377377
}];
378378
}
379379

380+
- (void)request_TransferProject:(Project *)project toUser:(User *)user passCode:(NSString *)passCode type:(VerifyType)type andBlock:(void (^)(Project *data, NSError *error))block{
381+
if (project.id.stringValue.length <= 0 || user.global_key.length <= 0|| passCode.length <= 0) {
382+
return;
383+
}
384+
NSString *path = [NSString stringWithFormat:@"api/project/%@/transfer_to/%@", project.id.stringValue, user.global_key];
385+
NSDictionary *params;
386+
if (type == VerifyTypePassword) {
387+
params = @{@"two_factor_code": [passCode sha1Str]};
388+
}else if (type == VerifyTypeTotp){
389+
params = @{@"two_factor_code": passCode};
390+
}else{
391+
return;
392+
}
393+
[NSObject showStatusBarQueryStr:@"正在转让项目"];
394+
[[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:path withParams:params withMethodType:Put andBlock:^(id data, NSError *error) {
395+
if (data) {
396+
[MobClick event:kUmeng_Event_Request_ActionOfServer label:@"转让项目"];
397+
398+
[NSObject showStatusBarSuccessStr:@"转让项目成功"];
399+
block(data, nil);
400+
}else{
401+
[NSObject showStatusBarError:error];
402+
block(nil, error);
403+
}
404+
}];
405+
}
406+
380407
- (void)request_ProjectTaskList_WithObj:(Tasks *)tasks andBlock:(void (^)(Tasks *data, NSError *error))block{
381408
tasks.isLoading = YES;
382409
[[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:[tasks toRequestPath] withParams:[tasks toParams] withMethodType:Get andBlock:^(id data, NSError *error) {

0 commit comments

Comments
 (0)