Prechádzať zdrojové kódy

Merge branch 'master' of http://git.dayaedu.com/yonge/mec

zouxuan 5 rokov pred
rodič
commit
08e0b0be3e

+ 7 - 0
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 1 - 1
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/filter/PhoneLoginAuthenticationFilter.java

@@ -57,7 +57,7 @@ public class PhoneLoginAuthenticationFilter extends AbstractAuthenticationProces
 		String clientId = request.getParameter(clientIdParameter);
 
 		if (userInfo == null) {
-			throw new UsernameNotFoundException("用户名或密码错误");
+			throw new UsernameNotFoundException("404.9");
 		}
 	
 		if (userInfo.getSysUser().getUserType() != SysUserType.SYSTEM && !StringUtils.equalsIgnoreCase(clientId, userInfo.getSysUser().getUserType().getCode())) {

+ 1 - 1
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/filter/UsernameAuthenticationFilter.java

@@ -68,7 +68,7 @@ public class UsernameAuthenticationFilter extends AbstractAuthenticationProcessi
 		String clientId = request.getParameter(clientIdParameter);
 
 		if (userInfo == null) {
-			throw new UsernameNotFoundException("用户名或密码错误");
+			throw new UsernameNotFoundException("404.9");
 		}
 	
 		if (userInfo.getSysUser().getUserType() != SysUserType.SYSTEM && !StringUtils.equalsIgnoreCase(clientId, userInfo.getSysUser().getUserType().getCode())) {

+ 7 - 1
mec-auth/mec-auth-server/src/main/java/com/ym/mec/auth/core/handler/BaseAuthenticationFailureEvenHandler.java

@@ -24,14 +24,20 @@ public class BaseAuthenticationFailureEvenHandler extends ExceptionMappingAuthen
 
     @Override
     public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {
+    	
+    	int resultCode = HttpStatus.SC_CONFLICT;
+    	
         String message = exception.getLocalizedMessage();
         if (message.equals("Bad credentials")) {
             message = "用户名或密码错误";
         }else if(message.equals("User is disabled")){
             message = "账户被锁定";
+        }else if(message.equals("404.9")){
+        	message = "用户名或密码错误";
+        	resultCode = 99;
         }
         logger.info("登录失败,异常:{}", message);
-        HttpResponseResult result = new HttpResponseResult(false, HttpStatus.SC_CONFLICT, null, message);
+        HttpResponseResult result = new HttpResponseResult(false, resultCode, null, message);
         response.setContentType("application/json; charset=utf-8");
         response.getWriter().write(objectMapper.writeValueAsString(result));
     }

+ 8 - 0
mec-education/src/main/java/com/ym/mec/education/config/WebMvcConfig.java

@@ -11,6 +11,8 @@ import java.util.Date;
 
 import com.ym.mec.common.config.EnumConverterFactory;
 import com.ym.mec.common.enums.BaseEnum;
+
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -58,6 +60,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 8 - 0
mec-im/src/main/java/com/ym/config/WebMvcConfig.java

@@ -13,6 +13,8 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
 import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
 import com.ym.mec.common.config.EnumConverterFactory;
 import com.ym.mec.common.enums.BaseEnum;
+
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -50,6 +52,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 7 - 0
mec-student/src/main/java/com/ym/mec/student/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 1 - 1
mec-student/src/main/java/com/ym/mec/student/controller/StudentDemoGroupController.java

@@ -37,7 +37,7 @@ public class StudentDemoGroupController extends BaseController {
 
     @ApiOperation(value = "试听课列表获取")
     @PostMapping("/queryStudentDemoGroups")
-    public Object queryStudentDemoGroups(StudentDemoGroupQueryInfo queryInfo){
+    public Object queryStudentDemoGroups(@RequestBody StudentDemoGroupQueryInfo queryInfo){
         return succeed(demoGroupService.queryStudentDemoGroups(queryInfo));
     }
 

+ 7 - 0
mec-task/src/main/java/com/ym/mec/task/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 7 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 70 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/controller/OrderController.java

@@ -0,0 +1,70 @@
+package com.ym.mec.teacher.controller;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.snaker.engine.SnakerEngine;
+import org.snaker.engine.access.Page;
+import org.snaker.engine.access.QueryFilter;
+import org.snaker.engine.entity.HistoryOrder;
+import org.snaker.engine.entity.HistoryTask;
+import org.snaker.engine.entity.Process;
+import org.snaker.engine.entity.Task;
+import org.snaker.engine.helper.AssertHelper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.common.controller.BaseController;
+
+@RestController
+@RequestMapping(value = "/snaker/order")
+public class OrderController extends BaseController {
+
+	@Autowired
+	private SnakerEngine snakerEngine;
+
+	@Autowired
+	private SysUserFeignService SysUserFeignService;
+
+	/**
+	 * 抄送实例已读
+	 * @param orderId
+	 * @param url
+	 * @return
+	 */
+	@PostMapping(value = "setCcread")
+	public Object ccread(String orderId) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		snakerEngine.order().updateCCStatus(orderId, new String[] { user.getId() + "" });
+		return succeed();
+	}
+
+	@GetMapping(value = "detail")
+	public Object json(String processId, String orderId) {
+		Process process = snakerEngine.process().getProcessById(processId);
+		AssertHelper.notNull(process);
+		Map<String, Object> jsonMap = new HashMap<String, Object>();
+		/*ProcessModel model = process.getModel();
+		if (model != null) {
+			jsonMap.put("process", model);
+		}*/
+
+		if (StringUtils.isNotEmpty(orderId)) {
+			List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
+			jsonMap.put("tasks", tasks);
+
+			List<HistoryTask> historyTasks = snakerEngine.query().getHistoryTasks(new QueryFilter().setOrderId(orderId));
+			jsonMap.put("historyTasks", historyTasks);
+		}
+		return jsonMap;
+	}
+
+}

+ 209 - 0
mec-teacher/src/main/java/com/ym/mec/teacher/controller/TaskController.java

@@ -0,0 +1,209 @@
+package com.ym.mec.teacher.controller;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.snaker.engine.SnakerEngine;
+import org.snaker.engine.access.Page;
+import org.snaker.engine.access.QueryFilter;
+import org.snaker.engine.core.AccessService;
+import org.snaker.engine.entity.HistoryOrder;
+import org.snaker.engine.entity.Task;
+import org.snaker.engine.entity.WorkItem;
+import org.snaker.engine.model.TaskModel.TaskType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.ym.mec.auth.api.client.SysUserFeignService;
+import com.ym.mec.auth.api.entity.SysUser;
+import com.ym.mec.common.controller.BaseController;
+
+/**
+ * Snaker流程引擎常用Controller
+ * @author yuqs
+ * @since 0.1
+ */
+@RestController
+@RequestMapping(value = "/snaker/task")
+public class TaskController extends BaseController {
+
+	@Autowired
+	private SnakerEngine snakerEngine;
+
+	@Autowired
+	private SysUserFeignService SysUserFeignService;
+
+	@GetMapping(value = "home")
+	public Object homeTaskList() {
+
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		List<String> list = new ArrayList<String>();
+		list.add(user.getUsername());
+
+		String[] assignees = new String[list.size()];
+		list.toArray(assignees);
+
+		Page<WorkItem> majorPage = new Page<WorkItem>(5);
+		Page<WorkItem> aidantPage = new Page<WorkItem>(3);
+		Page<HistoryOrder> ccorderPage = new Page<HistoryOrder>(3);
+		List<WorkItem> majorWorks = snakerEngine.query().getWorkItems(majorPage,
+				new QueryFilter().setOperators(assignees).setTaskType(TaskType.Major.ordinal()));
+		List<WorkItem> aidantWorks = snakerEngine.query().getWorkItems(aidantPage,
+				new QueryFilter().setOperators(assignees).setTaskType(TaskType.Aidant.ordinal()));
+		List<HistoryOrder> ccWorks = snakerEngine.query().getCCWorks(ccorderPage, new QueryFilter().setOperators(assignees).setState(1));
+
+		ModelMap model = new ModelMap();
+		
+		model.addAttribute("majorWorks", majorWorks);
+		model.addAttribute("majorTotal", majorPage.getTotalCount());
+		model.addAttribute("aidantWorks", aidantWorks);
+		model.addAttribute("aidantTotal", aidantPage.getTotalCount());
+		model.addAttribute("ccorderWorks", ccWorks);
+		model.addAttribute("ccorderTotal", ccorderPage.getTotalCount());
+		return succeed(model);
+	}
+
+	/**
+	 * 根据当前用户查询我发起的任务列表
+	 * @param model
+	 * @return
+	 */
+	@GetMapping(value = "queryCreatedList")
+	public Object queryCreatedList(Page<HistoryOrder> page) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		snakerEngine.query().getHistoryOrders(page, new QueryFilter().setOperator(user.getUsername()));
+		return succeed(page);
+	}
+
+	/**
+	 * 根据当前用户查询待办任务列表
+	 * @param model
+	 * @return
+	 */
+	@GetMapping(value = "queryWaitList")
+	public Object queryWaitList(Page<WorkItem> page) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		snakerEngine.query().getWorkItems(page, new QueryFilter().setOperator(user.getUsername()));
+		return succeed(page);
+	}
+
+	/**
+	 * 根据当前用户查询已办任务列表
+	 * @param model
+	 * @return
+	 */
+	@GetMapping(value = "querypProcessedList")
+	public Object querypProcessedList(Page<WorkItem> page) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		snakerEngine.query().getHistoryWorkItems(page, new QueryFilter().setOperator(user.getUsername()));
+		return succeed(page);
+	}
+
+	@PostMapping(value = "actor/add")
+	public Object addTaskActor(String orderId, String taskName, String operator) {
+		List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
+		for (Task task : tasks) {
+			if (task.getTaskName().equalsIgnoreCase(taskName) && StringUtils.isNotEmpty(operator)) {
+				snakerEngine.task().addTaskActor(task.getId(), operator);
+			}
+		}
+		return succeed();
+	}
+
+	@GetMapping(value = "tip")
+	public Object addTaskActor(String orderId, String taskName) {
+		List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(orderId));
+		StringBuilder builder = new StringBuilder();
+		String createTime = "";
+		for (Task task : tasks) {
+			if (task.getTaskName().equalsIgnoreCase(taskName)) {
+				String[] actors = snakerEngine.query().getTaskActorsByTaskId(task.getId());
+				for (String actor : actors) {
+					builder.append(actor).append(",");
+				}
+				createTime = task.getCreateTime();
+			}
+		}
+		if (builder.length() > 0) {
+			builder.deleteCharAt(builder.length() - 1);
+		}
+		Map<String, String> data = new HashMap<String, String>();
+		data.put("actors", builder.toString());
+		data.put("createTime", createTime);
+		return succeed(data);
+	}
+
+	/**
+	 * 活动任务查询列表
+	 * @param model
+	 * @return
+	 */
+	@GetMapping(value = "active/more")
+	public Object activeTaskList(Page<WorkItem> page, Integer taskType) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		List<String> list = new ArrayList<String>();
+		list.add(user.getUsername());
+
+		String[] assignees = new String[list.size()];
+		list.toArray(assignees);
+		snakerEngine.query().getWorkItems(page, new QueryFilter().setOperators(assignees).setTaskType(taskType));
+		return succeed(page);
+	}
+
+	/**
+	 * 活动任务查询列表
+	 * @param model
+	 * @return
+	 */
+	@GetMapping(value = "active/ccmore")
+	public Object activeCCList(Page<HistoryOrder> page) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		List<String> list = new ArrayList<String>();
+		list.add(user.getUsername());
+
+		String[] assignees = new String[list.size()];
+		list.toArray(assignees);
+		snakerEngine.query().getCCWorks(page, new QueryFilter().setOperators(assignees).setState(AccessService.STATE_ACTIVE));
+		return succeed(page);
+	}
+
+	/**
+	 * 活动任务的驳回
+	 * @param model
+	 * @param taskId
+	 * @return
+	 */
+	@PostMapping(value = "reject")
+	public Object activeTaskReject(String taskId) {
+
+		SysUser user = SysUserFeignService.queryUserInfo();
+
+		snakerEngine.executeAndJumpTask(taskId, user.getUsername(), null, null);
+		return succeed();
+	}
+
+	/**
+	 * 历史任务撤回
+	 * @param orderId
+	 * @return
+	 */
+	@PostMapping(value = "undo")
+	public Object historyTaskUndo(String orderId) {
+		SysUser user = SysUserFeignService.queryUserInfo();
+		snakerEngine.order().withdraw(orderId, user.getUsername());
+		return succeed();
+	}
+}

+ 7 - 0
mec-web/src/main/java/com/ym/mec/web/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 7 - 0
mec-workflow/src/main/java/com/ym/mec/workfow/config/WebMvcConfig.java

@@ -9,6 +9,7 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -57,6 +58,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 		// 序列化BigDecimal时不使用科学计数法输出
 		objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
+		objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
+			@Override
+			public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
+				jsonGenerator.writeString(StringUtils.EMPTY);
+			}
+		});
 		// 日期和时间格式化
 		JavaTimeModule javaTimeModule = new JavaTimeModule();
 		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));