记得上下班打卡 | git大法好,push需谨慎

Commit 29b0a1cc authored by 胡佳晨's avatar 胡佳晨

Merge remote-tracking branch 'origin/dev' into dev

parents 9aa48963 10ee3c9d
......@@ -34,7 +34,7 @@ public class AdamRedisConst {
public static final String INFO_MEMBER_ORDER = INFO.concat("morder:");
public static final String INFO_BUY_MEMBER_ORDER_CODE = INFO.concat("mordercode:");
public static final String INFO_LIBRARY_NKNAME = INFO.concat("library:nkname");
// public static final String INFO_LIBRARY_NKNAME = INFO.concat("library:nkname");
public static final String BLACK_LIST = ADAM.concat("blacklist:");
public static final String BLK_LIST_MEMBER_UID = BLACK_LIST.concat("member:uid");
......@@ -51,7 +51,6 @@ public class AdamRedisConst {
/* ----------------------------------------------------------------- */
// public static final String LOCK_KEY_UMEMBER_NO = "adam:lk:member:no";
// // // // // // // // // //
// public static final String LOCK_KEY_SMS_CODE_MOBILE = "adam:lk:sms:code:mobile:";
// public static final String LOCK_KEY_UREGISTER = "adam:lk:register:";
// public static final String LOCK_KEY_UIDENTITY = "adam:lk:identity:";
......
......@@ -30,6 +30,6 @@ public class AdamThirdPartParam implements Serializable {
private String mobile;
@ApiModelProperty(position = 16, required = false, value = "验证码[新账号时必传]")
private String code;
@ApiModelProperty(position = 17, required = false, value = "强制绑定[第三方账号已绑定其他手机号时]", example = "false")
private Boolean force;
// @ApiModelProperty(position = 17, required = false, value = "强制绑定[第三方账号已绑定其他手机号时]", example = "false")
// private Boolean force;
}
package com.liquidnet.service.base;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
......@@ -13,20 +15,22 @@ import java.util.Properties;
@Data
public class ErrorMapping {
private static final Logger log = LoggerFactory.getLogger(ErrorMapping.class);
private static final Properties errorsProperties;
static {
reload();
errorsProperties = reload();
}
private static Properties errorsProperties;
public static void reload() {
errorsProperties = new Properties();
public static Properties reload() {
Properties errorsProperties = new Properties();
InputStream in = ErrorMapping.class.getClassLoader().getResourceAsStream("errors.properties");
try {
errorsProperties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
System.out.printf("errorsProperties init count: %s\n", errorsProperties.size());
log.info("Load errorsProperties init count:{}", errorsProperties.size());
} catch (IOException e) {
e.printStackTrace();
}
return errorsProperties;
}
public static ErrorMessage get(long code) {
......
......@@ -2,33 +2,34 @@ package com.liquidnet.service.base;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
public class SqlMapping {
private static final Logger log = LoggerFactory.getLogger(SqlMapping.class);
private static final Properties sqlsProperties;
static {
reload();
sqlsProperties = reload();
}
private static Properties sqlsProperties;
public static void reload() {
sqlsProperties = new Properties();
public static Properties reload() {
Properties sqlsProperties = new Properties();
InputStream in = ErrorMapping.class.getClassLoader().getResourceAsStream("sqlmap.properties");
try {
sqlsProperties.load(new InputStreamReader(in, StandardCharsets.UTF_8));
System.out.printf("errorsProperties init count: %s\n", sqlsProperties.size());
log.info("Load sqlsProperties init count:{}", sqlsProperties.size());
} catch (IOException e) {
e.printStackTrace();
}
return sqlsProperties;
}
public static String get(String sql) {
......
......@@ -14,7 +14,6 @@ import com.liquidnet.common.sms.processor.SmsProcessor;
import com.liquidnet.commons.lang.constant.LnsEnum;
import com.liquidnet.commons.lang.core.JwtValidator;
import com.liquidnet.commons.lang.util.*;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.constant.AdamWechatConst;
import com.liquidnet.service.adam.dto.AdamThirdPartParam;
import com.liquidnet.service.adam.dto.vo.AdamLoginInfoVo;
......@@ -193,7 +192,7 @@ public class AdamLoginController {
@Pattern(regexp = "\\d{6}", message = "验证码格式有误")
@RequestParam String code) {
log.debug("mobile:{},code:{}", mobile, code);
ResponseDto checkSmsCodeDto = this.checkSmsCode(mobile, code);
ResponseDto<AdamLoginInfoVo> checkSmsCodeDto = this.checkSmsCode(mobile, code);
if (!checkSmsCodeDto.isSuccess()) return checkSmsCodeDto;
String uid = adamRdmService.getUidByMobile(mobile);
......@@ -278,7 +277,7 @@ public class AdamLoginController {
loginInfoVo.setUserMemberVo(adamRdmService.getUserMemberVoByUid(uid));
// loginInfoVo.setMemberVo(adamRdmService.getMemberSimpleVo());
} else {// 新账号注册
ResponseDto checkSmsCodeDto = this.checkSmsCode(parameter.getMobile(), parameter.getCode());
ResponseDto<AdamLoginInfoVo> checkSmsCodeDto = this.checkSmsCode(parameter.getMobile(), parameter.getCode());
if (!checkSmsCodeDto.isSuccess()) {
return checkSmsCodeDto;
}
......@@ -376,24 +375,13 @@ public class AdamLoginController {
/* ---------------------------- Internal Method ---------------------------- */
/* ---------------------------- Internal Method ---------------------------- */
private ResponseDto checkSmsCode(String mobile, String code) {
Integer switchGrayLoginSms = (Integer) redisUtil.get(AdamRedisConst.SWITCH_GRAY_LOGIN_SMS);
if (null != switchGrayLoginSms) {
if (switchGrayLoginSms == 615243) {
if (CurrentUtil.GRAY_LOGIN_SMS_CODE.equals(code)) {
return ResponseDto.success();
}
}
if (switchGrayLoginSms == 612543) {
if (reviewMobile.equals(mobile) ||
Arrays.asList(LnsEnum.ENV.dev.name(), LnsEnum.ENV.test.name()).contains(env.getProperty(CurrentUtil.CK_ENV_ACTIVE))
) {
if (CurrentUtil.GRAY_LOGIN_SMS_CODE.equals(code)) {
return ResponseDto.success();
}
}
private ResponseDto<AdamLoginInfoVo> checkSmsCode(String mobile, String code) {
// if (Arrays.asList(LnsEnum.ENV.dev.name(), LnsEnum.ENV.test.name()).contains(env.getProperty(CurrentUtil.CK_ENV_ACTIVE))
// || reviewMobile.equals(mobile)) {
if (CurrentUtil.GRAY_LOGIN_SMS_CODE.equals(code)) {
return ResponseDto.success();
}
}
// }
// LinkedMultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
// paramsMap.add("mobile", mobile);
......
......@@ -256,11 +256,11 @@ public class AdamUserController {
if (existUid.equals(currentUid)) {
return ResponseDto.success(adamRdmService.getThirdPartVoListByUid(currentUid));
}
Boolean force = parameter.getForce();
if (null != force && force) {// 强制解绑,并重新绑定当前账号
adamUserService.bindTpaForce(currentUid, existUid, parameter);
return ResponseDto.success();
}
// Boolean force = parameter.getForce();
// if (null != force && force) {// 强制解绑,并重新绑定当前账号
// adamUserService.bindTpaForce(currentUid, existUid, parameter);
// return ResponseDto.success();
// }
return ResponseDto.failure(ErrorMapping.get("10007"));
}
......
......@@ -35,15 +35,7 @@ public class AdamRdmService {
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Loader meta-fil */
public List<String> getNknameList() {
ArrayList<String> list = (ArrayList<String>) redisUtil.get(AdamRedisConst.INFO_LIBRARY_NKNAME);
if (CollectionUtils.isEmpty(list)) {
list = NknameUtil.readForStringList();
if (!CollectionUtils.isEmpty(list)) redisUtil.set(AdamRedisConst.INFO_LIBRARY_NKNAME, list);
}
return list;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | <Mobile, SMS CODE> */
......
......@@ -12,20 +12,18 @@ import com.liquidnet.service.adam.service.AdamRdmService;
import com.liquidnet.service.adam.service.IAdamEntersService;
import com.liquidnet.service.adam.service.IAdamRealNameService;
import com.liquidnet.service.adam.service.IAdamUserService;
import com.liquidnet.service.adam.util.NknameUtil;
import com.liquidnet.service.adam.util.QueueUtils;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
......@@ -67,13 +65,12 @@ public class AdamUserServiceImpl implements IAdamUserService {
AdamUserInfoVo userInfoVo = null;
// if (RedisLockUtil.tryLock(LOCK_KEY_UREGISTER + mobile, 1, 5)) {
String uid = adamRdmService.getUidByMobile(mobile);
if (StringUtils.isEmpty(uid)) {
// String uid = adamRdmService.getUidByMobile(mobile);
// if (StringUtils.isEmpty(uid)) {
userInfoVo = AdamUserInfoVo.getNew();
userInfoVo.setUid(IDGenerator.nextSnowId() + "");
userInfoVo.setMobile(mobile);
List<String> nknameList = adamRdmService.getNknameList();
userInfoVo.setNickname("宇航员".concat(nknameList.get(RandomUtils.nextInt(0, nknameList.size()))));
userInfoVo.setNickname(NknameUtil.randomNkname());
userInfoVo.setIsComplete(0);
userInfoVo.setState(1);
userInfoVo.setQrCode("lN".concat(userInfoVo.getUid()).concat(RandomStringUtils.randomAlphanumeric(5).toUpperCase()));
......@@ -103,9 +100,9 @@ public class AdamUserServiceImpl implements IAdamUserService {
SqlMapping.gets(toMqSqls, initUserObjs, initUserInfoObjs)
);
log.debug("#MQ耗时:{}ms", System.currentTimeMillis() - s);
} else {
userInfoVo = adamRdmService.getUserInfoVoByUid(uid);
}
// } else {
// userInfoVo = adamRdmService.getUserInfoVoByUid(uid);
// }
// RedisLockUtil.unlock(LOCK_KEY_UREGISTER + mobile);
// }
return userInfoVo;
......@@ -118,10 +115,10 @@ public class AdamUserServiceImpl implements IAdamUserService {
AdamUserInfoVo userInfoVo = null;
// if (RedisLockUtil.tryLock(LOCK_KEY_UREGISTER + param.getOpenId() + param.getPlatform(), 1, 5)) {
String uid = adamRdmService.getUidByPlatformOpenId(param.getPlatform(), param.getOpenId());
if (StringUtils.isEmpty(uid)) {
// String uid = adamRdmService.getUidByPlatformOpenId(param.getPlatform(), param.getOpenId());
// if (StringUtils.isEmpty(uid)) {
long s = System.currentTimeMillis();
uid = adamRdmService.getUidByMobile(param.getMobile());
String uid = adamRdmService.getUidByMobile(param.getMobile());
log.debug("#RDS耗时:{}ms", System.currentTimeMillis() - s);
LinkedList<String> toMqSqls = CollectionUtil.linkedListString();
LinkedList<Object[]> initUserObjs = CollectionUtil.linkedListObjectArr(),
......@@ -151,13 +148,13 @@ public class AdamUserServiceImpl implements IAdamUserService {
initUserObjs.add(new Object[]{userInfoVo.getUid(), userInfoVo.getMobile(), userInfoVo.getState(), now});
toMqSqls.add(SqlMapping.get("adam_user_info.add"));
initUserInfoObjs.add(new Object[]{userInfoVo.getUid(), userInfoVo.getNickname(), userInfoVo.getAvatar(), userInfoVo.getQrCode()});
} else {
s = System.currentTimeMillis();
userInfoVo = adamRdmService.getUserInfoVoByUid(uid);
log.debug("#RDS耗时:{}ms", System.currentTimeMillis() - s);
toMqSqls.add(SqlMapping.get("adam_user.add"));
toMqSqls.add(SqlMapping.get("adam_user_info.add"));
}
// } else {
// s = System.currentTimeMillis();
// userInfoVo = adamRdmService.getUserInfoVoByUid(uid);
// log.debug("#RDS耗时:{}ms", System.currentTimeMillis() - s);
// toMqSqls.add(SqlMapping.get("adam_user.add"));
// toMqSqls.add(SqlMapping.get("adam_user_info.add"));
// }
AdamThirdPartInfoVo thirdPartInfoVo = AdamThirdPartInfoVo.getNew();
BeanUtils.copyProperties(param, thirdPartInfoVo);
......@@ -190,7 +187,7 @@ public class AdamUserServiceImpl implements IAdamUserService {
}
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
// @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void bindTpa(String uid, AdamThirdPartParam param) {
LocalDateTime now = LocalDateTime.now();
......@@ -223,7 +220,7 @@ public class AdamUserServiceImpl implements IAdamUserService {
}
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
// @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void bindTpaForce(String bindUid, String unBindUid, AdamThirdPartParam param) {
this.unBindTpaProcess(unBindUid, param.getPlatform());
......
......@@ -4,19 +4,29 @@ import com.liquidnet.commons.lang.util.CollectionUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class NknameUtil {
private static final Logger log = LoggerFactory.getLogger(NknameUtil.class);
public static ArrayList<String> readForStringList() {
ArrayList<String> nknameList = CollectionUtil.arrayListString();
private static int bound;
private static final List<String> nknameList;
private static final String nknamePrefix = "宇航员";
private static final Random random = new Random();
static {
nknameList = reload();
}
public static List<String> reload() {
List<String> list = CollectionUtil.arrayListString();
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
......@@ -34,7 +44,10 @@ public class NknameUtil {
if (l > 11) {
line = line.substring(0, 11);
}
nknameList.add(line);
list.add(line);
}
if (!CollectionUtils.isEmpty(list)) {
bound = list.size();
}
} catch (IOException e) {
log.error("Read CSV[library_nickname.csv] failure.", e);
......@@ -47,6 +60,11 @@ public class NknameUtil {
log.error("Close stream failure.", e);
}
}
return nknameList;
log.info("Load nkname init:{}~{}", list.size(), bound);
return list;
}
public static String randomNkname() {
return nknamePrefix + nknameList.get(random.nextInt(bound));
}
}
\ No newline at end of file
......@@ -23,6 +23,7 @@ import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -77,9 +78,15 @@ public abstract class AbstractWepayStrategy implements IWepayStrategy {
HttpPost httpost = new HttpPost(this.getRequestUrl());
httpost.setEntity(new StringEntity(data, "UTF-8"));
startTime = System.currentTimeMillis();
CloseableHttpClient httpClient = PayWepayUtils.getInstance().getHttpClient();
log.info("wepay-->request--> getHttpClient耗时:{}",(System.currentTimeMillis() - startTime)+"毫秒");
startTime = System.currentTimeMillis();
CloseableHttpResponse response = PayWepayUtils.getInstance().getHttpClient().execute(httpost);
log.info("wepay-->request--> 耗时:{}",(System.currentTimeMillis() - startTime)+"毫秒");
CloseableHttpResponse response = httpClient.execute(httpost);
log.info("wepay-->request--> execute耗时:{}",(System.currentTimeMillis() - startTime)+"毫秒");
HttpEntity entity = response.getEntity();
//接受到返回信息
String xmlStr = EntityUtils.toString(response.getEntity(), "UTF-8");
......
......@@ -6,7 +6,6 @@ import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.dto.vo.*;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.platform.utils.NknameUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -38,15 +37,7 @@ public class DMRdmService {
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Loader meta-fil */
public List<String> getNknameList() {
ArrayList<String> list = (ArrayList<String>) redisUtil.get(AdamRedisConst.INFO_LIBRARY_NKNAME);
if (CollectionUtils.isEmpty(list)) {
list = NknameUtil.readForStringList();
if (!CollectionUtils.isEmpty(list)) redisUtil.set(AdamRedisConst.INFO_LIBRARY_NKNAME, list);
}
return list;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | <Mobile, SMS CODE> */
......
package com.liquidnet.service.platform.service.impl.adam.dm.processor;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.dto.vo.AdamMemberPriceVo;
import com.liquidnet.service.adam.dto.vo.AdamMemberVo;
import com.liquidnet.service.adam.entity.AdamMember;
......@@ -13,8 +12,6 @@ import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.sql.Connection;
......@@ -216,7 +213,5 @@ public class DMTracesInfoProcessor extends DataMigrationProcessorService {
private void setRdsCache() {
// dmRdmService.setSwitch(AdamRedisConst.SWITCH_GRAY_LOGIN_SMS, 612543);
// log.info("switch {}:{}", AdamRedisConst.SWITCH_GRAY_LOGIN_SMS, dmRdmService.getSwitch(AdamRedisConst.SWITCH_GRAY_LOGIN_SMS));
List<String> nknameList = dmRdmService.getNknameList();
log.info("init loader nknameList.size:{}", nknameList.size());
}
}
package com.liquidnet.service.platform.utils;
import com.liquidnet.commons.lang.util.CollectionUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
public class NknameUtil {
private static final Logger log = LoggerFactory.getLogger(NknameUtil.class);
public static ArrayList<String> readForStringList() {
ArrayList<String> nknameList = CollectionUtil.arrayListString();
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
try {
inputStream = NknameUtil.class.getClassLoader().getResourceAsStream("META-FIL/library_nickname.csv");
inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
bufferedReader = new BufferedReader(inputStreamReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
int l = StringUtils.length(line);
if (l == 0) {
break;
}
if (l > 11) {
line = line.substring(0, 11);
}
nknameList.add(line);
}
} catch (IOException e) {
log.error("Read CSV[library_nickname.csv] failure.", e);
} finally {
try {
if (null != bufferedReader) bufferedReader.close();
if (null != inputStreamReader) inputStreamReader.close();
if (null != inputStream) inputStream.close();
} catch (IOException e) {
log.error("Close stream failure.", e);
}
}
return nknameList;
}
}
\ No newline at end of file
......@@ -13,7 +13,7 @@ import java.io.PrintWriter;
@RestController
@RequestMapping("/actionCallback")
@Slf4j
public class SweetActionCallbackController {
public class SweetWechatActionCallbackController {
@GetMapping("record")
@ApiOperation("get")
......
......@@ -14,8 +14,8 @@ import org.springframework.web.bind.annotation.RestController;
@Api(tags = "小程序登陆")
@RestController
@RequestMapping("/sweet-login")
public class SweetLoginController {
@RequestMapping("/wechatLogin")
public class SweetWechatLoginController {
@Autowired
private SweetLoginServiceImpl sweetLoginService;
......
......@@ -11,8 +11,8 @@ import org.springframework.web.bind.annotation.*;
@Api(tags = "公众号模版消息")
@RestController
@RequestMapping("/sweet-template")
public class SweetTemplateController {
@RequestMapping("/wechatTemplate")
public class SweetWechatTemplateController {
@Autowired
private SweetTemplateServiceImpl sweetTemplateService;
......
......@@ -3,7 +3,6 @@ package com.liquidnet.service.sweet.service.impl;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.feign.kylin.api.FeignKylinPerformanceClient;
//import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.sweet.constant.SweetConstant;
import com.liquidnet.service.sweet.utils.RedisDataUtils;
......@@ -21,7 +20,6 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Set;
/**
......
......@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DateUtil;
//import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.sweet.constant.SweetConstant;
import com.liquidnet.service.sweet.dto.SweetManualAppletDto;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment