package com.cheikh.lazywaimai.controller; import com.cheikh.lazywaimai.model.bean.Business; import com.cheikh.lazywaimai.model.bean.Favorite; import com.cheikh.lazywaimai.model.bean.ResultsPage; import com.google.common.base.Preconditions; import com.squareup.otto.Subscribe; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.RequestBody; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action0; import rx.functions.Func1; import rx.schedulers.Schedulers; import com.cheikh.lazywaimai.base.BaseController; import com.cheikh.lazywaimai.context.AppConfig; import com.cheikh.lazywaimai.context.AppCookie; import com.cheikh.lazywaimai.model.bean.ResponseError; import com.cheikh.lazywaimai.model.bean.Token; import com.cheikh.lazywaimai.model.bean.User; import com.cheikh.lazywaimai.model.event.AccountChangedEvent; import com.cheikh.lazywaimai.network.RequestCallback; import com.cheikh.lazywaimai.network.RestApiClient; import com.cheikh.lazywaimai.ui.Display; import com.cheikh.lazywaimai.util.EventUtil; import static com.cheikh.lazywaimai.util.Constants.Key.PARAM_CLIENT_ID; import static com.cheikh.lazywaimai.util.Constants.Key.PARAM_CLIENT_SECRET; import static com.cheikh.lazywaimai.util.Constants.Key.PARAM_GRANT_TYPE; import static com.cheikh.lazywaimai.util.Constants.Key.PARAM_PASSWORD; import static com.cheikh.lazywaimai.util.Constants.Key.PARAM_USER_NAME; @Singleton public class UserController extends BaseController<UserController.UserUi, UserController.UserUiCallbacks> { private static final int PAGE_SIZE = 10; private final RestApiClient mRestApiClient; private int mPageIndex; @Inject public UserController(RestApiClient restApiClient) { super(); mRestApiClient = Preconditions.checkNotNull(restApiClient, "restApiClient cannot be null"); } @Subscribe public void onAccountChanged(AccountChangedEvent event) { User user = event.getUser(); if (user != null) { AppCookie.saveUserInfo(user); AppCookie.saveLastPhone(user.getMobile()); } else { AppCookie.saveUserInfo(null); AppCookie.saveAccessToken(null); AppCookie.saveRefreshToken(null); mRestApiClient.setToken(null); } populateUis(); } @Override protected void onInited() { super.onInited(); EventUtil.register(this); } @Override protected void onSuspended() { EventUtil.unregister(this); super.onSuspended(); } @Override protected synchronized void populateUi(UserUi ui) { if (ui instanceof UserCenterUi) { populateUserCenterUi((UserCenterUi) ui); } else if (ui instanceof UserProfileUi) { populateUserProfileUi((UserProfileUi) ui); } if (ui instanceof UserFavoriteListUi) { populateUserFavoriteListUi((UserFavoriteListUi) ui); } } private void populateUserCenterUi(UserCenterUi ui) { ui.showUserInfo(AppCookie.getUserInfo()); } private void populateUserProfileUi(UserProfileUi ui) { ui.showUserInfo(AppCookie.getUserInfo()); } private void populateUserFavoriteListUi(UserFavoriteListUi ui) { mPageIndex = 1; doFetchFavorites(getId(ui), mPageIndex, PAGE_SIZE); } /** * 注册的第1个步骤:发送短信验证码 * @param callingId * @param mobile */ private void doSendCode(final int callingId, String mobile) { mRestApiClient.accountService() .sendCode(mobile) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new RequestCallback<Boolean>() { @Override public void onResponse(Boolean response) { UserUi ui = findUi(callingId); if (ui instanceof RegisterFirstStepUi) { ((RegisterFirstStepUi) ui).sendCodeFinish(); } } @Override public void onFailure(ResponseError error) { UserUi ui = findUi(callingId); if (ui instanceof RegisterFirstStepUi) { ui.onResponseError(error); } } }); } /** * 注册的第2个步骤:检查短信验证码 * @param callingId * @param mobile * @param code */ private void doCheckCode(final int callingId, String mobile, String code) { mRestApiClient.accountService() .verifyCode(mobile, code) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new RequestCallback<Boolean>() { @Override public void onResponse(Boolean response) { UserUi ui = findUi(callingId); if (ui instanceof RegisterFirstStepUi) { ((RegisterSecondStepUi) ui).verifyMobileFinish(); } } @Override public void onFailure(ResponseError error) { UserUi ui = findUi(callingId); if (ui instanceof RegisterSecondStepUi) { ui.onResponseError(error); } } }); } /** * 注册的第3个步骤:创建账户 * @param callingId * @param mobile * @param password */ private void doCreateUser(final int callingId, String mobile, String password) { mRestApiClient.accountService() .register(mobile, password) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new RequestCallback<Boolean>() { @Override public void onResponse(Boolean response) { UserUi ui = findUi(callingId); if (ui instanceof RegisterThirdStepUi) { ((RegisterThirdStepUi) ui).userCreateFinish(); } } @Override public void onFailure(ResponseError error) { UserUi ui = findUi(callingId); if (ui instanceof RegisterThirdStepUi) { ui.onResponseError(error); } } }); } /** * 用户登录,获取 Access Token 以及用户资料 * @param callingId * @param username * @param password */ private void doLogin(final int callingId, String username, String password) { Map<String, String> params = new HashMap<>(); params.put(PARAM_CLIENT_ID, AppConfig.APP_KEY); params.put(PARAM_CLIENT_SECRET, AppConfig.APP_SECRET); params.put(PARAM_GRANT_TYPE, "password"); params.put(PARAM_USER_NAME, username); params.put(PARAM_PASSWORD, password); mRestApiClient.tokenService() .accessToken(params) .flatMap(new Func1<Token, Observable<User>>() { @Override public Observable<User> call(final Token token) { AppCookie.saveAccessToken(token.getAccessToken()); AppCookie.saveRefreshToken(token.getRefreshToken()); return mRestApiClient.setToken(token.getAccessToken()) .accountService() .profile(token.getUserId()); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new RequestCallback<User>() { @Override public void onResponse(User user) { UserUi ui = findUi(callingId); if (ui instanceof UserLoginUi) { ((UserLoginUi) ui).userLoginFinish(); // 发送用户账户改变的事件 EventUtil.sendEvent(new AccountChangedEvent(user)); } } @Override public void onFailure(ResponseError error) { UserUi ui = findUi(callingId); if (ui instanceof UserLoginUi) { ui.onResponseError(error); } } }); } /** * 保存用户名 * @param callingId * @param username */ private void doSetUsername(final int callingId, String username) { mRestApiClient.accountService() .setUsername(AppCookie.getUserInfo().getId(), username) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new RequestCallback<User>() { @Override public void onResponse(User user) { UserUi ui = findUi(callingId); if (ui instanceof UserNameUi) { ((UserNameUi) ui).onSetUsernameFinish(); // 发送用户账户改变的事件 EventUtil.sendEvent(new AccountChangedEvent(user)); } } @Override public void onFailure(ResponseError error) { UserUi ui = findUi(callingId); if (ui instanceof UserNameUi) { ui.onResponseError(error); } } }); } /** * 设置昵称 * @param callingId * @param nickname */ private void doSetNickname(final int callingId, String nickname) { mRestApiClient.accountService() .setNickname(AppCookie.getUserInfo().getId(), nickname) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new RequestCallback<User>() { @Override public void onResponse(User user) { UserUi ui = findUi(callingId); if (ui instanceof UserNicknameUi) { ((UserNicknameUi) ui).onSetNicknameFinish(); // 发送用户账户改变的事件 EventUtil.sendEvent(new AccountChangedEvent(user)); } } @Override public void onFailure(ResponseError error) { UserUi ui = findUi(callingId); if (ui instanceof UserNicknameUi) { ui.onResponseError(error); } } }); } /** * 用户退出登录 * @param callingId */ private void doLogout(final int callingId) { UserUi ui = findUi(callingId); if (ui instanceof SettingUi) { // 发送用户账户改变的事件 EventUtil.sendEvent(new AccountChangedEvent(null)); ((SettingUi) ui).logoutFinish(); } } /** * 用户上传头像 * @param callingId */ private void doUploadAvatar(final int callingId, File file) { RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file); MultipartBody.Part part = MultipartBody.Part.createFormData("avatar", file.getName(), requestBody); mRestApiClient.commonService() .singleFileUpload(part) .flatMap(new Func1<String, Observable<User>>() { @Override public Observable<User> call(final String url) { return mRestApiClient .accountService() .updateAvatar(AppCookie.getUserInfo().getId(), url); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new RequestCallback<User>() { @Override public void onResponse(User user) { UserUi ui = findUi(callingId); if (ui instanceof UserProfileUi) { ((UserProfileUi) ui).uploadAvatarFinish(); // 发送用户账户改变的事件 EventUtil.sendEvent(new AccountChangedEvent(user)); } } @Override public void onFailure(ResponseError error) { UserUi ui = findUi(callingId); if (ui instanceof UserProfileUi) { ui.onResponseError(error); } } }); } /** * 获取收藏的所有商家 * @param callingId * @param page * @param size */ private void doFetchFavorites(final int callingId, final int page, int size) { mRestApiClient.accountService() .favorites(page, size) .map(new Func1<ResultsPage<Favorite>, List<Favorite>>() { @Override public List<Favorite> call(ResultsPage<Favorite> results) { return results.results; } }) .subscribeOn(Schedulers.io()) .doOnSubscribe(new Action0() { @Override public void call() { UserUi ui = findUi(callingId); if (ui instanceof UserFavoriteListUi) { ((UserFavoriteListUi) ui).onStartRequest(page); } } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new RequestCallback<List<Favorite>>() { @Override public void onResponse(List<Favorite> favorites) { UserUi ui = findUi(callingId); if (ui instanceof UserFavoriteListUi) { boolean haveNextPage = favorites != null && favorites.size() == PAGE_SIZE; ((UserFavoriteListUi) ui).onFinishRequest(favorites, page, haveNextPage); } } @Override public void onFailure(ResponseError error) { UserUi ui = findUi(callingId); if (ui instanceof UserFavoriteListUi) { ui.onResponseError(error); } } }); } /** * 创建留给UI界面使用的回调 * @param ui * @return */ @Override protected UserUiCallbacks createUiCallbacks(final UserUi ui) { return new UserUiCallbacks() { @Override public void refresh() { if (ui instanceof UserFavoriteListUi) { mPageIndex = 1; doFetchFavorites(getId(ui), mPageIndex, PAGE_SIZE); } } @Override public void nextPage() { if (ui instanceof UserFavoriteListUi) { ++mPageIndex; doFetchFavorites(getId(ui), mPageIndex, PAGE_SIZE); } } @Override public void showRegister() { Display display = getDisplay(); if (display != null) { display.showRegister(); } } @Override public void showLogin() { Display display = getDisplay(); if (display != null) { display.showLogin(); } } @Override public void showUserProfile() { Display display = getDisplay(); if (display != null) { display.showUserProfile(); } } @Override public void showAddressList() { Display display = getDisplay(); if (display != null) { if (AppCookie.isLoggin()) { display.showAddresses(); } else { display.showLogin(); } } } @Override public void showFavoriteList() { Display display = getDisplay(); if (display != null) { if (AppCookie.isLoggin()) { display.showFavorites(); } else { display.showLogin(); } } } @Override public void showSetting() { Display display = getDisplay(); if (display != null) { display.showSetting(); } } @Override public void showFeedback() { Display display = getDisplay(); if (display != null) { display.showFeedback(); } } @Override public void showBusiness(Business business) { Preconditions.checkNotNull(business, "business cannot be null"); Display display = getDisplay(); if (display != null) { display.showBusiness(business); } } @Override public void checkUpdate() { } @Override public void sendCode(String mobile) { doSendCode(getId(ui), mobile); } @Override public void checkCode(String mobile, String code) { doCheckCode(getId(ui), mobile, code); } @Override public void createUser(String mobile, String password) { doCreateUser(getId(ui), mobile, password); } @Override public void uploadAvatar(File file) { doUploadAvatar(getId(ui), file); } @Override public boolean validateUsername(String username) { return false; } @Override public void setUsername(String username) { doSetUsername(getId(ui), username); } @Override public void setNickname(String nickname) { doSetNickname(getId(ui), nickname); } @Override public void login(String account, String password) { doLogin(getId(ui), account, password); } @Override public void logout() { doLogout(getId(ui)); } }; } public interface UserUiCallbacks { void refresh(); void nextPage(); void showLogin(); void showUserProfile(); void showRegister(); void showAddressList(); void showFavoriteList(); void showSetting(); void showFeedback(); void showBusiness(Business business); void checkUpdate(); void sendCode(String mobile); void checkCode(String mobile, String code); void createUser(String mobile, String password); void uploadAvatar(File file); boolean validateUsername(String username); void setUsername(String username); void setNickname(String nickname); void login(String account, String password); void logout(); } public interface UserUi extends BaseController.Ui<UserUiCallbacks> { } public interface UserRegisterUi extends UserUi {} public interface RegisterFirstStepUi extends UserRegisterUi { void sendCodeFinish(); } public interface RegisterSecondStepUi extends RegisterFirstStepUi { void verifyMobileFinish(); } public interface RegisterThirdStepUi extends UserRegisterUi { void userCreateFinish(); } public interface UserLoginUi extends UserUi { void userLoginFinish(); } public interface UserCenterUi extends UserUi { void showUserInfo(User user); } public interface UserProfileUi extends UserUi { void showUserInfo(User user); void uploadAvatarFinish(); } public interface UserNameUi extends UserUi { void onSetUsernameFinish(); } public interface UserNicknameUi extends UserUi { void onSetNicknameFinish(); } public interface UserFavoriteListUi extends UserUi, BaseController.ListUi<Favorite, UserUiCallbacks> {} public interface SettingUi extends UserUi { void logoutFinish(); } }