From eef6f9fe06c5d9b0ee3c670f35afc03f693a3ab7 Mon Sep 17 00:00:00 2001 From: lsymicc Date: Mon, 30 Jun 2025 15:59:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E7=94=9F=E6=88=90=E3=80=81?= =?UTF-8?q?=E4=B8=8B=E5=8F=91=E3=80=81=E6=9B=B4=E6=96=B0=E3=80=81=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E4=BB=BB=E5=8A=A1=E7=9A=84=E5=9F=BA=E6=9C=AC=E8=B0=83?= =?UTF-8?q?=E5=BA=A6=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/ruoyi/common/Constant.java | 2 +- .../java/com/ruoyi/common/TaskStatusCode.java | 26 ++++- .../queryAgvStatus/QueryAgvStatusRequest.java | 2 +- .../schedule/scheduleTask/Execution.java | 81 ++++++++++++++-- .../ruoyi/schedule/scheduleTask/Finish.java | 62 ++++++++++++ .../schedule/scheduleTask/StatusUpdate.java | 94 +++++++++++++++++++ .../schedule/scheduleTask/TaskHandler.java | 16 ++++ .../task/controller/WcsTaskController.java | 41 +++++++- .../ruoyi/schedule/task/domain/WcsTask.java | 18 ++-- .../task/service/impl/WcsTaskServiceImpl.java | 3 +- .../taskHistory/domain/WcsTaskHistory.java | 6 +- .../src/main/resources/application.yml | 2 +- 12 files changed, 329 insertions(+), 24 deletions(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/Finish.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/StatusUpdate.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/TaskHandler.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/common/Constant.java b/ruoyi-admin/src/main/java/com/ruoyi/common/Constant.java index 0497635..4e74fe5 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/common/Constant.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/common/Constant.java @@ -6,7 +6,7 @@ public class Constant { /** * REST协议接口基础地址 */ - public static final String BASEURL = "http://127.0.0.1:8080"; + public static final String BASEURL = "http://127.0.0.1:8081"; /** * REST协议接口基础地址 diff --git a/ruoyi-admin/src/main/java/com/ruoyi/common/TaskStatusCode.java b/ruoyi-admin/src/main/java/com/ruoyi/common/TaskStatusCode.java index 82e0e03..4932efa 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/common/TaskStatusCode.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/common/TaskStatusCode.java @@ -6,9 +6,19 @@ package com.ruoyi.common; public class TaskStatusCode { /** - * 任务状态-待执行 + * 任务状态-待请求下发 */ - public static final String TASK_READY = "100"; + public static final String TASK_READY = "0"; + + /** + * 任务状态-(向设备)请求下发任务成功 + */ + public static final String TASK_SEND_SUCCESS = "1"; + + /** + * 任务状态-已创建(设备请求成功) + */ + public static final String TASK_CREATED = "100"; /** * 任务状态-执行中 @@ -26,8 +36,18 @@ public class TaskStatusCode { public static final String TASK_FINISH_MANUAL = "103"; /** - * 任务状态-手动取消 + * 任务状态-已取消 */ public static final String TASK_CANCEL = "104"; + /** + * 任务状态-手动取消 + */ + public static final String TASK_CANCEL_MANUAL = "105"; + + /** + * 任务状态-手动取消 + */ + public static final String TASK_INTERUPTED = "109"; + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/device/agv/domain/queryAgvStatus/QueryAgvStatusRequest.java b/ruoyi-admin/src/main/java/com/ruoyi/device/agv/domain/queryAgvStatus/QueryAgvStatusRequest.java index 1ae20d0..ebd5967 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/device/agv/domain/queryAgvStatus/QueryAgvStatusRequest.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/device/agv/domain/queryAgvStatus/QueryAgvStatusRequest.java @@ -5,7 +5,7 @@ import lombok.Data; /** * 通过请求参数, 查询 AGV 状态信息,包括电池电量。 * 调用频次: 100车以下:5秒, 100~200车:10秒, 200 ~300车:15秒 - * 调用路径: http://IP:8182/rcms-dps/rest/queryAgvStatus + * 调用路径示例: http://IP:8182/rcms-dps/rest/queryAgvStatus */ @Data public class QueryAgvStatusRequest { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/Execution.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/Execution.java index 8373f6c..27f2b9f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/Execution.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/Execution.java @@ -1,16 +1,28 @@ package com.ruoyi.schedule.scheduleTask; +import cn.hutool.Hutool; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.Constant; +import com.ruoyi.common.TaskStatusCode; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.uuid.UUID; +import com.ruoyi.device.agv.domain.ResponseBase; import com.ruoyi.device.agv.domain.genAgvSchedulingTask.GenAgvSchedulingTaskRequest; import com.ruoyi.device.agv.domain.genAgvSchedulingTask.GenAgvSchedulingTaskResponse; +import com.ruoyi.device.agv.domain.genAgvSchedulingTask.PositionCodeData; +import com.ruoyi.device.agv.domain.queryTaskStatus.TaskStatusData; import com.ruoyi.schedule.job.mydojob.domain.MydoJob; +import com.ruoyi.schedule.task.domain.WcsTask; +import com.ruoyi.schedule.task.mapper.WcsTaskMapper; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import javax.annotation.PostConstruct; +import java.util.ArrayList; import java.util.List; /** @@ -20,6 +32,8 @@ import java.util.List; @Slf4j public class Execution { + @Autowired + WcsTaskMapper wcsTaskMapper; /** * 查询是否有wcs任务 @@ -37,6 +51,57 @@ public class Execution { } + /** + * 获取所有wcs任务 + */ + public void getAllTask(){ + + //查询实时任务表获取所有【待执行】任务 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(WcsTask::getTaskStatus, TaskStatusCode.TASK_READY); + List tasks = wcsTaskMapper.selectList(queryWrapper); + + //无【待执行】任务 + if (tasks.size() == 0) return; + + for (int i = 0; i < tasks.size(); i++) { + + //请求agv/ctu下发指令 + GenAgvSchedulingTaskRequest request = new GenAgvSchedulingTaskRequest(); + request.setReqCode(UUID.randomUUID().toString().replace("-", "")); + + //入库类型 + switch (tasks.get(i).getTaskType()) { + case "1": + request.setTaskTyp("F12"); + break; + case "2": + request.setTaskTyp("F11"); + break; + default: + log.warn("【向设备下发任务请求】TaskTyp:{},生成任务的请求参数错误,异常的任务类型!", request.getTaskTyp()); + return; + } + + //添加路径(未测试) + List path = new ArrayList<>(); + path.add(new PositionCodeData(tasks.get(i).getSourceLocation(),"05")); + path.add(new PositionCodeData(tasks.get(i).getTargetLocation(),"05")); + request.setPositionCodePath(path); + + //wcs任务号---设备任务编号 + request.setTaskCode(tasks.get(i).getTaskId()); + + //下发成功---更新【任务状态】为下发成功 + if (sendCommand(request)){ + tasks.get(i).setTaskStatus(TaskStatusCode.TASK_SEND_SUCCESS); + wcsTaskMapper.updateWcsTask(tasks.get(i)); + } + + } + + } + /** * 向AGV/CTU请求下发指令 @@ -68,14 +133,18 @@ public class Execution { return false; } - //返回码 - if (genAgvSchedulingTaskResponse.getCode() == 0 ) { - return true; - }else { - log.error("【下发设备任务】下发任务失败," + genAgvSchedulingTaskResponse.getMessage() + "!"); + //返回码错误 + if (genAgvSchedulingTaskResponse.getCode() != 0 ) { + if (genAgvSchedulingTaskResponse.getMessage() == ""){ + log.error("【下发设备任务】下发任务失败,发生了未知错误"); + }else{ + log.error("【下发设备任务】下发任务失败,{}", genAgvSchedulingTaskResponse.getMessage()); + } + return false; } + return true; } @@ -105,8 +174,6 @@ public class Execution { return false; } - //4.请求编号一致时避免重复下发 - return true; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/Finish.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/Finish.java new file mode 100644 index 0000000..0ac3045 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/Finish.java @@ -0,0 +1,62 @@ +package com.ruoyi.schedule.scheduleTask; + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.TaskStatusCode; +import com.ruoyi.schedule.task.domain.WcsTask; +import com.ruoyi.schedule.task.mapper.WcsTaskMapper; +import com.ruoyi.schedule.taskHistory.domain.WcsTaskHistory; +import com.ruoyi.schedule.taskHistory.mapper.WcsTaskHistoryMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; + +@Component +@Slf4j +public class Finish { + + @Autowired + WcsTaskMapper wcsTaskMapper; + + @Autowired + WcsTaskHistoryMapper wcsTaskHistoryMapper; + + public void taskFinish() { + + //查询实时任务表获取所有【已结束】,【已取消】和手动处理的任务任务 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(WcsTask::getTaskStatus, TaskStatusCode.TASK_FINISH) + .or() + .eq(WcsTask::getTaskStatus, TaskStatusCode.TASK_CANCEL) + .or() + .eq(WcsTask::getTaskStatus, TaskStatusCode.TASK_FINISH_MANUAL) + .or() + .eq(WcsTask::getTaskStatus, TaskStatusCode.TASK_CANCEL_MANUAL);; + List tasks = wcsTaskMapper.selectList(queryWrapper); + + for (int i = 0; i < tasks.size(); i++) { + + //todo 任务完成/取消请求wms + + + + WcsTaskHistory wcsTaskHistory = new WcsTaskHistory(); + BeanUtils.copyProperties(tasks.get(i), wcsTaskHistory); + wcsTaskHistory.setFinishTime(LocalDateTime.now()); + + //向历史记录添加任务数据 + wcsTaskHistoryMapper.insertWcsTaskHistory(wcsTaskHistory); + log.info("【添加到历任务记录】{}", JSON.toJSONString(wcsTaskHistory)); + + //移除实时任务表数据 + wcsTaskMapper.deleteWcsTaskByTaskId(tasks.get(i).getTaskId()); + log.info("【实时任务已完成】{}", JSON.toJSONString(tasks.get(i))); + } + + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/StatusUpdate.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/StatusUpdate.java new file mode 100644 index 0000000..abf86bc --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/StatusUpdate.java @@ -0,0 +1,94 @@ +package com.ruoyi.schedule.scheduleTask; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.Constant; +import com.ruoyi.common.TaskStatusCode; +import com.ruoyi.device.agv.domain.queryTaskStatus.TaskStatusData; +import com.ruoyi.schedule.task.domain.WcsTask; +import com.ruoyi.schedule.task.mapper.WcsTaskMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 通过【查询任务状态】接口获取当前任务的任务状态(待执行/执行中/结束...) + */ +@Component +@Slf4j +public class StatusUpdate { + + @Autowired + WcsTaskMapper wcsTaskMapper; + + public void statusUpdate() { + + //查询实时任务表获取所有【下发成功】任务 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(WcsTask::getTaskStatus, TaskStatusCode.TASK_SEND_SUCCESS); + List tasks = wcsTaskMapper.selectList(queryWrapper); + + //wcs本地任务轮询 + for (int i = 0; i < tasks.size(); i++) { + //查询【设备任务状态】接口是否有该任务号已 + HttpResponse response = HttpRequest.post(Constant.BASEURL + "/queryTaskStatus").execute(); + List deviceTasks = JSON.parseArray(response.body(), TaskStatusData.class); + + //接口查询的AGV/CTU设备任务轮询 + for (int j = 0; j < deviceTasks.size(); j++) { + + //wcs任务记录的任务号与接口查询的任务号匹配 + if (tasks.get(i).getTaskId() != deviceTasks.get(j).getTaskCode()) continue; + + switch (deviceTasks.get(j).getTaskStatus()) { + case "1": + //【任务状态】更新为已创建 + if (tasks.get(j).getTaskStatus() == TaskStatusCode.TASK_SEND_SUCCESS && tasks.get(j).getTaskStatus() != TaskStatusCode.TASK_CREATED) { + tasks.get(j).setTaskStatus(TaskStatusCode.TASK_CREATED); + wcsTaskMapper.updateWcsTask(tasks.get(i)); + } + break; + case "2"://【任务状态】更新为执行中 + if (tasks.get(j).getTaskStatus() == TaskStatusCode.TASK_CREATED && tasks.get(j).getTaskStatus() != TaskStatusCode.TASK_RUNNING) { + tasks.get(j).setTaskStatus(TaskStatusCode.TASK_RUNNING); + //更新【调度时间】 + tasks.get(j).setScheduleTime(LocalDateTime.now()); + wcsTaskMapper.updateWcsTask(tasks.get(i)); + } + break; + case "5"://【任务状态】更新为已取消 + if ((tasks.get(j).getTaskStatus() == TaskStatusCode.TASK_CREATED || + tasks.get(j).getTaskStatus() == TaskStatusCode.TASK_RUNNING) && + tasks.get(j).getTaskStatus() != TaskStatusCode.TASK_CANCEL) { + tasks.get(j).setTaskStatus(TaskStatusCode.TASK_CANCEL); + wcsTaskMapper.updateWcsTask(tasks.get(i)); + } + break; + case "9"://【任务状态】更新为已结束 + if (tasks.get(j).getTaskStatus() != TaskStatusCode.TASK_FINISH) { + tasks.get(j).setTaskStatus(TaskStatusCode.TASK_FINISH); + wcsTaskMapper.updateWcsTask(tasks.get(j)); + } + break; + case "10"://【任务状态】更新为被中断 + if (tasks.get(j).getTaskStatus() != TaskStatusCode.TASK_FINISH) { + tasks.get(j).setTaskStatus(TaskStatusCode.TASK_INTERUPTED); + wcsTaskMapper.updateWcsTask(tasks.get(j)); + } + break; + } + } + + } + + + + + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/TaskHandler.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/TaskHandler.java new file mode 100644 index 0000000..9e48157 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/TaskHandler.java @@ -0,0 +1,16 @@ +package com.ruoyi.schedule.scheduleTask; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + + +/** + * 用于处理没有正常执行或完成/取消的任务 + */ +@Component +@Slf4j +public class TaskHandler { + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/controller/WcsTaskController.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/controller/WcsTaskController.java index 7cbfb83..204fdad 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/controller/WcsTaskController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/controller/WcsTaskController.java @@ -118,7 +118,7 @@ public class WcsTaskController extends BaseController /** - * PTL拣选入口空---wms请求出库任务---生成wcs本地任务 + * PTL拣选入口空---wms推送请求出库---生成wcs本地任务 * @param task * @return */ @@ -137,14 +137,51 @@ public class WcsTaskController extends BaseController LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(WcsTask::getJobId, task.getJobId()); Long count= wcsTaskMapper.selectCount(wrapper); + //任务已存在---返回失败 if (count > 0) { response.setCode(1); response.setMessage("failed"); return response; } + //初始化任务状态---待执行 task.setTaskStatus(TaskStatusCode.TASK_READY); - task.setCreateTime(LocalDateTime.now().toLocalTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + wcsTaskService.insertWcsTask(task); + + return response; + } + + /** + * PTL拣选出口扫描到到位料箱---wms推送请求入库---生成wcs本地任务 + * @param task + * @return + */ + @PostMapping("/stockIn") + public ResponseBase stockIn(@RequestBody WcsTask task) { + + log.info("【获取入库请求】" + JSON.toJSONString(task)); + + ResponseBase response = new ResponseBase(); + response.setCode(0); + response.setMessage("success"); + response.setData(JSON.toJSONString(task)); + + //todo 有无信息校验 + //查询是否已经有该作业号的任务 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(WcsTask::getJobId, task.getJobId()); + Long count= wcsTaskMapper.selectCount(wrapper); + //任务已存在---返回失败 + if (count > 0) { + response.setCode(1); + response.setMessage("failed"); + return response; + } + + //初始化任务状态---待执行 + task.setTaskStatus(TaskStatusCode.TASK_READY); + wcsTaskService.insertWcsTask(task); return response; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/domain/WcsTask.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/domain/WcsTask.java index 6ad2998..45bc093 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/domain/WcsTask.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/domain/WcsTask.java @@ -1,10 +1,11 @@ package com.ruoyi.schedule.task.domain; import lombok.Data; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import com.ruoyi.common.annotation.Excel; -import com.ruoyi.common.core.domain.BaseEntity; +import org.springframework.data.annotation.Id; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; /** * 实时任务对象 wcs_task @@ -22,6 +23,7 @@ public class WcsTask private String jobId; /** wcs任务号 */ + @Excel(name = "任务号") private String taskId; /** 任务类型 */ @@ -42,11 +44,15 @@ public class WcsTask /** 生成时间 */ @Excel(name = "生成时间") - private String createTime; + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime = LocalDateTime.now(); - /** 调度时间 */ + /** + * 调度时间 + * 设备开始运行的时间 + */ @Excel(name = "调度时间") - private String scheduleTime; + private LocalDateTime scheduleTime; /** 设备编号 */ @Excel(name = "设备编号") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/service/impl/WcsTaskServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/service/impl/WcsTaskServiceImpl.java index 09ff153..0750536 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/service/impl/WcsTaskServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/task/service/impl/WcsTaskServiceImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.schedule.task.service.impl; +import java.time.LocalDateTime; import java.util.List; import com.ruoyi.common.utils.DateUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -65,7 +66,7 @@ public class WcsTaskServiceImpl implements IWcsTaskService @Override public int insertWcsTask(WcsTask wcsTask) { - wcsTask.setCreateTime(DateUtils.getNowDate().toString()); + wcsTask.setCreateTime(LocalDateTime.now()); return wcsTaskMapper.insertWcsTask(wcsTask); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/taskHistory/domain/WcsTaskHistory.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/taskHistory/domain/WcsTaskHistory.java index 9c51d05..c7b9780 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/taskHistory/domain/WcsTaskHistory.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/taskHistory/domain/WcsTaskHistory.java @@ -6,6 +6,8 @@ import org.apache.commons.lang3.builder.ToStringStyle; import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.core.domain.BaseEntity; +import java.time.LocalDateTime; + /** * 任务历史记录对象 wcs_task_history * @@ -43,11 +45,11 @@ public class WcsTaskHistory extends BaseEntity /** 调度时间 */ @Excel(name = "调度时间") - private String scheduleTime; + private LocalDateTime scheduleTime; /** 结束时间 */ @Excel(name = "结束时间") - private String finishTime; + private LocalDateTime finishTime; /** 设备编号 */ @Excel(name = "设备编号") diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 554238f..cc6e3c0 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -72,7 +72,7 @@ spring: # 端口,默认为6379 port: 6379 # 数据库索引 - database: 0 + database: 1 # 密码 password: 123456 # 连接超时时间