mirror of
https://github.com/201206030/novel-plus.git
synced 2025-04-26 17:20:52 +00:00
fix: 后台模块查询过滤相同的行
This commit is contained in:
parent
687eb61846
commit
a7d825cc54
@ -1,174 +1,212 @@
|
|||||||
package com.java2nb.system.domain;
|
package com.java2nb.system.domain;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import com.java2nb.common.jsonserializer.LongToStringSerializer;
|
import com.java2nb.common.jsonserializer.LongToStringSerializer;
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据权限管理
|
* 数据权限管理
|
||||||
*
|
*
|
||||||
* @author xiongxy
|
* @author xiongxy
|
||||||
* @email 1179705413@qq.com
|
* @email 1179705413@qq.com
|
||||||
* @date 2019-11-25 11:40:03
|
* @date 2019-11-25 11:40:03
|
||||||
*/
|
*/
|
||||||
public class DataPermDO implements Serializable {
|
public class DataPermDO implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
//
|
|
||||||
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
|
||||||
//所以通过序列化成字符串来解决
|
|
||||||
@JsonSerialize(using = LongToStringSerializer.class)
|
|
||||||
private Long id;
|
|
||||||
//权限名称
|
|
||||||
private String name;
|
|
||||||
//数据表名称
|
|
||||||
private String tableName;
|
|
||||||
//所属模块
|
|
||||||
private String moduleName;
|
|
||||||
//用户权限控制属性名
|
|
||||||
private String crlAttrName;
|
|
||||||
//数据表权限控制列名
|
|
||||||
private String crlColumnName;
|
|
||||||
//权限code,all_开头表示查看所有数据的权限,sup_开头表示查看下级数据的权限,own_开头表示查看本级数据的权限
|
|
||||||
private String permCode;
|
|
||||||
//排序
|
|
||||||
private Integer orderNum;
|
|
||||||
//创建时间
|
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date gmtCreate;
|
|
||||||
//修改时间
|
|
||||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
|
||||||
private Date gmtModified;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置:
|
//
|
||||||
*/
|
//java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值)
|
||||||
public void setId(Long id) {
|
//所以通过序列化成字符串来解决
|
||||||
this.id = id;
|
@JsonSerialize(using = LongToStringSerializer.class)
|
||||||
}
|
private Long id;
|
||||||
/**
|
//权限名称
|
||||||
* 获取:
|
private String name;
|
||||||
*/
|
//数据表名称
|
||||||
public Long getId() {
|
private String tableName;
|
||||||
return id;
|
//所属模块
|
||||||
}
|
private String moduleName;
|
||||||
/**
|
//用户权限控制属性名
|
||||||
* 设置:权限名称
|
private String crlAttrName;
|
||||||
*/
|
//数据表权限控制列名
|
||||||
public void setName(String name) {
|
private String crlColumnName;
|
||||||
this.name = name;
|
//权限code,all_开头表示查看所有数据的权限,sup_开头表示查看下级数据的权限,own_开头表示查看本级数据的权限
|
||||||
}
|
private String permCode;
|
||||||
/**
|
//排序
|
||||||
* 获取:权限名称
|
private Integer orderNum;
|
||||||
*/
|
//创建时间
|
||||||
public String getName() {
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
return name;
|
private Date gmtCreate;
|
||||||
}
|
//修改时间
|
||||||
/**
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
* 设置:数据表名称
|
private Date gmtModified;
|
||||||
*/
|
|
||||||
public void setTableName(String tableName) {
|
/**
|
||||||
this.tableName = tableName;
|
* 设置:
|
||||||
}
|
*/
|
||||||
/**
|
public void setId(Long id) {
|
||||||
* 获取:数据表名称
|
this.id = id;
|
||||||
*/
|
}
|
||||||
public String getTableName() {
|
|
||||||
return tableName;
|
/**
|
||||||
}
|
* 获取:
|
||||||
/**
|
*/
|
||||||
* 设置:所属模块
|
public Long getId() {
|
||||||
*/
|
return id;
|
||||||
public void setModuleName(String moduleName) {
|
}
|
||||||
this.moduleName = moduleName;
|
|
||||||
}
|
/**
|
||||||
/**
|
* 设置:权限名称
|
||||||
* 获取:所属模块
|
*/
|
||||||
*/
|
public void setName(String name) {
|
||||||
public String getModuleName() {
|
this.name = name;
|
||||||
return moduleName;
|
}
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 设置:用户权限控制属性名
|
* 获取:权限名称
|
||||||
*/
|
*/
|
||||||
public void setCrlAttrName(String crlAttrName) {
|
public String getName() {
|
||||||
this.crlAttrName = crlAttrName;
|
return name;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 获取:用户权限控制属性名
|
/**
|
||||||
*/
|
* 设置:数据表名称
|
||||||
public String getCrlAttrName() {
|
*/
|
||||||
return crlAttrName;
|
public void setTableName(String tableName) {
|
||||||
}
|
this.tableName = tableName;
|
||||||
/**
|
}
|
||||||
* 设置:数据表权限控制列名
|
|
||||||
*/
|
/**
|
||||||
public void setCrlColumnName(String crlColumnName) {
|
* 获取:数据表名称
|
||||||
this.crlColumnName = crlColumnName;
|
*/
|
||||||
}
|
public String getTableName() {
|
||||||
/**
|
return tableName;
|
||||||
* 获取:数据表权限控制列名
|
}
|
||||||
*/
|
|
||||||
public String getCrlColumnName() {
|
/**
|
||||||
return crlColumnName;
|
* 设置:所属模块
|
||||||
}
|
*/
|
||||||
/**
|
public void setModuleName(String moduleName) {
|
||||||
* 设置:权限code,all_开头表示查看所有数据的权限,sup_开头表示查看下级数据的权限,own_开头表示查看本级数据的权限
|
this.moduleName = moduleName;
|
||||||
*/
|
}
|
||||||
public void setPermCode(String permCode) {
|
|
||||||
this.permCode = permCode;
|
/**
|
||||||
}
|
* 获取:所属模块
|
||||||
/**
|
*/
|
||||||
* 获取:权限code,all_开头表示查看所有数据的权限,sup_开头表示查看下级数据的权限,own_开头表示查看本级数据的权限
|
public String getModuleName() {
|
||||||
*/
|
return moduleName;
|
||||||
public String getPermCode() {
|
}
|
||||||
return permCode;
|
|
||||||
}
|
/**
|
||||||
/**
|
* 设置:用户权限控制属性名
|
||||||
* 设置:排序
|
*/
|
||||||
*/
|
public void setCrlAttrName(String crlAttrName) {
|
||||||
public void setOrderNum(Integer orderNum) {
|
this.crlAttrName = crlAttrName;
|
||||||
this.orderNum = orderNum;
|
}
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 获取:排序
|
* 获取:用户权限控制属性名
|
||||||
*/
|
*/
|
||||||
public Integer getOrderNum() {
|
public String getCrlAttrName() {
|
||||||
return orderNum;
|
return crlAttrName;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 设置:创建时间
|
/**
|
||||||
*/
|
* 设置:数据表权限控制列名
|
||||||
public void setGmtCreate(Date gmtCreate) {
|
*/
|
||||||
this.gmtCreate = gmtCreate;
|
public void setCrlColumnName(String crlColumnName) {
|
||||||
}
|
this.crlColumnName = crlColumnName;
|
||||||
/**
|
}
|
||||||
* 获取:创建时间
|
|
||||||
*/
|
/**
|
||||||
public Date getGmtCreate() {
|
* 获取:数据表权限控制列名
|
||||||
return gmtCreate;
|
*/
|
||||||
}
|
public String getCrlColumnName() {
|
||||||
/**
|
return crlColumnName;
|
||||||
* 设置:修改时间
|
}
|
||||||
*/
|
|
||||||
public void setGmtModified(Date gmtModified) {
|
/**
|
||||||
this.gmtModified = gmtModified;
|
* 设置:权限code,all_开头表示查看所有数据的权限,sup_开头表示查看下级数据的权限,own_开头表示查看本级数据的权限
|
||||||
}
|
*/
|
||||||
/**
|
public void setPermCode(String permCode) {
|
||||||
* 获取:修改时间
|
this.permCode = permCode;
|
||||||
*/
|
}
|
||||||
public Date getGmtModified() {
|
|
||||||
return gmtModified;
|
/**
|
||||||
}
|
* 获取:权限code,all_开头表示查看所有数据的权限,sup_开头表示查看下级数据的权限,own_开头表示查看本级数据的权限
|
||||||
|
*/
|
||||||
|
public String getPermCode() {
|
||||||
|
return permCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置:排序
|
||||||
|
*/
|
||||||
|
public void setOrderNum(Integer orderNum) {
|
||||||
|
this.orderNum = orderNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取:排序
|
||||||
|
*/
|
||||||
|
public Integer getOrderNum() {
|
||||||
|
return orderNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置:创建时间
|
||||||
|
*/
|
||||||
|
public void setGmtCreate(Date gmtCreate) {
|
||||||
|
this.gmtCreate = gmtCreate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取:创建时间
|
||||||
|
*/
|
||||||
|
public Date getGmtCreate() {
|
||||||
|
return gmtCreate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置:修改时间
|
||||||
|
*/
|
||||||
|
public void setGmtModified(Date gmtModified) {
|
||||||
|
this.gmtModified = gmtModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取:修改时间
|
||||||
|
*/
|
||||||
|
public Date getGmtModified() {
|
||||||
|
return gmtModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DataPermDO that = (DataPermDO) o;
|
||||||
|
return Objects.equals(id, that.id) && Objects.equals(name, that.name)
|
||||||
|
&& Objects.equals(tableName, that.tableName) && Objects.equals(moduleName, that.moduleName)
|
||||||
|
&& Objects.equals(crlAttrName, that.crlAttrName) && Objects.equals(crlColumnName,
|
||||||
|
that.crlColumnName) && Objects.equals(permCode, that.permCode) && Objects.equals(orderNum,
|
||||||
|
that.orderNum) && Objects.equals(gmtCreate, that.gmtCreate) && Objects.equals(gmtModified,
|
||||||
|
that.gmtModified);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id, name, tableName, moduleName, crlAttrName, crlColumnName, permCode, orderNum, gmtCreate,
|
||||||
|
gmtModified);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package com.java2nb.system.service.impl;
|
package com.java2nb.system.service.impl;
|
||||||
|
|
||||||
import com.java2nb.common.domain.DictDO;
|
|
||||||
import com.java2nb.common.domain.Tree;
|
import com.java2nb.common.domain.Tree;
|
||||||
import com.java2nb.common.utils.BuildTree;
|
import com.java2nb.common.utils.BuildTree;
|
||||||
import com.java2nb.common.utils.IdWorker;
|
import com.java2nb.common.utils.IdWorker;
|
||||||
|
import com.java2nb.system.dao.DataPermDao;
|
||||||
import com.java2nb.system.dao.RoleDataPermDao;
|
import com.java2nb.system.dao.RoleDataPermDao;
|
||||||
|
import com.java2nb.system.domain.DataPermDO;
|
||||||
|
import com.java2nb.system.service.DataPermService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@ -12,119 +14,116 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import com.java2nb.system.dao.DataPermDao;
|
|
||||||
import com.java2nb.system.domain.DataPermDO;
|
|
||||||
import com.java2nb.system.service.DataPermService;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class DataPermServiceImpl implements DataPermService {
|
public class DataPermServiceImpl implements DataPermService {
|
||||||
@Autowired
|
|
||||||
private DataPermDao dataPermDao;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RoleDataPermDao roleDataPermDao;
|
private DataPermDao dataPermDao;
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataPermDO get(Long id){
|
|
||||||
return dataPermDao.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<DataPermDO> list(Map<String, Object> map){
|
|
||||||
return dataPermDao.list(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int count(Map<String, Object> map){
|
|
||||||
return dataPermDao.count(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int save(DataPermDO dataPerm){
|
|
||||||
return dataPermDao.save(dataPerm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int update(DataPermDO dataPerm){
|
|
||||||
return dataPermDao.update(dataPerm);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int remove(Long id){
|
|
||||||
return dataPermDao.remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int batchRemove(Long[] ids){
|
|
||||||
return dataPermDao.batchRemove(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Autowired
|
||||||
public List<DataPermDO> listModuleName() {
|
private RoleDataPermDao roleDataPermDao;
|
||||||
return dataPermDao.listModuleName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tree<DataPermDO> getTree() {
|
public DataPermDO get(Long id) {
|
||||||
List<Tree<DataPermDO>> trees = new ArrayList<Tree<DataPermDO>>();
|
return dataPermDao.get(id);
|
||||||
List<DataPermDO> permDOs = dataPermDao.list(new HashMap<>(16));
|
}
|
||||||
Map<String,String> topTree = new HashMap<>();
|
|
||||||
for (DataPermDO permDO : permDOs) {
|
|
||||||
Tree<DataPermDO> tree = new Tree<>();
|
|
||||||
tree.setId(permDO.getId().toString());
|
|
||||||
if(!topTree.containsKey(permDO.getModuleName())){
|
|
||||||
Tree<DataPermDO> parentTree = new Tree<>();
|
|
||||||
String id = new IdWorker().nextId()+"";
|
|
||||||
parentTree.setId(id);
|
|
||||||
parentTree.setParentId(0+"");
|
|
||||||
parentTree.setText(permDO.getModuleName());
|
|
||||||
topTree.put(permDO.getModuleName(),id);
|
|
||||||
trees.add(parentTree);
|
|
||||||
}
|
|
||||||
tree.setParentId(topTree.get(permDO.getModuleName()));
|
|
||||||
tree.setText(permDO.getName());
|
|
||||||
trees.add(tree);
|
|
||||||
}
|
|
||||||
// 默认顶级菜单为0,根据数据库实际情况调整
|
|
||||||
Tree<DataPermDO> t = BuildTree.build(trees);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tree<DataPermDO> getTree(Long roleId) {
|
public List<DataPermDO> list(Map<String, Object> map) {
|
||||||
List<Tree<DataPermDO>> trees = new ArrayList<Tree<DataPermDO>>();
|
return dataPermDao.list(map);
|
||||||
List<DataPermDO> permDOs = dataPermDao.list(new HashMap<>(16));
|
}
|
||||||
List<Long> permIds = roleDataPermDao.listPermIdByRoleId(roleId);
|
|
||||||
Map<String,String> topTree = new HashMap<>();
|
@Override
|
||||||
for (DataPermDO permDO : permDOs) {
|
public int count(Map<String, Object> map) {
|
||||||
Tree<DataPermDO> tree = new Tree<>();
|
return dataPermDao.count(map);
|
||||||
tree.setId(permDO.getId().toString());
|
}
|
||||||
if(!topTree.containsKey(permDO.getModuleName())){
|
|
||||||
Tree<DataPermDO> parentTree = new Tree<>();
|
@Override
|
||||||
String id = new IdWorker().nextId()+"";
|
public int save(DataPermDO dataPerm) {
|
||||||
parentTree.setId(id);
|
return dataPermDao.save(dataPerm);
|
||||||
parentTree.setParentId(0+"");
|
}
|
||||||
parentTree.setText(permDO.getModuleName());
|
|
||||||
topTree.put(permDO.getModuleName(),id);
|
@Override
|
||||||
trees.add(parentTree);
|
public int update(DataPermDO dataPerm) {
|
||||||
}
|
return dataPermDao.update(dataPerm);
|
||||||
tree.setParentId(topTree.get(permDO.getModuleName()));
|
}
|
||||||
tree.setText(permDO.getName());
|
|
||||||
Map<String, Object> state = new HashMap<>(16);
|
@Override
|
||||||
if (permIds.contains(permDO.getId())) {
|
public int remove(Long id) {
|
||||||
state.put("selected", true);
|
return dataPermDao.remove(id);
|
||||||
} else {
|
}
|
||||||
state.put("selected", false);
|
|
||||||
}
|
@Override
|
||||||
tree.setState(state);
|
public int batchRemove(Long[] ids) {
|
||||||
trees.add(tree);
|
return dataPermDao.batchRemove(ids);
|
||||||
}
|
}
|
||||||
// 默认顶级菜单为0,根据数据库实际情况调整
|
|
||||||
Tree<DataPermDO> t = BuildTree.build(trees);
|
@Override
|
||||||
return t;
|
public List<DataPermDO> listModuleName() {
|
||||||
}
|
return dataPermDao.listModuleName().stream().distinct().collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tree<DataPermDO> getTree() {
|
||||||
|
List<Tree<DataPermDO>> trees = new ArrayList<Tree<DataPermDO>>();
|
||||||
|
List<DataPermDO> permDOs = dataPermDao.list(new HashMap<>(16));
|
||||||
|
Map<String, String> topTree = new HashMap<>();
|
||||||
|
for (DataPermDO permDO : permDOs) {
|
||||||
|
Tree<DataPermDO> tree = new Tree<>();
|
||||||
|
tree.setId(permDO.getId().toString());
|
||||||
|
if (!topTree.containsKey(permDO.getModuleName())) {
|
||||||
|
Tree<DataPermDO> parentTree = new Tree<>();
|
||||||
|
String id = new IdWorker().nextId() + "";
|
||||||
|
parentTree.setId(id);
|
||||||
|
parentTree.setParentId(0 + "");
|
||||||
|
parentTree.setText(permDO.getModuleName());
|
||||||
|
topTree.put(permDO.getModuleName(), id);
|
||||||
|
trees.add(parentTree);
|
||||||
|
}
|
||||||
|
tree.setParentId(topTree.get(permDO.getModuleName()));
|
||||||
|
tree.setText(permDO.getName());
|
||||||
|
trees.add(tree);
|
||||||
|
}
|
||||||
|
// 默认顶级菜单为0,根据数据库实际情况调整
|
||||||
|
Tree<DataPermDO> t = BuildTree.build(trees);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tree<DataPermDO> getTree(Long roleId) {
|
||||||
|
List<Tree<DataPermDO>> trees = new ArrayList<Tree<DataPermDO>>();
|
||||||
|
List<DataPermDO> permDOs = dataPermDao.list(new HashMap<>(16));
|
||||||
|
List<Long> permIds = roleDataPermDao.listPermIdByRoleId(roleId);
|
||||||
|
Map<String, String> topTree = new HashMap<>();
|
||||||
|
for (DataPermDO permDO : permDOs) {
|
||||||
|
Tree<DataPermDO> tree = new Tree<>();
|
||||||
|
tree.setId(permDO.getId().toString());
|
||||||
|
if (!topTree.containsKey(permDO.getModuleName())) {
|
||||||
|
Tree<DataPermDO> parentTree = new Tree<>();
|
||||||
|
String id = new IdWorker().nextId() + "";
|
||||||
|
parentTree.setId(id);
|
||||||
|
parentTree.setParentId(0 + "");
|
||||||
|
parentTree.setText(permDO.getModuleName());
|
||||||
|
topTree.put(permDO.getModuleName(), id);
|
||||||
|
trees.add(parentTree);
|
||||||
|
}
|
||||||
|
tree.setParentId(topTree.get(permDO.getModuleName()));
|
||||||
|
tree.setText(permDO.getName());
|
||||||
|
Map<String, Object> state = new HashMap<>(16);
|
||||||
|
if (permIds.contains(permDO.getId())) {
|
||||||
|
state.put("selected", true);
|
||||||
|
} else {
|
||||||
|
state.put("selected", false);
|
||||||
|
}
|
||||||
|
tree.setState(state);
|
||||||
|
trees.add(tree);
|
||||||
|
}
|
||||||
|
// 默认顶级菜单为0,根据数据库实际情况调整
|
||||||
|
Tree<DataPermDO> t = BuildTree.build(trees);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user