Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
陈高翔
/
DreamSleep-iOS
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit d23ba692
由
cgx
编写于
2022-04-22 12:24:02 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
完成苹果登录
1 个父辈
4ca62a62
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
182 行增加
和
56 行删除
DreamSleep/DreamSleep.xcodeproj/project.pbxproj
DreamSleep/DreamSleep/Network/DSNetworkTool.m
DreamSleep/DreamSleep/Profile/Feedback/FeedbackController.h
DreamSleep/DreamSleep/Profile/Feedback/FeedbackController.m
DreamSleep/DreamSleep/Profile/Me/ProfileController.m
DreamSleep/DreamSleep/Profile/UserLogin/LoginController.m
DreamSleep/DreamSleep/Profile/UserLogin/UserModel.h
DreamSleep/DreamSleep/Profile/UserLogin/UserRequestModel.h
DreamSleep/DreamSleep/Profile/UserLogin/UserRequestModel.m
DreamSleep/DreamSleep.xcodeproj/project.pbxproj
查看文件 @
d23ba69
...
...
@@ -97,6 +97,7 @@
D0CFD3CF27FB3B920002982B /* launcher@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0CFD3CC27FB3B910002982B /* launcher@2x.png */; };
D0CFD3D027FB3B920002982B /* launcher@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D0CFD3CD27FB3B910002982B /* launcher@3x.png */; };
D0CFD3D127FB3B920002982B /* launcher.png in Resources */ = {isa = PBXBuildFile; fileRef = D0CFD3CE27FB3B920002982B /* launcher.png */; };
D0D3826728124E8A005BB219 /* FeedbackController.m in Sources */ = {isa = PBXBuildFile; fileRef = D0D3826628124E8A005BB219 /* FeedbackController.m */; };
D0E65FFA2807A654006562F2 /* NSArray+HYBUnicodeReadable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0E65FF42807A654006562F2 /* NSArray+HYBUnicodeReadable.m */; };
D0E65FFB2807A654006562F2 /* NSDictionary+HYBUnicodeReadable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0E65FF52807A654006562F2 /* NSDictionary+HYBUnicodeReadable.m */; };
D0E65FFC2807A654006562F2 /* NSSet+HYBUnicodeReadable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0E65FF62807A654006562F2 /* NSSet+HYBUnicodeReadable.m */; };
...
...
@@ -282,6 +283,8 @@
D0CFD3CC27FB3B910002982B /* launcher@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "launcher@2x.png"; sourceTree = "<group>"; };
D0CFD3CD27FB3B910002982B /* launcher@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "launcher@3x.png"; sourceTree = "<group>"; };
D0CFD3CE27FB3B920002982B /* launcher.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = launcher.png; sourceTree = "<group>"; };
D0D3826528124E8A005BB219 /* FeedbackController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FeedbackController.h; sourceTree = "<group>"; };
D0D3826628124E8A005BB219 /* FeedbackController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FeedbackController.m; sourceTree = "<group>"; };
D0D7480328118D0B00036379 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = "<group>"; };
D0D7480428118D0B00036379 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
D0E65FF42807A654006562F2 /* NSArray+HYBUnicodeReadable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+HYBUnicodeReadable.m"; sourceTree = "<group>"; };
...
...
@@ -473,6 +476,7 @@
D04567AD27F6D0F4009F0A82 /* Profile */ = {
isa = PBXGroup;
children = (
D0D3826428124E34005BB219 /* Feedback */,
D07A4B2E280EC1F100BA0EC0 /* Me */,
D07A4B2F280EC21B00BA0EC0 /* Account */,
D0CE3D80280A532D00D8B02D /* UserLogin */,
...
...
@@ -737,6 +741,15 @@
path = UserLogin;
sourceTree = "<group>";
};
D0D3826428124E34005BB219 /* Feedback */ = {
isa = PBXGroup;
children = (
D0D3826528124E8A005BB219 /* FeedbackController.h */,
D0D3826628124E8A005BB219 /* FeedbackController.m */,
);
path = Feedback;
sourceTree = "<group>";
};
D0E65FF32807A654006562F2 /* HYBUnicodeReadable */ = {
isa = PBXGroup;
children = (
...
...
@@ -1005,6 +1018,7 @@
D0E6600828080F97006562F2 /* SystemSetController.m in Sources */,
D091BBB72808F9DA00487A50 /* BreathTextView.m in Sources */,
D04B3DBB27F6F7940022F8DF /* AISleepCoachController.m in Sources */,
D0D3826728124E8A005BB219 /* FeedbackController.m in Sources */,
D027EE2627FB3DC0004BBA61 /* NetLoadingStateView.m in Sources */,
D0C09EE028007E5F00709D4C /* BreatheController.m in Sources */,
D0C50B4627FD66FB00DC68F0 /* DSConstUtil.m in Sources */,
...
...
DreamSleep/DreamSleep/Network/DSNetworkTool.m
查看文件 @
d23ba69
...
...
@@ -102,9 +102,6 @@ NSString * const NetworkUnableError = @"网络不给力,请检查您的网络
[
request
addValue
:[
LoginUtils
getSid
]
forHTTPHeaderField
:
@"sid"
];
NSURLSessionDataTask
*
dataTask
=
[[
DSNetworkTool
sharedManager
]
dataTaskWithRequest
:
request
uploadProgress
:
nil
downloadProgress
:
nil
completionHandler
:^
(
NSURLResponse
*
_Nonnull
response
,
id
_Nullable
responseObject
,
NSError
*
_Nullable
error
)
{
NSHTTPURLResponse
*
httpResponse
=
(
NSHTTPURLResponse
*
)
response
;
NSLog
(
@"allHeaderFieldsCookie:%@"
,
httpResponse
.
allHeaderFields
[
@"Set-Cookie"
]);
[[
UIApplication
sharedApplication
]
setNetworkActivityIndicatorVisible
:
NO
];
if
(
loadingInfo
)
{
[
DSProgressHUD
dissmissProgressHUD
];
}
...
...
DreamSleep/DreamSleep/Profile/Feedback/FeedbackController.h
0 → 100644
查看文件 @
d23ba69
//
// FeedbackController.h
// DreamSleep
//
// Created by peter on 2022/4/22.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/// 意见反馈
@interface
FeedbackController
:
UIViewController
@end
NS_ASSUME_NONNULL_END
DreamSleep/DreamSleep/Profile/Feedback/FeedbackController.m
0 → 100644
查看文件 @
d23ba69
//
// FeedbackController.m
// DreamSleep
//
// Created by peter on 2022/4/22.
//
#import "FeedbackController.h"
@interface
FeedbackController
()
@property
(
strong
,
nonatomic
)
UITextView
*
feedTV
;
@property
(
strong
,
nonatomic
)
UICollectionView
*
imgCollectionView
;
@property
(
strong
,
nonatomic
)
UIButton
*
commitBtn
;
@end
@implementation
FeedbackController
-
(
void
)
viewDidLoad
{
[
super
viewDidLoad
];
self
.
navigationItem
.
title
=
@"意见反馈"
;
self
.
view
.
dk_backgroundColorPicker
=
DKColorPickerWithKey
(
VCViewBG
);
UIButton
*
myFeedBtn
=
[
UIButton
btnWithTitle
:
@"我的反馈"
titleColor
:
DSWhite
font
:
SysFont
(
12
)];
myFeedBtn
.
size
=
CGSizeMake
(
82
,
26
);
[
myFeedBtn
cornerRadius
:
13
];
myFeedBtn
.
layer
.
borderColor
=
DSWhite
.
CGColor
;
myFeedBtn
.
layer
.
borderWidth
=
1
;
[
myFeedBtn
addTarget
:
self
action
:
@selector
(
myFeedAction
)
forControlEvents
:
UIControlEventTouchUpInside
];
self
.
navigationItem
.
rightBarButtonItem
=
[[
UIBarButtonItem
alloc
]
initWithCustomView
:
myFeedBtn
];
[
self
.
view
addSubview
:
self
.
feedTV
];
[
self
.
view
addSubview
:
self
.
imgCollectionView
];
[
self
.
view
addSubview
:
self
.
commitBtn
];
[
self
.
feedTV
mas_makeConstraints
:
^
(
MASConstraintMaker
*
make
)
{
make
.
left
.
equalTo
(
@15
);
make
.
right
.
equalTo
(
@
-
15
);
make
.
top
.
equalTo
(
@15
);
}];
[
self
.
imgCollectionView
mas_makeConstraints
:
^
(
MASConstraintMaker
*
make
)
{
make
.
left
.
equalTo
(
@15
);
make
.
right
.
equalTo
(
@
-
15
);
make
.
top
.
equalTo
(
self
.
feedTV
.
mas_bottom
).
offset
(
26
);
make
.
height
.
equalTo
(
@77
);
}];
[
self
.
commitBtn
mas_makeConstraints
:
^
(
MASConstraintMaker
*
make
)
{
make
.
centerX
.
equalTo
(
self
.
view
);
make
.
top
.
equalTo
(
self
.
imgCollectionView
.
mas_bottom
).
offset
(
60
);
make
.
bottom
.
equalTo
(
self
).
offset
(
-
91
);
make
.
width
.
equalTo
(
@155
);
make
.
height
.
equalTo
(
@40
);
}];
}
-
(
void
)
touchesBegan
:
(
NSSet
<
UITouch
*>
*
)
touches
withEvent
:
(
UIEvent
*
)
event
{
[
self
.
feedTV
endEditing
:
YES
];
}
#pragma mark - Actions
-
(
void
)
myFeedAction
{
}
-
(
void
)
commitAction
{
}
#pragma mark - lazy
-
(
UITextView
*
)
feedTV
{
if
(
!
_feedTV
)
{
_feedTV
=
[[
UITextView
alloc
]
init
];
_feedTV
.
dk_backgroundColorPicker
=
DKColorPickerWithColors
(
ColorFromHex
(
0xf0f0f0
),
CornerViewDarkColor
,
DSWhite
);
_feedTV
.
dk_textColorPicker
=
DKColorPickerWithColors
(
ColorFromHex
(
0x777777
),
DSWhite
,
DSWhite
);
_feedTV
.
font
=
SysFont
(
14
);
[
_feedTV
cornerRadius
:
12
];
[
_feedTV
becomeFirstResponder
];
}
return
_feedTV
;
}
-
(
UICollectionView
*
)
imgCollectionView
{
if
(
!
_imgCollectionView
)
{
UICollectionViewLayout
*
layout
=
[[
UICollectionViewLayout
alloc
]
init
];
_imgCollectionView
=
[[
UICollectionView
alloc
]
initWithFrame
:
CGRectZero
collectionViewLayout
:
layout
];
}
return
_imgCollectionView
;
}
-
(
UIButton
*
)
commitBtn
{
if
(
!
_commitBtn
)
{
_commitBtn
=
[
UIButton
btnWithTitle
:
@"提交"
titleColor
:
DSWhite
font
:
BoldFont
(
16
)
bgColor
:
BrandColor
];
[
_commitBtn
addTarget
:
self
action
:
@selector
(
commitAction
)
forControlEvents
:
UIControlEventTouchUpInside
];
[
_commitBtn
cornerRadius
:
22
];
}
return
_commitBtn
;
}
@end
DreamSleep/DreamSleep/Profile/Me/ProfileController.m
查看文件 @
d23ba69
...
...
@@ -6,6 +6,7 @@
//
#import "ProfileController.h"
#import "FeedbackController.h"
#import "AccountController.h"
#import "SystemSetController.h"
#import "InviteController.h"
...
...
@@ -61,6 +62,12 @@
[
LoginUtils
jumpToLoginControllerWithTarget
:
self
];
}
break
;
case
1
:
// 意见反馈入口
{
FeedbackController
*
feedVC
=
[
FeedbackController
new
];
[
self
.
navigationController
pushViewController
:
feedVC
animated
:
YES
];
}
break
;
case
2
:
// 系统设置入口
{
SystemSetController
*
sysVC
=
[
SystemSetController
new
];
...
...
DreamSleep/DreamSleep/Profile/UserLogin/LoginController.m
查看文件 @
d23ba69
...
...
@@ -10,7 +10,6 @@
#import "PrivacyViewController.h"
#import <AuthenticationServices/AuthenticationServices.h>
#import "UserRequestModel.h"
#import <UMShare/UMShare.h>
@interface
LoginController
()
<
LoginViewDelegate
,
ASAuthorizationControllerDelegate
,
ASAuthorizationControllerPresentationContextProviding
>
@property
(
strong
,
nonatomic
)
LoginView
*
loginView
;
...
...
@@ -44,6 +43,7 @@
-
(
void
)
wxLoginAuth
:
(
NSNotification
*
)
noti
{
NSString
*
code
=
noti
.
object
;
// 发送微信登录请求
[
UserRequestModel
wxLoginWithCode
:
code
completion
:
^
(
UserRequestModel
*
_Nonnull
requestModel
)
{
if
(
requestModel
.
resCode
==
DSResCodeSuccess
)
{
[
self
dismissViewControllerAnimated
:
YES
completion
:
nil
];
...
...
@@ -66,16 +66,6 @@
[
WXApi
sendReq
:
req
completion
:
^
(
BOOL
success
)
{
DSLog
(
@"调起微信成功..."
);
}];
// [[UMSocialManager defaultManager] getUserInfoWithPlatform:UMSocialPlatformType_WechatSession currentViewController:nil completion:^(id result, NSError *error) {
// UMSocialUserInfoResponse *resp = result;
//
// if (error) {
// DSLog(@"error:%@", error);
// } else {
// DSLog(@"调起微信成功...");
// }
// }];
}
break
;
case
2
:
// Apple登录
...
...
@@ -121,48 +111,21 @@
#pragma mark - ASAuthorizationControllerDelegate
#pragma mark - 授权成功地回调
-
(
void
)
authorizationController
:
(
ASAuthorizationController
*
)
controller
didCompleteWithAuthorization
:
(
ASAuthorization
*
)
authorization
API_AVAILABLE
(
ios
(
13
.
0
))
{
NSLog
(
@"%s"
,
__FUNCTION__
);
NSLog
(
@"%@"
,
controller
);
NSLog
(
@"%@"
,
authorization
);
NSLog
(
@"authorization.credential:%@"
,
authorization
.
credential
);
if
([
authorization
.
credential
isKindOfClass
:[
ASAuthorizationAppleIDCredential
class
]])
{
ASAuthorizationAppleIDCredential
*
credential
=
authorization
.
credential
;
NSLog
(
@"credential = %@"
,
credential
);
NSString
*
state
=
credential
.
state
;
NSString
*
userID
=
credential
.
user
;
NSPersonNameComponents
*
fullName
=
credential
.
fullName
;
NSString
*
email
=
credential
.
email
;
NSString
*
authorizationCode
=
[[
NSString
alloc
]
initWithData
:
credential
.
authorizationCode
encoding
:
NSUTF8StringEncoding
];
// 验证 token
NSString
*
identityToken
=
[[
NSString
alloc
]
initWithData
:
credential
.
identityToken
encoding
:
NSUTF8StringEncoding
];
// 用户 token
ASUserDetectionStatus
realUserStatus
=
credential
.
realUserStatus
;
NSArray
*
authorizedScopes
=
credential
.
authorizedScopes
;
NSLog
(
@"ios登陆成功 state: %@
\n
userID: %@
\n
fullName: %@
\n
email: %@
\n
authorizationCode: %@
\n
identityToken: %@
\n
realUserStatus: %@
\n
authorizedScopes: %@"
,
state
,
userID
,
fullName
,
email
,
authorizationCode
,
identityToken
,
@
(
realUserStatus
),
authorizedScopes
);
DSLog
(
@"ios登陆成功:userID: %@
\n
,authorizationCode: %@
\n
,identityToken: %@"
,
userID
,
authorizationCode
,
identityToken
);
// // 用户登录使用ASAuthorizationAppleIDCredential
// ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential;
// // 用户ID: user,苹果用户唯一标识,该值在同一个开发者账号下的所有 App 下是一样的。
// NSString *user = appleIDCredential.user;
// // 使用钥匙串的方式保存用户的唯一信息
// NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
//
// // 验证数据: identityToken , authorizationCode ,用于服务端验证授权请求的合法性。
// NSString *authorizationCode = [[NSString alloc] initWithData:appleIDCredential.authorizationCode encoding:NSUTF8StringEncoding];
// NSString *identityToken = [[NSString alloc] initWithData:appleIDCredential.identityToken encoding:NSUTF8StringEncoding];
//
// NSLog(@"user:%@, bundleId:%@, authorizationCode:%@, identityToken:%@", user, bundleId, authorizationCode, identityToken);
// 通过钥匙串保存用户授权信息
// [SAMKeychain setPassword:user forService:bundleId account:ShareCurrentIdentifier];
// 发送苹果登录请求
[
UserRequestModel
appleLoginWithUser
:
userID
identityToken
:
identityToken
authorizationCode
:
authorizationCode
completion
:^
(
UserRequestModel
*
_Nonnull
requestModel
)
{
if
(
requestModel
.
resCode
==
DSResCodeSuccess
)
{
[
self
dismissViewControllerAnimated
:
YES
completion
:
nil
];
}
else
{
[
DSProgressHUD
showToast
:
requestModel
.
errorInfo
];
}
}];
}
else
if
([
authorization
.
credential
isKindOfClass
:[
ASPasswordCredential
class
]])
{
// 用户登录使用现有的密码凭证
ASPasswordCredential
*
passwordCredential
=
authorization
.
credential
;
...
...
@@ -170,17 +133,14 @@
NSString
*
user
=
passwordCredential
.
user
;
// 密码凭证对象的密码
NSString
*
password
=
passwordCredential
.
password
;
NSLog
(
@"user:%@, password:%@"
,
user
,
password
);
DSLog
(
@"user:%@, password:%@"
,
user
,
password
);
}
else
{
N
SLog
(
@"授权信息均不符"
);
D
SLog
(
@"授权信息均不符"
);
}
}
#pragma mark - 授权失败的回调
-
(
void
)
authorizationController
:
(
ASAuthorizationController
*
)
controller
didCompleteWithError
:
(
NSError
*
)
error
API_AVAILABLE
(
ios
(
13
.
0
))
{
NSLog
(
@"%s"
,
__FUNCTION__
);
NSLog
(
@"错误信息:%@"
,
error
);
NSString
*
errorMsg
=
nil
;
switch
(
error
.
code
)
{
case
ASAuthorizationErrorCanceled
:
...
...
@@ -202,7 +162,7 @@
errorMsg
=
@"ASAuthorizationErrorNotInteractive"
;
break
;
}
N
SLog
(
@"controller requests:%@, errorMsg:%@"
,
controller
.
authorizationRequests
,
errorMsg
);
D
SLog
(
@"controller requests:%@, errorMsg:%@"
,
controller
.
authorizationRequests
,
errorMsg
);
}
#pragma mark - ASAuthorizationControllerPresentationContextProviding
...
...
DreamSleep/DreamSleep/Profile/UserLogin/UserModel.h
查看文件 @
d23ba69
...
...
@@ -15,7 +15,9 @@ NS_ASSUME_NONNULL_BEGIN
@property
(
nonatomic
,
assign
)
BOOL
gender
;
@property
(
nonatomic
,
copy
)
NSString
*
birthday
;
@property
(
nonatomic
,
assign
)
int
user_id
;
// 登录token
@property
(
nonatomic
,
copy
)
NSString
*
token
;
// 获取后每次发送请求存放到请求头
@property
(
nonatomic
,
copy
)
NSString
*
sid
;
@property
(
nonatomic
,
copy
)
NSString
*
user_name
;
@property
(
nonatomic
,
copy
)
NSString
*
face_img
;
...
...
DreamSleep/DreamSleep/Profile/UserLogin/UserRequestModel.h
查看文件 @
d23ba69
...
...
@@ -20,6 +20,12 @@ NS_ASSUME_NONNULL_BEGIN
/// @param completion completion
+
(
NSURLSessionDataTask
*
)
wxLoginWithCode
:(
NSString
*
)
code
completion
:(
void
(
^
)(
UserRequestModel
*
requestModel
))
completion
;
/// 苹果登录请求
+
(
NSURLSessionDataTask
*
)
appleLoginWithUser
:(
NSString
*
)
user
identityToken
:(
NSString
*
)
identityToken
authorizationCode
:(
NSString
*
)
authorizationCode
completion
:(
void
(
^
)(
UserRequestModel
*
requestModel
))
completion
;
/// 用户退出登录接口
/// @param completion completion
+
(
NSURLSessionDataTask
*
)
layoutRequestWithCompletion
:(
void
(
^
)(
UserRequestModel
*
requestModel
))
completion
;
...
...
DreamSleep/DreamSleep/Profile/UserLogin/UserRequestModel.m
查看文件 @
d23ba69
...
...
@@ -30,6 +30,30 @@
}];
}
+
(
NSURLSessionDataTask
*
)
appleLoginWithUser
:(
NSString
*
)
user
identityToken
:(
NSString
*
)
identityToken
authorizationCode
:(
NSString
*
)
authorizationCode
completion
:(
void
(
^
)(
UserRequestModel
*
requestModel
))
completion
{
UserRequestModel
*
requestModel
=
[[
UserRequestModel
alloc
]
init
];
NSString
*
api
=
@"verify_sign_with_appleid"
;
NSString
*
argStr
=
[
NSString
stringWithFormat
:
@"mutation{%@(user_id:
\"
%@
\"
,identity_token:
\"
%@
\"
,authorization_code:
\"
%@
\"
)}"
,
api
,
user
,
identityToken
,
authorizationCode
];
return
[
self
httpPostBodyRequestWithAPI
:
api
params
:@{
@"query"
:
argStr
}
view
:
nil
hasNetActivity
:
YES
loadingInfo
:
nil
hasFailInfo
:
YES
success
:^
(
NSDictionary
*
_Nonnull
apiDic
)
{
DSLog
(
@"苹果登录接口apiDic:%@"
,
apiDic
);
requestModel
.
resCode
=
DSResCodeSuccess
;
NSDictionary
*
resultDic
=
apiDic
[
@"result"
];
UserModel
*
userModel
=
[
UserModel
yy_modelWithJSON
:
resultDic
];
DSLog
(
@"userModel:%@"
,
userModel
.
debugDescription
);
// 保存用户信息
[
LoginUtils
saveUserLoginData
:
userModel
];
completion
(
requestModel
);
}
failure
:^
(
id
_Nonnull
failureInfo
)
{
requestModel
.
resCode
=
DSResCodeNetFail
;
requestModel
.
errorInfo
=
failureInfo
;
completion
(
requestModel
);
}];
}
+
(
NSURLSessionDataTask
*
)
layoutRequestWithCompletion
:(
void
(
^
)(
UserRequestModel
*
requestModel
))
completion
{
UserRequestModel
*
requestModel
=
[[
UserRequestModel
alloc
]
init
];
...
...
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论