优化:优化后端公共 CRUD 组件-修改接口,将 id 从请求体提取到路径变量,更符合 RESTful 风格

This commit is contained in:
Charles7c 2023-03-11 00:26:18 +08:00
parent 0d3f1ae633
commit 25e11ad9bc
17 changed files with 89 additions and 114 deletions

View File

@ -144,7 +144,7 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q,
@Operation(summary = "新增数据") @Operation(summary = "新增数据")
@ResponseBody @ResponseBody
@PostMapping @PostMapping
protected R<Long> add(@Validated(BaseRequest.Add.class) @RequestBody C request) { protected R<Long> add(@Validated @RequestBody C request) {
this.checkPermission("add"); this.checkPermission("add");
Long id = baseService.add(request); Long id = baseService.add(request);
return R.ok("新增成功", id); 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 request
* 修改信息 * 修改信息
* @param id
* ID
* @return / * @return /
*/ */
@Operation(summary = "修改数据") @Operation(summary = "修改数据")
@ResponseBody @ResponseBody
@PutMapping @PutMapping("/{id}")
protected R update(@Validated(BaseRequest.Update.class) @RequestBody C request) { protected R update(@Validated @RequestBody C request, @PathVariable Long id) {
this.checkPermission("update"); this.checkPermission("update");
baseService.update(request); baseService.update(request, id);
return R.ok("修改成功"); return R.ok("修改成功");
} }

View File

@ -18,14 +18,10 @@ package top.charles7c.cnadmin.common.base;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.groups.Default; import javax.validation.groups.Default;
import lombok.Data; import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
/** /**
* Request 基类 * Request 基类
* *
@ -37,14 +33,6 @@ public class BaseRequest implements Serializable {
private static final long serialVersionUID = 1L; 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;
/** /**
* 分组校验-创建 * 分组校验-创建
*/ */

View File

@ -100,8 +100,10 @@ public interface BaseService<V, D, Q, C extends BaseRequest> {
* *
* @param request * @param request
* 修改信息 * 修改信息
* @param id
* ID
*/ */
void update(C request); void update(C request, Long id);
/** /**
* 删除 * 删除

View File

@ -28,9 +28,6 @@ import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; 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 com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
@ -75,7 +72,7 @@ import top.charles7c.cnadmin.common.util.validate.CheckUtils;
* @author Charles7c * @author Charles7c
* @since 2023/1/26 21:52 * @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> { implements BaseService<V, D, Q, C> {
@Autowired @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<T> entityClass;
private final Class<V> voClass; private final Class<V> voClass;
private final Class<D> detailVoClass; private final Class<D> detailVoClass;
private final String entityIdName;
public BaseServiceImpl() { public BaseServiceImpl() {
this.entityClass = (Class<T>)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 1); this.entityClass = (Class<T>)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 1);
this.voClass = (Class<V>)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 2); this.voClass = (Class<V>)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 2);
this.detailVoClass = this.detailVoClass =
(Class<D>)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 3); (Class<D>)ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 3);
this.entityIdName = this.currentEntityIdName();
} }
@Override @Override
@ -178,19 +173,15 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T, V, D, Q, C ext
if (request == null) { if (request == null) {
return 0L; return 0L;
} }
// 保存信息
T entity = BeanUtil.copyProperties(request, entityClass); T entity = BeanUtil.copyProperties(request, entityClass);
baseMapper.insert(entity); baseMapper.insert(entity);
TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass); return entity.getId();
Object idValue = tableInfo.getPropertyValue(entity, entityIdName);
return Convert.toLong(idValue);
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void update(C request) { public void update(C request, Long id) {
Object idValue = ReflectUtil.getFieldValue(request, entityIdName); T entity = this.getById(id);
T entity = this.getById(idValue);
BeanUtil.copyProperties(request, entity, CopyOptions.create().ignoreNullValue()); BeanUtil.copyProperties(request, entity, CopyOptions.create().ignoreNullValue());
baseMapper.updateById(entity); 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))); 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;
}
} }

View File

@ -61,7 +61,7 @@ public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptVO,
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long add(DeptRequest request) { public Long add(DeptRequest request) {
String name = request.getName(); 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)); CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", name));
request.setStatus(DisEnableStatusEnum.ENABLE); request.setStatus(DisEnableStatusEnum.ENABLE);
@ -73,20 +73,20 @@ public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptVO,
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void update(DeptRequest request) { public void update(DeptRequest request, Long id) {
String name = request.getName(); 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)); 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())) { if (!Objects.equals(oldDept.getParentId(), request.getParentId())) {
DeptDO newParentDept = baseMapper.selectById(request.getParentId()); DeptDO newParentDept = baseMapper.selectById(request.getParentId());
CheckUtils.throwIfNull(newParentDept, "上级部门不存在"); CheckUtils.throwIfNull(newParentDept, "上级部门不存在");
request.setAncestors(String.format("%s,%s", newParentDept.getAncestors(), request.getParentId())); 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 @Override

View File

@ -50,7 +50,7 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO,
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long add(MenuRequest request) { public Long add(MenuRequest request) {
String title = request.getTitle(); 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)); CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", title));
request.setStatus(DisEnableStatusEnum.ENABLE); request.setStatus(DisEnableStatusEnum.ENABLE);
@ -59,12 +59,12 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO,
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void update(MenuRequest request) { public void update(MenuRequest request, Long id) {
String title = request.getTitle(); 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)); CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", title));
super.update(request); super.update(request, id);
} }
@Override @Override

View File

@ -65,9 +65,9 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long add(RoleRequest request) { public Long add(RoleRequest request) {
String name = request.getName(); 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(); 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); request.setStatus(DisEnableStatusEnum.ENABLE);
@ -81,19 +81,18 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void update(RoleRequest request) { public void update(RoleRequest request, Long id) {
String name = request.getName(); 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(); 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); super.update(request, id);
Long roleId = request.getId();
// 保存角色和菜单关联 // 保存角色和菜单关联
roleMenuService.save(request.getMenuIds(), roleId); roleMenuService.save(request.getMenuIds(), id);
// 保存角色和部门关联 // 保存角色和部门关联
roleDeptService.save(request.getDeptIds(), roleId); roleDeptService.save(request.getDeptIds(), id);
} }
@Override @Override

View File

@ -75,7 +75,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long add(UserRequest request) { public Long add(UserRequest request) {
String username = request.getUsername(); String username = request.getUsername();
boolean isExists = this.checkNameExists(username, request.getId()); boolean isExists = this.checkNameExists(username, null);
CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", username)); CheckUtils.throwIf(() -> isExists, String.format("新增失败,'%s'已存在", username));
// 新增信息 // 新增信息
@ -91,16 +91,15 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserVO,
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void update(UserRequest request) { public void update(UserRequest request, Long id) {
String username = request.getUsername(); String username = request.getUsername();
boolean isExists = this.checkNameExists(username, request.getId()); boolean isExists = this.checkNameExists(username, id);
CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", username)); CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", username));
// 更新信息 // 更新信息
super.update(request); super.update(request, id);
Long userId = request.getId();
// 保存用户和角色关联 // 保存用户和角色关联
userRoleService.save(request.getRoleIds(), userId); userRoleService.save(request.getRoleIds(), id);
} }
@Override @Override

View File

@ -40,8 +40,8 @@ export function addDept(req: DeptRecord) {
return axios.post(BASE_URL, req); return axios.post(BASE_URL, req);
} }
export function updateDept(req: DeptRecord) { export function updateDept(req: DeptRecord, id: string) {
return axios.put(BASE_URL, req); return axios.put(`${BASE_URL}/${id}`, req);
} }
export function deleteDept(ids: string | Array<string>) { export function deleteDept(ids: string | Array<string>) {

View File

@ -48,8 +48,8 @@ export function addMenu(req: MenuRecord) {
return axios.post(BASE_URL, req); return axios.post(BASE_URL, req);
} }
export function updateMenu(req: MenuRecord) { export function updateMenu(req: MenuRecord, id: string) {
return axios.put(BASE_URL, req); return axios.put(`${BASE_URL}/${id}`, req);
} }
export function deleteMenu(ids: string | Array<string>) { export function deleteMenu(ids: string | Array<string>) {

View File

@ -50,8 +50,8 @@ export function addRole(req: RoleRecord) {
return axios.post(BASE_URL, req); return axios.post(BASE_URL, req);
} }
export function updateRole(req: RoleRecord) { export function updateRole(req: RoleRecord, id: string) {
return axios.put(BASE_URL, req); return axios.put(`${BASE_URL}/${id}`, req);
} }
export function deleteRole(ids: string | Array<string>) { export function deleteRole(ids: string | Array<string>) {

View File

@ -55,8 +55,8 @@ export function addUser(req: UserRecord) {
return axios.post(BASE_URL, req); return axios.post(BASE_URL, req);
} }
export function updateUser(req: UserRecord) { export function updateUser(req: UserRecord, id: string) {
return axios.put(BASE_URL, req); return axios.put(`${BASE_URL}/${id}`, req);
} }
export function deleteUser(ids: string | Array<string>) { export function deleteUser(ids: string | Array<string>) {

View File

@ -431,7 +431,7 @@
proxy.$refs.formRef.validate((valid: any) => { proxy.$refs.formRef.validate((valid: any) => {
if (!valid) { if (!valid) {
if (form.value.id !== undefined) { if (form.value.id !== undefined) {
updateDept(form.value).then((res) => { updateDept(form.value, form.value.id).then((res) => {
handleCancel(); handleCancel();
getList(); getList();
proxy.$message.success(res.msg); proxy.$message.success(res.msg);
@ -559,14 +559,16 @@
* @param record 记录信息 * @param record 记录信息
*/ */
const handleChangeStatus = (record: DeptRecord) => { const handleChangeStatus = (record: DeptRecord) => {
const tip = record.status === 1 ? '启用' : '禁用'; if (record.id) {
updateDept(record) const tip = record.status === 1 ? '启用' : '禁用';
.then(() => { updateDept(record, record.id)
proxy.$message.success(`${tip}成功`); .then(() => {
}) proxy.$message.success(`${tip}成功`);
.catch(() => { })
record.status = record.status === 1 ? 2 : 1; .catch(() => {
}); record.status = record.status === 1 ? 2 : 1;
});
}
}; };
/** /**

View File

@ -482,7 +482,7 @@
proxy.$refs.formRef.validate((valid: any) => { proxy.$refs.formRef.validate((valid: any) => {
if (!valid) { if (!valid) {
if (form.value.id !== undefined) { if (form.value.id !== undefined) {
updateMenu(form.value).then((res) => { updateMenu(form.value, form.value.id).then((res) => {
handleCancel(); handleCancel();
getList(); getList();
proxy.$message.success(res.msg); proxy.$message.success(res.msg);
@ -596,14 +596,16 @@
* @param record 记录信息 * @param record 记录信息
*/ */
const handleChangeStatus = (record: MenuRecord) => { const handleChangeStatus = (record: MenuRecord) => {
const tip = record.status === 1 ? '启用' : '禁用'; if (record.id) {
updateMenu(record) const tip = record.status === 1 ? '启用' : '禁用';
.then(() => { updateMenu(record, record.id)
proxy.$message.success(`${tip}成功`); .then(() => {
}) proxy.$message.success(`${tip}成功`);
.catch(() => { })
record.status = record.status === 1 ? 2 : 1; .catch(() => {
}); record.status = record.status === 1 ? 2 : 1;
});
}
}; };
/** /**

View File

@ -625,7 +625,7 @@
if (form.value.id !== undefined) { if (form.value.id !== undefined) {
form.value.menuIds = getMenuAllCheckedKeys(); form.value.menuIds = getMenuAllCheckedKeys();
form.value.deptIds = getDeptAllCheckedKeys(); form.value.deptIds = getDeptAllCheckedKeys();
updateRole(form.value).then((res) => { updateRole(form.value, form.value.id).then((res) => {
handleCancel(); handleCancel();
getList(); getList();
proxy.$message.success(res.msg); proxy.$message.success(res.msg);
@ -731,14 +731,16 @@
* @param record 记录信息 * @param record 记录信息
*/ */
const handleChangeStatus = (record: RoleRecord) => { const handleChangeStatus = (record: RoleRecord) => {
const tip = record.status === 1 ? '启用' : '禁用'; if (record.id) {
updateRole(record) const tip = record.status === 1 ? '启用' : '禁用';
.then(() => { updateRole(record, record.id)
proxy.$message.success(`${tip}成功`); .then(() => {
}) proxy.$message.success(`${tip}成功`);
.catch(() => { })
record.status = record.status === 1 ? 2 : 1; .catch(() => {
}); record.status = record.status === 1 ? 2 : 1;
});
}
}; };
/** /**

View File

@ -695,7 +695,7 @@
proxy.$refs.formRef.validate((valid: any) => { proxy.$refs.formRef.validate((valid: any) => {
if (!valid) { if (!valid) {
if (form.value.id !== undefined) { if (form.value.id !== undefined) {
updateUser(form.value).then((res) => { updateUser(form.value, form.value.id).then((res) => {
handleCancel(); handleCancel();
getList(); getList();
proxy.$message.success(res.msg); proxy.$message.success(res.msg);
@ -825,14 +825,16 @@
* @param record 记录信息 * @param record 记录信息
*/ */
const handleChangeStatus = (record: UserRecord) => { const handleChangeStatus = (record: UserRecord) => {
const tip = record.status === 1 ? '启用' : '禁用'; if (record.id) {
updateUser(record) const tip = record.status === 1 ? '启用' : '禁用';
.then(() => { updateUser(record, record.id)
proxy.$message.success(`${tip}成功`); .then(() => {
}) proxy.$message.success(`${tip}成功`);
.catch(() => { })
record.status = record.status === 1 ? 2 : 1; .catch(() => {
}); record.status = record.status === 1 ? 2 : 1;
});
}
}; };
/** /**

View File

@ -74,9 +74,8 @@ public class UserCenterController {
@PatchMapping("/basic/info") @PatchMapping("/basic/info")
public R updateBasicInfo(@Validated @RequestBody UpdateBasicInfoRequest updateBasicInfoRequest) { public R updateBasicInfo(@Validated @RequestBody UpdateBasicInfoRequest updateBasicInfoRequest) {
UserRequest userRequest = new UserRequest(); UserRequest userRequest = new UserRequest();
userRequest.setId(LoginHelper.getUserId());
BeanUtil.copyProperties(updateBasicInfoRequest, userRequest); BeanUtil.copyProperties(updateBasicInfoRequest, userRequest);
userService.update(userRequest); userService.update(userRequest, LoginHelper.getUserId());
return R.ok("修改成功"); return R.ok("修改成功");
} }