feat: 初始化项目结构和基本功能
- 创建项目根目录和主要子模块 - 添加基本的 Activity 和布局文件 - 实现简单的导航和电话拨打功能 - 添加相机和图像处理相关代码 - 创建网络请求和数据加密工具类 - 设置 AndroidManifest 文件和权限
This commit is contained in:
123
servicing/src/main/java/com/za/net/AESUtils.java
Normal file
123
servicing/src/main/java/com/za/net/AESUtils.java
Normal file
@ -0,0 +1,123 @@
|
||||
package com.za.net;
|
||||
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class AESUtils {
|
||||
|
||||
private static final String cipherMode = "AES/ECB/PKCS5Padding";//算法/模式/补码方式
|
||||
|
||||
/* AES秘钥支持128bit/192bit/256bit三种长度的秘钥,一个字节等于8bit,
|
||||
* 因此支持生成的字符串的长度应该是 16/24/32
|
||||
* */
|
||||
private static final int keyLength = 16;
|
||||
|
||||
|
||||
// public static void main(String[] args) {
|
||||
//
|
||||
// /*构建一个随机密码*/
|
||||
// String key = getRandomKey(keyLength);
|
||||
// System.out.println("随机生成的key:" + key);
|
||||
//
|
||||
// String data = "{'fig':1,'message':'登录成功'}";
|
||||
//
|
||||
// try {
|
||||
// String encriptData = AESUtils.encrypt(data, key);
|
||||
// System.out.println("加密后的数据:" + encriptData);
|
||||
//
|
||||
// String decryptData = decrypt(encriptData, key);
|
||||
//
|
||||
// System.out.println("解密后的数据:" + decryptData);
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* @param length 需要生成的字符串长度
|
||||
* @return 随机生成的字符串
|
||||
*/
|
||||
public static String getRandomKey(int length) {
|
||||
|
||||
if (length != 16 && length != 24 && length != 32) {
|
||||
System.out.println("长度必须为16/24/32");
|
||||
return null;
|
||||
}
|
||||
|
||||
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
Random random = new Random();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
int number = random.nextInt(62);
|
||||
stringBuilder.append(str.charAt(number));
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param data 需要加密的数据
|
||||
* @param key 加密使用的key
|
||||
* @return 加密后的数据(Base64编码)
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encrypt(String data, String key) throws Exception {
|
||||
|
||||
int length = key.length();
|
||||
if (length != 16 && length != 24 && length != 32) {
|
||||
System.out.println("长度必须为16/24/32");
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] raw = key.getBytes(StandardCharsets.UTF_8);
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
|
||||
Cipher cipher = Cipher.getInstance(cipherMode);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
|
||||
byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
return Base64.encodeToString(encrypted, Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param data 需要解密的数据
|
||||
* @param key 解密用的key
|
||||
* @return 解密后的数据
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String decrypt(String data, String key) throws Exception {
|
||||
try {
|
||||
int length = key.length();
|
||||
if (length != 16 && length != 24 && length != 32) {
|
||||
System.out.println("长度必须为16/24/32");
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] raw = key.getBytes(StandardCharsets.UTF_8);
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
|
||||
Cipher cipher = Cipher.getInstance(cipherMode);
|
||||
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
|
||||
byte[] encrypted = Base64.decode(data,Base64.URL_SAFE | Base64.NO_WRAP);//先用base64解密
|
||||
try {
|
||||
byte[] original = cipher.doFinal(encrypted);
|
||||
return new String(original, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.toString());
|
||||
return null;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println(ex.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
265
servicing/src/main/java/com/za/net/ApiService.kt
Normal file
265
servicing/src/main/java/com/za/net/ApiService.kt
Normal file
@ -0,0 +1,265 @@
|
||||
package com.za.net
|
||||
|
||||
import com.za.bean.BaseResponse
|
||||
import com.za.bean.BatteryCostQueryBean
|
||||
import com.za.bean.BatteryCostQueryRequest
|
||||
import com.za.bean.ChangeBatteryResponse
|
||||
import com.za.bean.DriverIdentityAuthWebBean
|
||||
import com.za.bean.DriverIdentityAuthWebRequest
|
||||
import com.za.bean.DriverInfo
|
||||
import com.za.bean.FetchChangeBatteryPhotoRequest
|
||||
import com.za.bean.GeneralInfo
|
||||
import com.za.bean.HistoryPhotoTemplates
|
||||
import com.za.bean.HistoryTaskBean
|
||||
import com.za.bean.ImageBean
|
||||
import com.za.bean.JpushBean
|
||||
import com.za.bean.LoginWithTaskBean
|
||||
import com.za.bean.LoginWithTaskRequest
|
||||
import com.za.bean.NewOrderRequestBean
|
||||
import com.za.bean.PaymentInfoBean
|
||||
import com.za.bean.ReportHistoryBean
|
||||
import com.za.bean.ReportHistoryRequest
|
||||
import com.za.bean.ReportInfoRequest
|
||||
import com.za.bean.ReportItem
|
||||
import com.za.bean.SettleInfoRequest
|
||||
import com.za.bean.TaskSettlementAndTraceBean
|
||||
import com.za.bean.UpdateVersionBean
|
||||
import com.za.bean.UpdateVersionRequest
|
||||
import com.za.bean.UploadChangeBatteryRequest
|
||||
import com.za.bean.VehicleInfo
|
||||
import com.za.bean.db.order.OrderInfo
|
||||
import com.za.bean.db.order.PhotoTemplateInfo
|
||||
import com.za.bean.request.AcceptOrderRequest
|
||||
import com.za.bean.request.CustomerPaymentCreateBean
|
||||
import com.za.bean.request.CustomerPaymentCreateRequest
|
||||
import com.za.bean.request.DriverFaceCompareBean
|
||||
import com.za.bean.request.DriverFaceCompareRequest
|
||||
import com.za.bean.request.ElectronOrderResponse
|
||||
import com.za.bean.request.FetchVehicleMaintenanceSubmitHistoryRequestBean
|
||||
import com.za.bean.request.GeneralInfoRequest
|
||||
import com.za.bean.request.GiveUpTaskRequest
|
||||
import com.za.bean.request.HistoryDetailRequest
|
||||
import com.za.bean.request.HistoryPhotoTemplateRequest
|
||||
import com.za.bean.request.HistoryTasksRequest
|
||||
import com.za.bean.request.LoginRequest
|
||||
import com.za.bean.request.OrderListRequest
|
||||
import com.za.bean.request.OrderPhotoOcrRecognizeRequest
|
||||
import com.za.bean.request.PaymentInfoRequest
|
||||
import com.za.bean.request.PaymentUpdateRequest
|
||||
import com.za.bean.request.PhotoTemplateRequest
|
||||
import com.za.bean.request.QueryEleOrderRequest
|
||||
import com.za.bean.request.RecognizeRefuelOcrRequestBean
|
||||
import com.za.bean.request.RecognizeRefuelTicketBean
|
||||
import com.za.bean.request.RecognizeRefuelTicketRequestBean
|
||||
import com.za.bean.request.RefuseOrderRequest
|
||||
import com.za.bean.request.SaveEleOrderRequest
|
||||
import com.za.bean.request.SwitchTaskRequest
|
||||
import com.za.bean.request.TaskFinishRequest
|
||||
import com.za.bean.request.TaskFinishResponse
|
||||
import com.za.bean.request.TodayMaintainRequest
|
||||
import com.za.bean.request.TodayMaintainUploadRequest
|
||||
import com.za.bean.request.TodayMaintainbean
|
||||
import com.za.bean.request.UpdateOrderConfirmTaskRequest
|
||||
import com.za.bean.request.UpdatePhotoRequest
|
||||
import com.za.bean.request.UpdateTaskBean
|
||||
import com.za.bean.request.UpdateTaskRequest
|
||||
import com.za.bean.request.UpdateVehicleStateRequest
|
||||
import com.za.bean.request.UploadGpsRequest
|
||||
import com.za.bean.request.UploadPhotoBean
|
||||
import com.za.bean.request.VehicleListRequest
|
||||
import com.za.bean.request.VehicleLogoutRequest
|
||||
import com.za.bean.request.VehicleMaintenanceHistoryBean
|
||||
import com.za.bean.request.VehicleMaintenanceSubmitRequest
|
||||
import com.za.bean.request.VehicleRepairBean
|
||||
import com.za.bean.request.VehicleRepairPointMatcherItem
|
||||
import com.za.bean.request.VehicleRepairPointMatcherListRequest
|
||||
import com.za.bean.request.VerifyCodeRequest
|
||||
import com.za.bean.request.VerifyCodeResponse
|
||||
import com.za.call.ContactRecordRequest
|
||||
import com.za.water_marker.bean.MyWaterMarkerTemplateBean
|
||||
import com.za.water_marker.bean.WaterMarkerRequestBean
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import okhttp3.MultipartBody
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.Multipart
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Part
|
||||
|
||||
interface ApiService {
|
||||
|
||||
//获取车辆列表
|
||||
@POST("/driverApp/supplier/listVehicleNew")
|
||||
fun getVehicleList(@Body info : VehicleListRequest) : Observable<BaseResponse<List<VehicleInfo>>>
|
||||
|
||||
//更改车辆状态
|
||||
@POST("/driverApp/task/switchVehicleStatus")
|
||||
fun newUpdateVehicleState(@Body info : UpdateVehicleStateRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
@POST("/driverApp/v2/user/generalInfo")
|
||||
fun generalInfo(@Body info : GeneralInfoRequest) : Observable<BaseResponse<GeneralInfo>>
|
||||
|
||||
@POST("/driverApp/base/appVersion")
|
||||
fun getUpdate(@Body versionRequest : UpdateVersionRequest) : Observable<BaseResponse<UpdateVersionBean>>
|
||||
|
||||
@POST("/driverApp/base/getVerifyCode")
|
||||
fun getVerifyCode(@Body verifyCodeRequest : VerifyCodeRequest) : Observable<BaseResponse<VerifyCodeResponse>>
|
||||
|
||||
@Multipart
|
||||
@POST("/order/uploadImage")
|
||||
fun uploadImage(@Part part : MultipartBody.Part) : Observable<ImageBean>
|
||||
|
||||
@POST("/driverApp/task/uploadContactRecord")
|
||||
fun uploadContactRecord(@Body contactRecordRequest : ContactRecordRequest?) : Observable<BaseResponse<String>>
|
||||
|
||||
@POST("/driverApp/task/login")
|
||||
fun login(@Body info : LoginRequest) : Observable<BaseResponse<DriverInfo?>>
|
||||
|
||||
@POST("/driverApp/task/loginWithTask")
|
||||
fun loginWithTask(@Body loginWithTaskRequest : LoginWithTaskRequest) : Observable<BaseResponse<LoginWithTaskBean>>
|
||||
|
||||
@POST("/driverApp/supplier/vehicleLogout")
|
||||
fun vehicleLogout(@Body info : VehicleLogoutRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
//当前订单列表
|
||||
@POST("/driverApp/v2/task/listCurrentTask")
|
||||
fun queryOrderList(@Body info : OrderListRequest) : Observable<BaseResponse<List<OrderInfo>?>>
|
||||
|
||||
@POST("/driverApp/task/getNewOrder")
|
||||
fun getNewOrder(@Body newOrderRequestBean : NewOrderRequestBean) : Observable<BaseResponse<JpushBean>>
|
||||
|
||||
@POST("/driverApp/supplier/uploadGps")
|
||||
fun uploadGps(@Body info : UploadGpsRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
//获取报备内容列表
|
||||
@POST("/driverApp/base/getReportTemplates")
|
||||
fun getReportTemplates() : Observable<BaseResponse<List<ReportItem>>>
|
||||
|
||||
//提交报备
|
||||
@POST("/driverApp/task/submitReport")
|
||||
fun submitReport(@Body reportInfoRequest : ReportInfoRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
//历史报备内容
|
||||
@POST("/driverApp/task/reportHistory")
|
||||
fun getReportHistory(@Body reportHistoryRequest : ReportHistoryRequest) : Observable<BaseResponse<List<ReportHistoryBean>>>
|
||||
|
||||
//拒绝任务
|
||||
@POST("/driverApp/task/refuseTask")
|
||||
fun refuseOrder(@Body request : RefuseOrderRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
//接受任务
|
||||
@POST("/driverApp/task/acceptTask")
|
||||
fun acceptOrder(@Body request : AcceptOrderRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
//更新任务
|
||||
@POST("/driverApp/v4/task/updateTask")
|
||||
fun updateTask(@Body request : UpdateTaskRequest) : Observable<BaseResponse<UpdateTaskBean>>
|
||||
|
||||
//更新任务
|
||||
@POST("/driverApp/v4/task/updateTask")
|
||||
fun submitOrderConfirmTask(@Body request : UpdateOrderConfirmTaskRequest) : Observable<BaseResponse<UpdateTaskBean>>
|
||||
|
||||
@POST("/driverApp/v2/supplier/photoTemplate")
|
||||
fun fetchPhotoTemplate(@Body request : PhotoTemplateRequest) : Observable<BaseResponse<List<PhotoTemplateInfo>>>
|
||||
|
||||
@POST("/driverApp/supplier/getWatermarkTemplateConfig")
|
||||
fun getWatermarkTemplateConfig(@Body request : WaterMarkerRequestBean) : Observable<BaseResponse<MyWaterMarkerTemplateBean>>
|
||||
|
||||
@POST("/driverApp/supplier/orderPhotoOcrRecognize")
|
||||
fun orderPhotoOcrRecognize(@Body info : OrderPhotoOcrRecognizeRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
@POST("/driverApp/v4/supplier/saveElectronOrder")
|
||||
fun saveElectronOrder(@Body info : SaveEleOrderRequest?) : Observable<BaseResponse<String>>
|
||||
|
||||
@POST("/driverApp/supplier/queryElectronOrder")
|
||||
fun queryElectronOrder(@Body info : QueryEleOrderRequest?) : Observable<BaseResponse<ElectronOrderResponse>>
|
||||
|
||||
//查询支付信息
|
||||
@POST("/driverApp/payment/paymentInfoQuery")
|
||||
fun paymentInfoQuery(@Body info : PaymentInfoRequest?) : Observable<BaseResponse<PaymentInfoBean>>
|
||||
|
||||
@POST("/driverApp/payment/customerPaymentCreate")
|
||||
fun customerPaymentCreate(@Body customerPaymentCreateRequest : CustomerPaymentCreateRequest) : Observable<BaseResponse<CustomerPaymentCreateBean>>
|
||||
|
||||
@POST("/driverApp/payment/paymentAmountUpdate")
|
||||
fun paymentAmountUpdate(@Body paymentUpdateRequest : PaymentUpdateRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
@POST("/driverApp/battery/saveReplaceBatteryPhoto")
|
||||
fun saveReplaceBatteryPhoto(@Body info : UploadChangeBatteryRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
@POST("/driverApp/supplier/getReplaceBatteryPhoto")
|
||||
fun getReplaceBatteryPhoto(@Body info : FetchChangeBatteryPhotoRequest) : Observable<BaseResponse<List<ChangeBatteryResponse>>>
|
||||
|
||||
//电瓶费用查询
|
||||
@POST("/driverApp/battery/batteryCostQuery")
|
||||
fun batteryCostQuery(@Body info : BatteryCostQueryRequest) : Observable<BaseResponse<BatteryCostQueryBean>>
|
||||
|
||||
@POST("/driverApp/v4/task/taskFinish")
|
||||
fun taskFinish(@Body info : TaskFinishRequest) : Observable<BaseResponse<TaskFinishResponse>>
|
||||
|
||||
@POST("/driverApp/task/giveUpTask")
|
||||
fun giveUpTask(@Body info : GiveUpTaskRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
//历史订单补传照片
|
||||
@POST("/driverApp/task/updatePhoto")
|
||||
fun addPhoto(@Body params : UpdatePhotoRequest) : Observable<BaseResponse<UploadPhotoBean>>
|
||||
|
||||
@POST("/driverApp/v2/task/switchTask")
|
||||
fun switchTask(@Body info : SwitchTaskRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
@POST("/driverApp/task/listHistoryTaskNew")
|
||||
fun getHistory(@Body info : HistoryTasksRequest) : Observable<BaseResponse<List<HistoryTaskBean>>>
|
||||
|
||||
@POST("/driverApp/task/getHistoryTaskPhotos")
|
||||
fun getHistoryTaskPhotos(@Body info : HistoryPhotoTemplateRequest) : Observable<BaseResponse<List<HistoryPhotoTemplates>>>
|
||||
|
||||
//历史结算单和轨迹
|
||||
@POST("/driverApp/task/getTaskSettlementAndTrace")
|
||||
fun getTaskSettlementAndTrace(@Body info : HistoryDetailRequest) : Observable<BaseResponse<TaskSettlementAndTraceBean>>
|
||||
|
||||
@POST("driverApp/task/updateSettleInfo")
|
||||
fun updateSettleInfo(@Body settleInfoRequest : SettleInfoRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
|
||||
//人脸比对
|
||||
@POST("driverApp/supplier/driverFaceCompare")
|
||||
fun driverFaceCompare(@Body driverFaceCompareRequest : DriverFaceCompareRequest) : Observable<BaseResponse<DriverFaceCompareBean>>
|
||||
|
||||
@POST("driverApp/supplier/driverIdentityAuthWeb")
|
||||
fun driverIdentityAuthWeb(@Body request : DriverIdentityAuthWebRequest) : Observable<BaseResponse<DriverIdentityAuthWebBean>>
|
||||
|
||||
//今日保养
|
||||
@POST("driverApp/supplier/getTodayMaintain")
|
||||
fun getTodayMaintain(@Body info : TodayMaintainRequest) : Observable<BaseResponse<List<TodayMaintainbean>>>
|
||||
|
||||
//今日保养
|
||||
@POST("driverApp/supplier/uploadTodayMaintain")
|
||||
fun uploadTodayMaintain(@Body params : TodayMaintainUploadRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
//加油小票识别
|
||||
@POST("driverApp/supplier/recognizeRefuelTicket")
|
||||
fun recognizeRefuelTicket(@Body bean : RecognizeRefuelOcrRequestBean?) : Observable<BaseResponse<RecognizeRefuelTicketBean>>
|
||||
|
||||
//提交加油记录
|
||||
@POST("driverApp/supplier/vehicleRefuelSubmit")
|
||||
fun vehicleRefuelSubmit(@Body info : RecognizeRefuelTicketRequestBean?) : Observable<BaseResponse<String>>
|
||||
|
||||
//获取车辆维保记录
|
||||
@POST("driverApp/supplier/v2/getVehicleMaintenanceSubmit")
|
||||
fun getVehicleMaintenanceSubmit(@Body info : FetchVehicleMaintenanceSubmitHistoryRequestBean) : Observable<BaseResponse<VehicleRepairBean>>
|
||||
|
||||
//获取车辆维保详细信息
|
||||
@POST("driverApp/supplier/v2/getVehicleMaintenanceDetail")
|
||||
fun getVehicleRepairDetail(@Body info : FetchVehicleMaintenanceSubmitHistoryRequestBean) : Observable<BaseResponse<VehicleRepairBean>>
|
||||
|
||||
//维修地点匹配
|
||||
@POST("driverApp/supplier/v2/vehicleRepairPointMatcherList")
|
||||
fun vehicleRepairPointMatcherList(@Body info : VehicleRepairPointMatcherListRequest) : Observable<BaseResponse<List<VehicleRepairPointMatcherItem>>>
|
||||
|
||||
//提交维保记录
|
||||
@POST("driverApp/supplier/v2/vehicleMaintenanceSubmit")
|
||||
fun vehicleMaintenanceSubmit(@Body info : VehicleMaintenanceSubmitRequest) : Observable<BaseResponse<String>>
|
||||
|
||||
//获取车辆维修历史
|
||||
@POST("/driverApp/supplier/v2/vehicleMaintenanceList")
|
||||
fun vehicleMaintenanceList(@Body info : FetchVehicleMaintenanceSubmitHistoryRequestBean) : Observable<BaseResponse<List<VehicleMaintenanceHistoryBean>>>
|
||||
}
|
127
servicing/src/main/java/com/za/net/BaseObserver.kt
Normal file
127
servicing/src/main/java/com/za/net/BaseObserver.kt
Normal file
@ -0,0 +1,127 @@
|
||||
package com.za.net
|
||||
|
||||
import android.net.ParseException
|
||||
import com.blankj.utilcode.util.ActivityUtils
|
||||
import com.blankj.utilcode.util.NetworkUtils
|
||||
import com.blankj.utilcode.util.ToastUtils
|
||||
import com.google.gson.JsonParseException
|
||||
import com.za.base.Const
|
||||
import com.za.bean.BaseResponse
|
||||
import com.za.common.GlobalData
|
||||
import com.za.common.log.LogUtil
|
||||
import com.za.service.location.ZdLocationManager
|
||||
import io.reactivex.rxjava3.core.Observer
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import org.json.JSONException
|
||||
import java.net.ConnectException
|
||||
import java.net.SocketTimeoutException
|
||||
import java.net.UnknownHostException
|
||||
import java.util.concurrent.TimeoutException
|
||||
import javax.net.ssl.SSLHandshakeException
|
||||
|
||||
/**
|
||||
* Created by DoggieX on 2017/7/26.
|
||||
*/
|
||||
abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
// if (!NetworkUtils.isAvailable()) {
|
||||
// doFailure(999, "网络无法使用")
|
||||
// d.dispose()
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onNext(tBaseResponse: BaseResponse<T>) {
|
||||
if (tBaseResponse.isOk) {
|
||||
doSuccess(tBaseResponse.result)
|
||||
} else {
|
||||
when (tBaseResponse.code) {
|
||||
3, 401 -> handlerTokenExpired()
|
||||
// 4 -> RsaRouter.navigate(context, "/page/Standby")
|
||||
}
|
||||
if (null != tBaseResponse.msg) {
|
||||
doFailure(tBaseResponse.code, tBaseResponse.msg)
|
||||
} else if (null != tBaseResponse.message) {
|
||||
doFailure(tBaseResponse.code, tBaseResponse.message)
|
||||
} else {
|
||||
doFailure(tBaseResponse.code, "error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
LogUtil.print("net error", e)
|
||||
when (e) {
|
||||
is JsonParseException -> {
|
||||
doFailure(1, "数据解析错误")
|
||||
}
|
||||
|
||||
is JSONException -> {
|
||||
doFailure(1, "数据解析错误")
|
||||
}
|
||||
|
||||
is ParseException -> {
|
||||
doFailure(1, "数据解析错误")
|
||||
}
|
||||
|
||||
is ConnectException -> {
|
||||
doFailure(Const.NetWorkException, "与服务器断开连接")
|
||||
}
|
||||
|
||||
is UnknownHostException -> {
|
||||
doFailure(Const.NetWorkException, "与服务器断开连接")
|
||||
}
|
||||
|
||||
is SSLHandshakeException -> {
|
||||
doFailure(1, "证书验证失败")
|
||||
LogUtil.print("SSLHandshakeException", e)
|
||||
}
|
||||
|
||||
is TimeoutException -> {
|
||||
doFailure(Const.NetWorkException, "网络连接超时1")
|
||||
LogUtil.print("TimeoutException", e)
|
||||
}
|
||||
|
||||
is SocketTimeoutException -> {
|
||||
doFailure(Const.NetWorkException, "网络连接超时2")
|
||||
LogUtil.print("SocketTimeoutException2", e)
|
||||
}
|
||||
else -> {
|
||||
doFailure(1, "error:" + e.message)
|
||||
LogUtil.print("other error", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
}
|
||||
|
||||
abstract fun doSuccess(it: T?)
|
||||
|
||||
abstract fun doFailure(code: Int, msg: String?)
|
||||
|
||||
private fun handlerTokenExpired() {
|
||||
ToastUtils.showShort("登陆信息已过期,请重新登录")
|
||||
try {
|
||||
GlobalData.clearUserCache()
|
||||
ZdLocationManager.stopContinuousLocation()
|
||||
ActivityUtils.finishAllActivities()
|
||||
// val oldLoginInfo: LoginInfo = DbManager.getInstance(context).queryLoginInfo()
|
||||
// val loginInfo: LoginInfo = LoginInfo()
|
||||
// loginInfo.setSupplierId(oldLoginInfo.getSupplierId())
|
||||
// loginInfo.setSupplierCode(oldLoginInfo.getSupplierCode())
|
||||
// loginInfo.setJobNumber(oldLoginInfo.getJobNumber())
|
||||
// loginInfo.setPassword(oldLoginInfo.getPassword())
|
||||
// DbManager.getInstance(context).deleteLoginInfo()
|
||||
// DbManager.getInstance(context).saveLoginInfo(loginInfo)
|
||||
// SPKit.saveString(context, "userId", "-1")
|
||||
// SPKit.saveString(context, "vehicleId", "-1")
|
||||
//
|
||||
// LBSManager.getInstance().cancel()
|
||||
// DaemonService.stopService()
|
||||
// //跳转
|
||||
// RsaRouter.navigateNoFlag(context, "/page/login")
|
||||
} catch (e: Exception) {
|
||||
LogUtil.print("handlerTokenExpired", e)
|
||||
}
|
||||
}
|
||||
}
|
405
servicing/src/main/java/com/za/net/CommonMethod.kt
Normal file
405
servicing/src/main/java/com/za/net/CommonMethod.kt
Normal file
@ -0,0 +1,405 @@
|
||||
package com.za.net
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
import com.blankj.utilcode.util.ActivityUtils
|
||||
import com.blankj.utilcode.util.ImageUtils
|
||||
import com.za.base.Const
|
||||
import com.za.bean.DriverInfo
|
||||
import com.za.bean.GeneralInfo
|
||||
import com.za.bean.ImageBean
|
||||
import com.za.bean.JpushBean
|
||||
import com.za.bean.NewOrderRequestBean
|
||||
import com.za.bean.VehicleInfo
|
||||
import com.za.bean.db.ele.EleCarDamagePhotoBean
|
||||
import com.za.bean.db.ele.EleWorkOrderBean
|
||||
import com.za.bean.db.order.OrderInfo
|
||||
import com.za.bean.db.order.PhotoTemplateInfo
|
||||
import com.za.bean.request.ElectronOrderResponse
|
||||
import com.za.bean.request.GeneralInfoRequest
|
||||
import com.za.bean.request.OrderListRequest
|
||||
import com.za.bean.request.PhotoTemplateRequest
|
||||
import com.za.bean.request.QueryEleOrderRequest
|
||||
import com.za.bean.request.UpdateTaskBean
|
||||
import com.za.bean.request.UpdateTaskRequest
|
||||
import com.za.bean.request.UploadGpsRequest
|
||||
import com.za.common.GlobalData
|
||||
import com.za.common.log.LogUtil
|
||||
import com.za.common.util.DeviceUtil
|
||||
import com.za.ext.toJson
|
||||
import com.za.offline.OfflineManager
|
||||
import com.za.room.RoomHelper
|
||||
import com.za.ui.new_order.NewOrderActivity
|
||||
import com.za.ui.order_report.ReportFloatingManager
|
||||
import com.za.water_marker.WaterMarkerTemplateManager
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Observer
|
||||
import io.reactivex.rxjava3.disposables.Disposable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody.Companion.asRequestBody
|
||||
import java.io.File
|
||||
|
||||
object CommonMethod {
|
||||
fun uploadGps(uploadGpsRequest : UploadGpsRequest,
|
||||
success : () -> Unit = {},
|
||||
failed : (String?) -> Unit = {}) {
|
||||
RetrofitHelper.getDefaultService().uploadGps(uploadGpsRequest).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread()).subscribe(object : BaseObserver<String>() {
|
||||
override fun doSuccess(it : String?) {
|
||||
success()
|
||||
LogUtil.print("uploadGps", uploadGpsRequest.toString())
|
||||
}
|
||||
|
||||
override fun doFailure(code : Int, msg : String?) {
|
||||
failed(msg)
|
||||
LogUtil.print("uploadGps", "failed==$msg")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun uploadImage(file : File,
|
||||
preview : () -> Unit = {},
|
||||
success : (String?) -> Unit = {},
|
||||
failed : (String?) -> Unit = {}) {
|
||||
file.writeBytes(ImageUtils.compressByQuality(BitmapFactory.decodeStream(file.inputStream()),
|
||||
Const.Image_Max_length,
|
||||
true))
|
||||
val requestFile = file.asRequestBody("image/*".toMediaTypeOrNull())
|
||||
val body = MultipartBody.Part.createFormData("file", file.name, requestFile)
|
||||
preview()
|
||||
RetrofitHelper.getDefaultService().uploadImage(body).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread()).subscribe(object : Observer<ImageBean> {
|
||||
override fun onSubscribe(d : Disposable) {
|
||||
|
||||
}
|
||||
|
||||
override fun onError(e : Throwable) {
|
||||
failed(e.message)
|
||||
LogUtil.print("uploadImage", e)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
|
||||
}
|
||||
|
||||
override fun onNext(t : ImageBean) {
|
||||
if (t.isOk()) {
|
||||
success(t.data)
|
||||
return
|
||||
}
|
||||
failed(t.msg)
|
||||
LogUtil.print("uploadImage failed", t.toJson() ?: "")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//更新订单状态
|
||||
fun updateTask(taskRequest : UpdateTaskRequest,
|
||||
success : (UpdateTaskBean?) -> Unit,
|
||||
failed : (String?, Int) -> Unit) {
|
||||
|
||||
RetrofitHelper.getDefaultService().updateTask(taskRequest).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BaseObserver<UpdateTaskBean>() {
|
||||
override fun doSuccess(it : UpdateTaskBean?) {
|
||||
success(it)
|
||||
LogUtil.print("updateTask", "success=$it request=${taskRequest.toJson()}")
|
||||
}
|
||||
|
||||
override fun doFailure(code : Int, msg : String?) {
|
||||
failed(msg, code)
|
||||
LogUtil.print("updateTask", "doFailure=$msg request=${taskRequest.toJson()}")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun getGenerateInfo(vehicleId : Int? = null,
|
||||
userId : Int? = null,
|
||||
success : (GeneralInfo) -> Unit = {},
|
||||
failed : (String?) -> Unit = {}) {
|
||||
val generalInfoRequest =
|
||||
GeneralInfoRequest(vehicleId = vehicleId ?: GlobalData.vehicleInfo?.vehicleId,
|
||||
driverId = userId ?: GlobalData.driverInfo?.userId,
|
||||
deviceId = DeviceUtil.getAndroidId(ActivityUtils.getTopActivity()))
|
||||
RetrofitHelper.getDefaultService().generalInfo(generalInfoRequest)
|
||||
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BaseObserver<GeneralInfo>() {
|
||||
override fun doSuccess(it : GeneralInfo?) {
|
||||
if (it == null) {
|
||||
failed("获取车辆信息失败")
|
||||
return
|
||||
}
|
||||
if (GlobalData.vehicleInfo == null) {
|
||||
GlobalData.vehicleInfo = VehicleInfo(vehicleId = it.vehicleId,
|
||||
vehicleName = it.vehicleName,
|
||||
userName = it.userName,
|
||||
userPhone = it.userPhone,
|
||||
status = it.vehicleState,
|
||||
plateNumber = it.plateNumber,
|
||||
vehicleState = it.vehicleState,
|
||||
supplierType = it.supplierType)
|
||||
} else {
|
||||
GlobalData.vehicleInfo =
|
||||
GlobalData.vehicleInfo?.copy(vehicleId = it.vehicleId,
|
||||
vehicleName = it.vehicleName,
|
||||
userName = it.userName,
|
||||
userPhone = it.userPhone,
|
||||
status = it.vehicleState,
|
||||
plateNumber = it.plateNumber,
|
||||
vehicleState = it.vehicleState,
|
||||
supplierType = it.supplierType)
|
||||
}
|
||||
|
||||
if (GlobalData.driverInfo == null) {
|
||||
GlobalData.driverInfo = DriverInfo(userPortrait = it.userPortrait,
|
||||
userName = it.userName,
|
||||
userId = it.userId,
|
||||
userPhone = it.userPhone,
|
||||
supplierId = it.supplierId.toString(),
|
||||
supplierName = it.supplierName,
|
||||
authStatus = it.authStatus,
|
||||
supplierType = it.supplierType,
|
||||
serviceList = it.serviceList)
|
||||
} else {
|
||||
GlobalData.driverInfo =
|
||||
GlobalData.driverInfo?.copy(userPortrait = it.userPortrait,
|
||||
userName = it.userName,
|
||||
userId = it.userId,
|
||||
userPhone = it.userPhone,
|
||||
supplierId = it.supplierId.toString(),
|
||||
supplierName = it.supplierName,
|
||||
authStatus = it.authStatus,
|
||||
supplierType = it.supplierType,
|
||||
serviceList = it.serviceList)
|
||||
}
|
||||
|
||||
success(it)
|
||||
}
|
||||
|
||||
override fun doFailure(code : Int, msg : String?) {
|
||||
failed(msg)
|
||||
LogUtil.print("getGenerateInfo",
|
||||
"doFailure=$msg request=${generalInfoRequest.toJson()}")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun getNewOrder(context : Context) {
|
||||
val newOrderRequestBean = NewOrderRequestBean(GlobalData.vehicleInfo?.vehicleId)
|
||||
RetrofitHelper.getDefaultService().getNewOrder(newOrderRequestBean)
|
||||
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BaseObserver<JpushBean>() {
|
||||
override fun doSuccess(order : JpushBean?) {
|
||||
NewOrderActivity.goNewOrderActivity(context,
|
||||
jpushBean = JpushBean(taskId = order?.taskId,
|
||||
taskCode = order?.taskCode,
|
||||
customerName = order?.customerName,
|
||||
customerPhone = order?.customerPhone,
|
||||
carBrand = order?.carBrand,
|
||||
carModel = order?.carModel,
|
||||
carNo = order?.carNo,
|
||||
taskState = order?.taskState,
|
||||
address = order?.address,
|
||||
addressProperty = order?.addressProperty,
|
||||
hotline = order?.hotline,
|
||||
expectArriveTime = order?.expectArriveTime,
|
||||
serviceTypeName = order?.serviceTypeName,
|
||||
dispatchTime = order?.dispatchTime,
|
||||
lat = order?.lat,
|
||||
lng = order?.lng,
|
||||
distLat = order?.distLat,
|
||||
distLng = order?.distLng,
|
||||
importantTip = order?.importantTip,
|
||||
hasReplaceBatteryCapable = order?.hasReplaceBatteryCapable,
|
||||
distAddress = order?.distAddress,
|
||||
distAddressRemark = order?.distAddressRemark,
|
||||
addressRemark = order?.addressRemark,
|
||||
voiceType = order?.voiceType))
|
||||
}
|
||||
|
||||
override fun doFailure(code : Int, msg : String?) {
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun queryOrderList(context : Context? = null,
|
||||
success : (OrderInfo?, List<OrderInfo>?) -> Unit,
|
||||
failed : (String?) -> Unit) {
|
||||
RetrofitHelper.getDefaultService()
|
||||
.queryOrderList(OrderListRequest(vehicleId = GlobalData.vehicleInfo?.vehicleId,
|
||||
deviceId = DeviceUtil.getAndroidId(ActivityUtils.getTopActivity())))
|
||||
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BaseObserver<List<OrderInfo>?>() {
|
||||
override fun doSuccess(it : List<OrderInfo>?) {
|
||||
LogUtil.print("queryOrderList", "${it.toJson()}")
|
||||
if (it.isNullOrEmpty()) {
|
||||
GlobalData.clearAllOrderCache()
|
||||
ReportFloatingManager.stopService()
|
||||
success(null, null)
|
||||
return
|
||||
}
|
||||
|
||||
val inServicingOrder = it.find { it.isCurrent == true }
|
||||
val waitServiceOrders = it.filter { it.isCurrent == false }
|
||||
|
||||
if (inServicingOrder == null) {
|
||||
context?.let { context ->
|
||||
val order = it[0]
|
||||
NewOrderActivity.goNewOrderActivity(context,
|
||||
jpushBean = JpushBean(taskId = order.taskId,
|
||||
taskCode = order.taskCode,
|
||||
customerName = order.customerName,
|
||||
customerPhone = order.customerPhone,
|
||||
carBrand = order.carBrand,
|
||||
carModel = order.carModel,
|
||||
carNo = order.carNo,
|
||||
taskState = order.taskState,
|
||||
address = order.address,
|
||||
addressProperty = order.addressProperty,
|
||||
hotline = order.hotline,
|
||||
expectArriveTime = order.expectArriveTime,
|
||||
serviceTypeName = order.serviceTypeName,
|
||||
dispatchTime = order.dispatchTime,
|
||||
lat = order.lat,
|
||||
lng = order.lng,
|
||||
distLat = order.distLat,
|
||||
distLng = order.distLng,
|
||||
importantTip = order.importantTip,
|
||||
hasReplaceBatteryCapable = order.hasReplaceBatteryCapable,
|
||||
distAddress = order.distAddress,
|
||||
distAddressRemark = order.distAddressRemark,
|
||||
addressRemark = order.addressRemark))
|
||||
}
|
||||
success(null, waitServiceOrders)
|
||||
return
|
||||
}
|
||||
|
||||
GlobalData.currentOrder = inServicingOrder
|
||||
it.forEach {
|
||||
if (RoomHelper.db?.orderDao()
|
||||
?.getOrderInfoFromTaskId(it.taskId ?: 0) != null
|
||||
) {
|
||||
RoomHelper.db?.orderDao()?.update(orderInfo = it)
|
||||
} else {
|
||||
RoomHelper.db?.orderDao()?.insertOrder(orderInfo = it)
|
||||
}
|
||||
}
|
||||
fetchPhotoTemplate(inServicingOrder)
|
||||
queryElectronOrder(orderInfo = inServicingOrder)
|
||||
WaterMarkerTemplateManager.fetchWaterTemplate(inServicingOrder.taskCode ?: "",
|
||||
taskId = inServicingOrder.taskId ?: 0,
|
||||
inServicingOrder.userOrderId ?: 0)
|
||||
OfflineManager.start(GlobalData.currentOrder?.taskId)
|
||||
|
||||
context?.let {
|
||||
ReportFloatingManager.startService(it)
|
||||
}
|
||||
|
||||
success(inServicingOrder, waitServiceOrders)
|
||||
}
|
||||
|
||||
override fun doFailure(code : Int, msg : String?) {
|
||||
val list = RoomHelper.db?.orderDao()?.getAllOrder()
|
||||
val inServicingOrder = list?.find { it.isCurrent == true }
|
||||
val waitServiceOrders = list?.filter { it.isCurrent == false }
|
||||
GlobalData.currentOrder = inServicingOrder
|
||||
success(inServicingOrder, waitServiceOrders)
|
||||
OfflineManager.start(GlobalData.currentOrder?.taskId)
|
||||
LogUtil.print("queryOrderList", "queryOrderList failed 是用离线数据==$msg")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun fetchPhotoTemplate(orderInfo : OrderInfo?,
|
||||
success : () -> Unit = {},
|
||||
failed : (String?) -> Unit = {}) {
|
||||
val photoTemplateRequest = PhotoTemplateRequest(orderInfo?.userOrderId)
|
||||
RetrofitHelper.getDefaultService().fetchPhotoTemplate(photoTemplateRequest)
|
||||
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BaseObserver<List<PhotoTemplateInfo>>() {
|
||||
override fun doSuccess(it : List<PhotoTemplateInfo>?) {
|
||||
if (it.isNullOrEmpty()) {
|
||||
LogUtil.print("fetchPhotoTemplate",
|
||||
"模板为null ${photoTemplateRequest.toJson()}")
|
||||
failed("未找到模版")
|
||||
return
|
||||
}
|
||||
|
||||
val listData = RoomHelper.db?.photoTemplateDao()
|
||||
?.queryCurrentOrderHasTaskNode(orderInfo?.userOrderId ?: 0)
|
||||
if (! listData.isNullOrEmpty()) {
|
||||
LogUtil.print("queryPhotoTemplate", "模板已经存在==${listData.toJson()}")
|
||||
success()
|
||||
return
|
||||
}
|
||||
|
||||
it.forEachIndexed { _, item ->
|
||||
val photoTemplateInfo = item.copy(userOrderId = orderInfo?.userOrderId,
|
||||
taskCode = orderInfo?.taskCode,
|
||||
myCustomPhotoType = Const.PhotoType.InServicing,
|
||||
advanceTime = orderInfo?.advanceTime,
|
||||
taskId = orderInfo?.taskId,
|
||||
needWaterMarker = orderInfo?.needWaterMarker,
|
||||
needShowPhoneBrand = orderInfo?.needShowPhoneBrand,
|
||||
photoSource = 0)
|
||||
RoomHelper.db?.photoTemplateDao()?.insert(photoTemplateInfo)
|
||||
}
|
||||
LogUtil.print("fetchPhotoTemplate", " ${it.toJson()}")
|
||||
success()
|
||||
}
|
||||
|
||||
override fun doFailure(code : Int, msg : String?) {
|
||||
LogUtil.print("fetchPhotoTemplate", "err==$msg")
|
||||
failed(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun queryElectronOrder(orderInfo : OrderInfo?,
|
||||
success : (EleWorkOrderBean) -> Unit = {},
|
||||
failed : (String?) -> Unit = {}) {
|
||||
val ele = RoomHelper.db?.eleWorkOrderDao()?.getEleWorkOrder(taskId = orderInfo?.taskId ?: 0)
|
||||
if (ele != null) {
|
||||
success(ele)
|
||||
return
|
||||
}
|
||||
val queryEleOrderRequest = QueryEleOrderRequest(taskOrderId = orderInfo?.taskId,
|
||||
userOrderId = orderInfo?.userOrderId)
|
||||
RetrofitHelper.getDefaultService().queryElectronOrder(queryEleOrderRequest)
|
||||
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BaseObserver<ElectronOrderResponse>() {
|
||||
override fun doSuccess(it : ElectronOrderResponse?) {
|
||||
val temp = EleWorkOrderBean(orderId = orderInfo?.taskId ?: 0,
|
||||
userOrderId = it?.userOrderId,
|
||||
date = it?.createTime,
|
||||
orderWorkStatus = it?.state,
|
||||
hasBad = it?.hasDamage == 1,
|
||||
serverCustomSignPath = it?.customerSignPath,
|
||||
carNO = it?.plateNumberBean?.value,
|
||||
carVin = it?.vinNo,
|
||||
serviceContent = it?.serviceTerm,
|
||||
serverAcceptCarSignPath = it?.recipientSignPath,
|
||||
serverServicePeopleSignPath = it?.waitstaffSignPath,
|
||||
orderType = it?.serviceName)
|
||||
it?.damageFileList?.forEach { item ->
|
||||
val damagePhotoBean = EleCarDamagePhotoBean(userOrderId = it.userOrderId,
|
||||
orderId = orderInfo?.taskId,
|
||||
isPhoto = true,
|
||||
uploadStatus = 1,
|
||||
serverPath = item)
|
||||
RoomHelper.db?.eleCarDamagePhotoDao()?.insert(damagePhotoBean)
|
||||
}
|
||||
RoomHelper.db?.eleWorkOrderDao()?.insertEleWorkOrder(temp)
|
||||
success(temp)
|
||||
}
|
||||
|
||||
override fun doFailure(code : Int, msg : String?) {
|
||||
failed(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
347
servicing/src/main/java/com/za/net/RSAUtils.java
Normal file
347
servicing/src/main/java/com/za/net/RSAUtils.java
Normal file
@ -0,0 +1,347 @@
|
||||
package com.za.net;
|
||||
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Signature;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
public class RSAUtils {
|
||||
|
||||
/**
|
||||
* 加密算法RSA
|
||||
*/
|
||||
private static final String KEY_ALGORITHM = "RSA";
|
||||
|
||||
/**
|
||||
* 签名算法
|
||||
*/
|
||||
// public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
|
||||
private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
|
||||
|
||||
/**
|
||||
* 获取公钥的key
|
||||
*/
|
||||
private static final String PUBLIC_KEY = "RSAPublicKey";
|
||||
|
||||
|
||||
/**
|
||||
* 获取私钥的key
|
||||
*/
|
||||
private static final String PRIVATE_KEY = "RSAPrivateKey";
|
||||
|
||||
|
||||
/**
|
||||
* RSA最大加密明文大小
|
||||
*/
|
||||
private static final int MAX_ENCRYPT_BLOCK = 117;
|
||||
|
||||
|
||||
/**
|
||||
* RSA最大解密密文大小
|
||||
*/
|
||||
private static final int MAX_DECRYPT_BLOCK = 256;
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// try {
|
||||
// genKeyPair(2048);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
/*RSA 2048*/
|
||||
// String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAichGTEP0QFswnvn+ZAQrgGHM8VeDZLJuezGhgxh4d9SyRUfnIW/zefT71rwS4bZUs1MPxJwavOyxABJOHLuckdHXknCsGEWz78gsA6D0+O+9dl1gCZR29nnN/NlzmNbSjFnzvsTJYBlS88qSr35RXFE+6DM7uPsS8Fm2I+65FteJ8p2yMvpSg72QkIX8xvI1F1uwXrciIB+4u7uTozxIplMOo4a6uhAm3W+Kjpz3ni2btjGqHRbqb3ebSZyl+nFfnjQaBe3XyVxAWDSanjgFj/wbqbeug9FBs+nQFVPIZR9z0aE5Ndi5o3eSkV7HFmWpkxaiPZ0BLRK3XHMaBtuSpwIDAQAB";
|
||||
// String privateKey = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCJyEZMQ/RAWzCe+f5kBCuAYczxV4Nksm57MaGDGHh31LJFR+chb/N59PvWvBLhtlSzUw/EnBq87LEAEk4cu5yR0deScKwYRbPvyCwDoPT47712XWAJlHb2ec382XOY1tKMWfO+xMlgGVLzypKvflFcUT7oMzu4+xLwWbYj7rkW14nynbIy+lKDvZCQhfzG8jUXW7BetyIgH7i7u5OjPEimUw6jhrq6ECbdb4qOnPeeLZu2MaodFupvd5tJnKX6cV+eNBoF7dfJXEBYNJqeOAWP/Bupt66D0UGz6dAVU8hlH3PRoTk12Lmjd5KRXscWZamTFqI9nQEtErdccxoG25KnAgMBAAECggEBAIPz1b88ZTMtIgdejA7lH3Q4Nbn8gc1yRPSet3uBd/3rKT/IeMZBHQBzaqxgOgUIRV3n8nXsun6sf2b+IOjLlErimH2agnZMauL85YokH/g4QU6WZl9GXBf41xmMd3SsZ8AadaEBfYoXNqZcHtcLNogfFwvx5QRnD+A3SoRnH8OLBeVvOEe4AqHLT2xEZ9TeCf3fJe0Rf0fUIbw7I5ioiRZV/ir0L1VM7+1k2JODUkdC2Luj5Tl3nl1Eg6EmkYCmGE1bip1NAatsfjPBLMF7XdPNjLboiffjgKVBOjb7Y9vL18BCoLtWeTT2GkMpi5Sr94T1te1Ox77dF4BP33Xn7eECgYEA1TNUrAQsh14NbbkwFtUHXS8/YXt81p9wbSpFBymIawF2Lkk0913TB4CHSun45LhYXjdZZxK/TgqC5EIq5v2RA0jY3cSxoqVe6RZKB04E8wszeJHiEJPdu2vFnpZh9iAyhswiM5FmuKZKoWsVc2SZrBXAI02smSn3lXYok1VBS3sCgYEApXEZS6gjUu4o7ZL53Ur1HDfi/nxpkxqrPh+D1HVYjzjT+4vTeZwtLXt2VCInPWNXH+f11mzhxIrLkI0jMcSCah81DuU8aFXnqvPuyFvt9uaQBYlVWBtkcGZyeaxHFrbfCyeu0jm7SfwmiIg12hKlIHtPTjEZQUX+kkWr8cdaZ8UCgYEAh0Pl+K09QzVc97yC0jmeTnTnlYWvksvdnKUw3nZvYtSukndH75nLhfr524HOs+5xwnUDd+3hCjaJDSEd7yf5lUfmr+1XdoXNTb0igrfxU/JLWbfU4geuqnaaDyACTxHmfLePC4C413ZJ61fxaCDvjsrN+JgTZanGt0EcRT3WC3kCgYEAgf5/GMJxlw0JXbs515a5R8Xl9358Whj/at3KcRsPTeIiNqnkrc54dR9ol60KViMDZ0+VDDobn5pLXzZ26/jzXD1PLHgU4gp18Q6glhAdx/3cNm11gLhtUCA/XLlwVjm0wggZRpgUQIr/IBKe9c3mr8IUS2Uq6e38nKRf+adhst0CgYAM4tvl+U1MPbbz3YzDv8QPepZ7Pglgdfxqfr5OkXA7jNhqTZjSq10B6oClGvirBo1m6f26F02iUKk1n67AuiLlTP/RRZHi1cfq6P9IaXl23PcxJfUMvIxQDS0U+UTFpNXryTw/qNAkSfufN48YzKdGvc8vHrYJyaeemaVlbdJOCw==";
|
||||
//
|
||||
//
|
||||
// try {
|
||||
//
|
||||
// String data = "测试提交数据";
|
||||
//
|
||||
// byte[] publicEncryptBytes = RSAUtils.encryptByPublicKey(data.getBytes(), publicKey);
|
||||
// System.out.println("公钥加密后的数据:" + Base64.encodeToString(publicEncryptBytes, Base64.URL_SAFE | Base64.NO_WRAP));
|
||||
// byte[] privatDecryptBytes = RSAUtils.decryptByPrivateKey(publicEncryptBytes, privateKey);
|
||||
// System.out.println("私钥解密后的数据:" + new String(privatDecryptBytes));
|
||||
//
|
||||
//
|
||||
// System.out.println("--------------------");
|
||||
//
|
||||
// byte[] privateKeyEncryptBytes = RSAUtils.encryptByPrivateKey(data.getBytes(), privateKey);
|
||||
// System.out.println("私钥加密后的数据:" + Base64.encodeToString(privateKeyEncryptBytes, Base64.URL_SAFE | Base64.NO_WRAP));
|
||||
//
|
||||
// String singnData = RSAUtils.sign(data.getBytes(), privateKey);
|
||||
// System.out.println("私钥签名后的数据:" + singnData);
|
||||
//
|
||||
//
|
||||
// byte[] publicDecryptBytes = RSAUtils.decryptByPublicKey(privateKeyEncryptBytes, publicKey);
|
||||
// System.out.println("公钥解密后的数据:" + new String(publicDecryptBytes));
|
||||
//
|
||||
// boolean isSign = RSAUtils.verify(data.getBytes(), publicKey, singnData);
|
||||
// System.out.println("签名是否正确:" + isSign);
|
||||
//
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param keySize 生成的秘钥长度 一般为1024或2048
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Map<String, Object> genKeyPair(int keySize) throws Exception {
|
||||
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
|
||||
keyPairGen.initialize(keySize);
|
||||
KeyPair keyPair = keyPairGen.generateKeyPair();
|
||||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
Map<String, Object> keyMap = new HashMap<String, Object>(2);
|
||||
keyMap.put(PUBLIC_KEY, publicKey);
|
||||
keyMap.put(PRIVATE_KEY, privateKey);
|
||||
|
||||
// Log.d("DoggieX","publicKey:" + Base64.encodeToString(publicKey.getEncoded(), Base64.URL_SAFE | Base64.NO_WRAP));
|
||||
// Log.d("DoggieX","privateKey:" + Base64.encodeToString(privateKey.getEncoded(), Base64.URL_SAFE | Base64.NO_WRAP));
|
||||
Log.d("DoggieX","publicKey:" + Base64.encodeToString(publicKey.getEncoded(), Base64.NO_WRAP));
|
||||
Log.d("DoggieX","privateKey:" + Base64.encodeToString(privateKey.getEncoded(), Base64.NO_WRAP));
|
||||
|
||||
return keyMap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对已加密数据进行签名
|
||||
*
|
||||
* @param data 已加密的数据
|
||||
* @param privateKey 私钥
|
||||
* @return 对已加密数据生成的签名
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
public static String sign(byte[] data, String privateKey) throws Exception {
|
||||
byte[] keyBytes = Base64.decode(privateKey, Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
||||
signature.initSign(privateK);
|
||||
signature.update(data);
|
||||
return Base64.encodeToString(signature.sign(), Base64.URL_SAFE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验签
|
||||
*
|
||||
* @param data 签名之前的数据
|
||||
* @param publicKey 公钥
|
||||
* @param sign 签名之后的数据
|
||||
* @return 验签是否成功
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
|
||||
byte[] keyBytes = Base64.decode(publicKey, Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
PublicKey publicK = keyFactory.generatePublic(keySpec);
|
||||
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
|
||||
signature.initVerify(publicK);
|
||||
signature.update(data);
|
||||
return signature.verify(Base64.decode(sign, Base64.URL_SAFE));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用私钥对数据进行解密
|
||||
*
|
||||
* @param encryptedData 使用公钥加密过的数据
|
||||
* @param privateKey 私钥
|
||||
* @return 解密后的数据
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
|
||||
byte[] keyBytes = Base64.decode(privateKey, Base64.NO_WRAP);
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||
//Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding","BC");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateK);
|
||||
Log.d("DoggieX","provider:"+cipher.getProvider().getClass().getName());
|
||||
|
||||
int inputLen = encryptedData.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段解密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_DECRYPT_BLOCK;
|
||||
}
|
||||
byte[] decryptedData = out.toByteArray();
|
||||
out.close();
|
||||
|
||||
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 公钥解密
|
||||
*
|
||||
* @param encryptedData 使用私钥加密过的数据
|
||||
* @param publicKey 公钥
|
||||
* @return 解密后的数据
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
|
||||
byte[] keyBytes = Base64.decode(publicKey, Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
cipher.init(Cipher.DECRYPT_MODE, publicK);
|
||||
int inputLen = encryptedData.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段解密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_DECRYPT_BLOCK;
|
||||
}
|
||||
byte[] decryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return decryptedData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 公钥加密
|
||||
*
|
||||
* @param data 需要加密的数据
|
||||
* @param publicKey 公钥
|
||||
* @return 使用公钥加密后的数据
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
|
||||
byte[] keyBytes = Base64.decode(publicKey, Base64.NO_WRAP);
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key publicK = keyFactory.generatePublic(x509KeySpec);
|
||||
// 对数据加密
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding","BC");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicK);
|
||||
Log.d("DoggieX",cipher.getProvider().getClass().toString());
|
||||
int inputLen = data.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段加密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||
}
|
||||
byte[] encryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return encryptedData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 私钥加密
|
||||
*
|
||||
* @param data 待加密的数据
|
||||
* @param privateKey 私钥
|
||||
* @return 使用私钥加密后的数据
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
|
||||
byte[] keyBytes = Base64.decode(privateKey, Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
||||
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, privateK);
|
||||
int inputLen = data.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段加密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||
}
|
||||
byte[] encryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return encryptedData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取私钥
|
||||
*
|
||||
* @param keyMap 生成的秘钥对
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
|
||||
Key key = (Key) keyMap.get(PRIVATE_KEY);
|
||||
return Base64.encodeToString(key.getEncoded(), Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取公钥
|
||||
*
|
||||
* @param keyMap 生成的秘钥对
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
|
||||
Key key = (Key) keyMap.get(PUBLIC_KEY);
|
||||
return Base64.encodeToString(key.getEncoded(), Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package com.za.net;
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.za.common.GlobalData;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okio.Buffer;
|
||||
|
||||
/**
|
||||
* @author DoggieX
|
||||
* @create 2021/8/23 15:00
|
||||
* @mail coldpuppy@163.com
|
||||
*/
|
||||
public class RequestEncryptInterceptor implements Interceptor {
|
||||
|
||||
static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7UM6zdWdBuO0DZZVkxVfJioawUe6qH1p5Uz/qR9zbawl2oWyxxcBfxQyPS+HxOej/ZnyS4bu7qhh99alDqkJzk6g9oGZWs+jEF5GRWt9nChlfUsjvHQwuF2TSQMTdPtDPCByF/QgMFCAfbCqTrNmOETrZ/2GFy1Re0BTlhh6X/XzpzqtK+enikEMlQ5fIM5ljdXgyCnvDou9ptWqzw8Zmsat6LeA0UKz+bgpJAbw6KfK+8lPMqUpNFfkmJuEd5+JQOG9McH7j9pBagohkC6k3Cn92dAf9iD6NSDKSNgt1vxXhaNnfAbYJ5pqeSGy6QMSVO0TXYj4asln5OutD/284QIDAQAB";
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Response intercept(@NonNull Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
String method = request.method().toLowerCase().trim();
|
||||
HttpUrl url = request.url();
|
||||
boolean skipEncrypt = url.encodedPath().endsWith("appVersion")
|
||||
|| url.encodedPath().endsWith("getVerifyCode")
|
||||
|| url.encodedPath().endsWith("listVehicleNew")
|
||||
|| url.encodedPath().endsWith("getExitMileage")
|
||||
|| url.encodedPath().endsWith("uploadImage")
|
||||
|| url.encodedPath().endsWith("upload")
|
||||
|| url.encodedPath().endsWith("matchAppUploadTime");
|
||||
|
||||
if (method.equals("post") && !skipEncrypt) {
|
||||
RequestBody body = request.body();
|
||||
if (null != body) {
|
||||
Buffer buffer = new Buffer();
|
||||
body.writeTo(buffer);
|
||||
String data = URLDecoder.decode(buffer.readString(StandardCharsets.UTF_8), "utf-8");
|
||||
JSONObject jsonObject = JSON.parseObject(data);
|
||||
if (null == jsonObject) {
|
||||
jsonObject = new JSONObject();
|
||||
}
|
||||
jsonObject.put("requestTime", System.currentTimeMillis());
|
||||
data = jsonObject.toJSONString();
|
||||
|
||||
String aesKey;
|
||||
try {
|
||||
if (url.encodedPath().endsWith("login")
|
||||
|| url.encodedPath().endsWith("fastLogin")) {
|
||||
// 登录接口生成新key
|
||||
aesKey = AESUtils.getRandomKey(16);
|
||||
GlobalData.INSTANCE.setAesKey(aesKey);
|
||||
} else {
|
||||
|
||||
aesKey = GlobalData.INSTANCE.getAesKey();
|
||||
if (null == aesKey && url.encodedPath().endsWith("loginWithTask")) {
|
||||
aesKey = AESUtils.getRandomKey(16);
|
||||
GlobalData.INSTANCE.setAesKey(aesKey);
|
||||
} else if (null == aesKey) {
|
||||
throw new IOException("缺失加密密钥");
|
||||
} else {
|
||||
aesKey = GlobalData.INSTANCE.getAesKey();
|
||||
}
|
||||
}
|
||||
if (!url.encodedPath().endsWith("login")
|
||||
&& !url.encodedPath().endsWith("fastLogin")
|
||||
&& !url.encodedPath().endsWith("loginWithTask")) {
|
||||
|
||||
data = AESUtils.encrypt(data, aesKey);
|
||||
}
|
||||
RequestBody requestBody = RequestBody.create(body.contentType(), data);
|
||||
Request.Builder requestBuilder = request.newBuilder().post(requestBody);
|
||||
|
||||
if (url.encodedPath().endsWith("login")
|
||||
|| url.encodedPath().endsWith("fastLogin")
|
||||
|| url.encodedPath().endsWith("loginWithTask")) {
|
||||
|
||||
byte[] bytes = RSAUtils.encryptByPublicKey(aesKey.getBytes(StandardCharsets.UTF_8), PUBLIC_KEY);
|
||||
String tokenSecret = Base64.encodeToString(bytes, Base64.NO_WRAP);
|
||||
requestBuilder.addHeader("secret", tokenSecret);
|
||||
} else {
|
||||
String token = GlobalData.INSTANCE.getToken();
|
||||
if (null == token) {
|
||||
throw new IOException("缺失token");
|
||||
} else {
|
||||
requestBuilder.addHeader("token", token);
|
||||
}
|
||||
}
|
||||
request = requestBuilder.build();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return chain.proceed(request);
|
||||
}
|
||||
}
|
83
servicing/src/main/java/com/za/net/RetrofitHelper.kt
Normal file
83
servicing/src/main/java/com/za/net/RetrofitHelper.kt
Normal file
@ -0,0 +1,83 @@
|
||||
package com.za.net
|
||||
|
||||
import android.util.Log
|
||||
import com.za.base.AppConfig
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import java.io.UnsupportedEncodingException
|
||||
import java.net.URLDecoder
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object RetrofitHelper {
|
||||
private var retrofit: Retrofit? = null
|
||||
private var apiService: ApiService? = null
|
||||
private val loggerInterceptor = HttpLoggingInterceptor {
|
||||
try {
|
||||
|
||||
if (it.contains("image/*") || it.contains("form-data; name=\"file\"")
|
||||
|| it.startsWith("Content-Type")
|
||||
|| it.startsWith("Content-Length")
|
||||
|| it.startsWith("Server")
|
||||
|| it.startsWith("Date")
|
||||
|| it.startsWith("Transfer-Encoding")
|
||||
|| it.startsWith("Connection")
|
||||
|| it.startsWith("X-")
|
||||
|| it.startsWith("token")
|
||||
|| it.startsWith("Cache-Control")
|
||||
|| it.startsWith("Expires")
|
||||
|| it.startsWith("Accept")
|
||||
|| it.startsWith("Vary")
|
||||
|| it.isEmpty()
|
||||
|| it.startsWith("Pragma")
|
||||
) {
|
||||
return@HttpLoggingInterceptor
|
||||
}
|
||||
|
||||
if (it.contains("name=\"file\"; filename")) {
|
||||
return@HttpLoggingInterceptor
|
||||
}
|
||||
Log.e(
|
||||
"--network--",
|
||||
URLDecoder.decode(it.replace(Regex("%(?![0-9a-fA-F]{2})"), ""), "utf-8")
|
||||
)
|
||||
} catch (e: UnsupportedEncodingException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}.setLevel(HttpLoggingInterceptor.Level.BODY)
|
||||
|
||||
fun getDefaultService(): ApiService {
|
||||
return if (apiService == null) {
|
||||
apiService = getDefaultRetrofit().create(ApiService::class.java)
|
||||
apiService!!
|
||||
} else {
|
||||
apiService!!
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDefaultRetrofit(): Retrofit {
|
||||
return if (retrofit == null) {
|
||||
retrofit = Retrofit.Builder().baseUrl(AppConfig.BASE_URL)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
|
||||
.client(getOkHttpClient())
|
||||
.build()
|
||||
retrofit!!
|
||||
} else {
|
||||
retrofit!!
|
||||
}
|
||||
}
|
||||
|
||||
private fun getOkHttpClient(): OkHttpClient {
|
||||
return OkHttpClient.Builder()
|
||||
.connectTimeout(30, TimeUnit.SECONDS)
|
||||
.writeTimeout(60, TimeUnit.SECONDS)
|
||||
.readTimeout(60, TimeUnit.SECONDS)
|
||||
.addInterceptor(RequestEncryptInterceptor())
|
||||
.addInterceptor(loggerInterceptor)
|
||||
.build()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user