Commit be7bc113 authored by 孙 楠's avatar 孙 楠

Merge branch 'feature-modify-phone-no-20230510' into 'master'

Feature modify phone no 20230510

See merge request !108
parents 67ce7215 28550325
...@@ -237,6 +237,10 @@ public interface Constants { ...@@ -237,6 +237,10 @@ public interface Constants {
* 验证类型 - 量化派图形验证 * 验证类型 - 量化派图形验证
*/ */
String VERIFY_TYPE_QG = "qg"; String VERIFY_TYPE_QG = "qg";
/**
* 验证类型 - 不验证
*/
String VERIFY_TYPE_NONE = "none";
// -- End -- 验证码常量组 // -- End -- 验证码常量组
/** 注销用户后再次允许注册时间间隔-天数 */ /** 注销用户后再次允许注册时间间隔-天数 */
......
...@@ -67,6 +67,9 @@ public class CaptchaNewValidateAdvisor { ...@@ -67,6 +67,9 @@ public class CaptchaNewValidateAdvisor {
} else { } else {
return JsonResult.buildErrorStateResult("验证码不正确", ""); return JsonResult.buildErrorStateResult("验证码不正确", "");
} }
} else if (Objects.equals(Constants.VERIFY_TYPE_NONE, request.getParameter(Constants.VERIFY_PARAM))) {
//不校验验证码,针对电商用户端修改手机号场景
return pjp.proceed();
} else { } else {
if (qgValid(request)) { if (qgValid(request)) {
return pjp.proceed(); return pjp.proceed();
......
...@@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
...@@ -83,6 +84,11 @@ public class SmsController implements IBaseController { ...@@ -83,6 +84,11 @@ public class SmsController implements IBaseController {
return sendVerificationCode2(phoneNo, randomCode, appName, smsMerchant); return sendVerificationCode2(phoneNo, randomCode, appName, smsMerchant);
} }
@PostMapping("/verify_sms_verification_code")
public JsonResult verifyCode(String phoneNo, String verificationCode) {
return JsonResult.buildSuccessResult("校验验证码", smsService.verifyPhoneAndCode(phoneNo, verificationCode));
}
/** /**
* 短信验证码 : 重置密码 * 短信验证码 : 重置密码
* *
......
...@@ -206,13 +206,13 @@ public class InnerController implements IBaseController { ...@@ -206,13 +206,13 @@ public class InnerController implements IBaseController {
public JsonResult findByPhoneNo(String phoneNo, Integer tenantId) { public JsonResult findByPhoneNo(String phoneNo, Integer tenantId) {
User user = userService.findByPhoneInDb(phoneNo); User user = userService.findByPhoneInDb(phoneNo);
if (user == null) { if (user == null) {
return JsonResult.buildErrorStateResult("查无此人", null); return JsonResult.buildErrorStateResult("查无此人", null, 4L);
} }
if (tenantId != null && !TenantUtil.TENANT_DEFAULT.equals(tenantId)) { if (tenantId != null && !TenantUtil.TENANT_DEFAULT.equals(tenantId)) {
// userId 查询对应productLogin 获取手机号和customerId // userId 查询对应productLogin 获取手机号和customerId
user = tenantService.getTenantUser(user, tenantId); user = tenantService.getTenantUser(user, tenantId);
if (user == null) { if (user == null) {
return JsonResult.buildErrorStateResult("查无此人", null); return JsonResult.buildErrorStateResult("查无此人", null, 4L);
} }
} }
UserRet userRet = new UserRet(user); UserRet userRet = new UserRet(user);
......
...@@ -2,6 +2,8 @@ package cn.quantgroup.xyqb.controller.modifyphoneno; ...@@ -2,6 +2,8 @@ package cn.quantgroup.xyqb.controller.modifyphoneno;
import cn.quantgroup.xyqb.controller.IBaseController; import cn.quantgroup.xyqb.controller.IBaseController;
import cn.quantgroup.xyqb.controller.modifyphoneno.req.*; import cn.quantgroup.xyqb.controller.modifyphoneno.req.*;
import cn.quantgroup.xyqb.controller.modifyphoneno.req.ModifyPhoneRecord.UserClient;
import cn.quantgroup.xyqb.controller.modifyphoneno.resp.ModifyPhoneNoResp;
import cn.quantgroup.xyqb.controller.modifyphoneno.resp.ProgressResp; import cn.quantgroup.xyqb.controller.modifyphoneno.resp.ProgressResp;
import cn.quantgroup.xyqb.controller.modifyphoneno.resp.UserModifyPhoneRecordResp; import cn.quantgroup.xyqb.controller.modifyphoneno.resp.UserModifyPhoneRecordResp;
import cn.quantgroup.xyqb.entity.ModifyPhoneNo; import cn.quantgroup.xyqb.entity.ModifyPhoneNo;
...@@ -12,6 +14,7 @@ import cn.quantgroup.xyqb.service.user.IModifyPhoneNoService; ...@@ -12,6 +14,7 @@ import cn.quantgroup.xyqb.service.user.IModifyPhoneNoService;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
...@@ -83,7 +86,8 @@ public class ModifyPhoneNoController implements IBaseController { ...@@ -83,7 +86,8 @@ public class ModifyPhoneNoController implements IBaseController {
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
String s; String s;
try { try {
s = objectMapper.writeValueAsString(list); Page<ModifyPhoneNoResp> result = list.map(ModifyPhoneNoResp::from);
s = objectMapper.writeValueAsString(result);
Object o = objectMapper.readValue(s, Object.class); Object o = objectMapper.readValue(s, Object.class);
return JsonResult.buildSuccessResultGeneric(o); return JsonResult.buildSuccessResultGeneric(o);
} catch (Exception ignored) { } catch (Exception ignored) {
...@@ -133,6 +137,17 @@ public class ModifyPhoneNoController implements IBaseController { ...@@ -133,6 +137,17 @@ public class ModifyPhoneNoController implements IBaseController {
return JsonResult.buildSuccessResult(); return JsonResult.buildSuccessResult();
} }
/**
* 用户端修改手机号
* @param modifyPhoneRecord
* @return
*/
@PostMapping("/client/submitModify")
public JsonResult clientSubmitModify(@Validated(value = UserClient.class) @RequestBody ModifyPhoneRecord modifyPhoneRecord) {
modifyPhoneNoService.clientSubmitModify(modifyPhoneRecord);
return JsonResult.buildSuccessResult();
}
@PostMapping( "/modifyPhoneNolist") @PostMapping( "/modifyPhoneNolist")
public JsonResult getModifyPhoneNolist(@RequestParam("userId") Long userId, public JsonResult getModifyPhoneNolist(@RequestParam("userId") Long userId,
@RequestParam(value = "pageNo", defaultValue = "1", required = false) int pageNo, @RequestParam(value = "pageNo", defaultValue = "1", required = false) int pageNo,
...@@ -147,4 +162,22 @@ public class ModifyPhoneNoController implements IBaseController { ...@@ -147,4 +162,22 @@ public class ModifyPhoneNoController implements IBaseController {
return JsonResult.buildSuccessResult("修改手机号列表", pageData); return JsonResult.buildSuccessResult("修改手机号列表", pageData);
} }
@GetMapping("/lastRecord")
public JsonResult getLastRecord(@RequestParam("userId") Long userId){
UserModifyPhoneRecordResp resp = modifyPhoneNoService.getLastRecord(userId);
return JsonResult.buildSuccessResult("最后修改记录", resp);
}
@PostMapping("/rejectReason/save")
public JsonResult saveRejectReason(@Valid @RequestBody ModifyRejectRecord modifyRejectRecord){
modifyPhoneNoService.saveRejectReason(modifyRejectRecord);
return JsonResult.buildSuccessResult("保存手机号修改失败原因成功");
}
@GetMapping("/modifyRecord")
public JsonResult modifyRecord(@RequestParam("prevPhoneNo") String prevPhoneNo){
UserModifyPhoneRecordResp resp = modifyPhoneNoService.modifyRecord(prevPhoneNo);
return JsonResult.buildSuccessResult("手机号修改记录", resp);
}
} }
package cn.quantgroup.xyqb.controller.modifyphoneno.req; package cn.quantgroup.xyqb.controller.modifyphoneno.req;
import cn.quantgroup.xyqb.entity.enums.ApplySource;
import cn.quantgroup.xyqb.entity.enums.Reason; import cn.quantgroup.xyqb.entity.enums.Reason;
import cn.quantgroup.xyqb.util.ValidationUtil; import cn.quantgroup.xyqb.util.ValidationUtil;
import feign.Client.Default;
import lombok.Data; import lombok.Data;
import org.hibernate.validator.constraints.NotBlank; import org.hibernate.validator.constraints.NotBlank;
...@@ -15,12 +17,12 @@ public class ModifyPhoneRecord implements Serializable { ...@@ -15,12 +17,12 @@ public class ModifyPhoneRecord implements Serializable {
// @NotNull(message = "用户ID不能为空") // @NotNull(message = "用户ID不能为空")
private Long userId; private Long userId;
@NotBlank(message = "原手机号不能为空") @NotBlank(message = "原手机号不能为空", groups = {Default.class, UserClient.class})
@Pattern(regexp = ValidationUtil.phoneRegExp, message = "原手机号码格式错误") @Pattern(regexp = ValidationUtil.phoneRegExp, message = "原手机号码格式错误", groups = {Default.class, UserClient.class})
private String prevPhoneNo; private String prevPhoneNo;
@NotBlank(message = "新手机号不能为空") @NotBlank(message = "新手机号不能为空", groups = {Default.class, UserClient.class})
@Pattern(regexp = ValidationUtil.phoneRegExp, message = "新手机号码格式错误") @Pattern(regexp = ValidationUtil.phoneRegExp, message = "新手机号码格式错误", groups = {Default.class, UserClient.class})
private String curPhoneNo; private String curPhoneNo;
@NotNull(message = "修改原因不能为空") @NotNull(message = "修改原因不能为空")
...@@ -32,4 +34,12 @@ public class ModifyPhoneRecord implements Serializable { ...@@ -32,4 +34,12 @@ public class ModifyPhoneRecord implements Serializable {
// @NotBlank(message = "备注不能为空") // @NotBlank(message = "备注不能为空")
private String remark; private String remark;
/**
* 申请来源
*/
private ApplySource applySource;
public interface Background{}
public interface UserClient{}
public interface Finance{}
} }
package cn.quantgroup.xyqb.controller.modifyphoneno.req;
import cn.quantgroup.xyqb.entity.enums.ApplySource;
import cn.quantgroup.xyqb.util.ValidationUtil;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;
@Data
public class ModifyRejectRecord {
@NotNull(message = "用户id不能为空")
private Long userId;
@NotBlank(message = "原手机号不能为空")
@Pattern(regexp = ValidationUtil.phoneRegExp, message = "原手机号码格式错误")
private String prevPhoneNo;
@NotBlank(message = "新手机号不能为空")
@Pattern(regexp = ValidationUtil.phoneRegExp, message = "新手机号码格式错误")
private String curPhoneNo;
private String remark;
@NotBlank(message = "拒绝原因不能为空")
private String rejectReason;
}
package cn.quantgroup.xyqb.controller.modifyphoneno.resp; package cn.quantgroup.xyqb.controller.modifyphoneno.resp;
import cn.quantgroup.xyqb.entity.ModifyPhoneNo;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.sql.Timestamp;
import java.util.Date; import java.util.Date;
import lombok.Data; import lombok.Data;
...@@ -11,31 +14,94 @@ import lombok.Data; ...@@ -11,31 +14,94 @@ import lombok.Data;
*/ */
@Data @Data
public class ModifyPhoneNoResp { public class ModifyPhoneNoResp {
private static final long serialVersionUID = 0x93c999d06b6f64d2L;
private Long id; private Long id;
// //@ApiModelProperty("申请编号")
private String applyNo; @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
// //@ApiModelProperty("申请人姓名") private Timestamp createdAt;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Timestamp updatedAt;
/**
* user.id
*/
private Long userId;
/**
* 注册人真实姓名
*/
private String name; private String name;
// //@ApiModelProperty("申请人身份证号")
/**
* 注册人身份证件号
*/
private String idCard; private String idCard;
//@ApiModelProperty("申请人原手机号")
/**
* 原手机号码
*/
private String prevPhoneNo; private String prevPhoneNo;
//@ApiModelProperty("申请人现手机号")
/**
* 新手机号码
*/
private String curPhoneNo; private String curPhoneNo;
//@ApiModelProperty("申请时间")
private Date createdAt; /**
//@ApiModelProperty("申请结果") * 身份证正面
private Integer applyStatus; */
//@ApiModelProperty("拒绝原因")
private String applyStatusReason;
//@ApiModelProperty("处理状态")
private Integer processStatus;
//@ApiModelProperty("最近更新时间")
private Date updatedAt;
//@ApiModelProperty("身份证正面")
private String idCardFaceUrl; private String idCardFaceUrl;
//@ApiModelProperty("身份证背面")
/**
* 身份证背面
*/
private String idCardRearUrl; private String idCardRearUrl;
//@ApiModelProperty("本人手持身份证照片")
/**
* 本人手持身份证照片
*/
private String idCardHoldUrl; private String idCardHoldUrl;
/**
* 申请状态 0处理中; 1修改完成; 2不允许修改;
*/
private Integer applyStatus;
/**
* 申请状态补充原因
*/
private String applyStatusReason;
/**
* 处理状态 0待人工处理 1待用户反馈结果 2已反馈
*/
private Integer processingStatus;
/**
* 申请来源
*/
private Integer applySource;
public static ModifyPhoneNoResp from(ModifyPhoneNo modifyPhoneNo){
ModifyPhoneNoResp modifyPhoneNoResp = new ModifyPhoneNoResp();
modifyPhoneNoResp.setId(modifyPhoneNo.getId());
modifyPhoneNoResp.setCreatedAt(modifyPhoneNo.getCreatedAt());
modifyPhoneNoResp.setUpdatedAt(modifyPhoneNo.getUpdatedAt());
modifyPhoneNoResp.setUserId(modifyPhoneNo.getUserId());
modifyPhoneNoResp.setName(modifyPhoneNo.getName());
modifyPhoneNoResp.setIdCard(modifyPhoneNo.getIdCard());
modifyPhoneNoResp.setPrevPhoneNo(modifyPhoneNo.getPrevPhoneNo());
modifyPhoneNoResp.setCurPhoneNo(modifyPhoneNo.getCurPhoneNo());
modifyPhoneNoResp.setIdCardFaceUrl(modifyPhoneNo.getIdCardFaceUrl());
modifyPhoneNoResp.setIdCardRearUrl(modifyPhoneNo.getIdCardRearUrl());
modifyPhoneNoResp.setIdCardHoldUrl(modifyPhoneNo.getIdCardHoldUrl());
modifyPhoneNoResp.setApplyStatus(modifyPhoneNo.getApplyStatus());
modifyPhoneNoResp.setApplyStatusReason(modifyPhoneNo.getApplyStatusReason());
modifyPhoneNoResp.setProcessingStatus(modifyPhoneNo.getProcessingStatus());
modifyPhoneNoResp.setApplySource(modifyPhoneNo.getApplySource().ordinal());
return modifyPhoneNoResp;
}
} }
package cn.quantgroup.xyqb.controller.modifyphoneno.resp; package cn.quantgroup.xyqb.controller.modifyphoneno.resp;
import cn.quantgroup.xyqb.entity.enums.ApplySource;
import cn.quantgroup.xyqb.entity.enums.Reason; import cn.quantgroup.xyqb.entity.enums.Reason;
import com.fasterxml.jackson.annotation.JsonFormat;
import javax.persistence.Column;
import lombok.Data; import lombok.Data;
import java.sql.Timestamp; import java.sql.Timestamp;
...@@ -23,7 +26,18 @@ public class UserModifyPhoneRecordResp { ...@@ -23,7 +26,18 @@ public class UserModifyPhoneRecordResp {
private String financialResponse; private String financialResponse;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
private Timestamp createdAt; private Timestamp createdAt;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
private Timestamp updatedAt; private Timestamp updatedAt;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
private Timestamp operationAt;
private ApplySource applySource;
private Integer applyStatus;
private String applyStatusReason;
} }
package cn.quantgroup.xyqb.entity; package cn.quantgroup.xyqb.entity;
import cn.quantgroup.xyqb.entity.enums.ApplySource;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serializable; import java.io.Serializable;
import javax.persistence.Column; import javax.persistence.Column;
...@@ -85,4 +86,10 @@ public class ModifyPhoneNo extends BaseEntity implements Serializable { ...@@ -85,4 +86,10 @@ public class ModifyPhoneNo extends BaseEntity implements Serializable {
*/ */
@Column(name = "processing_status") @Column(name = "processing_status")
private Integer processingStatus; private Integer processingStatus;
/**
* 申请来源
*/
@Column(name = "apply_source")
private ApplySource applySource;
} }
package cn.quantgroup.xyqb.entity; package cn.quantgroup.xyqb.entity;
import cn.quantgroup.xyqb.entity.enums.ApplySource;
import cn.quantgroup.xyqb.entity.enums.Reason; import cn.quantgroup.xyqb.entity.enums.Reason;
import cn.quantgroup.xyqb.util.encrypt.CryptConverter; import cn.quantgroup.xyqb.util.encrypt.CryptConverter;
import javax.persistence.Convert; import javax.persistence.Convert;
...@@ -40,4 +41,22 @@ public class UserModifyPhoneRecord extends BaseEntity implements Serializable { ...@@ -40,4 +41,22 @@ public class UserModifyPhoneRecord extends BaseEntity implements Serializable {
@Column(name = "financial_response") @Column(name = "financial_response")
private String financialResponse; private String financialResponse;
/**
* 申请来源
*/
@Column(name = "apply_source")
private ApplySource applySource;
/**
* 申请状态 0处理中; 1修改完成; 2不允许修改;
*/
@Column(name = "apply_status")
private Integer applyStatus;
/**
* 申请状态补充原因
*/
@Column(name = "apply_status_reason")
private String applyStatusReason;
} }
package cn.quantgroup.xyqb.entity.enums;
public enum ApplySource {
CLIENT("用户端"),
BACKGROUND("客服后台"),
FINANCE_CLIENT("金融用户端"),
FINANCE_BACKGROUND("金融客服后台"),
;
private final String name;
ApplySource(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
...@@ -31,7 +31,11 @@ public enum SmsMerchant { ...@@ -31,7 +31,11 @@ public enum SmsMerchant {
CIRCULATION_QUOTA(17, 1, "外部循环额度"), CIRCULATION_QUOTA(17, 1, "外部循环额度"),
FLYING_COW_TO_BORROW(18, 5033, "飞牛贷"), FLYING_COW_TO_BORROW(18, 5033, "飞牛贷"),
VCC(20, 5108, "VCC-真享花,vcc-talos"), VCC(20, 5108, "VCC-真享花,vcc-talos"),
ZXH(20, 5337, "信用钱包马甲包"); ZXH(20, 5337, "信用钱包马甲包"),
STMS(22,5641,"stms短信")
;
private int merchantId; private int merchantId;
private int contentId; private int contentId;
......
...@@ -3,7 +3,18 @@ package cn.quantgroup.xyqb.repository; ...@@ -3,7 +3,18 @@ package cn.quantgroup.xyqb.repository;
import cn.quantgroup.xyqb.entity.UserModifyPhoneRecord; import cn.quantgroup.xyqb.entity.UserModifyPhoneRecord;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface IModifyPhoneRecordRepository extends JpaRepository<UserModifyPhoneRecord, Long>, JpaSpecificationExecutor<UserModifyPhoneRecord> { public interface IModifyPhoneRecordRepository extends JpaRepository<UserModifyPhoneRecord, Long>, JpaSpecificationExecutor<UserModifyPhoneRecord> {
@Query(nativeQuery = true, value = "select * from user_modify_phone_record " +
"where user_id = :userId "
+ "order by created_at desc limit 1")
UserModifyPhoneRecord findLastRecord(@Param("userId") Long userId);
@Query(nativeQuery = true, value = "select * from user_modify_phone_record " +
"where prev_phone_no = :prevPhoneNo "
+ "order by created_at desc limit 1")
UserModifyPhoneRecord modifyRecord(@Param("prevPhoneNo")String prevPhoneNo);
} }
...@@ -2,6 +2,7 @@ package cn.quantgroup.xyqb.service.user; ...@@ -2,6 +2,7 @@ package cn.quantgroup.xyqb.service.user;
import cn.quantgroup.xyqb.controller.modifyphoneno.req.*; import cn.quantgroup.xyqb.controller.modifyphoneno.req.*;
import cn.quantgroup.xyqb.controller.modifyphoneno.resp.ProgressResp; import cn.quantgroup.xyqb.controller.modifyphoneno.resp.ProgressResp;
import cn.quantgroup.xyqb.controller.modifyphoneno.resp.UserModifyPhoneRecordResp;
import cn.quantgroup.xyqb.entity.ModifyPhoneNo; import cn.quantgroup.xyqb.entity.ModifyPhoneNo;
import cn.quantgroup.xyqb.entity.UserModifyPhoneRecord; import cn.quantgroup.xyqb.entity.UserModifyPhoneRecord;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
...@@ -37,4 +38,12 @@ public interface IModifyPhoneNoService { ...@@ -37,4 +38,12 @@ public interface IModifyPhoneNoService {
void financialSubmitModify(ModifyPhoneRecord modifyPhoneRecord); void financialSubmitModify(ModifyPhoneRecord modifyPhoneRecord);
Page<UserModifyPhoneRecord> query(Long userId, int pageNo, int pageSize); Page<UserModifyPhoneRecord> query(Long userId, int pageNo, int pageSize);
void clientSubmitModify(ModifyPhoneRecord modifyPhoneRecord);
UserModifyPhoneRecordResp getLastRecord(Long userId);
void saveRejectReason(ModifyRejectRecord modifyRejectRecord);
UserModifyPhoneRecordResp modifyRecord(String prevPhoneNo);
} }
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