完成部门管理

This commit is contained in:
none 2023-02-19 17:12:52 +08:00
parent 384d61437f
commit 4ada5e9ff8
11 changed files with 88 additions and 137 deletions

18
pom.xml
View File

@ -20,12 +20,6 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -87,18 +81,6 @@
<version>2.3.2</version>
</dependency>
<!--Fastjson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.21</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2-extension</artifactId>
<version>2.0.21</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>

View File

@ -24,9 +24,18 @@ public class DepartmentBus {
if (parentDepartment == null) {
throw new NotFoundException("父级部门不存在");
}
parentChain = parentDepartment.getParentChain() + "," + parentId;
String pc = parentDepartment.getParentChain();
parentChain = pc == null || pc.length() == 0 ? parentId + "" : pc + "," + parentId;
}
return parentChain;
}
public static String childrenParentChain(Department department) {
String prefix = department.getId() + "";
if (department.getParentChain() != null && department.getParentChain().length() > 0) {
prefix = department.getParentChain() + "," + prefix;
}
return prefix;
}
}

View File

@ -1,10 +1,10 @@
package xyz.playedu.api.config;
import com.alibaba.fastjson2.support.spring.data.redis.FastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@ -21,9 +21,9 @@ public class RedisConfig {
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// value值采用fastjson2序列化
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
redisTemplate.setValueSerializer(fastJsonRedisSerializer);
redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
return redisTemplate;
}

View File

@ -1,24 +1,15 @@
package xyz.playedu.api.config;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.support.config.FastJsonConfig;
import com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import xyz.playedu.api.middleware.AdminAuthMiddleware;
import java.util.ArrayList;
import java.util.List;
@Configuration
@Slf4j
public class WebMvcConfig implements WebMvcConfigurer {
@ -43,26 +34,4 @@ public class WebMvcConfig implements WebMvcConfigurer {
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins(ConfigOrigins).allowedHeaders("*").allowedMethods("GET", "POST", "DELETE", "PUT").maxAge(3600);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(fastJsonHttpMessageConverter());
}
private HttpMessageConverter<?> fastJsonHttpMessageConverter() {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
// 中文乱码解决方案
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.APPLICATION_JSON);
fastConverter.setSupportedMediaTypes(mediaTypes);
// 配置
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
fastJsonConfig.setWriterFeatures(JSONWriter.Feature.PrettyFormat);
fastConverter.setFastJsonConfig(fastJsonConfig);
return fastConverter;
}
}

View File

@ -15,10 +15,10 @@ import java.util.List;
@RestControllerAdvice
public class ExceptionController {
@ExceptionHandler(Exception.class)
public JsonResponse exceptionHandler(Exception e) {
return JsonResponse.error("系统错误", 500);
}
// @ExceptionHandler(Exception.class)
// public JsonResponse exceptionHandler(Exception e) {
// return JsonResponse.error("系统错误", 500);
// }
@ExceptionHandler(ServiceException.class)
public JsonResponse serviceExceptionHandler(ServiceException e) {

View File

@ -42,7 +42,7 @@ public class DepartmentController {
}
@PostMapping("/create")
public JsonResponse store(@RequestBody DepartmentRequest request) throws NotFoundException {
public JsonResponse store(@RequestBody @Validated DepartmentRequest request) throws NotFoundException {
String parentChain = "";
if (request.getParentId() != 0) {
parentChain = departmentBus.compParentChain(request.getParentId());

View File

@ -1,6 +1,6 @@
package xyz.playedu.api.middleware;
import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@ -16,6 +16,7 @@ import xyz.playedu.api.service.AdminUserService;
import xyz.playedu.api.service.JWTService;
import xyz.playedu.api.types.JWTPayload;
import xyz.playedu.api.types.JsonResponse;
import xyz.playedu.api.util.HelperUtil;
import xyz.playedu.api.util.RequestUtil;
import java.io.IOException;
@ -69,9 +70,10 @@ public class AdminAuthMiddleware implements HandlerInterceptor {
}
private boolean responseTransform(HttpServletResponse response, int code, String msg) throws IOException {
ObjectMapper mapper = new ObjectMapper();
response.setStatus(code);
response.setContentType("application/json;charset=utf-8");
response.getWriter().print(JSON.toJSONString(JsonResponse.error(msg)));
response.getWriter().print(HelperUtil.toJsonStr(JsonResponse.error(msg)));
return false;
}

View File

@ -1,10 +1,9 @@
package xyz.playedu.api.request.backend;
import jakarta.validation.constraints.Min;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.springframework.validation.annotation.Validated;
import java.io.Serial;
import java.io.Serializable;
@ -13,7 +12,6 @@ import java.io.Serializable;
* @Author 杭州白书科技有限公司
* @create 2023/2/19 10:42
*/
@Validated
@Data
public class DepartmentRequest implements Serializable {
@Serial
@ -23,11 +21,11 @@ public class DepartmentRequest implements Serializable {
@Length(min = 1, max = 20, message = "部门名称长度在1-20个字符之间")
private String name;
@NotNull(message = "请选择部门上级")
@JsonProperty("parent_id")
@NotNull(message = "请选择上级部门")
private Integer parentId;
@NotNull(message = "请输入排序值")
@Min(value = 0, message = "排序值不能小于0")
private Integer sort;
}

View File

@ -3,7 +3,9 @@ package xyz.playedu.api.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import xyz.playedu.api.bus.DepartmentBus;
import xyz.playedu.api.domain.Department;
import xyz.playedu.api.exception.NotFoundException;
import xyz.playedu.api.service.DepartmentService;
@ -22,14 +24,15 @@ import java.util.List;
@Service
@Slf4j
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {
@Override
public List<Department> listByParentId(Integer id) {
return this.getBaseMapper().selectList(query().eq("parent_id", id));
return list(query().getWrapper().eq("parent_id", id));
}
@Override
public Department findOrFail(Integer id) throws NotFoundException {
Department department = this.getBaseMapper().selectById(id);
Department department = getById(id);
if (department == null) {
throw new NotFoundException("部门不存在");
}
@ -40,53 +43,68 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
@Transactional
public void deleteById(Integer id) throws NotFoundException {
Department department = findOrFail(id);
updateParentChain(department);
updateParentChain(department.getParentChain(), DepartmentBus.childrenParentChain(department));
removeById(department.getId());
}
@Override
@Transactional
public void update(Department department, String name, Integer parentId, Integer sort) throws NotFoundException {
//计算该部门作为其它子部门的parentChain值
String childrenChainPrefix = DepartmentBus.childrenParentChain(department);
Department data = new Department();
if (!department.getName().equals(name)) {
data.setId(department.getId());
if (!department.getName().equals(name)) {//更换部门名称
data.setName(name);
}
if (!department.getParentId().equals(parentId)) {
data.setParentId(parentId);
Department parent = findOrFail(parentId);
data.setParentChain(parent.getParentChain() + "," + parent.getId());
if (parentId.equals(0)) {//重置一级部门
data.setParentChain("");
} else {
Department parentDepartment = findOrFail(parentId);
data.setParentChain(DepartmentBus.childrenParentChain(parentDepartment));
}
}
if (!department.getSort().equals(sort)) {
if (!department.getSort().equals(sort)) {//更换部门排序值
data.setSort(sort);
}
save(data);
//提交更换
updateById(data);
department = getById(department.getId());
updateParentChain(department);
updateParentChain(DepartmentBus.childrenParentChain(department), childrenChainPrefix);
}
private void updateParentChain(Department department) {
if (department.getParentId().equals(0)) {
return;
}
//需要重置chain的子部门
List<Department> children = list(query().like("parent_chain", "%" + department.getParentChain()));
private void updateParentChain(String newChildrenPC, String oldChildrenPC) {
List<Department> children = list(query().getWrapper().like("parent_chain", oldChildrenPC + "%"));
if (children.size() == 0) {
return;
}
// 计算新的parentChain前缀
String[] chainIds = department.getParentChain().split(",");
String newChainPrefix = String.join(",", Arrays.copyOfRange(chainIds, 0, chainIds.length - 1));
log.info("新的前缀:" + newChainPrefix);
ArrayList<Department> updateRows = new ArrayList<>();
for (Department tmpDepartment : children) {
Department tmpUpdateDepartment = new Department();
tmpUpdateDepartment.setId(tmpDepartment.getId());
tmpUpdateDepartment.setParentChain(tmpDepartment.getParentChain().replaceFirst(department.getParentChain(), newChainPrefix));
// parentChain计算
String pc = newChildrenPC;
if (!tmpDepartment.getParentChain().equals(oldChildrenPC)) {
pc = tmpDepartment.getParentChain().replaceFirst(oldChildrenPC + ",", newChildrenPC.length() == 0 ? newChildrenPC : newChildrenPC + ',');
}
tmpUpdateDepartment.setParentChain(pc);
// parentId计算
int parentId = 0;
if (pc != null && pc.length() > 0) {
String[] parentIds = pc.split(",");
parentId = Integer.parseInt(parentIds[parentIds.length - 1]);
}
tmpUpdateDepartment.setParentId(parentId);
updateRows.add(tmpUpdateDepartment);
}

View File

@ -1,12 +1,11 @@
package xyz.playedu.api.util;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.gson.reflect.TypeToken;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.util.DigestUtils;
import java.io.*;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
@ -124,45 +123,6 @@ public class HelperUtil {
}
}
/**
* JSON转 Map<String, String>
*
* @param json 对象
* @return Map<String, String>
* @author fzr
*/
public static Map<String, String> jsonToMap(String json) {
Type type = new TypeToken<Map<String, String>>() {
}.getType();
return JSON.parseObject(json, type);
}
/**
* JSON转 Map<String, Object>
*
* @param json 对象
* @return Map<String, String>
* @author fzr
*/
public static Map<String, Object> jsonToMapAsObj(String json) {
Type type = new TypeToken<Map<String, Object>>() {
}.getType();
return JSON.parseObject(json, type);
}
/**
* JSON转Map<String, String>
*
* @param object 对象
* @return Map<String, String>
* @author fzr
*/
public static Map<String, String> objectToMap(Object object) {
Type type = new TypeToken<Map<String, String>>() {
}.getType();
return JSON.parseObject(JSONObject.toJSONString(object), type);
}
/**
* 对象类型Map合并
*
@ -191,4 +151,9 @@ public class HelperUtil {
return map2;
}
public static String toJsonStr(Object obj) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
}
}

View File

@ -1,6 +1,7 @@
package xyz.playedu.api.util;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -60,16 +61,23 @@ public class IpUtil {
return "内网";
}
@Data
class Response {
private String pro;
private String city;
private String region;
private String addr;
}
try {
String rspStr = HttpUtil.sendGet(IP_URL, "ip=" + ip + "&json=true", "GBK");
if (StringUtil.isEmpty(rspStr)) {
log.error("获取地理位置异常 {}", ip);
return UNKNOWN;
}
JSONObject obj = JSONObject.parseObject(rspStr);
String region = obj.getString("pro");
String city = obj.getString("city");
return String.format("%s-%s", region, city);
ObjectMapper objectMapper = new ObjectMapper();
Response obj = objectMapper.readValue(rspStr, Response.class);
return String.format("%s-%s", obj.getPro(), obj.getCity());
} catch (Exception e) {
log.error("获取地理位置异常 {}", ip);
}