From a494d456c3212f43fc631594aeb09b1f1e25aad6 Mon Sep 17 00:00:00 2001 From: "USER-20220102CG\\noblelift" <546428999@qq.com> Date: Mon, 6 Feb 2023 23:29:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SiemensConveyorDeviceDriver.java | 11 +-- .../service/impl/LiKuToAcsServiceImpl.java | 67 +++++++++---------- .../wms/service/impl/WmsToAcsServiceImpl.java | 2 + .../java/org/nl/acs/log/LokiLogAspect.java | 2 +- .../org/nl/acs/task/rest/TaskController.java | 11 +++ .../org/nl/acs/task/service/TaskService.java | 2 + .../task/service/impl/TaskServiceImpl.java | 60 ++++++++--------- .../nl/modules/logging/InterfaceLogType.java | 4 +- .../nl/modules/logging/aspect/LogAspect.java | 61 ++++++----------- .../main/resources/config/application-dev.yml | 13 ++-- .../resources/config/application-prod.yml | 5 ++ .../src/main/resources/logback-spring.xml | 22 +++++- 12 files changed, 139 insertions(+), 121 deletions(-) diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/basedriver/siemens_conveyor/SiemensConveyorDeviceDriver.java b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/basedriver/siemens_conveyor/SiemensConveyorDeviceDriver.java index aeefd94c8..c5ac3a170 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/basedriver/siemens_conveyor/SiemensConveyorDeviceDriver.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/device_driver/basedriver/siemens_conveyor/SiemensConveyorDeviceDriver.java @@ -188,7 +188,7 @@ public class SiemensConveyorDeviceDriver extends AbstractOpcDeviceDriver impleme logServer.deviceExecuteLog(this.device_code, "", "", "信号task:" + last_task + "->" + task); } - if (move != 0 && task > 0) { + if (move != 0 && task > 0 ) { // logServer.deviceExecuteLog(device_code, "", "", "输送线任务开始反馈任务状态,指令号:" + task); //inst_message inst = instructionService.findByCodeFromCache(String.valueOf(task)); @@ -781,18 +781,21 @@ public class SiemensConveyorDeviceDriver extends AbstractOpcDeviceDriver impleme Instruction instruction = instructionService.findByCodeFromCache(String.valueOf(task)); if(ObjectUtil.isEmpty(instruction)){ message = "申请捆扎电气设备任务号:" + task + "未找到对应指令"; - throw new RuntimeException("该电气任务号未找到对应指令!"); + return ; +// throw new RuntimeException("该电气任务号未找到对应指令!"); } vehicle_code = instruction.getVehicle_code(); } else { logServer.deviceExecuteLog(device_code, "", "", "申请捆扎电气设备任务号:" + task + "异常"); message = "申请捆扎电气设备任务号:" + task + "异常"; - throw new RuntimeException("任务号为空!"); + return ; +// throw new RuntimeException("任务号为空!"); } if (StrUtil.isEmpty(vehicle_code)) { logServer.deviceExecuteLog(device_code, "", "", "申请捆扎电气设备任务号:" + task + "未找到载具号"); message = "申请捆扎电气设备任务号:" + task + "未找到载具号"; - throw new RuntimeException("载具号为空!"); + return ; +// throw new RuntimeException("载具号为空!"); } ApplyLabelingAndBindingRequest applyLabelingAndBindingRequest = new ApplyLabelingAndBindingRequest(); diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/LiKuToAcsServiceImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/LiKuToAcsServiceImpl.java index 942392c4d..1bcc665ef 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/LiKuToAcsServiceImpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/LiKuToAcsServiceImpl.java @@ -56,45 +56,40 @@ public class LiKuToAcsServiceImpl implements LiKuToAcsService { //入库任务状态反馈 @Override public Resp inStoreReport(InStoreReportRequest requestParam) throws Exception { - try { - MDC.put(log_file_type, log_type); - log.info("入库任务状态反馈-----输入参数{}", JSON.toJSONString(requestParam)); - String inst_code = requestParam.getOrderId(); - String status = requestParam.getState(); - String carNo = requestParam.getRobotId(); - Instruction inst = instructionService.findByCodeFromCache(inst_code); - TaskDto task = taskService.findByCodeFromCache(inst.getTask_code()); - // 1 已接收 2 开始执行 3执行完成 4 5 取消 - if(StrUtil.equals(status,"1") || StrUtil.equals(status,"2") ){ - task.setTask_status("1"); - taskService.update(task); - inst.setInstruction_status("1"); - inst.setExecute_device_code(carNo); - inst.setCarno(carNo); - instructionService.update(inst); - } else if(StrUtil.equals(status,"3")){ - inst.setInstruction_status("2"); - instructionService.finish(inst.getInstruction_id()); - } else if(StrUtil.equals(status,"4")) { - // 5 取消指令 - } else if(StrUtil.equals(status,"5")) { + log.info("入库任务状态反馈-----输入参数{}", JSON.toJSONString(requestParam)); + String inst_code = requestParam.getOrderId(); + String status = requestParam.getState(); + String carNo = requestParam.getRobotId(); + Instruction inst = instructionService.findByCodeFromCache(inst_code); + TaskDto task = taskService.findByCodeFromCache(inst.getTask_code()); + // 1 已接收 2 开始执行 3执行完成 4 5 取消 + if(StrUtil.equals(status,"1") || StrUtil.equals(status,"2") ){ + task.setTask_status("1"); + taskService.update(task); + inst.setInstruction_status("1"); + inst.setExecute_device_code(carNo); + inst.setCarno(carNo); + instructionService.update(inst); + } else if(StrUtil.equals(status,"3")){ + inst.setInstruction_status("2"); + instructionService.finish(inst.getInstruction_id()); + } else if(StrUtil.equals(status,"4")) { - instructionService.cancel(inst.getInstruction_id()); - } - InStoreReportResponse inStoreReportResponse = new InStoreReportResponse(); - inStoreReportResponse.setOrderId(inst_code); - JSONObject result = new JSONObject(); - result.put("result", "true"); - result.put("code", "0"); - result.put("comment", ""); - result.put("data", inStoreReportResponse ); - log.info("入库任务状态反馈-----输出参数{}", result); - return RespUtil.getResp(result.toString(), new InStoreReportResponse()); - } finally { - MDC.remove(log_file_type); + // 5 取消指令 + } else if(StrUtil.equals(status,"5")) { + + instructionService.cancel(inst.getInstruction_id()); } - + InStoreReportResponse inStoreReportResponse = new InStoreReportResponse(); + inStoreReportResponse.setOrderId(inst_code); + JSONObject result = new JSONObject(); + result.put("result", "true"); + result.put("code", "0"); + result.put("comment", ""); + result.put("data", inStoreReportResponse ); + log.info("入库任务状态反馈-----输出参数{}", result); + return RespUtil.getResp(result.toString(), new InStoreReportResponse()); } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java index 2ab2c8efe..15564de89 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/ext/wms/service/impl/WmsToAcsServiceImpl.java @@ -691,6 +691,7 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { json.put("code", resp.code); json.put("data", data); errArr.add(json); + continue; } } else { @@ -703,6 +704,7 @@ public class WmsToAcsServiceImpl implements WmsToAcsService { json.put("ext_task_id", ext_task_id); json.put("message", e.getMessage()); errArr.add(json); + continue; } } if (ObjectUtil.isEmpty(errArr)) { diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/log/LokiLogAspect.java b/acs/nladmin-system/src/main/java/org/nl/acs/log/LokiLogAspect.java index d41679d25..7caa9b538 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/log/LokiLogAspect.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/log/LokiLogAspect.java @@ -37,7 +37,7 @@ public class LokiLogAspect { * @return */ @Around("operatorLog()") - public synchronized Object around(ProceedingJoinPoint pjp) throws Throwable { + public Object around(ProceedingJoinPoint pjp) throws Throwable { // ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); // HttpServletRequest request = attributes.getRequest(); // HttpServletResponse response = attributes.getResponse(); diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/task/rest/TaskController.java b/acs/nladmin-system/src/main/java/org/nl/acs/task/rest/TaskController.java index e2089997c..9b37cfca3 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/task/rest/TaskController.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/task/rest/TaskController.java @@ -2,6 +2,7 @@ package org.nl.acs.task.rest; +import cn.dev33.satoken.annotation.SaIgnore; import com.alibaba.fastjson.JSONObject; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -46,6 +47,7 @@ public class TaskController { @GetMapping("/reload") @Log("数据同步") @ApiOperation("数据同步") + @SaIgnore //@PreAuthorize("@el.check('task:list')") public ResponseEntity reload() { taskService.reload(); @@ -146,4 +148,13 @@ public class TaskController { return new ResponseEntity<>(HttpStatus.CREATED); } + @SaIgnore + @Log("查询缓存所有任务") + @ApiOperation("查询缓存任务") + @PostMapping(value = "/findAllTaskFromCache") + public ResponseEntity findAllTaskFromCache() { + return new ResponseEntity<>(taskService.findAllTaskFromCache(), HttpStatus.OK); + } + + } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/task/service/TaskService.java b/acs/nladmin-system/src/main/java/org/nl/acs/task/service/TaskService.java index ee6ab66cd..2acbb63fb 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/task/service/TaskService.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/task/service/TaskService.java @@ -313,4 +313,6 @@ public interface TaskService { * @return */ Integer querySameDeviceReadyTask(String start_device,String next_device,String status); + + } diff --git a/acs/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java b/acs/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java index 64a8523b0..877d6e05e 100644 --- a/acs/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java +++ b/acs/nladmin-system/src/main/java/org/nl/acs/task/service/impl/TaskServiceImpl.java @@ -666,12 +666,16 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { wo.update(json); Iterator iterator = tasks.iterator(); - while (iterator.hasNext()) { - TaskDto task = iterator.next(); - if (task.getTask_code().equals(dto.getTask_code())) { - iterator.remove(); - } - } +// while (iterator.hasNext()) { +// TaskDto task = iterator.next(); +// if (task.getTask_code().equals(dto.getTask_code())) { +// iterator.remove(); +// } +// } + + + removeByCodeFromCache(entity.getTask_code()); + if (StrUtil.equals(dto.getTask_status(), "0") || StrUtil.equals(dto.getTask_status(), "1")) { tasks.add(dto); } @@ -913,15 +917,17 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { JSONObject json = (JSONObject) JSONObject.toJSON(entity); wo.update(json); - synchronized (TaskServiceImpl.class){ - Iterator it = tasks.iterator(); - // 清理缓存 - while (it.hasNext()) { - TaskDto taskDto = it.next(); - if (taskDto.getTask_id().equals(id)) { - tasks.remove(taskDto); - } - }} +// synchronized (TaskServiceImpl.class){ +// Iterator it = tasks.iterator(); +// // 清理缓存 +// while (it.hasNext()) { +// TaskDto taskDto = it.next(); +// if (taskDto.getTask_id().equals(id)) { +// tasks.remove(taskDto); +// } +// }} + + removeByCodeFromCache(entity.getTask_code()); // 判断是否为WMS下发的任务,如果是反馈任务状态给WMS String hasWms = paramService.findByCode(AcsConfig.HASWMS).getValue(); @@ -1263,14 +1269,11 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { @Override public boolean removeByCodeFromCache(String code) { - Iterator iterator = tasks.iterator(); - while (iterator.hasNext()) { - TaskDto task = iterator.next(); - if (task.getTask_code().equals(code)) { - iterator.remove(); - return true; - } - } + CopyOnWriteArrayList taskDtos = (CopyOnWriteArrayList) this.tasks; + taskDtos.removeIf((task) -> { + task.getTask_code().equals(code); + return true; + }); return false; } @@ -1496,14 +1499,8 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { @Override public void updateByCodeFromCache(TaskDto dto) { - Iterator iterator = tasks.iterator(); - while (iterator.hasNext()) { - TaskDto task = iterator.next(); - if (task.getTask_code().equals(dto.getTask_code())) { - iterator.remove(); - } - } - tasks.add(dto); + removeByCodeFromCache(dto.getTask_code()); + tasks.add(dto); } @Override @@ -1563,6 +1560,7 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial { return num; } + @Override public Integer querySameTaskByType(String taskType) { int num = 0; diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/logging/InterfaceLogType.java b/acs/nladmin-system/src/main/java/org/nl/modules/logging/InterfaceLogType.java index 35ad0d397..41c489623 100644 --- a/acs/nladmin-system/src/main/java/org/nl/modules/logging/InterfaceLogType.java +++ b/acs/nladmin-system/src/main/java/org/nl/modules/logging/InterfaceLogType.java @@ -9,8 +9,8 @@ public enum InterfaceLogType { DEFAULT("默认"), LMS_TO_ACS("LMS请求ACS"), ACS_TO_LMS("ACS请求LMS"), - ACS_TO_LK("ACS请求LMS"), - LK_TO_ACS("ACS请求LMS"); + ACS_TO_LK("ACS请求立库"), + LK_TO_ACS("立库请求ACS"); private String desc; diff --git a/acs/nladmin-system/src/main/java/org/nl/modules/logging/aspect/LogAspect.java b/acs/nladmin-system/src/main/java/org/nl/modules/logging/aspect/LogAspect.java index 6805932bf..78b69b45d 100644 --- a/acs/nladmin-system/src/main/java/org/nl/modules/logging/aspect/LogAspect.java +++ b/acs/nladmin-system/src/main/java/org/nl/modules/logging/aspect/LogAspect.java @@ -18,19 +18,15 @@ package org.nl.modules.logging.aspect; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; -import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.nl.common.utils.IdUtil; import org.nl.modules.common.utils.RequestHolder; -import org.nl.modules.common.utils.SecurityUtils; import org.nl.modules.common.utils.StringUtils; import org.nl.modules.common.utils.ThrowableUtil; import org.nl.modules.logging.domain.Log; @@ -56,8 +52,6 @@ public class LogAspect { private final LogService logService; - ThreadLocal currentTime = new ThreadLocal<>(); - public LogAspect(LogService logService) { this.logService = logService; } @@ -88,19 +82,18 @@ public class LogAspect { //是否输出到日志文件 if (logInfo.isPrintToLogFile()) { - log.info("track_id:{},请求方法:{},请求方法参数:{}",trackId,methodName,params); + log.info("track_id:{},请求方法:{},请求方法参数:{}", trackId, methodName, params); } HttpServletRequest request = RequestHolder.getHttpServletRequest(); String requestIp = StringUtils.getIp(request); Object result; - currentTime.set(System.currentTimeMillis()); + long startTime = System.currentTimeMillis(); try { result = joinPoint.proceed(); //是否把日志存到日志表 if (logInfo.isAddLogTable()) { - Log log = new Log("INFO", System.currentTimeMillis() - currentTime.get()); - currentTime.remove(); - logService.save(getUsername(), StringUtils.getBrowser(request), requestIp, joinPoint, log); + Log log = new Log("INFO", System.currentTimeMillis() - startTime); + logService.save("", StringUtils.getBrowser(request), requestIp, joinPoint, log); } if (logInfo.isInterfaceLog()) { try { @@ -113,25 +106,24 @@ public class LogAspect { json.put("method", methodName); json.put("params", getParameter(method, joinPoint.getArgs())); json.put("request_ip", StringUtils.getIp(request)); -// json.put("time", System.currentTimeMillis() - currentTime.get()); - json.put("username", getUsername()); + json.put("time", System.currentTimeMillis() - startTime); + json.put("username", ""); json.put("address", StringUtils.getCityInfo(requestIp)); json.put("browser", StringUtils.getBrowser(request)); json.put("exception_detail", IdUtil.getStringId()); json.put("create_time", DateUtil.now()); - json.put("return_result", result.toString()); + json.put("return_result", JSONObject.parse(result.toString())); interfaceLog.insert(json); } catch (Exception e) { } } - }catch (Exception ex){ - log.error("track_id:{},error:{}",trackId,ex.getMessage()); - Log log = new Log("ERROR", System.currentTimeMillis() - currentTime.get()); - currentTime.remove(); + } catch (Exception ex) { + log.error("track_id:{},error:{}", trackId, ex.getMessage()); + Log log = new Log("ERROR", System.currentTimeMillis() - startTime); log.setExceptionDetail(ThrowableUtil.getStackTrace(ex).getBytes()); - logService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint) joinPoint, log); - throw ex; + logService.save("", StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint) joinPoint, log); + throw ex; } return result; } @@ -166,26 +158,11 @@ public class LogAspect { return argList.size() == 1 ? JSONUtil.toJsonStr(argList.get(0)) : JSONUtil.toJsonStr(argList); } - /** - * 配置异常通知 - * - * @param joinPoint join point for advice - * @param e exception - */ - @AfterThrowing(pointcut = "logPointcut()", throwing = "e") - public void logAfterThrowing(JoinPoint joinPoint, Throwable e) { - Log log = new Log("ERROR",System.currentTimeMillis() - currentTime.get()); - currentTime.remove(); - log.setExceptionDetail(ThrowableUtil.getStackTrace(e).getBytes()); - HttpServletRequest request = RequestHolder.getHttpServletRequest(); - logService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint)joinPoint, log); - } - - public String getUsername() { - try { - return SecurityUtils.getCurrentUsername(); - }catch (Exception e){ - return ""; - } - } +// public String getUsername() { +// try { +// return SecurityUtils.getCurrentUsername(); +// } catch (Exception e) { +// return ""; +// } +// } } diff --git a/acs/nladmin-system/src/main/resources/config/application-dev.yml b/acs/nladmin-system/src/main/resources/config/application-dev.yml index da186d068..d4bbec25a 100644 --- a/acs/nladmin-system/src/main/resources/config/application-dev.yml +++ b/acs/nladmin-system/src/main/resources/config/application-dev.yml @@ -1,18 +1,23 @@ server: port: 8010 + tomcat: + accept-count: 1000 + max-connections: 10000 + max-threads: 800 + min-spare-threads: 100 #配置数据源 spring: datasource: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy -# url: jdbc:log4jdbc:mysql://${DB_HOST:10.1.3.91}:${DB_PORT:3306}/${DB_NAME:acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true -# url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:lzhl_one_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true - url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:lzhl_one_wcs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + # url: jdbc:log4jdbc:mysql://${DB_HOST:10.1.3.91}:${DB_PORT:3306}/${DB_NAME:acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + # url: jdbc:log4jdbc:mysql://${DB_HOST:192.168.81.252}:${DB_PORT:3306}/${DB_NAME:lzhl_one_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true + url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:lzhl_one_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true username: ${DB_USER:root} # password: ${DB_PWD:P@ssw0rd} # password: ${DB_PWD:Root.123456} - password: ${DB_PWD:password} + password: ${DB_PWD:123456} # 初始连接数 initial-size: 5 diff --git a/acs/nladmin-system/src/main/resources/config/application-prod.yml b/acs/nladmin-system/src/main/resources/config/application-prod.yml index e95a76390..e6113d90b 100644 --- a/acs/nladmin-system/src/main/resources/config/application-prod.yml +++ b/acs/nladmin-system/src/main/resources/config/application-prod.yml @@ -1,5 +1,10 @@ server: port: 8011 + tomcat: + accept-count: 1000 + max-connections: 10000 + max-threads: 800 + min-spare-threads: 100 #配置数据源 spring: datasource: diff --git a/acs/nladmin-system/src/main/resources/logback-spring.xml b/acs/nladmin-system/src/main/resources/logback-spring.xml index 89c60a213..34e8af111 100644 --- a/acs/nladmin-system/src/main/resources/logback-spring.xml +++ b/acs/nladmin-system/src/main/resources/logback-spring.xml @@ -92,6 +92,26 @@ https://juejin.cn/post/6844903775631572999 + + + error + + + + ${LOG_HOME}/ERROR/%d{yyyy-MM-dd}.%i.log + + 15 + + 200MB + + 20GB + + + ${log.pattern} + ${log.charset} + + + @@ -150,7 +170,7 @@ https://juejin.cn/post/6844903775631572999 - +