登录
This commit is contained in:
parent
b679d45fc4
commit
9f2bf7c53a
@ -19,6 +19,7 @@ import com.navinfo.outdoor.http.Callback;
|
||||
import com.navinfo.outdoor.http.HttpInterface;
|
||||
import com.navinfo.outdoor.http.OkGoBuilder;
|
||||
import com.navinfo.outdoor.util.Base64;
|
||||
import com.navinfo.outdoor.util.Md5Util;
|
||||
|
||||
/**
|
||||
* 登录页
|
||||
@ -43,11 +44,11 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
|
||||
@Override
|
||||
protected void initView() {
|
||||
super.initView();
|
||||
tvRegister = (TextView) findViewById(R.id.tv_register);
|
||||
etLoginName = (EditText) findViewById(R.id.et_login_name);
|
||||
etLoginPaw = (EditText) findViewById(R.id.et_login_paw);
|
||||
tvForgetPaw = (TextView) findViewById(R.id.tv_forget_paw);
|
||||
btnLogin = (Button) findViewById(R.id.btn_login);
|
||||
tvRegister = findViewById(R.id.tv_register);
|
||||
etLoginName = findViewById(R.id.et_login_name);
|
||||
etLoginPaw = findViewById(R.id.et_login_paw);
|
||||
tvForgetPaw = findViewById(R.id.tv_forget_paw);
|
||||
btnLogin = findViewById(R.id.btn_login);
|
||||
btnLogin.setOnClickListener(this::onClick);
|
||||
tvRegister.setOnClickListener(this);
|
||||
tvForgetPaw.setOnClickListener(this);
|
||||
@ -68,12 +69,12 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
|
||||
break;
|
||||
case R.id.btn_login:
|
||||
String name = etLoginName.getText().toString().trim();
|
||||
if (name == null) {
|
||||
if (name == null||name.equals("")) {
|
||||
Toast.makeText(this, "请输入账号", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
String paw = etLoginPaw.getText().toString().trim();
|
||||
if (paw == null) {
|
||||
if (paw == null||paw.equals("")) {
|
||||
Toast.makeText(this, "请输入密码", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
@ -83,35 +84,40 @@ public class LoginActivity extends BaseActivity implements View.OnClickListener
|
||||
}
|
||||
|
||||
private void initLogIn(String name, String paw) {
|
||||
HttpParams httpParams = new HttpParams();
|
||||
try {
|
||||
HttpParams httpParams = new HttpParams();
|
||||
httpParams.put("username",name);
|
||||
long time=System.currentTimeMillis();
|
||||
httpParams.put("grant_type",Base64.desEncrypt(time + MD5.md5sum(paw)));
|
||||
httpParams.put("password",Base64.desEncrypt(time + Md5Util.toMD5(paw)));
|
||||
httpParams.put("grant_type","password");
|
||||
httpParams.put("datetime",time);
|
||||
showLoadingDialog();
|
||||
OkGoBuilder.getInstance().Builder(this)
|
||||
.url(HttpInterface.USER_LOGIN_OAUTH_TOKEN)
|
||||
.cls(LoginOauthTokenBean.class)
|
||||
.params(httpParams)
|
||||
.postRequest(new Callback<LoginOauthTokenBean>() {
|
||||
@Override
|
||||
public void onSuccess(LoginOauthTokenBean response, int id) {
|
||||
dismissLoadingDialog();
|
||||
Toast.makeText(LoginActivity.this, response.getMessage() + "", Toast.LENGTH_SHORT).show();
|
||||
if (response.getCode()==200){
|
||||
|
||||
Intent intent = new Intent(LoginActivity.this, HomeActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onError(Throwable e, int id) {
|
||||
dismissLoadingDialog();
|
||||
Toast.makeText(LoginActivity.this, e.getMessage()+"", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
showLoadingDialog();
|
||||
OkGoBuilder.getInstance().Builder(this)
|
||||
.url(HttpInterface.USER_LOGIN_OAUTH_TOKEN)
|
||||
.cls(LoginOauthTokenBean.class)
|
||||
.params(httpParams)
|
||||
.postRequest(new Callback<LoginOauthTokenBean>() {
|
||||
@Override
|
||||
public void onSuccess(LoginOauthTokenBean response, int id) {
|
||||
dismissLoadingDialog();
|
||||
Toast.makeText(LoginActivity.this, response.getMessage() + "", Toast.LENGTH_SHORT).show();
|
||||
Intent intent = new Intent(LoginActivity.this, HomeActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e, int id) {
|
||||
dismissLoadingDialog();
|
||||
Toast.makeText(LoginActivity.this, e.getMessage()+"", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -44,6 +44,19 @@ public class Constant {
|
||||
|
||||
public static final String DATA_FILE = "dataFile";
|
||||
|
||||
/**
|
||||
* 存储用户信息
|
||||
* access_token 后续需求需要用到的key 过期时间8小时
|
||||
* refresh_token 刷新token用 过期时间1个月
|
||||
* userId 用户id
|
||||
* username 用户编号
|
||||
*/
|
||||
public static final String access_token=null;
|
||||
public static final String refresh_token=null;
|
||||
public static final String userId=null;
|
||||
public static final String username=null;
|
||||
|
||||
|
||||
|
||||
//message word 值
|
||||
public static final int TREASURE_FRAGMENT = 100;//抽屉界面的展示和隐藏
|
||||
|
@ -79,11 +79,11 @@ public class UserApplication extends Application {
|
||||
//builder.cookieJar(new CookieJarImpl(new MemoryCookieStore()));
|
||||
//超时时间设置,默认60秒
|
||||
//全局的读取超时时间
|
||||
builder.readTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
|
||||
builder.readTimeout(5000, TimeUnit.MILLISECONDS);
|
||||
//全局的写入超时时间
|
||||
builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
|
||||
builder.writeTimeout(5000, TimeUnit.MILLISECONDS);
|
||||
//全局的连接超时时间
|
||||
builder.connectTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
|
||||
builder.connectTimeout(5000, TimeUnit.MILLISECONDS);
|
||||
OkGo.getInstance().init(this)
|
||||
.setOkHttpClient(builder.build())
|
||||
//全局统一缓存模式,默认不使用缓存,可以不传
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.navinfo.outdoor.bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LoginOauthTokenBean {
|
||||
/**
|
||||
* code : 100
|
||||
@ -8,6 +10,7 @@ public class LoginOauthTokenBean {
|
||||
|
||||
private int code;
|
||||
private String message;
|
||||
private BodyBean body;
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
@ -24,4 +27,57 @@ public class LoginOauthTokenBean {
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public BodyBean getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(BodyBean body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public static class BodyBean {
|
||||
/**
|
||||
* access_token 后续需求需要用到的key 过期时间8小时
|
||||
* * refresh_token 刷新token用 过期时间1个月
|
||||
* * userId 用户id
|
||||
* * username 用户编号
|
||||
* */
|
||||
private String access_token;
|
||||
private String refresh_token;
|
||||
private String userId;
|
||||
private String username;
|
||||
|
||||
public String getAccess_token() {
|
||||
return access_token;
|
||||
}
|
||||
|
||||
public void setAccess_token(String access_token) {
|
||||
this.access_token = access_token;
|
||||
}
|
||||
|
||||
public String getRefresh_token() {
|
||||
return refresh_token;
|
||||
}
|
||||
|
||||
public void setRefresh_token(String refresh_token) {
|
||||
this.refresh_token = refresh_token;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ public class HttpInterface {
|
||||
|
||||
public static final String IPm8 = "http://172.23.139.4:9999/m4/";
|
||||
//http://172.23.139.4:9999/m4/userlogin/oauth/token
|
||||
public static final String USER_LOGIN_OAUTH_TOKEN = IPm7 + "userlogin/oauth/token"; //登录
|
||||
public static final String USER_LOGIN_OAUTH_TOKEN = IPm8 + "userlogin/oauth/token"; //登录
|
||||
|
||||
/**
|
||||
* 面状任务
|
||||
|
@ -8,15 +8,20 @@ import com.lzy.okgo.model.HttpParams;
|
||||
import com.lzy.okgo.model.Response;
|
||||
import com.lzy.okgo.request.PostRequest;
|
||||
import com.navinfo.outdoor.bean.PoiUploadBean;
|
||||
import com.navinfo.outdoor.util.Md5Util;
|
||||
import com.umeng.umcrash.UMCrash;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.RequestBody;
|
||||
|
||||
/**
|
||||
* 作用:OKGO帮助类-建造者模式
|
||||
*/
|
||||
@ -84,15 +89,16 @@ public class OkGoBuilder<T> {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public OkGoBuilder params(HttpParams params) {
|
||||
this.params = params;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OkGoBuilder token(String token) {
|
||||
this.token = token;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OkGoBuilder fileList(List<File> files) {
|
||||
this.files = files;
|
||||
return this;
|
||||
@ -110,69 +116,81 @@ public class OkGoBuilder<T> {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* post异步请求
|
||||
*/
|
||||
public void postRequest(Callback<T> callback) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
if (token==null){
|
||||
headers.put("Authorization","Basic YXBwOmFwcHNlY3JldA==");
|
||||
}else {
|
||||
headers.put("Authorization","bearer"+token);
|
||||
|
||||
}
|
||||
headers.put("key",null);
|
||||
OkGo
|
||||
// 请求方式和请求url
|
||||
.<T>post(url)
|
||||
.params(params)
|
||||
OkGo
|
||||
// 请求方式和请求url
|
||||
.<T>post(url)
|
||||
.isMultipart(true)
|
||||
.params(params)
|
||||
// .upJson(json)
|
||||
// 请求的 tag, 主要用于取消对应的请求
|
||||
.tag(this)
|
||||
.headers(headers)
|
||||
// 设置当前请求的缓存key,建议每个不同功能的请求设置一个
|
||||
// 请求的 tag, 主要用于取消对应的请求
|
||||
.tag(this)
|
||||
.headers(getHeader())
|
||||
// 设置当前请求的缓存key,建议每个不同功能的请求设置一个
|
||||
// .cacheKey("cacheKey")
|
||||
// 缓存模式,详细请看缓存介绍
|
||||
// 缓存模式,详细请看缓存介绍
|
||||
// .cacheMode(CacheMode.DEFAULT)
|
||||
.execute(new DialogCallback<T>(clazz) {
|
||||
@Override
|
||||
public void onSuccess(Response<T> response) {
|
||||
callback.onSuccess(response.body(), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Response<T> response) {
|
||||
super.onError(response);
|
||||
Throwable throwable = response.getException();
|
||||
if (throwable != null) {
|
||||
throwable.printStackTrace();
|
||||
callback.onError(throwable, 2);
|
||||
/**
|
||||
* 友盟+
|
||||
* 使用自定义错误,查看时请在错误列表页面选择【自定义异常】
|
||||
*/
|
||||
UMCrash.generateCustomLog("网络请求报错-位置:OKGOBuilder" + throwable, "UmengException");
|
||||
.execute(new DialogCallback<T>(clazz) {
|
||||
@Override
|
||||
public void onSuccess(Response<T> response) {
|
||||
callback.onSuccess(response.body(), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Response<T> response) {
|
||||
super.onError(response);
|
||||
Throwable throwable = response.getException();
|
||||
if (throwable != null) {
|
||||
throwable.printStackTrace();
|
||||
callback.onError(throwable, 2);
|
||||
/**
|
||||
* 友盟+
|
||||
* 使用自定义错误,查看时请在错误列表页面选择【自定义异常】
|
||||
*/
|
||||
UMCrash.generateCustomLog("网络请求报错-位置:OKGOBuilder" + throwable, "UmengException");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public HttpHeaders getHeader() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
try {
|
||||
if (token == null) {
|
||||
headers.put("Authorization", "Basic YXBwOmFwcHNlY3JldA==");
|
||||
} else {
|
||||
headers.put("Authorization", "bearer" + token);
|
||||
}
|
||||
String util = "";//k1=v1&k2=v2&k3=v3
|
||||
if (params != null && params.urlParamsMap != null) {
|
||||
for (Map.Entry<String, List<String>> entry : params.urlParamsMap.entrySet()) {
|
||||
if (!"file".equals(entry.getKey())) {
|
||||
util += entry.getKey() + "=" + entry.getValue().get(0).toString() + "&";
|
||||
}
|
||||
});
|
||||
}
|
||||
if (util != null && !util.equals("")) {
|
||||
util = util.substring(0, util.length() - 1);
|
||||
}
|
||||
}
|
||||
headers.put("key", Md5Util.toMD5("dtxb_2021_navinfo" + util));
|
||||
return headers;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* post 文件 同步请求
|
||||
*
|
||||
* @return
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public okhttp3.Response postFileSynchronization(int id) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
if (token==null){
|
||||
headers.put("Authorization","Basic YXBwOmFwcHNlY3JldA==");
|
||||
}else {
|
||||
headers.put("Authorization","bearer"+token);
|
||||
|
||||
}
|
||||
headers.put("key",null);
|
||||
try {
|
||||
okhttp3.Response execute = OkGo
|
||||
// 请求方式和请求url
|
||||
@ -180,7 +198,7 @@ public class OkGoBuilder<T> {
|
||||
// 请求的 tag, 主要用于取消对应的请求
|
||||
.params("auditId", id)
|
||||
.addFileParams("file", files)
|
||||
.headers(headers)
|
||||
.headers(getHeader())
|
||||
.tag(this)
|
||||
.execute();
|
||||
return execute;
|
||||
@ -194,25 +212,18 @@ public class OkGoBuilder<T> {
|
||||
/**
|
||||
* post 文件 异步请求
|
||||
*
|
||||
* @return
|
||||
* @param id
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
public void postFileAsynchronous(int id, Callback callback) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
if (token==null){
|
||||
headers.put("Authorization","Basic YXBwOmFwcHNlY3JldA==");
|
||||
}else {
|
||||
headers.put("Authorization","bearer"+token);
|
||||
|
||||
}
|
||||
headers.put("key",null);
|
||||
OkGo
|
||||
// 请求方式和请求url
|
||||
.<T>post(url)
|
||||
.params("auditId", id)
|
||||
.addFileParams("file", files)
|
||||
.headers(headers)
|
||||
.headers(getHeader())
|
||||
// .upJson(json)
|
||||
// 请求的 tag, 主要用于取消对应的请求
|
||||
.tag(this)
|
||||
@ -241,66 +252,53 @@ public class OkGoBuilder<T> {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get异步请求
|
||||
*/
|
||||
public void getRequest(Callback<T> callback) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
if (token==null){
|
||||
headers.put("Authorization","Basic YXBwOmFwcHNlY3JldA==");
|
||||
}else {
|
||||
headers.put("Authorization","bearer"+token);
|
||||
|
||||
}
|
||||
headers.put("key",null);
|
||||
OkGo
|
||||
// 请求方式和请求url
|
||||
.<T>get(url)
|
||||
.params(params)
|
||||
.headers(headers)
|
||||
// 请求的 tag, 主要用于取消对应的请求
|
||||
.tag(this)
|
||||
// 设置当前请求的缓存key,建议每个不同功能的请求设置一个
|
||||
OkGo
|
||||
// 请求方式和请求url
|
||||
.<T>get(url)
|
||||
.params(params)
|
||||
.headers(getHeader())
|
||||
// 请求的 tag, 主要用于取消对应的请求
|
||||
.tag(this)
|
||||
// 设置当前请求的缓存key,建议每个不同功能的请求设置一个
|
||||
// .cacheKey("cacheKey")
|
||||
// 缓存模式,详细请看缓存介绍
|
||||
// 缓存模式,详细请看缓存介绍
|
||||
// .cacheMode(CacheMode.DEFAULT)
|
||||
.execute(new DialogCallback<T>(clazz) {
|
||||
@Override
|
||||
public void onSuccess(Response<T> response) {
|
||||
callback.onSuccess(response.body(), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Response<T> response) {
|
||||
super.onError(response);
|
||||
Throwable throwable = response.getException();
|
||||
if (throwable != null) {
|
||||
throwable.printStackTrace();
|
||||
callback.onError(throwable, 2);
|
||||
.execute(new DialogCallback<T>(clazz) {
|
||||
@Override
|
||||
public void onSuccess(Response<T> response) {
|
||||
callback.onSuccess(response.body(), 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public void onError(Response<T> response) {
|
||||
super.onError(response);
|
||||
Throwable throwable = response.getException();
|
||||
if (throwable != null) {
|
||||
throwable.printStackTrace();
|
||||
callback.onError(throwable, 2);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get同步请求
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public okhttp3.Response getSynchronization() {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
if (token==null){
|
||||
headers.put("Authorization","Basic YXBwOmFwcHNlY3JldA==");
|
||||
}else {
|
||||
headers.put("Authorization","bearer"+token);
|
||||
|
||||
}
|
||||
headers.put("key",null);
|
||||
try {
|
||||
okhttp3.Response execute = OkGo.<String>get(HttpInterface.SUBMIT_CSTASK)
|
||||
.params(params)
|
||||
.headers(headers)
|
||||
.headers(getHeader())
|
||||
.tag(this)
|
||||
.execute();
|
||||
return execute;
|
||||
|
85
app/src/main/java/com/navinfo/outdoor/util/Md5Util.java
Normal file
85
app/src/main/java/com/navinfo/outdoor/util/Md5Util.java
Normal file
@ -0,0 +1,85 @@
|
||||
package com.navinfo.outdoor.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/*******************************************************************************
|
||||
* 文件名: Md5Util.java <br>
|
||||
* 版本: 1.0<br>
|
||||
* 描述: Md5Util.java <br>
|
||||
* 版权所有: <br>
|
||||
* //////////////////////////////////////////////////////// <br>
|
||||
* 创建者: <br>
|
||||
* 创建日期: <br>
|
||||
* 修改者: <br>
|
||||
* 修改日期: <br>
|
||||
* 修改说明: <br>
|
||||
******************************************************************************/
|
||||
public class Md5Util {
|
||||
|
||||
/**
|
||||
* MD5加密类
|
||||
* @param str 要加密的字符串
|
||||
* @return 加密后的字符串
|
||||
* @throws UnsupportedEncodingException
|
||||
*/
|
||||
public static String
|
||||
toMD5(String str) throws UnsupportedEncodingException{
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(str.getBytes("UTF-8"));
|
||||
byte[]byteDigest = md.digest();
|
||||
int i;
|
||||
StringBuffer buf = new StringBuffer("");
|
||||
for (int offset = 0; offset < byteDigest.length; offset++) {
|
||||
i = byteDigest[offset];
|
||||
if (i < 0)
|
||||
i += 256;
|
||||
if (i < 16)
|
||||
buf.append("0");
|
||||
buf.append(Integer.toHexString(i));
|
||||
}
|
||||
//32位加密
|
||||
return buf.toString();
|
||||
// 16位的加密
|
||||
//return buf.toString().substring(8, 24);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 进行md5加密
|
||||
* @param value
|
||||
* @param salt
|
||||
* @return md5
|
||||
*/
|
||||
public static String md5(String value, String salt) {
|
||||
String resultStr = "";
|
||||
try {
|
||||
byte[] temp = salt.getBytes();
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.update(temp);
|
||||
// resultStr = new String(md5.digest());
|
||||
byte[] b = md5.digest();
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
char[] digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
'9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
char[] ob = new char[2];
|
||||
ob[0] = digit[(b[i] >>> 4) & 0X0F];
|
||||
ob[1] = digit[b[i] & 0X0F];
|
||||
resultStr += new String(ob);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return resultStr;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws UnsupportedEncodingException {
|
||||
System.out.println(toMD5("123456"));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user