Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop into feature/pg
This commit is contained in:
commit
5ce5384230
@ -104,11 +104,4 @@ public class UploadController {
|
|||||||
}
|
}
|
||||||
return ResultUtil.data(result);
|
return ResultUtil.data(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ApiOperation(value = "返回licences")
|
|
||||||
@PostMapping(value = "/licences")
|
|
||||||
public ResultMessage<Object> licences() {
|
|
||||||
return ResultUtil.data(systemSettingProperties.getLicences());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ spring:
|
|||||||
props:
|
props:
|
||||||
#是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭
|
#是否打印逻辑SQL语句和实际SQL语句,建议调试时打印,在生产环境关闭
|
||||||
sql:
|
sql:
|
||||||
show: false
|
show: true
|
||||||
|
|
||||||
# 忽略鉴权url
|
# 忽略鉴权url
|
||||||
ignored:
|
ignored:
|
||||||
@ -227,6 +227,12 @@ lili:
|
|||||||
system:
|
system:
|
||||||
isDemoSite: false
|
isDemoSite: false
|
||||||
isTestModel: true
|
isTestModel: true
|
||||||
|
# 脱敏级别:
|
||||||
|
# 0:不做脱敏处理
|
||||||
|
# 1:管理端用户手机号等信息脱敏
|
||||||
|
# 2:商家端信息脱敏(为2时,表示管理端,商家端同时脱敏)
|
||||||
|
# sensitiveLevel: 2
|
||||||
|
|
||||||
statistics:
|
statistics:
|
||||||
# 在线人数统计 X 小时。这里设置48,即统计过去48小时每小时在线人数
|
# 在线人数统计 X 小时。这里设置48,即统计过去48小时每小时在线人数
|
||||||
onlineMember: 48
|
onlineMember: 48
|
||||||
|
@ -27,7 +27,34 @@ public class SystemSettingProperties {
|
|||||||
private Boolean isTestModel = false;
|
private Boolean isTestModel = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 授权信息
|
* 脱敏级别:
|
||||||
|
* 0:不做脱敏处理
|
||||||
|
* 1:管理端用户手机号等信息脱敏
|
||||||
|
* 2:商家端信息脱敏(为2时,表示管理端,商家端同时脱敏)
|
||||||
|
* <p>
|
||||||
|
* PS:
|
||||||
*/
|
*/
|
||||||
private String licences = "";
|
private Integer sensitiveLevel = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public Boolean getDemoSite() {
|
||||||
|
if (isDemoSite == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return isDemoSite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getTestModel() {
|
||||||
|
if (isTestModel == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return isTestModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSensitiveLevel() {
|
||||||
|
if (sensitiveLevel == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return sensitiveLevel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
package cn.lili.common.security.filter;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonGenerator;
|
|
||||||
import com.fasterxml.jackson.databind.BeanProperty;
|
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
||||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
|
||||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
|
||||||
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author liushuai(liushuai711 @ gmail.com)
|
|
||||||
* @version v4.1
|
|
||||||
* @Description:
|
|
||||||
* @since 2021/9/8 3:03 下午
|
|
||||||
*/
|
|
||||||
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
|
|
||||||
private SensitiveStrategy strategy;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
|
||||||
gen.writeString(strategy.desensitizer().apply(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
|
|
||||||
|
|
||||||
Sensitive annotation = property.getAnnotation(Sensitive.class);
|
|
||||||
if (Objects.nonNull(annotation)&&Objects.equals(String.class, property.getType().getRawClass())) {
|
|
||||||
this.strategy = annotation.strategy();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
return prov.findValueSerializer(property.getType(), property);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
package cn.lili.common.security.filter;
|
package cn.lili.common.security.sensitive;
|
||||||
|
|
||||||
|
import cn.lili.common.security.sensitive.enums.SensitiveStrategy;
|
||||||
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
|
||||||
@ -8,6 +9,15 @@ import java.lang.annotation.Retention;
|
|||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 敏感注解
|
||||||
|
*
|
||||||
|
* @author liushuai(liushuai711 @ gmail.com)
|
||||||
|
* @version v4.0
|
||||||
|
* @Description:
|
||||||
|
* @since 2021/9/10 16:45
|
||||||
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.FIELD)
|
@Target(ElementType.FIELD)
|
||||||
@JacksonAnnotationsInside
|
@JacksonAnnotationsInside
|
@ -0,0 +1,101 @@
|
|||||||
|
package cn.lili.common.security.sensitive;
|
||||||
|
|
||||||
|
import cn.lili.common.properties.SystemSettingProperties;
|
||||||
|
import cn.lili.common.security.AuthUser;
|
||||||
|
import cn.lili.common.security.context.UserContext;
|
||||||
|
import cn.lili.common.security.enums.UserEnums;
|
||||||
|
import cn.lili.common.security.sensitive.enums.SensitiveStrategy;
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.BeanProperty;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 敏感信息序列化时 过滤
|
||||||
|
*
|
||||||
|
* @author liushuai(liushuai711 @ gmail.com)
|
||||||
|
* @version v4.0
|
||||||
|
* @Description:
|
||||||
|
* @since 2021/9/10 16:46
|
||||||
|
*/
|
||||||
|
public class SensitiveJsonSerializer extends JsonSerializer<String>
|
||||||
|
implements ContextualSerializer, ApplicationContextAware {
|
||||||
|
private SensitiveStrategy strategy;
|
||||||
|
|
||||||
|
//系统配置
|
||||||
|
private SystemSettingProperties systemSettingProperties;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||||
|
// 字段序列化处理
|
||||||
|
gen.writeString(strategy.desensitizer().apply(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
|
||||||
|
|
||||||
|
// 判定是否 需要脱敏处理
|
||||||
|
if (desensitization()) {
|
||||||
|
//获取敏感枚举
|
||||||
|
Sensitive annotation = property.getAnnotation(Sensitive.class);
|
||||||
|
//如果有敏感注解,则加入脱敏规则
|
||||||
|
if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {
|
||||||
|
this.strategy = annotation.strategy();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prov.findValueSerializer(property.getType(), property);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
systemSettingProperties = applicationContext.getBean(SystemSettingProperties.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否需要脱敏处理
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean desensitization() {
|
||||||
|
|
||||||
|
//当前用户
|
||||||
|
AuthUser authUser = UserContext.getCurrentUser();
|
||||||
|
//默认脱敏
|
||||||
|
if (authUser == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//如果是店铺
|
||||||
|
if (authUser.getRole().equals(UserEnums.STORE)) {
|
||||||
|
//店铺需要进行脱敏,则脱敏处理
|
||||||
|
if (systemSettingProperties.getSensitiveLevel() == 2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//默认不需要
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//如果是店铺
|
||||||
|
if (authUser.getRole().equals(UserEnums.MANAGER)) {
|
||||||
|
//店铺需要进行脱敏,则脱敏处理
|
||||||
|
if (systemSettingProperties.getSensitiveLevel() >= 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//默认不需要
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,16 @@
|
|||||||
package cn.lili.common.security.filter;
|
package cn.lili.common.security.sensitive.enums;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 敏感策略枚举
|
||||||
|
*
|
||||||
* @author liushuai(liushuai711 @ gmail.com)
|
* @author liushuai(liushuai711 @ gmail.com)
|
||||||
* @version v4.1
|
* @version v4.0
|
||||||
* @Description:
|
* @Description:
|
||||||
* @since 2021/9/8 3:03 下午
|
* @since 2021/9/10 16:46
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public enum SensitiveStrategy {
|
public enum SensitiveStrategy {
|
||||||
/**
|
/**
|
||||||
* Username sensitive strategy.
|
* Username sensitive strategy.
|
@ -13,8 +13,8 @@ public enum ConnectEnum {
|
|||||||
*/
|
*/
|
||||||
QQ("QQ登录"),
|
QQ("QQ登录"),
|
||||||
WEIBO("微博联合登录"),
|
WEIBO("微博联合登录"),
|
||||||
WECHAT("微信联合登录"),
|
|
||||||
//只存放unionid
|
//只存放unionid
|
||||||
|
WECHAT("微信联合登录"),
|
||||||
WECHAT_OPEN_ID("微信openid登录"),
|
WECHAT_OPEN_ID("微信openid登录"),
|
||||||
WECHAT_MP_OPEN_ID("微信openid登录"),
|
WECHAT_MP_OPEN_ID("微信openid登录"),
|
||||||
ALIPAY("支付宝登录"),
|
ALIPAY("支付宝登录"),
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package cn.lili.modules.member.entity.dos;
|
package cn.lili.modules.member.entity.dos;
|
||||||
|
|
||||||
import cn.lili.common.enums.ClientTypeEnum;
|
import cn.lili.common.enums.ClientTypeEnum;
|
||||||
import cn.lili.common.security.filter.Sensitive;
|
import cn.lili.common.security.sensitive.Sensitive;
|
||||||
import cn.lili.common.security.filter.SensitiveStrategy;
|
import cn.lili.common.security.sensitive.enums.SensitiveStrategy;
|
||||||
import cn.lili.mybatis.BaseEntity;
|
import cn.lili.mybatis.BaseEntity;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cn.lili.modules.member.entity.dos;
|
package cn.lili.modules.member.entity.dos;
|
||||||
|
|
||||||
import cn.lili.common.security.filter.Sensitive;
|
import cn.lili.common.security.sensitive.Sensitive;
|
||||||
import cn.lili.common.security.filter.SensitiveStrategy;
|
import cn.lili.common.security.sensitive.enums.SensitiveStrategy;
|
||||||
import cn.lili.common.validation.Phone;
|
import cn.lili.common.validation.Phone;
|
||||||
import cn.lili.mybatis.BaseEntity;
|
import cn.lili.mybatis.BaseEntity;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
@ -4,8 +4,8 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import cn.lili.common.enums.ClientTypeEnum;
|
import cn.lili.common.enums.ClientTypeEnum;
|
||||||
import cn.lili.common.enums.PromotionTypeEnum;
|
import cn.lili.common.enums.PromotionTypeEnum;
|
||||||
import cn.lili.common.security.filter.Sensitive;
|
import cn.lili.common.security.sensitive.Sensitive;
|
||||||
import cn.lili.common.security.filter.SensitiveStrategy;
|
import cn.lili.common.security.sensitive.enums.SensitiveStrategy;
|
||||||
import cn.lili.common.utils.BeanUtil;
|
import cn.lili.common.utils.BeanUtil;
|
||||||
import cn.lili.modules.goods.entity.enums.GoodsTypeEnum;
|
import cn.lili.modules.goods.entity.enums.GoodsTypeEnum;
|
||||||
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
|
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
|
||||||
|
@ -274,9 +274,9 @@ public class AfterSaleServiceImpl extends ServiceImpl<AfterSaleMapper, AfterSale
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@AfterSaleLogPoint(sn = "#afterSaleSn", description = "'售后-商家收货:单号['+#afterSaleSn+'],物流单号为['+#logisticsNo+']" +
|
@AfterSaleLogPoint(sn = "#afterSaleSn", description = "'售后-商家收货:单号['+#afterSaleSn+'],物流单号为['+#logisticsNo+']" +
|
||||||
",处理结果['+serviceStatus='PASS'?+'商家收货':'商家拒收'+']'")
|
",处理结果['+serviceStatus='PASS'?'商家收货':'商家拒收'+']'")
|
||||||
@SystemLogPoint(description = "售后-商家收货", customerLog = "'售后-商家收货:单号['+#afterSaleSn+'],物流单号为['+#logisticsNo+']" +
|
@SystemLogPoint(description = "售后-商家收货", customerLog = "'售后-商家收货:单号['+#afterSaleSn+'],物流单号为['+#logisticsNo+']" +
|
||||||
",处理结果['+serviceStatus='PASS'?+'商家收货':'商家拒收'+']'")
|
",处理结果['+serviceStatus='PASS'?'商家收货':'商家拒收'+']'")
|
||||||
public AfterSale storeConfirm(String afterSaleSn, String serviceStatus, String remark) {
|
public AfterSale storeConfirm(String afterSaleSn, String serviceStatus, String remark) {
|
||||||
//根据售后单号获取售后单
|
//根据售后单号获取售后单
|
||||||
AfterSale afterSale = OperationalJudgment.judgment(this.getBySn(afterSaleSn));
|
AfterSale afterSale = OperationalJudgment.judgment(this.getBySn(afterSaleSn));
|
||||||
|
@ -552,23 +552,38 @@ public class WechatPlugin implements Payment {
|
|||||||
String result = HttpKit.readData(request);
|
String result = HttpKit.readData(request);
|
||||||
log.info("微信退款通知密文 {}", result);
|
log.info("微信退款通知密文 {}", result);
|
||||||
JSONObject ciphertext = JSONUtil.parseObj(result);
|
JSONObject ciphertext = JSONUtil.parseObj(result);
|
||||||
if (!("REFUND.SUCCESS").equals(ciphertext.getStr("event_type"))) {
|
|
||||||
return;
|
try { //校验服务器端响应¬
|
||||||
}
|
|
||||||
try {
|
|
||||||
//校验服务器端响应¬
|
|
||||||
String plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp,
|
String plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp,
|
||||||
wechatPaymentSetting().getApiKey3(), Objects.requireNonNull(getPlatformCert()));
|
wechatPaymentSetting().getApiKey3(), Objects.requireNonNull(getPlatformCert()));
|
||||||
log.info("微信退款通知明文 {}", plainText);
|
log.info("微信退款通知明文 {}", plainText);
|
||||||
JSONObject jsonObject = JSONUtil.parseObj(plainText);
|
|
||||||
String transactionId = jsonObject.getStr("transaction_id");
|
|
||||||
String refundId = jsonObject.getStr("refund_id");
|
|
||||||
|
|
||||||
RefundLog refundLog = refundLogService.getOne(new LambdaQueryWrapper<RefundLog>().eq(RefundLog::getPaymentReceivableNo, transactionId));
|
if (("REFUND.SUCCESS").equals(ciphertext.getStr("event_type"))) {
|
||||||
if (refundLog != null) {
|
log.info("退款成功 {}", plainText);
|
||||||
refundLog.setIsRefund(true);
|
//校验服务器端响应
|
||||||
refundLog.setReceivableNo(refundId);
|
JSONObject jsonObject = JSONUtil.parseObj(plainText);
|
||||||
refundLogService.saveOrUpdate(refundLog);
|
String transactionId = jsonObject.getStr("transaction_id");
|
||||||
|
String refundId = jsonObject.getStr("refund_id");
|
||||||
|
|
||||||
|
RefundLog refundLog = refundLogService.getOne(new LambdaQueryWrapper<RefundLog>().eq(RefundLog::getPaymentReceivableNo, transactionId));
|
||||||
|
if (refundLog != null) {
|
||||||
|
refundLog.setIsRefund(true);
|
||||||
|
refundLog.setReceivableNo(refundId);
|
||||||
|
refundLogService.saveOrUpdate(refundLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.info("退款失败 {}", plainText);
|
||||||
|
JSONObject jsonObject = JSONUtil.parseObj(plainText);
|
||||||
|
String transactionId = jsonObject.getStr("transaction_id");
|
||||||
|
String refundId = jsonObject.getStr("refund_id");
|
||||||
|
|
||||||
|
RefundLog refundLog = refundLogService.getOne(new LambdaQueryWrapper<RefundLog>().eq(RefundLog::getPaymentReceivableNo, transactionId));
|
||||||
|
if (refundLog != null) {
|
||||||
|
refundLog.setReceivableNo(refundId);
|
||||||
|
refundLog.setErrorMessage(ciphertext.getStr("summary"));
|
||||||
|
refundLogService.saveOrUpdate(refundLog);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("微信退款失败", e);
|
log.error("微信退款失败", e);
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package cn.lili.modules.store.entity.dto;
|
package cn.lili.modules.store.entity.dto;
|
||||||
|
|
||||||
import cn.lili.common.security.filter.Sensitive;
|
|
||||||
import cn.lili.common.security.filter.SensitiveStrategy;
|
|
||||||
import cn.lili.common.validation.Mobile;
|
import cn.lili.common.validation.Mobile;
|
||||||
import cn.lili.common.validation.Phone;
|
import cn.lili.common.validation.Phone;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
@ -76,7 +74,6 @@ public class StoreEditDTO {
|
|||||||
@NotBlank(message = "手机号不能为空")
|
@NotBlank(message = "手机号不能为空")
|
||||||
@Phone
|
@Phone
|
||||||
@ApiModelProperty(value = "联系人电话")
|
@ApiModelProperty(value = "联系人电话")
|
||||||
@Sensitive(strategy = SensitiveStrategy.PHONE)
|
|
||||||
private String linkPhone;
|
private String linkPhone;
|
||||||
|
|
||||||
@Size(min = 18, max = 18, message = "营业执照长度为18位字符")
|
@Size(min = 18, max = 18, message = "营业执照长度为18位字符")
|
||||||
|
@ -3,7 +3,6 @@ package cn.lili.controller.member;
|
|||||||
import cn.lili.common.enums.ResultUtil;
|
import cn.lili.common.enums.ResultUtil;
|
||||||
import cn.lili.common.vo.PageVO;
|
import cn.lili.common.vo.PageVO;
|
||||||
import cn.lili.common.vo.ResultMessage;
|
import cn.lili.common.vo.ResultMessage;
|
||||||
import cn.lili.modules.system.aspect.annotation.DemoSite;
|
|
||||||
import cn.lili.modules.member.entity.dos.Member;
|
import cn.lili.modules.member.entity.dos.Member;
|
||||||
import cn.lili.modules.member.entity.dto.ManagerMemberEditDTO;
|
import cn.lili.modules.member.entity.dto.ManagerMemberEditDTO;
|
||||||
import cn.lili.modules.member.entity.dto.MemberAddDTO;
|
import cn.lili.modules.member.entity.dto.MemberAddDTO;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user