修改名称。

This commit is contained in:
2025-11-07 09:22:39 +08:00
parent d9cf55b053
commit a8dcfbb6a7
2203 changed files with 3 additions and 4 deletions

View File

@@ -0,0 +1,24 @@
package com.xscm.moduleutil.http;
public class APIException extends RuntimeException {
private int code;
public APIException(String message) {
super(message);
}
public APIException(int code, String message) {
super(message);
this.code = code;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}

View File

@@ -0,0 +1,96 @@
package com.xscm.moduleutil.http;
import android.util.Log;
import com.xscm.moduleutil.base.CommonAppContext;
import com.xscm.moduleutil.bean.UserBean;
import com.xscm.moduleutil.utils.Sha1Util;
import com.xscm.moduleutil.utils.SpUtil;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class AccessTokenInterceptor implements Interceptor {
private final static String TAG = AccessTokenInterceptor.class.getCanonicalName();
private static final Map<String, String> mHeaderMap = new ConcurrentHashMap<>();
public static String token = "";
public AccessTokenInterceptor(Map<String, String> headers) {
mHeaderMap.putAll(headers);
}
public Map<String, String> getHeaders() {
return mHeaderMap;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// 确保所有 put 到 mHeaderMap 的值都不为 null
String xToken = getTokenSafely();
mHeaderMap.put("X-Token", xToken != null ? xToken : "");
String token = getTokenSafely();
mHeaderMap.put("token", token != null ? token : "");
Log.e(TAG, "intercept: "+token);
long timestamp = System.currentTimeMillis() / 1000;
mHeaderMap.put("timestamp", String.valueOf(timestamp));
mHeaderMap.put("sign", Sha1Util.shaEncode(timestamp));
Request newRequest = request.newBuilder()
.headers(Headers.of(mHeaderMap))
.build();
return chain.proceed(newRequest);
}
private String getTokenSafely() {
try {
String token = SpUtil.getToken();
if (isNotEmpty(token)) {
return token;
}
CommonAppContext appContext = CommonAppContext.getInstance();
if (appContext != null) {
token = appContext.getToken();
if (isNotEmpty(token)) {
return token;
}
}
UserBean userBean = SpUtil.getUserBean();
if (userBean != null) {
token = userBean.getToken();
if (isNotEmpty(token)) {
return token;
}
}
} catch (Exception e) {
// 添加异常处理,避免因获取 token 异常导致整个应用崩溃
return "";
}
return "";
}
private boolean isNotEmpty(String str) {
return str != null && !str.equals("");
}
}

View File

@@ -0,0 +1,134 @@
package com.xscm.moduleutil.http;
import android.content.Context;
import android.widget.Toast;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.xscm.moduleutil.base.CommonAppContext;
import org.greenrobot.eventbus.EventBus;
import java.io.IOException;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* 通用的API响应处理回调类
* 统一处理所有接口的响应和错误情况
*/
public abstract class ApiResponseCallback<T> implements Callback<BaseModel<T>> {
private Context mContext;
// 构造方法,传入上下文用于显示提示
public ApiResponseCallback(Context context) {
this.mContext = context;
}
@Override
public void onResponse(Call<BaseModel<T>> call, Response<BaseModel<T>> response) {
// 统一处理HTTP响应
if (response.isSuccessful()) {
// 处理200-299范围内的HTTP状态码
BaseModel<T> body = response.body();
if (body != null) {
// 根据code值进行不同处理
switch (body.getCode()) {
case 1: // 接口返回成功
// 业务成功,回调给具体实现
// 即使data为null也调用onSuccess由具体实现决定如何处理null值
onSuccess(body.getData());
break;
case 0: // 接口请求成功但数据错误
// 显示错误信息
// String errorMsg = body.getMsg() != null ? body.getMsg() : "操作失败,请重试";
// showToast(errorMsg);
onFailure(new Exception(body.getMsg()));
break;
case 301: // 登录失效
// 显示错误信息并退出应用
// String loginErrorMsg = body.getMsg() != null ? body.getMsg() : "登录已失效,请重新登录";
showToast(body.getMsg());
try {
// 发送退出登录事件
// EventBus.getDefault().post(new com.xscm.moduleutil.event.LogOutEvent());
// 清除登录信息
CommonAppContext.getInstance().clearLoginInfo();
// 跳转到登录页面
// android.content.Intent intent = new android.content.Intent(CommonAppContext.getInstance(), Class.forName("com.xscm.midi.LaunchPageActivity"));
// intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK | android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK);
// CommonAppContext.getInstance().startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
onFailure(new Exception(body.getMsg()));
break;
default:
// 其他错误情况
String defaultErrorMsg = body.getMsg() != null ? body.getMsg() : "未知错误";
showToast(defaultErrorMsg);
onFailure(new Exception(defaultErrorMsg));
break;
}
} else {
// 响应体为空的情况
String errorMsg = "获取数据失败,请重试";
showToast(errorMsg);
onFailure(new Exception(errorMsg));
}
} else {
// 处理HTTP错误状态码
String errorInfo;
try {
if (response.errorBody() != null) {
errorInfo = response.errorBody().string();
// 可以在这里统一解析错误响应体
} else {
errorInfo = "请求失败,状态码:" + response.code();
}
} catch (IOException e) {
errorInfo = "请求失败,状态码:" + response.code();
e.printStackTrace();
}
showToast("");
onFailure(new Exception(errorInfo));
}
}
@Override
public void onFailure(Call<BaseModel<T>> call, Throwable t) {
// 统一处理网络异常
String errorMsg;
if (t instanceof IOException) {
// errorMsg = "网络异常,请检查网络连接";
} else {
// errorMsg = "请求处理失败,请重试";
}
showToast("");
// 回调给具体实现处理
onFailure(t);
}
// 显示提示信息
private void showToast(String message) {
if (mContext != null) {
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
}
// 业务成功时的回调,由具体接口实现
public abstract void onSuccess(T data);
// 错误时的回调,可选实现
public void onFailure(Throwable t) {
// 可以留空,由子类选择性实现
LogUtils.e("接口错误:",t);
}
}

View File

@@ -0,0 +1,788 @@
package com.xscm.moduleutil.http;
import com.xscm.moduleutil.bean.*;
import com.xscm.moduleutil.bean.blindboxwheel.BlindBoxBean;
import com.xscm.moduleutil.bean.blindboxwheel.BlindReslutBean;
import com.xscm.moduleutil.bean.blindboxwheel.XlhDrawBean;
import com.xscm.moduleutil.bean.room.*;
import com.xscm.moduleutil.bean.zhuangb.ZhuangBanShangChengBean;
import com.xscm.moduleutil.utils.cos.TempKeyBean;
import com.xscm.moduleutil.widget.Constants;
import java.util.List;
import io.reactivex.Observable;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
public interface ApiServer {
@FormUrlEncoded //请求验证码
@POST(Constants.SEND_CODE)
Observable<BaseModel<Object>> sendCode(@Field("mobile") String mobile, @Field("event") String event);
@FormUrlEncoded
@POST(Constants.LOGIN)
Call<BaseModel<List<UserBean>>> login(@Field("user_login") String user_login, @Field("sms_code") String sms_code);
@FormUrlEncoded
@POST(Constants.ROOM_HOUR_BEAN)
Call<BaseModel<RoomHourBean>> getRoomHourRanking(@Field("page") String page,@Field("page_limit")String page_limit);
@FormUrlEncoded //手机换绑
@POST(Constants.MODIFY_MOBILE)
Call<BaseModel<String>> mobileView(@Field("mobile") String mobile, @Field("new_mobile") String new_mobile, @Field("sms_code") String sms_code);
@GET(Constants.GET_EMOTION)
Call<BaseModel<List<Emotion>>> upEmotion();
@GET(Constants.GET_EMOTION_DEATILS)
Call<BaseModel<List<EmotionDeatils>>> getEmotionDeatils(@Query("type_id") String type_id,@Query("pid") String pid);
@FormUrlEncoded //手机绑定
@POST(Constants.BIND_MOBILE)
Call<BaseModel<String>> mobileView2(@Field("new_mobile") String new_mobile, @Field("sms_code") String sms_code);
@FormUrlEncoded
@POST(Constants.USER_ROOM_BACK)
Call<ResponseBody> userRoomBack(@Field("room_id")String room_id,@Field("type")String type);
@FormUrlEncoded
@POST(Constants.USER_LOGIN)
Call<BaseModel<List<UserBean>>> userLogin(@Field("user_login") String user_login, @Field("password") String password);
@FormUrlEncoded
@POST(Constants.EARNINGS_NUM)
Call<BaseModel<String>> exchangeCoin(@Field("earnings_num") String earnings_num);
@GET(Constants.DELETE_ROOM_HISTORY)
Call<BaseModel<String>> delfoot();
@GET(Constants.GET_FIRST_CHARGE)
Call<BaseModel<FirstChargeBean>> firstCharge(@Query("uid") String user_id);
@POST(Constants.UPLOAD_NICK_NAME)
Call<ResponseBody> upUserNickname();
@GET(Constants.GET_APP_UPDATE)
Observable<BaseModel<AppUpdateModel>> appUpdate();
@FormUrlEncoded
@POST(Constants.dailyTasksOpenBox)
Observable<BaseModel<GiftName>> dailyTasksOpenBox(@Field("gift_box_id") String gift_box_id);
@FormUrlEncoded
@POST(Constants.dailyTasksReceive)
Call<ResponseBody> dailyTasksReceive(@Field("task_id") String task_id);
@FormUrlEncoded
@POST(Constants.dailyTasksComplete)
Call<ResponseBody> dailyTasksComplete(@Field("task_id") String task_id);
@FormUrlEncoded
@POST(Constants.SEND_HEADLINE)
Call<BaseModel<String>> sendHeadine(@Field("content") String content, @Field("money") String money, @Field("room_id") String roomId);
@FormUrlEncoded
@POST(Constants.POST_WITHDRAWAL)
Call<ResponseBody> withdrawal(@Field("number") String number, @Field("type") String type, @Field("sms_code") String sms_code);
@FormUrlEncoded
@POST(Constants.POST_USER_WALL)
Observable<BaseModel<GiftUserWallBean>> giftWall(@Field("user_id") String userId);
@GET(Constants.CURRENT_HEADLINE)
Observable<BaseModel<HeadlineBean>> currentHeadline();
@GET(Constants.GET_TASKS_LIHEN)
Call<ResponseBody> tasksLihen();
@FormUrlEncoded
@POST(Constants.POST_LOG_LIST)
Call<BaseModel<List<RevenueBean>>> getRevenueData(@Field("page") String page, @Field("page_limit") String page_limit, @Field("in_out_type") String in_out_type, @Field("start_time") String start_time, @Field("end_time") String end_time, @Field("gift_type") String gift_type);
@FormUrlEncoded
@POST(Constants.POST_WEALTH_RANKING)
Observable<BaseModel<PlaceholderBean>> wealthRanking(@Field("ranking_type") String ranking_type, @Field("type") String type);
@GET(Constants.GUILD_RANKING)
Observable<BaseModel<PlaceholderBean>> guildRanking();
@GET(Constants.GET_WITHDRAWAL_LIST)
Call<BaseModel<List<WithdrawalBean>>> withdrawalList(@Query("page") String page, @Query("page_limit") String page_limit, @Query("search_stime") String search_stime, @Query("search_etime") String search_etime);
@FormUrlEncoded
@POST(Constants.POST_BIND_DETAIL)
Call<BaseModel<BindDetail>> bindDetai(@Field("user_id") String user_id, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_MESSAGE_LIST)
Call<BaseModel<List<NewsMessageList>>> getMessagetitle(@Field("type") String type, @Field("page") String page, @Field("page_limit") String page_limit);
@GET(Constants.GET_TEMP_KEY)
Call<BaseModel<TempKeyBean>> getTempKey();
@FormUrlEncoded
@POST(Constants.POST_ROOM_RANK)
Call<BaseModel<List<CharmRankingResp>>> getRoomRank(@Field("room_id") String room_id, @Field("type") String type, @Field("time_type") String time_type, @Field("page") String page, @Field("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.POST_ROOM_RANKING)
Observable<BaseModel<PlaceholderBean>> roomRanking(@Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_LOVE_RANKING)
Observable<BaseModel<PlaceholderBean>> loveRanking(@Field("type") String type);
@GET(Constants.GET_REAL_NAME)
Call<BaseModel<RealNameBean>> realNameInfo();
@GET(Constants.GET_DAILY_TASK_BOX)
Call<BaseModel<List<GiftBoxRecordBean>>> dailyTasksBoxRecord();
@GET(Constants.GET_MY_BAG_DATA)
Call<BaseModel<List<MyBagDataBean>>> packIncome(@Query("page") String page, @Query("page_limit") String page_size);
@GET(Constants.GET_MY_BAG_OUTCOME)
Call<BaseModel<List<MyBagDataBean>>> packOutcome(@Query("page") String page, @Query("page_limit") String page_size);
@GET(Constants.GET_GIFT_PACK)
Call<BaseModel<List<GiftPackBean>>> giftPack();
@FormUrlEncoded
@POST(Constants.ADD_BLACK_LIST)
Call<ResponseBody> addBlackList(@Field("user_id") String user_id);
@FormUrlEncoded
@POST(Constants.POST_SEND_PK)
Call<ResponseBody> sendPk(@Field("room_id_a") String room_id_a, @Field("create_user_id") String create_user_id, @Field("room_id_b") String room_id_b);
@FormUrlEncoded
@POST(Constants.POST_REFUSE_PK)
Call<ResponseBody> refusePk(@Field("is_pk") String is_pk, @Field("room_id") String room_id);
@FormUrlEncoded
@POST(Constants.POST_END_PK)
Call<ResponseBody> endPk(@Field("pk_id") String is_pk, @Field("type") String type, @Field("user_id") String user_id);
@GET(Constants.GET_RECHARGE)
Call<BaseModel<List<RechargeBean>>> recharge();
@FormUrlEncoded
@POST(Constants.POST_START_PK)
Call<ResponseBody> startPk(@Field("pk_id") String pk_id, @Field("pk_times") String pk_times);
@FormUrlEncoded
@POST(Constants.UPLOAD_USER_PIC)
Call<ResponseBody> upUserPic(@Field("sex") String sex);
@FormUrlEncoded
@POST(Constants.SWITCH_ACCOUNTS)
Call<BaseModel<List<UserBean>>> switchAccounts(@Field("user_login") String user_id);
@FormUrlEncoded
@POST(Constants.FORGOT_PASSWORD)
Call<BaseModel<String>> forgotPassword(@Field("new_password") String new_password, @Field("mobile") String mobile, @Field("sms_code") String sms_code);
@FormUrlEncoded
@POST(Constants.USER_UPDATE)
Call<BaseModel<UserBean>> userUpdate(@Field("nickname") String nickname, @Field("birthday") String birthday, @Field("sex") String sex, @Field("avatar") String avatar, @Field("init_code") String init_code, @Field("user_id") String user_id);
@GET(Constants.AUTHORIZATION)
Call<ResponseBody> authorization();
@FormUrlEncoded
@POST(Constants.CHANGE_PASSWORD)
Call<BaseModel<String>> getPostData(@Field("new_password") String new_password, @Field("mobile") String mobile, @Field("sms_code") String code, @Field("user_id") String userId);
@FormUrlEncoded
@POST(Constants.REAL_NAME_RESULT)
Call<BaseModel<String>> getRealNameResult(@Field("orderNo") String order_no);
@FormUrlEncoded
@POST(Constants.URL_LOGIN)
Call<BaseModel<List<UserBean>>> oauthLogin(@Field("login_token") String login_token);
@GET(Constants.GET_THEME_DATA)
Call<BaseModel<ThemeBean>> getThemeData();
@FormUrlEncoded
@POST(Constants.URL_AUTH_CODE)
Observable<BaseModel<List<UserBean>>> authCode(@Field("auth_code") String login_token);
@FormUrlEncoded
@POST(Constants.URL_WX_CODE)
Observable<BaseModel<List<UserBean>>> authCode1(@Field("code") String login_token);
@FormUrlEncoded
@POST(Constants.REAL_NAME)
Call<BaseModel<RealNameBean>> realName(@Field("real_name") String real_name, @Field("card_number") String card_number);
@FormUrlEncoded
@POST(Constants.GET_EXPAND_COLUMN)
Call<BaseModel<List<ExpandColumnBean>>> getExpandColumn(@Field("type") String type, @Field("page") String page, @Field("page_limit") String page_limit);
@GET(Constants.GET_OFFICIAL_NOTICE)
Call<BaseModel<NewsDataBean>> getOfficialNotice();
@FormUrlEncoded
@POST(Constants.GET_ALBUM_LIST)
Call<BaseModel<List<AlbumBean>>> getAlbumList(@Field("page") String page, @Field("page_limit") String page_limit, @Field("user_id") String user_id);
@FormUrlEncoded
@POST(Constants.CREATE_ALBUM)
Call<BaseModel<String>> createAlbum(@Field("name") String name, @Field("pwd") String pwd, @Field("image") String image);
@FormUrlEncoded
@POST(Constants.EDIT_ALBUM)
Call<BaseModel<String>> editAlbum(@Field("album_id") String album_id, @Field("name") String name, @Field("pwd") String pwd, @Field("image") String image);
@GET(Constants.GET_SJ_ROOM_NAME)
Call<ResponseBody> sjRoomName();
@FormUrlEncoded
@POST(Constants.POST_FOLLOW_LIST)
Call<BaseModel<List<BlackUserBean>>> getUserFollowList(@Field("page") String page, @Field("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.POST_FANS_LIST)
Call<BaseModel<List<BlackUserBean>>> getUserFansList(@Field("page") String page, @Field("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.POST_BLACK_LIST)
Call<BaseModel<List<BlackUserBean>>> getBlacklist(@Field("page") String page, @Field("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.POST_LOCK_MI_LIST)
Call<BaseModel<List<BlackUserBean>>> getLockMiniList(@Field("page") String page, @Field("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.GET_MY_ROOM)
Call<BaseModel<List<MyRoomBean>>> getMyRoom(@Field("type") String type, @Field("page") String page, @Field("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.POST_MY_ROOM_BEAN)
Call<BaseModel<List<BannerModel>>> getBanners(@Field("type") String type);
@FormUrlEncoded
@POST(Constants.GET_TOP_ROOM)
Call<BaseModel<List<TopRoom>>> getTopRooms(@Field("page") String page, @Field("page_limit") String page_limit, @Field("is_top") String is_top, @Field("label_id") String label_id);
@GET(Constants.GET_ROOM_TYPE)
Call<BaseModel<List<RoomTypeModel>>> getRoomCategories();
@FormUrlEncoded
@POST(Constants.CHECK_TXT)
Call<ResponseBody> checkTxt(@Field("room_name") String room_name, @Field("room_cover") String room_cover, @Field("room_intro") String room_intro);
@FormUrlEncoded
@POST(Constants.GET_REWARD_LIST)
Call<BaseModel<List<RewardUserBean>>> getRewardList(@Field("id") String id, @Field("page") String page, @Field("page_limit") String page_limit);
@GET(Constants.GET_GIFT_LABEL)
Call<BaseModel<List<GiftLabelBean>>> getGiftLabel(@Query("have_hot") String have_hot);
@GET(Constants.GIFT_LIST)
//获取礼物列表
Call<BaseModel<List<RoonGiftModel>>> getGiftList(@Query("label") int label,@Query("room_id")String room_id);
@GET(Constants.TOPIC_LIST)
//获取话题
Call<BaseModel<List<HeatedBean>>> topicList(@Query("page") String page, @Query("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.PUBLISH_ZONE)
Call<BaseModel<String>> publishZone(@Field("images") String images, @Field("content") String content, @Field("topic_id") String topic_id, @Field("room_id") String room_id, @Field("ip") String ip);
@GET(Constants.GET_CATEGORIES)
Call<BaseModel<List<HeatedBean>>> getCategories();
@GET(Constants.GET_CIRCLE_LIST)
Call<BaseModel<List<CircleListBean>>> getCircleList(@Query("page") String page, @Query("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.GET_USER_HOME_ZONE)
Call<BaseModel<List<CircleListBean>>> getCircleUserList(@Field("user_id") String user_id, @Field("page") String page, @Field("page_limit") String page_limit);
@GET(Constants.GET_MY_FOOT)
Call<BaseModel<List<MyFootResp>>> getMyFoot(@Query("page") String page, @Query("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.LIKE_ZONE)
Call<BaseModel<String>> likeZone(@Field("id") String zone_id);
@FormUrlEncoded
@POST(Constants.TOPIC_ID)
Call<BaseModel<List<CircleListBean>>> topicId(@Field("topic_id") String topic_id);
@FormUrlEncoded
@POST(Constants.ZONE_DETAIL)
Call<BaseModel<CircleListBean>> zoneDetail(@Field("id") String topic_id);
@FormUrlEncoded
@POST(Constants.GET_USER_HOME)
Call<BaseModel<UserInfo>> getUserHome(@Field("user_id") String user_id);
@FormUrlEncoded
@POST(Constants.DELETE_COMMENT)
Call<BaseModel<String>> deleteComment(@Field("id") String zone_id);
@FormUrlEncoded
@POST(Constants.GET_COMMENT_LIST)
Call<BaseModel<CommentBean>> getCommentList(@Field("id") String id, @Field("page") String page, @Field("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.POST_SONG)
Call<BaseModel<List<SongMusicBean>>> song(@Field("room_id") String roomId, @Field("user_id") String userId, @Field("song_code") String songCode, @Field("song_name") String songName, @Field("singer") String singer, @Field("poster") String poster, @Field("duration") String duration);
@FormUrlEncoded
@POST(Constants.COMMENT_ZONE)
Call<BaseModel<String>> commentZone(@Field("id") String id, @Field("content") String content, @Field("pid") String pid, @Field("reply_to") String reply_to);
@GET(Constants.GET_MY_CP_ROOM_LIST)
Call<BaseModel<List<MyCpRoom>>> myCpRoom();
@FormUrlEncoded
@POST(Constants.CLEAR_LOGIN_INFO)
Call<BaseModel<String>> clearLoginInfo(@Field("token") String token);
@FormUrlEncoded
@POST(Constants.CANCEL)
Call<BaseModel<String>> cancel(@Field("token") String token);
@FormUrlEncoded
@POST(Constants.DELETE_ZONE)
Call<BaseModel<String>> deleteZone(@Field("id") String id);
@GET(Constants.GET_MY_INFO)
Call<BaseModel<UserInfo>> getMyInfo();
@FormUrlEncoded
@POST(Constants.ED_USER_INFO)
Call<BaseModel<String>> editUserInfo(@Field("nickname") String nickname, @Field("birthday") String birthday, @Field("sex") String sex, @Field("avatar") String avatar, @Field("images") String images, @Field("profile") String profile, @Field("tag_id") String tag_id);
@FormUrlEncoded
@POST(Constants.ED_USER_BG)
Call<BaseModel<String>> editUserBg(@Field("images") String images);
@GET(Constants.GET_USER_TAG_LIST)
Call<BaseModel<List<UserTagBean>>> getUserTagList();
@FormUrlEncoded
@POST(Constants.GET_LIKE_LIST)
Call<BaseModel<List<CircleListBean.LikeList>>> getLikeList(@Field("id") String id);
@FormUrlEncoded
@POST(Constants.GET_ALBUM_DETAIL)
Call<BaseModel<AlbumBean>> getAlbumDetail(@Field("album_id") String albumId, @Field("pwd") String pwd, @Field("page") String page, @Field("page_limit") String page_limit);
@GET(Constants.GET_PERSONALTY)
Call<BaseModel<List<PersonaltyBean>>> getPersonaltyList();
@FormUrlEncoded
@POST(Constants.GET_SUBSIDY)
Call<BaseModel<RoomSubsidy>> getSubsidy(@Field("room_id") String roomId);
@GET(Constants.GET_DECORATE)
Call<BaseModel<List<ZhuangBanShangChengBean>>> getDecorateList(@Query("type") String type);
@FormUrlEncoded
@POST(Constants.POST_GZ)
Call<BaseModel<String>> userGuanz(@Field("user_id") String userId, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_FOLLOW_ROOM)
Call<BaseModel<String>> followRoom(@Field("room_id") String roomId, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.ACCEPT_PK)
Call<BaseModel<String>> acceptPk(@Field("pk_id") String pk_id, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_CLEAR_USER_CHARM)
Call<BaseModel<String>> clearUserCharm(@Field("room_id") String roomId, @Field("user_id") String userId);
@FormUrlEncoded
@POST(Constants.REMOVE_BLACK_LIST)
Call<BaseModel<String>> removeBlackList(@Field("uid") String userId);
@FormUrlEncoded
@POST(Constants.POST_USER_OLINE_STATUS)
Call<BaseModel<List<UserOnlineStatusBean>>> userOnlineStatus(@Field("user_id") String userId, @Field("room_id") String roomId);
@FormUrlEncoded
@POST(Constants.postRoomSwToken)
Call<BaseModel<PkSwTokenBean>> postRoomSwToken(@Field("room_id") String roomId);
@FormUrlEncoded
@POST(Constants.SET_USER_DECORATE)
Call<BaseModel<String>> setUserDecorate(@Field("udid") String udid);
@FormUrlEncoded
@POST(Constants.POST_CANCEL_USER_DECORATE)
Call<BaseModel<String>> cancelUserDecorate(@Field("type") String type);
@FormUrlEncoded
@POST(Constants.UP_ALBUM)
Call<BaseModel<String>> upAddAlbum(@Field("album_id") String album_id, @Field("images") String images, @Field("content") String content);
@FormUrlEncoded
@POST(Constants.MOVE_ALBUM)
Call<BaseModel<String>> moveAlbum(@Field("id") String id, @Field("new_album_id") String new_album_id);
@FormUrlEncoded
@POST(Constants.JOIN_ROOM)
Call<BaseModel<RoomInfoResp>> roomGetIn(@Field("room_id") String roomId, @Field("password") String password);
@FormUrlEncoded
@POST(Constants.DELETE_ALBUM_IMAGE)
Call<BaseModel<String>> deleteAlbumImage(@Field("id") String id);
@FormUrlEncoded
@POST(Constants.DELETE_ALBUM)
Call<BaseModel<String>> deleteAlbum(@Field("album_id") String id);
@FormUrlEncoded
@POST(Constants.LIKE_ALBUM)
Call<BaseModel<String>> likeAlbum(@Field("album_id") String id);
@FormUrlEncoded
@POST(Constants.ADDRESS_IP)
Call<BaseModel<String>> address_ip(@Field("address_ip") String address_ip);
@FormUrlEncoded
@POST(Constants.UPDATEPASSWORD)
Call<BaseModel<String>> updatePassword(@Field("room_id") String roomId, @Field("password") String password);
@FormUrlEncoded
@POST(Constants.GET_ROOM_ONLINE)
Call<BaseModel<RoomOnline>> getRoomOnline(@Field("room_id") String roomId, @Field("page") String page, @Field("page_limit") String page_limit);
@FormUrlEncoded
@POST(Constants.GET_GIVE_GIFT)
Call<BaseModel<String>> giveGift(@Field("user_id") String user_id, @Field("gid") String gid, @Field("num") String num, @Field("to_uid") String to_uid, @Field("gift_type") String gift_type);
@FormUrlEncoded
@POST(Constants.GET_ROOM_GIFT)
Call<BaseModel<String>> roomGift(@Field("room_id") String room_id, @Field("gift_id") String gift_id, @Field("gift_num") String num, @Field("to_uid") String to_uid, @Field("type") String gift_type, @Field("pit_number") String pit_number, @Field("heart_id") String heat_id);
@GET(Constants.GET_FIRST_CHARGE_GIFT)
Call<BaseModel<FirstChargeGiftBean>> firstChargeGift();
@GET(Constants.GET_NEW_CHARGE_GIFT)
Call<BaseModel<FirstChargeGiftBean>> getNewChargeGift();
@GET(Constants.GET_ACTIVITIES_PERMISSION)
Call<BaseModel<ActivitiesPermission>> activitiesPermission();
@GET(Constants.GET_DAY_DROP_GIFT)
Call<BaseModel<HeavenGiftBean>> getDayDropGift();
@GET(Constants.GET_WALLET)
Call<BaseModel<WalletBean>> wallet();
@FormUrlEncoded
@POST(Constants.REDPACKET_CREATE)
Call<ResponseBody> redPacketCreate(@Field("type") int type, @Field("password") String password, @Field("coin_type") int coin_type, @Field("total_amount") String total_amount,
@Field("total_count")String total_count, @Field("conditions") String conditions, @Field("countdown") String countdown, @Field("room_id") String room_id,
@Field("remark") String remark);
@GET(Constants.ROOM_REDPACKET)
Call<BaseModel<List<RedPacketInfo>>> roomRedPackets(@Query("room_id") String roomId);
@GET(Constants.GET_REDPACKET_DETAIL)
Call<BaseModel<RedpacketDetail>> redPacketDetail(@Query("redpacket_id") String redpacket_id);
@FormUrlEncoded
@POST(Constants.POST_GRAB)
Call<BaseModel<RedPackGrab>> grab(@Field("redpacket_id") String redpacket_id);
@FormUrlEncoded
@POST(Constants.POST_APPLY_Pay)
Call<BaseModel<AppPay>> appPay
(@Field("user_id") String user_id,
@Field("money") String money,
@Field("coin") String coin,
@Field("type") String type,
@Field("type_params") String type_params,
@Field("type_id") String type_id
);
@FormUrlEncoded
@POST(Constants.POST_APPLY_LIST)
Call<BaseModel<RoomApplyListBean>> roomApplyListBean(@Field("room_id") String room_id);
@FormUrlEncoded
@POST(Constants.GET_ROOM_USER)
Call<BaseModel<UserInfo>> getRoomUserInfo(@Field("room_id") String roomId, @Field("user_id") String userId);
@FormUrlEncoded
@POST(Constants.POST_BIND_TYPE)
Call<BaseModel<BindType>> bindType(@Field("user_id") String userId);
@GET(Constants.GET_WALLET_CONFIG)
Call<BaseModel<WalletConfig>> getWalletConfig();
@FormUrlEncoded
@POST(Constants.POST_BIND)
Call<BaseModel<String>> bind(@Field("user_id") String userId, @Field("type") String type, @Field("alipay_account") String alipay_account, @Field("bank_card_number") String bank_card_number, @Field("bank_card") String bank_card, @Field("open_bank") String open_bank);
@FormUrlEncoded
@POST(Constants.POST_SONG_LIST)
Call<BaseModel<List<MusicSongBean>>> songList(@Field("room_id") String room_id);
@FormUrlEncoded
@POST(Constants.APPLY_PIT)
Call<BaseModel<String>> applyPit(@Field("room_id") String room_id, @Field("pit_number") String pit_number);
@FormUrlEncoded
@POST(Constants.START_FRIEND)
Call<BaseModel<String>> startFriend(@Field("room_id") String room_id);
@FormUrlEncoded
@POST(Constants.END_FRIEND)
Call<BaseModel<FriendUserBean>> endFriend(@Field("friend_id") String friend_id, @Field("room_id") String room_id);
@FormUrlEncoded
@POST(Constants.CREATE_RELATION)
Call<BaseModel<String>> createRelation(@Field("room_id") String room_id, @Field("friend_id") String friend_id, @Field("user1_id") String user1_id, @Field("user2_id") String user2_id, @Field("relation_id") String relation_id);
@FormUrlEncoded
@POST(Constants.DELAY)
Call<BaseModel<String>> delay(@Field("friend_id") String friend_id, @Field("room_id") String room_id, @Field("delay_times") String delay_times);
@POST(Constants.POST_KEEP_XINTIAO)
Call<ResponseBody> keepXintiao();
@FormUrlEncoded
@POST(Constants.DOWN_PIT)
Call<BaseModel<String>> downPit(@Field("room_id") String room_id, @Field("pit_number") String pit_number);
@FormUrlEncoded
@POST(Constants.REWARD_ZONE)
Call<BaseModel<String>> reward_zone(@Field("id") String id, @Field("gift_id") String gift_id, @Field("num") String num, @Field("is_pack") String is_pack);
@FormUrlEncoded
@POST(Constants.POST_UP_SONG)
Call<BaseModel<String>> upSong(@Field("did") String did, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_CHANGE_ROOM)
Call<BaseModel<String>> changeRoom(@Field("room_id") String room_id, @Field("user_id") String userId);
@FormUrlEncoded
@POST(Constants.POST_CHANGE_ROOM_TYPE)
Call<BaseModel<String>> changeRoomType(@Field("room_id") String room_id, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.SET_ROOM_APPLY)
Call<BaseModel<String>> setRoomApply(@Field("room_id") String room_id, @Field("gift_id") String gift_id, @Field("gift_price") String gift_price);
@FormUrlEncoded
@POST(Constants.CLEAR_APPLY)
Call<BaseModel<String>> clearApply(@Field("room_id") String room_id);
@FormUrlEncoded
@POST(Constants.AGREE_PIT)
Call<BaseModel<String>> agreePit(@Field("room_id") String roomId, @Field("user_id") String userId);
@FormUrlEncoded
@POST(Constants.REFUSE_PIT)
Call<BaseModel<String>> refusePit(@Field("room_id") String roomId, @Field("user_id") String userId);
@FormUrlEncoded
@POST(Constants.HELP_APPLY)
Call<BaseModel<String>> helpApply(@Field("room_id") String roomId, @Field("user_id") String userId);
@FormUrlEncoded
@POST(Constants.POST_APPLY_SONG)
Call<BaseModel<String>> applySong(@Field("room_id") String roomId);
@FormUrlEncoded
@POST(Constants.POST_AGREE_SONG)
Call<BaseModel<String>> agreeSong(@Field("room_id") String roomId, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_END_SONG)
Call<BaseModel<String>> endSong(@Field("room_id") String roomId);
@FormUrlEncoded
@POST(Constants.POST_ROOM_INFO)
Call<BaseModel<RoomInfoResp>> postRoomInfo(@Field("room_id") String roomId);
@FormUrlEncoded
@POST(Constants.CHANGE_SONG)
Call<BaseModel<String>> changeSong(@Field("room_id") String roomId, @Field("now_did") String now_did);
@FormUrlEncoded
@POST(Constants.POST_HOST_LIST)
Call<BaseModel<List<HostBean>>> getHostList(@Query("room_id") String room_id, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.GET_CHARM_RANK)
Call<BaseModel<List<RoomCharmRankBean>>> getCharmRank(@Field("room_id") String roomId);
@FormUrlEncoded
@POST(Constants.POST_ROOM_RELATION_LIST)
Call<BaseModel<List<RoomRelationBean>>> roomRelationList(@Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_ROOM_AUCTION_LIST)
Call<BaseModel<List<RoomAuction.AuctionListBean>>> roomAuctionList(@Field("auction_id") String auction_id);
@FormUrlEncoded
@POST(Constants.POST_SEARCH)
Call<BaseModel<List<RoomSearchResp>>> getSearch(@Field("search") String room_id, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_SEARCH_ALL)
Call<BaseModel<SearchAll>> getSearchAll(@Field("search") String search);
@FormUrlEncoded
@POST(Constants.SET_PRESIDED_RATIO)
Call<BaseModel<String>> setPresidedRatio(@Field("room_id") String room_id, @Field("user_id") String userId, @Field("ratio") String ration);
@FormUrlEncoded
@POST(Constants.GET_PRESIDED_RATIO)
Call<BaseModel<String>> getPresidedRatio(@Field("room_id") String room_id, @Field("user_id") String userId, @Field("type") String type, @Field("is_add") String is_add);
@FormUrlEncoded
@POST(Constants.POST_ROOM_HOST_PIT)
Call<BaseModel<String>> hostUserPit(@Field("room_id") String room_id, @Field("pit_number") String pit_number, @Field("user_id") String userId, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_GIVE_COIN)
Call<BaseModel<String>> giveCoin(@Field("user_id") String user_id, @Field("coin") String coin);
@FormUrlEncoded
@POST(Constants.POST_SET_MUTE_PIT)
Call<BaseModel<String>> setMutePit(@Field("room_id") String room_id, @Field("user_id") String user_id, @Field("is_mute") String is_mute);
@FormUrlEncoded
@POST(Constants.POST_SET_LOCK_PIT)
Call<BaseModel<String>> setLockPit(@Field("room_id") String room_id, @Field("pit_number") String pit_number, @Field("is_lock") String is_lock);
@GET(Constants.GET_ROOM_BJ)
Call<BaseModel<RoomBgBean>> getBackgroundList();
@FormUrlEncoded
@POST(Constants.POST_CHARM_LIST)
Call<BaseModel<RoomDetails>> getCharmList(@Field("room_id") String room_id, @Field("start_time") String start_time, @Field("end_time") String end_time, @Field("page") String page);
@FormUrlEncoded
@POST(Constants.POST_SET_UPLOAD_BG_IMG)
Call<BaseModel<String>> setUploadBgImg(@Field("id") String id, @Field("image_url") String image_url);
@FormUrlEncoded
@POST(Constants.POST_AUCTION_DELAY)
Call<BaseModel<String>> auctionDelay(@Field("auction_id") String auction_id);
@FormUrlEncoded
@POST(Constants.POST_AUCTION_END)
Call<BaseModel<String>> auctionEnd(@Field("auction_id") String auction_id, @Field("room_id") String room_id);
@FormUrlEncoded
@POST(Constants.POST_AUCTION_MODE)
Call<BaseModel<String>> auctionMode(@Field("room_id") String room_id, @Field("label_id") String label_id);
@FormUrlEncoded
@POST(Constants.POST_EDIT_ROOM)
Call<BaseModel<String>> editRoom(@Field("room_id") String room_id, @Field("room_name") String room_name, @Field("room_cover") String room_cover, @Field("room_intro") String room_intro, @Field("room_background") String room_background);
@FormUrlEncoded
@POST(Constants.POST_KICK_OUT_ROOM)
Call<BaseModel<String>> kickOutRoom(@Field("room_id") String room_id, @Field("user_id") String user_id);
@FormUrlEncoded
@POST(Constants.POST_QUIT_ROOM)
Call<ResponseBody> quitRoom(@Field("room_id") String room_id, @Field("user_id") String user_id);
@FormUrlEncoded
@POST(Constants.POST_RELATION_CARD)
Call<BaseModel<RelationCardBean>> relationCard(@Field("user_id") String user_id);
@FormUrlEncoded
@POST(Constants.POST_TOP_RELATION_CARD)
Call<BaseModel<String>> topRelationCard(@Field("id") String id);
@FormUrlEncoded
@POST(Constants.POST_DELETE_RELATION_CARD)
Call<BaseModel<String>> deleteRelationCard(@Field("id") String id);
@FormUrlEncoded
@POST(Constants.POST_ROOM_AUCTION)
Call<BaseModel<AuctionBean>> roomAuction(@Field("room_id") String room_id, @Field("user_id") String user_id, @Field("gift_id") String gift_id, @Field("relation_id") String relation_id, @Field("auction_type") String auction_type, @Field("time_day") String time_day);
@FormUrlEncoded
@POST(Constants.POST_ROOM_AUCTION_TIME)
Call<BaseModel<RoomTime>> roomAuctionTime(@Field("gift_id") String gift_id);
@FormUrlEncoded
@POST(Constants.POST_ROOM_AUCTION_JOIN)
Call<BaseModel<RoomAuction.AuctionListBean>> roomAuctionJoin(@Field("auction_id") String auction_id, @Field("user_id") String user_id, @Field("gift_id") String gift_id, @Field("num") String num, @Field("type") String type);
@FormUrlEncoded
@POST(Constants.POST_SEARCH_PK_ROOM)
Call<BaseModel<List<RoomBean>>> searchPkRoom(@Field("room_id") String room_id, @Field("page") String page, @Field("limit") String limit);
@GET(Constants.GET_BOX_GIFT_LIST)
Call<BaseModel<BlindBoxBean>> getBoxGiftList(@Query("gift_bag_id") String gift_bag_id, @Query("room_id") String room_id);
@FormUrlEncoded
@POST(Constants.POST_DRAW_GIFT_LIST)
Call<BaseModel<BlindReslutBean>> drawGiftList(@Field("gift_bag_id") String gift_bag_id, @Field("gift_user_ids") String gift_user_ids,@Field("room_id")String room_id,@Field("num")String num,@Field("heart_id") String heart_id,@Field("auction_id") String auction_id);
@GET(Constants.GET_MY_RECORD)
Call<BaseModel<List<GiftBean>>> getMyRecord(@Query("gift_bag_id")String gift_bag_id,@Query("page")String page,@Query("page_size")String page_size);
@GET(Constants.GET_ALL_RECORD)
Call<BaseModel<List<GiftBean>>> getAllRecord(@Query("gift_bag_id")String gift_bag_id,@Query("page")String page,@Query("page_size")String page_size);
@FormUrlEncoded
@POST(Constants.GIFT_SEND)
Call<BaseModel<String>> giftSend(@Field("send_id")String send_id);
@GET(Constants.GET_BOX_GIFT_LIST_XLH)
Call<BaseModel<BlindBoxBean>> getBoxGiftListXLH( @Query("room_id") String room_id);
@FormUrlEncoded
@POST(Constants.POST_DRAW_GIFT_LIST_XLH)
Call<BaseModel<List<XlhDrawBean>>> xlhChou(@Field("room_id") String room_id, @Field("num") String num);
@FormUrlEncoded
@POST(Constants.POST_XLH_ALL_RECORD)
Call<BaseModel<List<GiftBean>>> xlhAllRecord(@Field("room_id") String room_id, @Field("page") String page, @Field("page_size") String page_size);
@FormUrlEncoded
@POST(Constants.Get_XH_RANking)
Call<BaseModel<List<GiftBean>>> xlXH_RANking(@Field("room_id") String room_id, @Field("page") String page, @Field("page_size") String page_size);
@GET(Constants.GET_XLH_MY_RECORD)
Call<BaseModel<List<GiftBean>>> xlhMyRecord(@Query("room_id") String room_id, @Query("page") String page, @Query("page_size") String page_size);
@FormUrlEncoded
@POST(Constants.POST_GIFT_ALL_CLEAR)
Call<BaseModel<String>> getGiftPack(@Field("room_id") String roomId,@Field("to_uid") String user_id,@Field("heart_id") String heart_id,@Field("auction_id") String auction_id);
@FormUrlEncoded
@POST(Constants.POST_ROOM_USER_CHARM_LIST)
Call<BaseModel<List<RoomUserCharmListBean>>> roomUserCharmList(@Field("room_id") String roomId,@Field("user_id") String user_id);
@GET(Constants.GET_GIFT_PACK_LIST_COUNT)
Call<BaseModel<GiftPackListCount>> getGiftPackListCount();
@FormUrlEncoded
@POST(Constants.ROOM_USER_RECONNECT)
Call<BaseModel<String>> roomUserReconnect(@Field("room_id") String room_id);
}

View File

@@ -0,0 +1,77 @@
package com.xscm.moduleutil.http;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.gson.annotations.SerializedName;
public class BaseModel<T> implements Parcelable {
@SerializedName("code")
private int code;
@SerializedName("data")
private T data;
@SerializedName("msg")
private String msg;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public BaseModel() {
}
public boolean isSuccess() {
return code == 1; // 根据实际业务码判断是否成功
}
public boolean isTokenExpired() {
return code == 301; // token过期码
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.code);
dest.writeString(this.msg);
}
protected BaseModel(Parcel in) {
this.code = in.readInt();
this.msg = in.readString();
}
public static final Creator<BaseModel> CREATOR = new Creator<BaseModel>() {
@Override
public BaseModel createFromParcel(Parcel source) {
return new BaseModel(source);
}
@Override
public BaseModel[] newArray(int size) {
return new BaseModel[size];
}
};
}

View File

@@ -0,0 +1,90 @@
package com.xscm.moduleutil.http;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
public class BaseModelTypeAdapter<T> extends TypeAdapter<BaseModel<T>> {
private final Gson gson;
private final TypeAdapter<T> dataAdapter;
public BaseModelTypeAdapter(Gson gson, TypeAdapter<T> dataAdapter) {
this.gson = gson;
this.dataAdapter = dataAdapter;
}
@Override
public void write(JsonWriter out, BaseModel<T> value) throws IOException {
out.beginObject();
out.name("code").value(value.getCode());
out.name("msg").value(value.getMsg());
out.name("data");
if (value.getData() == null) {
out.nullValue();
} else {
dataAdapter.write(out, value.getData());
}
out.endObject();
}
@Override
public BaseModel<T> read(JsonReader reader) throws IOException {
BaseModel<T> model = new BaseModel<>();
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
switch (name) {
case "code":
model.setCode(reader.nextInt());
break;
case "msg":
model.setMsg(reader.nextString());
break;
case "data":
JsonToken token = reader.peek();
Log.d("BaseModelTypeAdapter", "data token: " + token); // 打印 token 类型用于调试
if (token == JsonToken.NULL) {
reader.nextNull();
model.setData(null);
} else if (token == JsonToken.STRING) {
String value = reader.nextString();
if ("null".equals(value)) {
model.setData(null);
} else {
// 如果 data 是字符串类型但不是 "null",可根据业务决定是否抛异常或处理
reader.skipValue();
model.setData(null);
}
} else {
try {
T data = dataAdapter.read(reader);
model.setData(data);
} catch (Exception e) {
// 捕获解析异常,防止崩溃
Log.e("BaseModelTypeAdapter", "解析 data 出错", e);
reader.skipValue();
model.setData(null);
}
}
break;
default:
reader.skipValue();
break;
}
}
reader.endObject();
return model;
}
}

View File

@@ -0,0 +1,53 @@
package com.xscm.moduleutil.http;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class BaseModelTypeAdapterFactory implements TypeAdapterFactory {
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
if (!BaseModel.class.isAssignableFrom(typeToken.getRawType())) {
return null;
}
// 获取实际类型
Type type = typeToken.getType();
// 确保是 ParameterizedType 类型
if (!(type instanceof ParameterizedType)) {
return null; // 或者抛出异常,视业务需求而定
}
// 获取泛型参数类型
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
if (actualTypeArguments.length == 0) {
return null;
}
Type dataType = actualTypeArguments[0];
TypeAdapter<?> dataAdapter = gson.getAdapter(TypeToken.get(dataType));
return new TypeAdapter<T>() {
private final BaseModelTypeAdapter baseModelAdapter = new BaseModelTypeAdapter(gson, dataAdapter);
@Override
public void write(JsonWriter out, T value) throws IOException {
baseModelAdapter.write(out, (BaseModel) value);
}
@Override
public T read(JsonReader in) throws IOException {
return (T) baseModelAdapter.read(in);
}
};
}
}

View File

@@ -0,0 +1,136 @@
package com.xscm.moduleutil.http;
import android.text.TextUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.google.gson.JsonSyntaxException;
import com.hjq.toast.ToastUtils;
import com.xscm.moduleutil.base.CommonAppContext;
import com.xscm.moduleutil.event.LogOutEvent;
import com.xscm.moduleutil.utils.DialogUtils;
import com.xscm.moduleutil.utils.logger.Logger;
import org.apache.http.conn.ConnectTimeoutException;
import org.greenrobot.eventbus.EventBus;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.reactivex.Observer;
/**
* Created by Administrator on 2017/11/22.
*/
public abstract class BaseObserver<T> implements Observer<T> {
private boolean showErrMsg;
public BaseObserver() {
this(true);
}
public BaseObserver(boolean showErrMsg) {
this.showErrMsg = showErrMsg;
}
@Override
public void onError(Throwable e) {
if (e instanceof SocketTimeoutException) {
ToastUtils.show("网络中断,请检查您的网络状态");
} else if (e instanceof ConnectException) {
ToastUtils.show("网络中断,请检查您的网络状态");
} else if (e instanceof ConnectTimeoutException) {
ToastUtils.show("网络中断,请检查您的网络状态");
} else if (e instanceof UnknownHostException) {
ToastUtils.show("网络中断,请检查您的网络状态");
} else if (e instanceof IllegalStateException) {
ToastUtils.show("解析失败");
} else if (e instanceof APIException) {
APIException apiException = (APIException) e;
if (apiException.getCode() == 301) {
try {
ToastUtils.show(extractChinese(apiException.getMessage()));
// com.blankj.utilcode.util.ToastUtils.showShort("提示当前账号已在别的地方登陆,如果不是本人操作请修改密码");
EventBus.getDefault().post(new LogOutEvent());
CommonAppContext.getInstance().clearLoginInfo();
} catch (ClassNotFoundException ex) {
throw new RuntimeException(ex);
}
}
if (showErrMsg && !TextUtils.isEmpty(apiException.getMessage())) {
// ToastUtils.show(extractChinese(apiException.getMessage()));
}
} else if (e instanceof APIException) {
APIException apiException = (APIException) e;
if (showErrMsg && !TextUtils.isEmpty(apiException.getMessage())) {
// ToastUtils.show(apiException.getMessage());
}
} else if (e instanceof JsonSyntaxException) {
ToastUtils.show("网络请求错误……");
}
else {
// ToastUtils.show(e.getMessage());
// CrashReport.postCatchedException(e); //bugly收集错误信息
}
e.printStackTrace();
onComplete();
}
private String extractChinese(String message) {
// 使用正则表达式提取中文字符
StringBuilder chinesePart = new StringBuilder();
Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+");
Matcher matcher = pattern.matcher(message);
while (matcher.find()) {
chinesePart.append(matcher.group());
}
return chinesePart.toString();
}
public void onErrorCode(int code) {
Logger.e("onErrorCode", code);
if (code == 2) {
ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
DialogUtils.showNoBalance();
}
});
}
}
public void onComplete() {
Logger.i("onComplete");
}
// @Override
// public void onNext(BaseModel<T> response) {
// if (response.isSuccess()) {
// onSuccess(response.getData());
// } else if (response.isTokenExpired()) {
// // 触发退出登录
// handleTokenExpired();
// } else {
// onError(response.getMsg());
// }
// }
//
// protected abstract void onSuccess(T data);
// protected abstract void onError(String msg);
// protected abstract void onFail(String error);
//
// @SneakyThrows
// private void handleTokenExpired() {
// // 退出登录逻辑
// ToastUtils.show("登录已过期,请重新登录");
// // 示例:跳转到登录页
// CommonAppContext.getInstance().clearLoginInfo();
// }
}

View File

@@ -0,0 +1,74 @@
package com.xscm.moduleutil.http;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import com.blankj.utilcode.util.ToastUtils;
import com.xscm.moduleutil.base.CommonAppContext;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class BusinessAwareConverterFactory extends Converter.Factory {
private final GsonConverterFactory originalFactory;
private final Context context;
public BusinessAwareConverterFactory(Context context) {
this.context = context;
this.originalFactory = GsonConverterFactory.create();
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations,
Retrofit retrofit) {
final Converter<ResponseBody, ?> delegate =
originalFactory.responseBodyConverter(type, annotations, retrofit);
return new Converter<ResponseBody, Object>() {
@Override
public Object convert(ResponseBody value) throws IOException {
// 先读取响应字符串检查业务状态码
String responseString = value.string();
try {
JSONObject jsonObject = new JSONObject(responseString);
int code = jsonObject.getInt("code");
String msg = jsonObject.getString("msg");
if (code == 301) {
handleForceLogout();
ToastUtils.showShort(msg);
}
// 重新构建 ResponseBody 供原始转换器使用
ResponseBody newValue = ResponseBody.create(value.contentType(), responseString);
return delegate.convert(newValue);
} catch (JSONException e) {
throw new IOException("");
}
}
private void handleForceLogout() {
new Handler(Looper.getMainLooper()).post(() -> {
try {
CommonAppContext.getInstance().clearLoginInfo();
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
});
}
};
}
}

View File

@@ -0,0 +1,91 @@
package com.xscm.moduleutil.http;
import com.blankj.utilcode.util.ToastUtils;
import com.xscm.moduleutil.base.CommonAppContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
public class DefaultTransformer<T> implements ObservableTransformer<BaseModel<T>, T> {
// @Override
// public ObservableSource<R> apply(Observable<T> upstream) {
// return upstream.compose(SchedulerTransformer.<T>create())
// .compose(new ErrorCheckerTransformer<T, R>());
// }
@Override
public ObservableSource<T> apply(Observable<BaseModel<T>> upstream) {
return upstream
.map(response -> {
if (response.isTokenExpired()) {
if (response.getCode()==301){
CommonAppContext.getInstance().clearLoginInfo();
ToastUtils.showShort(response.getMsg());
}else {
// 触发登出事件EventBus
// com.blankj.utilcode.util.ToastUtils.showShort("提示当前账号已在别的地方登陆,如果不是本人操作请修改密码");
// CommonAppContext.getInstance().clearLoginInfo();
}
throw new APIException(response.getCode(), response.getMsg());
}
if (!response.isSuccess()) {
throw new APIException(response.getCode(), response.getMsg());
}
// 确保不会返回null值
T data = response.getData();
if (data == null) {
return getDefaultValue();
}
return data;
// return response.getData();
})
.onErrorResumeNext(throwable -> {
// 可以在这里统一处理异常
if (throwable instanceof APIException && ((APIException) throwable).getCode() == -1) {
// 已经触发过登出事件
}
return Observable.error(throwable);
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
@SuppressWarnings("unchecked")
private T getDefaultValue() {
try {
// 根据类型返回合理的默认值
Class<T> type = (Class<T>) Object.class;
if (String.class.isAssignableFrom(type)) {
return (T) "";
} else if (List.class.isAssignableFrom(type)) {
return (T) new ArrayList<>();
} else if (Integer.class.isAssignableFrom(type) || int.class.isAssignableFrom(type)) {
return (T) Integer.valueOf(0);
} else if (Long.class.isAssignableFrom(type) || long.class.isAssignableFrom(type)) {
return (T) Long.valueOf(0L);
} else if (Double.class.isAssignableFrom(type) || double.class.isAssignableFrom(type)) {
return (T) Double.valueOf(0.0);
} else if (Float.class.isAssignableFrom(type) || float.class.isAssignableFrom(type)) {
return (T) Float.valueOf(0.0f);
} else if (Boolean.class.isAssignableFrom(type) || boolean.class.isAssignableFrom(type)) {
return (T) Boolean.FALSE;
} else {
// 对于其他对象类型返回一个新的Object实例
return (T) new Object();
}
} catch (Exception e) {
return null;
}
}
}

View File

@@ -0,0 +1,40 @@
package com.xscm.moduleutil.http;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.functions.Function;
public class ErrorCheckerTransformer<T extends BaseModel<R>, R>
implements ObservableTransformer<T, R> {
@Override
public ObservableSource<R> apply(Observable<T> upstream) {
return upstream.map(new Function<T, R>() {
@Override
public R apply(T t) throws Exception {
if (t != null) {
int code = t.getCode();
String msg = t.getMsg();
if (code == 1) {//请求成功
return t.getData();
} else if (code == 301) {
throw new APIException(code, msg);
} else {
String message = ErrorMessage.get(code);
if (message != null) {
throw new APIException(code, message);
} else {
throw new APIException(code, t.getMsg());
}
}
} else {
return null;
}
}
});
}
}

View File

@@ -0,0 +1,87 @@
package com.xscm.moduleutil.http;
/**
* 常见错误码对应的错误信息
* Created by dmx on 16/12/1.
*/
public class ErrorMessage {
/**
* 根据编码获取对应的错误信息没有对应编码则返回null
*
* @param code
* @return
*/
public static String get(int code) {
switch (code) {
case 0:
return "失败";
//
case 203:
return "系统维护中";
case 301:
return "token失效";
case 204:
return "账号封禁";
case 205:
return "设备封禁";
case 206:
return "Ip封禁";
//
// case 20:
// return "用户不存在";
//
// case 21:
// return "用户已经存在";
//
// case 22:
// return "用户状态已改变,请刷新重试";
//
// case 100:
// return "验证码获取太频繁";
//
// case 101:
// return "获取验证码次数限制";
//
// case 102:
// return "验证码错误";
// case 103:
// return "密码错误";
// case 104:
// return "第一次登录需要设置密码";
// case 500:
// return "接口不存在";
//
// case 502:
// return "已经提交代理申请";
//
// case 504:
// return "已经是雇员了";
//// case 528:
//// return "不在续保期内,无法续保";
// case 661:
// return "客户身份证重复";
//
// case 1000:
// return "employeeId错误或者缺少";
//
//
// case 1009:
// return "手机号错误";
//
// case 1020:
// return "参数pwd错误或者缺失";
//
// case 1022:
// return "参数id错误或者缺失";
default:
return null;
}
}
}

View File

@@ -0,0 +1,109 @@
package com.xscm.moduleutil.http;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.os.Build;
import android.os.IBinder;
import android.view.Gravity;
import android.view.View;
import androidx.annotation.Nullable;
import com.lzf.easyfloat.EasyFloat;
import com.lzf.easyfloat.enums.ShowPattern;
import com.lzf.easyfloat.enums.SidePattern;
import com.xscm.moduleutil.R;
public class FloatingWindowService extends Service {
private static final int NOTIFICATION_ID = 1;
private View floatView;
@SuppressLint("WrongConstant")
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
// Android 14API 34及以上需要指定具体的 foregroundServiceType
startForeground(NOTIFICATION_ID, buildNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Android 10 - 13 使用通用类型
startForeground(NOTIFICATION_ID, buildNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST);
} else {
startForeground(NOTIFICATION_ID, buildNotification());
}
// 初始化浮窗(建议使用 ApplicationContext
if (floatView == null) {
EasyFloat.with(getApplicationContext())
.setLayout(R.layout.floating_layout)
.setTag("testFloat")
.setShowPattern(ShowPattern.ALL_TIME)
.setDragEnable(true)
.setSidePattern(SidePattern.RESULT_HORIZONTAL)
.setGravity(Gravity.END)
.show();
}
// 创建通知防止服务被杀死
// Notification notification = new Notification.Builder(this, "channel_id")
// .setContentTitle("浮窗运行中")
// .setSmallIcon(R.mipmap.ic_launcher)
// .build();
// startForeground(NOTIFICATION_ID, notification);
}
private Notification buildNotification() {
String channelId = "floating_window_service";
String channelName = "悬浮窗服务";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
channelId,
channelName,
NotificationManager.IMPORTANCE_LOW
);
channel.setShowBadge(false); // 不显示角标
channel.setSound(null, null); // 禁止声音
channel.enableVibration(false); // 禁止震动
NotificationManager manager = getSystemService(NotificationManager.class);
if (manager != null) {
manager.createNotificationChannel(channel);
}
}
Notification.Builder builder = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder = new Notification.Builder(this, channelId)
.setContentTitle("悬浮窗运行中")
.setContentText("点击打开应用")
.setSmallIcon(R.mipmap.default_avatar) // ✅ 必须有效存在
.setAutoCancel(true)
.setOngoing(true);
}
return builder.build();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
// 停止浮窗
EasyFloat.dismiss("testFloat");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

View File

@@ -0,0 +1,57 @@
package com.xscm.moduleutil.http;
import android.app.Dialog;
/**
* Created by cxf on 2017/8/7.
*/
public abstract class HttpCallback {
private Dialog mLoadingDialog;
public abstract void onSuccess(int code, String msg, String[] info);
public void onError() {
}
/**
* 登录过期
*/
public void onLoginInvalid() {
}
public void onStart() {
try {
if (showLoadingDialog()) {
if (mLoadingDialog == null) {
mLoadingDialog = createLoadingDialog();
}
mLoadingDialog.show();
}
} catch (Exception e) {
}
}
public void onFinish() {
if (showLoadingDialog() && mLoadingDialog != null) {
mLoadingDialog.dismiss();
}
}
public Dialog createLoadingDialog() {
return null;
}
public boolean showLoadingDialog() {
return false;
}
public boolean isUseLoginInvalid() {
return false;
}
}

View File

@@ -0,0 +1,57 @@
package com.xscm.moduleutil.http;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.xscm.moduleutil.utils.GsonUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
public class MyConverterFactory extends Converter.Factory {
/**
* Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
public static MyConverterFactory create() {
return create(GsonUtils.getGSON());
}
/**
* Create an instance using {@code gson} for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static MyConverterFactory create(Gson gson) {
if (gson == null) {
throw new NullPointerException("gson == null");
}
return new MyConverterFactory(gson);
}
private final Gson gson;
private MyConverterFactory(Gson gson) {
this.gson = gson;
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new RequestBodyConverter<>(gson, adapter);
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new ResponseBodyConverter<>(gson, adapter);
// return new ResponseBodyConverter<>(gson, TypeToken.get(type));
}
}

View File

@@ -0,0 +1,41 @@
package com.xscm.moduleutil.http;
import androidx.annotation.NonNull;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import retrofit2.Converter;
public class RequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final Gson gson;
private final TypeAdapter<T> adapter;
RequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override public RequestBody convert(@NonNull T value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
JsonWriter jsonWriter = gson.newJsonWriter(writer);
adapter.write(jsonWriter, value);
jsonWriter.close();
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}

View File

@@ -0,0 +1,101 @@
package com.xscm.moduleutil.http;
import com.blankj.utilcode.util.ToastUtils;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.google.gson.TypeAdapter;
import com.xscm.moduleutil.utils.GsonUtils;
import java.io.IOException;
import io.reactivex.annotations.NonNull;
import okhttp3.ResponseBody;
import retrofit2.Converter;
public class ResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
ResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override
public T convert(@NonNull ResponseBody value) throws IOException {
String json = value.string();
try {
BaseModel obj = GsonUtils.GsonToBean(json, BaseModel.class);
if (obj.getCode() != 1) {
String info = obj.getMsg();
if ("当前余额不足".equals(info)) {
value.close();
return parseDataSafely(json);
} else {
if (!info.contains("更新失败")) {
// ToastUtils.showShort(info);
}
// throw new APIException(obj.getCode(), info);
}
}
value.close();
return parseDataSafely(json);
} catch (Exception e) {
// 处理解析异常,避免崩溃
value.close();
try {
// 尝试返回默认值
return createDefaultInstance();
} catch (Exception ex) {
return null;
}
}
}
/**
* 安全地解析数据,处理各种可能的返回类型
*/
private T parseDataSafely(String json) {
try {
return adapter.fromJson(json);
} catch (IOException | JsonParseException e) {
// 当解析失败时,尝试其他方式处理
try {
// 尝试返回默认值
return createDefaultInstance();
} catch (Exception ex) {
return null;
}
}
}
/**
* 创建默认实例以避免null返回
*/
@SuppressWarnings("unused")
private T createDefaultInstance() {
try {
// 对于基本类型和常见集合类型,返回默认值
Class<?> rawType = adapter.getClass();
if (rawType.isAssignableFrom(String.class)) {
return (T) "";
} else if (rawType.isAssignableFrom(Boolean.class) || rawType.isAssignableFrom(boolean.class)) {
return (T) Boolean.FALSE;
} else if (rawType.isAssignableFrom(Integer.class) || rawType.isAssignableFrom(int.class)) {
return (T) Integer.valueOf(0);
} else if (rawType.isAssignableFrom(Long.class) || rawType.isAssignableFrom(long.class)) {
return (T) Long.valueOf(0L);
} else if (rawType.isAssignableFrom(Double.class) || rawType.isAssignableFrom(double.class)) {
return (T) Double.valueOf(0.0);
} else if (rawType.isAssignableFrom(Float.class) || rawType.isAssignableFrom(float.class)) {
return (T) Float.valueOf(0.0f);
} else {
// 对于其他类型返回null而不是抛出异常
return null;
}
} catch (Exception e) {
return null;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
package com.xscm.moduleutil.http;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* 默认线程调度
* Created by dmx on 16/12/1.
*/
public class SchedulerTransformer<T> implements ObservableTransformer<T, T> {
public static <T> SchedulerTransformer<T> create() {
return new SchedulerTransformer<>();
}
@Override
public ObservableSource<T> apply(Observable<T> upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
}