mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 22:57:17 +08:00 
			
		
		
		
	优化:优化后端公共 CRUD 组件-修改接口,将 id 从请求体提取到路径变量,更符合 RESTful 风格
This commit is contained in:
		| @@ -144,7 +144,7 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q, | ||||
|     @Operation(summary = "新增数据") | ||||
|     @ResponseBody | ||||
|     @PostMapping | ||||
|     protected R<Long> add(@Validated(BaseRequest.Add.class) @RequestBody C request) { | ||||
|     protected R<Long> add(@Validated @RequestBody C request) { | ||||
|         this.checkPermission("add"); | ||||
|         Long id = baseService.add(request); | ||||
|         return R.ok("新增成功", id); | ||||
| @@ -155,14 +155,16 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q, | ||||
|      * | ||||
|      * @param request | ||||
|      *            修改信息 | ||||
|      * @param id | ||||
|      *            ID | ||||
|      * @return / | ||||
|      */ | ||||
|     @Operation(summary = "修改数据") | ||||
|     @ResponseBody | ||||
|     @PutMapping | ||||
|     protected R update(@Validated(BaseRequest.Update.class) @RequestBody C request) { | ||||
|     @PutMapping("/{id}") | ||||
|     protected R update(@Validated @RequestBody C request, @PathVariable Long id) { | ||||
|         this.checkPermission("update"); | ||||
|         baseService.update(request); | ||||
|         baseService.update(request, id); | ||||
|         return R.ok("修改成功"); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -18,14 +18,10 @@ package top.charles7c.cnadmin.common.base; | ||||
|  | ||||
| import java.io.Serializable; | ||||
|  | ||||
| import javax.validation.constraints.NotNull; | ||||
| import javax.validation.constraints.Null; | ||||
| import javax.validation.groups.Default; | ||||
|  | ||||
| import lombok.Data; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| /** | ||||
|  * Request 基类 | ||||
|  * | ||||
| @@ -37,14 +33,6 @@ public class BaseRequest implements Serializable { | ||||
|  | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * ID | ||||
|      */ | ||||
|     @Schema(description = "ID") | ||||
|     @Null(message = "新增时,ID 必须为空", groups = Add.class) | ||||
|     @NotNull(message = "修改时,ID 不能为空", groups = Update.class) | ||||
|     private Long id; | ||||
|  | ||||
|     /** | ||||
|      * 分组校验-创建 | ||||
|      */ | ||||
|   | ||||
| @@ -100,8 +100,10 @@ public interface BaseService<V, D, Q, C extends BaseRequest> { | ||||
|      * | ||||
|      * @param request | ||||
|      *            修改信息 | ||||
|      * @param id | ||||
|      *            ID | ||||
|      */ | ||||
|     void update(C request); | ||||
|     void update(C request, Long id); | ||||
|  | ||||
|     /** | ||||
|      * 删除 | ||||
|   | ||||
| @@ -28,9 +28,6 @@ import org.springframework.transaction.annotation.Transactional; | ||||
|  | ||||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
| import com.baomidou.mybatisplus.core.metadata.TableInfo; | ||||
| import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Assert; | ||||
| import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; | ||||
|  | ||||
| import cn.hutool.core.bean.BeanUtil; | ||||
| @@ -75,7 +72,7 @@ import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||
|  * @author Charles7c | ||||
|  * @since 2023/1/26 21:52 | ||||
|  */ | ||||
| public abstract class BaseServiceImpl<M extends BaseMapper<T>, T, V, D, Q, C extends BaseRequest> | ||||
| public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseDO, V, D, Q, C extends BaseRequest> | ||||
|     implements BaseService<V, D, Q, C> { | ||||
|  | ||||
|     @Autowired | ||||
| @@ -84,14 +81,12 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T, V, D, Q, C ext | ||||
|     private final Class<T> entityClass; | ||||
|     private final Class<V> voClass; | ||||
|     private final Class<D> detailVoClass; | ||||
|     private final String entityIdName; | ||||
|  | ||||
|     public BaseServiceImpl() { | ||||
|         this.entityClass = (Class<T>)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 1); | ||||
|         this.voClass = (Class<V>)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 2); | ||||
|         this.detailVoClass = | ||||
|             (Class<D>)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 3); | ||||
|         this.entityIdName = this.currentEntityIdName(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -178,19 +173,15 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T, V, D, Q, C ext | ||||
|         if (request == null) { | ||||
|             return 0L; | ||||
|         } | ||||
|         // 保存信息 | ||||
|         T entity = BeanUtil.copyProperties(request, entityClass); | ||||
|         baseMapper.insert(entity); | ||||
|         TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass); | ||||
|         Object idValue = tableInfo.getPropertyValue(entity, entityIdName); | ||||
|         return Convert.toLong(idValue); | ||||
|         return entity.getId(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void update(C request) { | ||||
|         Object idValue = ReflectUtil.getFieldValue(request, entityIdName); | ||||
|         T entity = this.getById(idValue); | ||||
|     public void update(C request, Long id) { | ||||
|         T entity = this.getById(id); | ||||
|         BeanUtil.copyProperties(request, entity, CopyOptions.create().ignoreNullValue()); | ||||
|         baseMapper.updateById(entity); | ||||
|     } | ||||
| @@ -258,17 +249,4 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T, V, D, Q, C ext | ||||
|             detailVO.setUpdateUserString(ExceptionUtils.exToNull(() -> userService.getNicknameById(updateUser))); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取实体类 ID 名称 | ||||
|      * | ||||
|      * @return 实体类 ID 名称 | ||||
|      */ | ||||
|     private String currentEntityIdName() { | ||||
|         TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass); | ||||
|         Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!"); | ||||
|         String keyProperty = tableInfo.getKeyProperty(); | ||||
|         Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!"); | ||||
|         return keyProperty; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -61,7 +61,7 @@ public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptVO, | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public Long add(DeptRequest request) { | ||||
|         String name = request.getName(); | ||||
|         boolean isExists = this.checkNameExists(name, request.getParentId(), request.getId()); | ||||
|         boolean isExists = this.checkNameExists(name, request.getParentId(), null); | ||||
|         CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", name)); | ||||
|  | ||||
|         request.setStatus(DisEnableStatusEnum.ENABLE); | ||||
| @@ -73,20 +73,20 @@ public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptVO, | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void update(DeptRequest request) { | ||||
|     public void update(DeptRequest request, Long id) { | ||||
|         String name = request.getName(); | ||||
|         boolean isExists = this.checkNameExists(name, request.getParentId(), request.getId()); | ||||
|         boolean isExists = this.checkNameExists(name, request.getParentId(), id); | ||||
|         CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", name)); | ||||
|  | ||||
|         DeptDO oldDept = baseMapper.selectById(request.getId()); | ||||
|         DeptDO oldDept = baseMapper.selectById(id); | ||||
|         // 更新祖级列表 | ||||
|         if (!Objects.equals(oldDept.getParentId(), request.getParentId())) { | ||||
|             DeptDO newParentDept = baseMapper.selectById(request.getParentId()); | ||||
|             CheckUtils.throwIfNull(newParentDept, "上级部门不存在"); | ||||
|             request.setAncestors(String.format("%s,%s", newParentDept.getAncestors(), request.getParentId())); | ||||
|             this.updateChildrenAncestors(request.getId(), request.getAncestors(), oldDept.getAncestors()); | ||||
|             this.updateChildrenAncestors(id, request.getAncestors(), oldDept.getAncestors()); | ||||
|         } | ||||
|         super.update(request); | ||||
|         super.update(request, id); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -50,7 +50,7 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO, | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public Long add(MenuRequest request) { | ||||
|         String title = request.getTitle(); | ||||
|         boolean isExists = this.checkNameExists(title, request.getParentId(), request.getId()); | ||||
|         boolean isExists = this.checkNameExists(title, request.getParentId(), null); | ||||
|         CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", title)); | ||||
|  | ||||
|         request.setStatus(DisEnableStatusEnum.ENABLE); | ||||
| @@ -59,12 +59,12 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO, | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void update(MenuRequest request) { | ||||
|     public void update(MenuRequest request, Long id) { | ||||
|         String title = request.getTitle(); | ||||
|         boolean isExists = this.checkNameExists(title, request.getParentId(), request.getId()); | ||||
|         boolean isExists = this.checkNameExists(title, request.getParentId(), id); | ||||
|         CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", title)); | ||||
|  | ||||
|         super.update(request); | ||||
|         super.update(request, id); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -65,9 +65,9 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO, | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public Long add(RoleRequest request) { | ||||
|         String name = request.getName(); | ||||
|         CheckUtils.throwIf(() -> this.checkNameExists(name, request.getId()), String.format("新增失败,'%s'已存在", name)); | ||||
|         CheckUtils.throwIf(() -> this.checkNameExists(name, null), String.format("新增失败,'%s'已存在", name)); | ||||
|         String code = request.getCode(); | ||||
|         CheckUtils.throwIf(() -> this.checkCodeExists(code, request.getId()), String.format("新增失败,'%s'已存在", code)); | ||||
|         CheckUtils.throwIf(() -> this.checkCodeExists(code, null), String.format("新增失败,'%s'已存在", code)); | ||||
|  | ||||
|         // 新增信息 | ||||
|         request.setStatus(DisEnableStatusEnum.ENABLE); | ||||
| @@ -81,19 +81,18 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO, | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void update(RoleRequest request) { | ||||
|     public void update(RoleRequest request, Long id) { | ||||
|         String name = request.getName(); | ||||
|         CheckUtils.throwIf(() -> this.checkNameExists(name, request.getId()), String.format("修改失败,'%s'已存在", name)); | ||||
|         CheckUtils.throwIf(() -> this.checkNameExists(name, id), String.format("修改失败,'%s'已存在", name)); | ||||
|         String code = request.getCode(); | ||||
|         CheckUtils.throwIf(() -> this.checkCodeExists(code, request.getId()), String.format("修改失败,'%s'已存在", code)); | ||||
|         CheckUtils.throwIf(() -> this.checkCodeExists(code, id), String.format("修改失败,'%s'已存在", code)); | ||||
|  | ||||
|         // 更新信息 | ||||
|         super.update(request); | ||||
|         Long roleId = request.getId(); | ||||
|         super.update(request, id); | ||||
|         // 保存角色和菜单关联 | ||||
|         roleMenuService.save(request.getMenuIds(), roleId); | ||||
|         roleMenuService.save(request.getMenuIds(), id); | ||||
|         // 保存角色和部门关联 | ||||
|         roleDeptService.save(request.getDeptIds(), roleId); | ||||
|         roleDeptService.save(request.getDeptIds(), id); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -75,7 +75,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO, | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public Long add(UserRequest request) { | ||||
|         String username = request.getUsername(); | ||||
|         boolean isExists = this.checkNameExists(username, request.getId()); | ||||
|         boolean isExists = this.checkNameExists(username, null); | ||||
|         CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", username)); | ||||
|  | ||||
|         // 新增信息 | ||||
| @@ -91,16 +91,15 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO, | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void update(UserRequest request) { | ||||
|     public void update(UserRequest request, Long id) { | ||||
|         String username = request.getUsername(); | ||||
|         boolean isExists = this.checkNameExists(username, request.getId()); | ||||
|         boolean isExists = this.checkNameExists(username, id); | ||||
|         CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", username)); | ||||
|  | ||||
|         // 更新信息 | ||||
|         super.update(request); | ||||
|         Long userId = request.getId(); | ||||
|         super.update(request, id); | ||||
|         // 保存用户和角色关联 | ||||
|         userRoleService.save(request.getRoleIds(), userId); | ||||
|         userRoleService.save(request.getRoleIds(), id); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -40,8 +40,8 @@ export function addDept(req: DeptRecord) { | ||||
|   return axios.post(BASE_URL, req); | ||||
| } | ||||
|  | ||||
| export function updateDept(req: DeptRecord) { | ||||
|   return axios.put(BASE_URL, req); | ||||
| export function updateDept(req: DeptRecord, id: string) { | ||||
|   return axios.put(`${BASE_URL}/${id}`, req); | ||||
| } | ||||
|  | ||||
| export function deleteDept(ids: string | Array<string>) { | ||||
|   | ||||
| @@ -48,8 +48,8 @@ export function addMenu(req: MenuRecord) { | ||||
|   return axios.post(BASE_URL, req); | ||||
| } | ||||
|  | ||||
| export function updateMenu(req: MenuRecord) { | ||||
|   return axios.put(BASE_URL, req); | ||||
| export function updateMenu(req: MenuRecord, id: string) { | ||||
|   return axios.put(`${BASE_URL}/${id}`, req); | ||||
| } | ||||
|  | ||||
| export function deleteMenu(ids: string | Array<string>) { | ||||
|   | ||||
| @@ -50,8 +50,8 @@ export function addRole(req: RoleRecord) { | ||||
|   return axios.post(BASE_URL, req); | ||||
| } | ||||
|  | ||||
| export function updateRole(req: RoleRecord) { | ||||
|   return axios.put(BASE_URL, req); | ||||
| export function updateRole(req: RoleRecord, id: string) { | ||||
|   return axios.put(`${BASE_URL}/${id}`, req); | ||||
| } | ||||
|  | ||||
| export function deleteRole(ids: string | Array<string>) { | ||||
|   | ||||
| @@ -55,8 +55,8 @@ export function addUser(req: UserRecord) { | ||||
|   return axios.post(BASE_URL, req); | ||||
| } | ||||
|  | ||||
| export function updateUser(req: UserRecord) { | ||||
|   return axios.put(BASE_URL, req); | ||||
| export function updateUser(req: UserRecord, id: string) { | ||||
|   return axios.put(`${BASE_URL}/${id}`, req); | ||||
| } | ||||
|  | ||||
| export function deleteUser(ids: string | Array<string>) { | ||||
|   | ||||
| @@ -431,7 +431,7 @@ | ||||
|     proxy.$refs.formRef.validate((valid: any) => { | ||||
|       if (!valid) { | ||||
|         if (form.value.id !== undefined) { | ||||
|           updateDept(form.value).then((res) => { | ||||
|           updateDept(form.value, form.value.id).then((res) => { | ||||
|             handleCancel(); | ||||
|             getList(); | ||||
|             proxy.$message.success(res.msg); | ||||
| @@ -559,14 +559,16 @@ | ||||
|    * @param record 记录信息 | ||||
|    */ | ||||
|   const handleChangeStatus = (record: DeptRecord) => { | ||||
|     const tip = record.status === 1 ? '启用' : '禁用'; | ||||
|     updateDept(record) | ||||
|       .then(() => { | ||||
|         proxy.$message.success(`${tip}成功`); | ||||
|       }) | ||||
|       .catch(() => { | ||||
|         record.status = record.status === 1 ? 2 : 1; | ||||
|       }); | ||||
|     if (record.id) { | ||||
|       const tip = record.status === 1 ? '启用' : '禁用'; | ||||
|       updateDept(record, record.id) | ||||
|         .then(() => { | ||||
|           proxy.$message.success(`${tip}成功`); | ||||
|         }) | ||||
|         .catch(() => { | ||||
|           record.status = record.status === 1 ? 2 : 1; | ||||
|         }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   /** | ||||
|   | ||||
| @@ -482,7 +482,7 @@ | ||||
|     proxy.$refs.formRef.validate((valid: any) => { | ||||
|       if (!valid) { | ||||
|         if (form.value.id !== undefined) { | ||||
|           updateMenu(form.value).then((res) => { | ||||
|           updateMenu(form.value, form.value.id).then((res) => { | ||||
|             handleCancel(); | ||||
|             getList(); | ||||
|             proxy.$message.success(res.msg); | ||||
| @@ -596,14 +596,16 @@ | ||||
|    * @param record 记录信息 | ||||
|    */ | ||||
|   const handleChangeStatus = (record: MenuRecord) => { | ||||
|     const tip = record.status === 1 ? '启用' : '禁用'; | ||||
|     updateMenu(record) | ||||
|       .then(() => { | ||||
|         proxy.$message.success(`${tip}成功`); | ||||
|       }) | ||||
|       .catch(() => { | ||||
|         record.status = record.status === 1 ? 2 : 1; | ||||
|       }); | ||||
|     if (record.id) { | ||||
|       const tip = record.status === 1 ? '启用' : '禁用'; | ||||
|       updateMenu(record, record.id) | ||||
|         .then(() => { | ||||
|           proxy.$message.success(`${tip}成功`); | ||||
|         }) | ||||
|         .catch(() => { | ||||
|           record.status = record.status === 1 ? 2 : 1; | ||||
|         }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   /** | ||||
|   | ||||
| @@ -625,7 +625,7 @@ | ||||
|         if (form.value.id !== undefined) { | ||||
|           form.value.menuIds = getMenuAllCheckedKeys(); | ||||
|           form.value.deptIds = getDeptAllCheckedKeys(); | ||||
|           updateRole(form.value).then((res) => { | ||||
|           updateRole(form.value, form.value.id).then((res) => { | ||||
|             handleCancel(); | ||||
|             getList(); | ||||
|             proxy.$message.success(res.msg); | ||||
| @@ -731,14 +731,16 @@ | ||||
|    * @param record 记录信息 | ||||
|    */ | ||||
|   const handleChangeStatus = (record: RoleRecord) => { | ||||
|     const tip = record.status === 1 ? '启用' : '禁用'; | ||||
|     updateRole(record) | ||||
|       .then(() => { | ||||
|         proxy.$message.success(`${tip}成功`); | ||||
|       }) | ||||
|       .catch(() => { | ||||
|         record.status = record.status === 1 ? 2 : 1; | ||||
|       }); | ||||
|     if (record.id) { | ||||
|       const tip = record.status === 1 ? '启用' : '禁用'; | ||||
|       updateRole(record, record.id) | ||||
|         .then(() => { | ||||
|           proxy.$message.success(`${tip}成功`); | ||||
|         }) | ||||
|         .catch(() => { | ||||
|           record.status = record.status === 1 ? 2 : 1; | ||||
|         }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   /** | ||||
|   | ||||
| @@ -695,7 +695,7 @@ | ||||
|     proxy.$refs.formRef.validate((valid: any) => { | ||||
|       if (!valid) { | ||||
|         if (form.value.id !== undefined) { | ||||
|           updateUser(form.value).then((res) => { | ||||
|           updateUser(form.value, form.value.id).then((res) => { | ||||
|             handleCancel(); | ||||
|             getList(); | ||||
|             proxy.$message.success(res.msg); | ||||
| @@ -825,14 +825,16 @@ | ||||
|    * @param record 记录信息 | ||||
|    */ | ||||
|   const handleChangeStatus = (record: UserRecord) => { | ||||
|     const tip = record.status === 1 ? '启用' : '禁用'; | ||||
|     updateUser(record) | ||||
|       .then(() => { | ||||
|         proxy.$message.success(`${tip}成功`); | ||||
|       }) | ||||
|       .catch(() => { | ||||
|         record.status = record.status === 1 ? 2 : 1; | ||||
|       }); | ||||
|     if (record.id) { | ||||
|       const tip = record.status === 1 ? '启用' : '禁用'; | ||||
|       updateUser(record, record.id) | ||||
|         .then(() => { | ||||
|           proxy.$message.success(`${tip}成功`); | ||||
|         }) | ||||
|         .catch(() => { | ||||
|           record.status = record.status === 1 ? 2 : 1; | ||||
|         }); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   /** | ||||
|   | ||||
| @@ -74,9 +74,8 @@ public class UserCenterController { | ||||
|     @PatchMapping("/basic/info") | ||||
|     public R updateBasicInfo(@Validated @RequestBody UpdateBasicInfoRequest updateBasicInfoRequest) { | ||||
|         UserRequest userRequest = new UserRequest(); | ||||
|         userRequest.setId(LoginHelper.getUserId()); | ||||
|         BeanUtil.copyProperties(updateBasicInfoRequest, userRequest); | ||||
|         userService.update(userRequest); | ||||
|         userService.update(userRequest, LoginHelper.getUserId()); | ||||
|         return R.ok("修改成功"); | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user