1
xiazhengtongxue
2 天以前 5b34a1458e74f8902d01ebd844c2954f554c9e74
1
已修改14个文件
870 ■■■■■ 文件已修改
Code/WCS/WIDESEAWCS_Client/src/extension/taskinfo/extend/AddRobotTask.vue 170 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskTypeEnum.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_DTO/TaskInfo/CreateTaskDto.cs 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/IRobotTaskService.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/Task/RobotTaskController.cs 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/OutboundTaskFlowService.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient/src/views/Home.vue 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_TaskStatus.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs 86 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Client/src/extension/taskinfo/extend/AddRobotTask.vue
@@ -1,8 +1,29 @@
<template>
  <div>
    <!-- 手动创建换盘机械手任务弹窗 -->
    <vol-box v-model="showManualCreate" :lazy="true" width="500px" :padding="15" title="手动创建换盘机械手任务">
    <!-- 手动创建机器人任务弹窗 -->
    <vol-box v-model="showManualCreate" :lazy="true" width="550px" :padding="15" title="手动创建机器人任务">
      <el-form :model="manualFormData" ref="form" label-width="120px">
        <!-- 任务类型选择 -->
        <el-form-item label="任务类型" prop="robotRoadway" required>
          <el-select v-model="manualFormData.robotRoadway" placeholder="请选择任务类型" @change="onTaskTypeChange">
            <el-option label="组盘任务" value="GroupPallet"></el-option>
            <el-option label="换盘任务" value="ChangePallet"></el-option>
            <el-option label="拆盘任务" value="SplitPallet"></el-option>
          </el-select>
        </el-form-item>
        <!-- 组盘任务:仅需目标地址托盘码和任务总数 -->
        <template v-if="manualFormData.robotRoadway === 'GroupPallet'">
          <el-form-item label="目标地址托盘码" prop="robotTargetAddressPalletCode" required>
            <el-input v-model="manualFormData.robotTargetAddressPalletCode" placeholder="请输入目标地址托盘码"></el-input>
          </el-form-item>
          <el-form-item label="任务总数" prop="robotTaskTotalNum" required>
            <el-input-number v-model="manualFormData.robotTaskTotalNum" :min="1" :max="999" label="任务总数"></el-input-number>
          </el-form-item>
        </template>
        <!-- 换盘任务:需来源、目标托盘码和4个方向 -->
        <template v-if="manualFormData.robotRoadway === 'ChangePallet'">
        <el-form-item label="来源地址托盘码" prop="robotSourceAddressPalletCode" required>
          <el-input v-model="manualFormData.robotSourceAddressPalletCode" placeholder="请输入来源地址托盘码"></el-input>
        </el-form-item>
@@ -11,16 +32,30 @@
        </el-form-item>
        <el-form-item label="方向" prop="forward" required>
          <el-radio-group v-model="manualFormData.forward">
            <el-radio :label="1">去化成(源:1→目标:3)</el-radio>
            <el-radio :label="2">去化成(源:2→目标:4)</el-radio>
            <el-radio :label="3">回高温(源:3→目标:1)</el-radio>
            <el-radio :label="4">回高温(源:4→目标:2)</el-radio>
              <el-radio :label="1">去化成1: 源:1(11010) → 目标:3(2103)</el-radio>
              <el-radio :label="2">去化成2: 源:2(11001) → 目标:4(2101)</el-radio>
              <el-radio :label="3">回高温3: 源:4(2103) → 目标:2(11010)</el-radio>
              <el-radio :label="4">回高温4: 源:4(2101) → 目标:2(11001)</el-radio>
          </el-radio-group>
        </el-form-item>
          <el-form-item label="任务总数" prop="robotTaskTotalNum" required>
            <el-input-number v-model="manualFormData.robotTaskTotalNum" :min="1" :max="999" label="任务总数"></el-input-number>
          </el-form-item>
        </template>
        <!-- 拆盘任务:仅需来源地址托盘码和任务总数 -->
        <template v-if="manualFormData.robotRoadway === 'SplitPallet'">
          <el-form-item label="来源地址托盘码" prop="robotSourceAddressPalletCode" required>
            <el-input v-model="manualFormData.robotSourceAddressPalletCode" placeholder="请输入来源地址托盘码"></el-input>
          </el-form-item>
          <el-form-item label="任务总数" prop="robotTaskTotalNum" required>
            <el-input-number v-model="manualFormData.robotTaskTotalNum" :min="1" :max="999" label="任务总数"></el-input-number>
          </el-form-item>
        </template>
      </el-form>
      <template #footer>
        <el-button type="primary" size="small" @click="submitManualCreate">确定</el-button>
        <el-button type="danger" size="small" @click="showManualCreate = false">关闭</el-button>
        <el-button type="danger" size="small" @click="closeDialog">关闭</el-button>
      </template>
    </vol-box>
  </div>
@@ -35,10 +70,25 @@
  data() {
    return {
      showManualCreate: false,
      // 任务类型映射(用于显示中文名称)
      taskTypeMap: {
        GroupPallet: "组盘任务",
        ChangePallet: "换盘任务",
        SplitPallet: "拆盘任务",
      },
      // 方向描述映射
      directionMap: {
        1: "去化成1: 源:1(11010) → 目标:3(2103)",
        2: "去化成2: 源:2(11001) → 目标:4(2101)",
        3: "回高温3: 源:4(2103) → 目标:2(11010)",
        4: "回高温4: 源:4(2101) → 目标:2(11001)",
      },
      manualFormData: {
        robotSourceAddressPalletCode: "",
        robotTargetAddressPalletCode: "",
        forward: 1, // 1=去化成(1→3), 2=去化成(2→4), 3=回高温(3→1), 4=回高温(4→2)
        robotRoadway: "",               // 机器人名称/任务类型
        robotSourceAddressPalletCode: "", // 来源地址托盘码
        robotTargetAddressPalletCode: "", // 目标地址托盘码
        forward: 1,                     // 方向(换盘任务使用,1-4)
        robotTaskTotalNum: 1,           // 任务总数
      },
    };
  },
@@ -49,40 +99,110 @@
      this.resetManualForm();
    },
    
    // 关闭弹窗
    closeDialog() {
      this.showManualCreate = false;
    },
    // 重置表单
    resetManualForm() {
      this.manualFormData = {
        robotRoadway: "",
        robotSourceAddressPalletCode: "",
        robotTargetAddressPalletCode: "",
        forward: 1,
        robotTaskTotalNum: 1,
      };
    },
    // 任务类型切换时重置相关字段
    onTaskTypeChange(value) {
      this.manualFormData.robotSourceAddressPalletCode = "";
      this.manualFormData.robotTargetAddressPalletCode = "";
      this.manualFormData.forward = 1;
    },
    // 表单验证
    validateForm() {
      const data = this.manualFormData;
      // 1. 必选任务类型
      if (!data.robotRoadway) {
        this.$message.error("请选择任务类型");
        return false;
      }
      // 2. 根据任务类型验证必填字段
      const taskType = data.robotRoadway;
      if (taskType === "GroupPallet") {
        if (!data.robotTargetAddressPalletCode) {
          this.$message.error("组盘任务:请输入目标地址托盘码");
          return false;
        }
      } else if (taskType === "ChangePallet") {
        if (!data.robotSourceAddressPalletCode) {
          this.$message.error("换盘任务:请输入来源地址托盘码");
          return false;
        }
        if (!data.robotTargetAddressPalletCode) {
          this.$message.error("换盘任务:请输入目标地址托盘码");
          return false;
        }
        // 验证方向 1-4
        if (![1, 2, 3, 4].includes(data.forward)) {
          this.$message.error("换盘任务:请选择有效的方向(1-4)");
          return false;
        }
      } else if (taskType === "SplitPallet") {
        if (!data.robotSourceAddressPalletCode) {
          this.$message.error("拆盘任务:请输入来源地址托盘码");
          return false;
        }
      }
      // 3. 验证任务总数
      if (data.robotTaskTotalNum < 1) {
        this.$message.error("任务总数不能小于1");
        return false;
      }
      return true;
    },
    
    // 提交手动创建任务
    submitManualCreate() {
      // 表单验证
      if (!this.manualFormData.robotSourceAddressPalletCode) {
        return this.$message.error("请输入来源地址托盘码");
      }
      if (!this.manualFormData.robotTargetAddressPalletCode) {
        return this.$message.error("请输入目标地址托盘码");
      }
      if (this.manualFormData.forward === undefined || this.manualFormData.forward === null) {
        return this.$message.error("请选择方向");
      if (!this.validateForm()) {
        return;
      }
      // 调用后端API创建换盘机械手任务
      this.http
        .post("api/RobotTask/AddRobotTask", {
      // 构建请求参数(与后端 ManualRobotTaskDto 对应)
      const params = {
        robotRoadway: this.manualFormData.robotRoadway,
          robotSourceAddressPalletCode: this.manualFormData.robotSourceAddressPalletCode,
          robotTargetAddressPalletCode: this.manualFormData.robotTargetAddressPalletCode,
          forward: this.manualFormData.forward,  // 注意字段名改为forward,类型为整数
        }, "创建换盘机械手任务中...")
        robotTaskTotalNum: this.manualFormData.robotTaskTotalNum,
        forward: this.manualFormData.forward,  // 方向,整型 1-4
      };
      // 获取任务类型中文名称用于提示
      const taskTypeName = this.taskTypeMap[params.robotRoadway] || "机器人";
      // 获取方向描述(仅换盘任务)
      let directionDesc = "";
      if (params.robotRoadway === "ChangePallet") {
        directionDesc = this.directionMap[params.forward] || "";
      }
      // 调用后端API创建机器人任务
      this.http
        .post("api/RobotTask/CreateRobotTaskManually", params, `创建${taskTypeName}${directionDesc ? ' - ' + directionDesc : ''}中...`)
        .then((res) => {
          if (!res.status) {
            return this.$message.error(res.message);
          }
          this.$message.success("换盘机械手任务创建成功");
          this.$message.success(`${taskTypeName}${directionDesc ? ' - ' + directionDesc : ''}创建成功`);
          this.showManualCreate = false;
          // 刷新父页面数据
          this.$emit("parentCall", ($vue) => {
@@ -90,7 +210,7 @@
          });
        })
        .catch((err) => {
          this.$message.error("创建换盘机械手任务失败:" + (err.message || "未知错误"));
          this.$message.error(`创建${taskTypeName}失败:` + (err.message || "未知错误"));
        });
    },
  },
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskTypeEnum.cs
@@ -109,7 +109,7 @@
        /// <summary>
        /// 拆盘任务
        /// </summary>
        [Description("换盘任务")]
        [Description("拆盘任务")]
        SplitPallet = 520
    }
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_DTO/TaskInfo/CreateTaskDto.cs
@@ -1,4 +1,5 @@
using System;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
@@ -50,4 +51,36 @@
        /// </summary>
        public int TaskType { get; set; }
    }
    /// <summary>
    /// 手动创建机器人任务
    /// </summary>
    public class ManualRobotTaskDto
    {
        /// <summary>
        /// 机器人名称
        /// </summary>
        public string RobotRoadway { get; set; }
        /// <summary>
        /// 机器人来源地址输送线托盘号
        /// </summary>
        public String RobotSourceAddressPalletCode { get; set; }
        /// <summary>
        /// 机器人目标地址线托盘号
        /// </summary>
        public String RobotTargetAddressPalletCode { get; set; }
        /// <summary>
        /// 机器人任务总数
        /// </summary>
        public int RobotTaskTotalNum { get; set; }
        /// <summary>
        /// 方向
        /// </summary>
        public int Forward { get; set; }
    }
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/IRobotTaskService.cs
@@ -91,5 +91,6 @@
        int MapWarehouseIdConfigKey(string? targetAddress);
        string ResolveRobotRuleValue(string? targetAddress, string addressSectionName, string? fallback);
        WebResponseContent CreateRobotTaskManually(ManualRobotTaskDto request);
    }
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/Task/RobotTaskController.cs
@@ -3,6 +3,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.BaseController;
using WIDESEAWCS_Core.Enums;
@@ -30,67 +31,11 @@
            return WebResponseContent.Instance.Error();
        }
        // 暂时创建换盘机械手任务
        [HttpGet, HttpPost, Route("AddRobotTask"), AllowAnonymous]
        public WebResponseContent AddRobotTask([FromBody] RobotMoveRequest request)
        // 手动机械手任务
        [HttpGet, HttpPost, Route("CreateRobotTaskManually"), AllowAnonymous]
        public WebResponseContent CreateRobotTaskManually([FromBody] ManualRobotTaskDto request)
        {
            try
            {
                Dt_RobotTask robotTask = new Dt_RobotTask();
                robotTask.RobotTaskNum = Random.Shared.StrictNext();
                robotTask.RobotRoadway = "换盘机械手";
                robotTask.RobotTaskType = 510;
                robotTask.RobotTaskState = 300;
                robotTask.RobotTaskTotalNum = 48;
                robotTask.RobotGrade = 1;
                robotTask.RobotDispatchertime = DateTime.Now;
                robotTask.RobotRemark = "人工手动创建";
                robotTask.RobotSourceAddressPalletCode = request.robotSourceAddressPalletCode;
                robotTask.RobotTargetAddressPalletCode = request.robotTargetAddressPalletCode;
                // 根据方向设置源和目标
                switch (request.Forward)
                {
                    case 1:
                        robotTask.RobotSourceAddress = "1";
                        robotTask.RobotSourceAddressLineCode = "11010";
                        robotTask.RobotTargetAddress = "3";
                        robotTask.RobotTargetAddressLineCode = "2103";
                        break;
                    case 2:
                        robotTask.RobotSourceAddress = "2";
                        robotTask.RobotSourceAddressLineCode = "11001";
                        robotTask.RobotTargetAddress = "4";
                        robotTask.RobotTargetAddressLineCode = "2101";
                        break;
                    case 3:
                        robotTask.RobotSourceAddress = "3";
                        robotTask.RobotSourceAddressLineCode = "2103";
                        robotTask.RobotTargetAddress = "1";
                        robotTask.RobotTargetAddressLineCode = "11010";
                        break;
                    case 4:
                        robotTask.RobotSourceAddress = "4";
                        robotTask.RobotSourceAddressLineCode = "2101";
                        robotTask.RobotTargetAddress = "2";
                        robotTask.RobotTargetAddressLineCode = "11001";
                        break;
                    default:
                        return WebResponseContent.Instance.Error($"添加机器人任务失败");
                }
                return Service.AddData(robotTask);
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error($"添加机器人任务失败: {ex.Message}");
            return Service.CreateRobotTaskManually(request);
            }
        }
    }
}
public class RobotMoveRequest
{
    public int Forward { get; set; }
    public String robotSourceAddressPalletCode { get; set; }
    public String robotTargetAddressPalletCode { get; set; }
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
@@ -52,7 +52,7 @@
    "EnableConsoleOutput": false, //是否输出到控制台
    "EnableFloderByLevel": true //是否按日志级别生成不同的文件夹
  },
  "ApiLogIgnore": "", //记录日志时,忽略的API名称,多个用逗号分隔,配置的不记录到数据库中
  "ApiLogIgnore": "Export,Get,get", //记录日志时,忽略的API名称,多个用逗号分隔,配置的不记录到数据库中
  "ApiName": "WIDESEAWCS",
  "ExpMinutes": 120,
  "QuartzJobAutoStart": true,
@@ -112,7 +112,7 @@
  },
  "RedisConfig": {
    "Enabled": true, //是否启用Redis,false时仅使用内存缓存
    "ConnectionString": "127.0.0.1:6379,password=P@ssw0rd,defaultDatabase=0,connectTimeout=5000,abortConnect=false", //Redis连接字符串
    "ConnectionString": "127.0.0.1:6379,password=,defaultDatabase=0,connectTimeout=5000,abortConnect=false", //Redis连接字符串
    "InstanceName": "WIDESEAWCS:", //实例名称,用于区分不同应用
    "DefaultDatabase": 0, //默认数据库索引(0-15)
    "EnableSentinel": false, //是否启用哨兵模式
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs
@@ -1,12 +1,14 @@
using System.Diagnostics.CodeAnalysis;
using Serilog;
using Serilog;
using System.Diagnostics.CodeAnalysis;
using WIDESEA_Core;
using WIDESEAWCS_Common.HttpEnum;
using WIDESEAWCS_Common.TaskEnum;
using WIDESEA_Core;
using WIDESEAWCS_Core;
using WIDESEAWCS_Core.Enums;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_DTO;
using WIDESEAWCS_DTO.TaskInfo;
using WIDESEAWCS_ITaskInfoRepository;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob.Models;
@@ -22,6 +24,7 @@
    public class InboundTaskFlowService : IInboundTaskFlowService
    {
        private readonly IRouterService _routerService;
        private readonly ITaskRepository _taskRepository;
        private readonly HttpClientHelper _httpClientHelper;
        private readonly ILogger _logger;
@@ -30,9 +33,10 @@
        /// </summary>
        /// <param name="routerService">路由服务。</param>
        /// <param name="httpClientHelper">WMS接口调用帮助类。</param>
        public InboundTaskFlowService(IRouterService routerService, HttpClientHelper httpClientHelper, ILogger logger)
        public InboundTaskFlowService(IRouterService routerService, ITaskRepository taskRepository, HttpClientHelper httpClientHelper, ILogger logger)
        {
            _routerService = routerService;
            _taskRepository = taskRepository;
            _httpClientHelper = httpClientHelper;
            _logger = logger;
        }
@@ -153,9 +157,36 @@
        /// <returns>同步结果。</returns>
        private WebResponseContent UpdateWMSTaskStatus(Dt_Task task)
        {
            DateTime startTime = DateTime.Now;
            // 处理入库完成状态的特殊同步
            if (task.TaskStatus == (int)TaskInStatusEnum.InFinish)
            {
                string InboundFinishKey = nameof(ConfigKey.InboundFinishTaskAsync);
                var requestDto = new CreateTaskDto()
                {
                    PalletCode = task.PalletCode,
                    SourceAddress = task.SourceAddress,
                    TargetAddress = task.TargetAddress,
                    Roadway = task.Roadway,
                    TaskType = task.TaskType,
                }.ToJson();
                var resultFinish = _httpClientHelper.Post<WebResponseContent>(InboundFinishKey, requestDto);
                if (!resultFinish.IsSuccess || !resultFinish.Data.Status)
                {
                    QuartzLogHelper.LogError(_logger, $"调用WMS接口失败,接口:【{resultFinish}】,请求参数:【{requestDto}】,错误信息:【{resultFinish.Data?.Message}】", "InboundTaskFlowService");
                    return WebResponseContent.Instance.Error($"调用WMS接口更新任务状态失败,任务号:【{task.TaskNum}】,错误信息:【{resultFinish.Data?.Message}】");
                }
                QuartzLogHelper.LogInfo(_logger, $"调用WMS接口成功,接口:【{InboundFinishKey}】,响应数据:【{resultFinish.Data?.Data}】,耗时:{(DateTime.Now - startTime).TotalMilliseconds}ms", "InboundTaskFlowService");
                _taskRepository.DeleteAndMoveIntoHty(task, OperateTypeEnum.人工完成);
                return WebResponseContent.Instance.OK();
            }
            string configKey = nameof(ConfigKey.UpdateTaskByStatus);
            string requestParam = new UpdateTaskDto { Id = task.TaskNum, NewStatus = task.TaskStatus, NextAddress = task.NextAddress, CurrentAddress = task.CurrentAddress }.ToJson();
            DateTime startTime = DateTime.Now;
            var result = _httpClientHelper.Post<WebResponseContent>(
                configKey,
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/OutboundTaskFlowService.cs
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
using Masuit.Tools.Hardware;
using Newtonsoft.Json;
using Serilog;
using System.Diagnostics.CodeAnalysis;
using WIDESEA_Core;
@@ -254,9 +255,35 @@
        /// <returns>同步结果。</returns>
        private WebResponseContent UpdateWMSTaskStatus(Dt_Task task)
        {
            DateTime startTime = DateTime.Now;
            // 处理出库完成状态的特殊同步
            if (task.TaskStatus == (int)TaskOutStatusEnum.SC_OutFinish)
            {
                string OutboundFinishKey = nameof(ConfigKey.OutboundFinishTaskAsync);
                var requestDto = new CreateTaskDto()
                {
                    PalletCode = task.PalletCode,
                    SourceAddress = task.SourceAddress,
                    TargetAddress = task.TargetAddress,
                    Roadway = task.Roadway,
                    TaskType = task.TaskType,
                }.ToJson();
                var resultFinish = _httpClientHelper.Post<WebResponseContent>(OutboundFinishKey, requestDto);
                if (!resultFinish.IsSuccess || !resultFinish.Data.Status)
                {
                    QuartzLogHelper.LogError(_logger, $"调用WMS接口失败,接口:【{resultFinish}】,请求参数:【{requestDto}】,错误信息:【{resultFinish.Data?.Message}】", "OutboundTaskFlowService");
                    return WebResponseContent.Instance.Error($"调用WMS接口更新任务状态失败,任务号:【{task.TaskNum}】,错误信息:【{resultFinish.Data?.Message}】");
                }
                QuartzLogHelper.LogInfo(_logger, $"调用WMS接口成功,接口:【{OutboundFinishKey}】,响应数据:【{resultFinish.Data?.Data}】,耗时:{(DateTime.Now - startTime).TotalMilliseconds}ms", "OutboundTaskFlowService");
                return WebResponseContent.Instance.OK();
            }
            string configKey = nameof(ConfigKey.UpdateTaskByStatus);
            string requestParam = new UpdateTaskDto { Id = task.TaskNum, NewStatus = task.TaskStatus, NextAddress = task.NextAddress, CurrentAddress = task.CurrentAddress }.ToJson();
            DateTime startTime = DateTime.Now;
            var result = _httpClientHelper.Post<WebResponseContent>(
                configKey,
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotTaskService.cs
@@ -17,7 +17,9 @@
#endregion << 版 本 注 释 >>
using Autofac.Core;
using MapsterMapper;
using Masuit.Tools;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Serilog;
@@ -448,5 +450,82 @@
                .Where(x => !string.IsNullOrWhiteSpace(x.Key) && !string.IsNullOrWhiteSpace(x.Value))
                .ToDictionary(x => x.Key.Trim(), x => x.Value!.Trim());
        }
        public WebResponseContent CreateRobotTaskManually(ManualRobotTaskDto request)
        {
            try
            {
                Dt_RobotTask robotTask = new Dt_RobotTask();
                robotTask.RobotTaskNum = Random.Shared.StrictNext();
                robotTask.RobotRoadway = request.RobotRoadway;
                if (request.RobotRoadway == RobotTaskTypeEnum.GroupPallet.ToString())
                {
                    robotTask.RobotTaskType = (int)RobotTaskTypeEnum.GroupPallet;
                    robotTask.RobotTaskState = (int)TaskRobotStatusEnum.RobotNew;
                    robotTask.RobotTaskTotalNum = request.RobotTaskTotalNum;
                    robotTask.RobotDispatchertime = DateTime.Now;
                    robotTask.RobotRemark = "人工手动创建";
                    robotTask.RobotTargetAddressPalletCode = request.RobotTargetAddressPalletCode;
                    robotTask.RobotTargetAddressLineCode = "11068";
                }
                else if (request.RobotRoadway == RobotTaskTypeEnum.ChangePallet.ToString())
                {
                    switch (request.Forward)
                    {
                        case 1:
                            robotTask.RobotSourceAddress = "1";
                            robotTask.RobotSourceAddressLineCode = "11010";
                            robotTask.RobotTargetAddress = "3";
                            robotTask.RobotTargetAddressLineCode = "2103";
                            break;
                        case 2:
                            robotTask.RobotSourceAddress = "2";
                            robotTask.RobotSourceAddressLineCode = "11001";
                            robotTask.RobotTargetAddress = "4";
                            robotTask.RobotTargetAddressLineCode = "2101";
                            break;
                        case 3:
                            robotTask.RobotSourceAddress = "3";
                            robotTask.RobotSourceAddressLineCode = "2103";
                            robotTask.RobotTargetAddress = "1";
                            robotTask.RobotTargetAddressLineCode = "11010";
                            break;
                        case 4:
                            robotTask.RobotSourceAddress = "4";
                            robotTask.RobotSourceAddressLineCode = "2101";
                            robotTask.RobotTargetAddress = "2";
                            robotTask.RobotTargetAddressLineCode = "11001";
                            break;
                        default:
                            return WebResponseContent.Instance.Error($"添加机器人任务失败,方向不对");
                    }
                    robotTask.RobotTaskType = (int)RobotTaskTypeEnum.ChangePallet;
                    robotTask.RobotTaskState = (int)TaskRobotStatusEnum.RobotNew;
                    robotTask.RobotTaskTotalNum = request.RobotTaskTotalNum;
                    robotTask.RobotDispatchertime = DateTime.Now;
                    robotTask.RobotRemark = "人工手动创建";
                    robotTask.RobotSourceAddressPalletCode = request.RobotSourceAddressPalletCode;
                    robotTask.RobotTargetAddressPalletCode = request.RobotTargetAddressPalletCode;
                }
                else if (request.RobotRoadway == RobotTaskTypeEnum.SplitPallet.ToString())
                {
                    robotTask.RobotTaskType = (int)RobotTaskTypeEnum.SplitPallet;
                    robotTask.RobotTaskState = (int)TaskRobotStatusEnum.RobotNew;
                    robotTask.RobotTaskTotalNum = request.RobotTaskTotalNum;
                    robotTask.RobotDispatchertime = DateTime.Now;
                    robotTask.RobotRemark = "人工手动创建";
                    robotTask.RobotSourceAddressPalletCode = request.RobotSourceAddressPalletCode;
                }
                else
                {
                    return WebResponseContent.Instance.Error($"添加机器人任务失败,机器人名称错误{request.RobotRoadway}");
                }
                return base.AddData(robotTask);
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error($"添加机器人任务失败: {ex.Message}");
            }
        }
    }
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs
@@ -206,10 +206,10 @@
                            if (state.ChangePalletPhase == 5)
                            {
                                // FlowB 最终阶段:假电芯取完,源空托盘回库 HCSC1
                                //if (!await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: true, isRoadway: "HCSC1"))
                                //{
                                //    return false;
                                //}
                                if (!await _taskProcessor.HandleInboundTaskAsync(state, useSourceAddress: true, isRoadway: "HCSC1"))
                                {
                                    return false;
                                }
                                if (_taskProcessor.DeleteTask(currentTask.RobotTaskId) != true)
                                {
Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
@@ -1,26 +1,10 @@
<template>
  <div class="dashboard-container">
    <!-- 顶部:本月出入库趋势 (全宽) -->
    <!-- 各仓库月度出入库对比图 -->
    <div class="chart-row full-width">
      <div class="chart-card">
        <div class="card-title">每月出入库趋势</div>
        <div id="chart-monthly-trend" class="chart-content"></div>
      </div>
    </div>
    <!-- 第二行:每日出入库趋势 (全宽) -->
    <div class="chart-row full-width">
      <div class="chart-card">
        <div class="card-title">每日出入库趋势</div>
        <div id="chart-daily" class="chart-content"></div>
      </div>
    </div>
    <!-- 第四行:仓库分布 -->
    <div class="chart-row">
      <div class="chart-card">
        <div class="card-title">各仓库库存分布</div>
        <div id="chart-warehouse" class="chart-content"></div>
        <div class="card-title">各仓库月度出入库对比</div>
        <div id="chart-warehouse-monthly" class="chart-content"></div>
      </div>
    </div>
  </div>
@@ -34,9 +18,8 @@
  data() {
    return {
      charts: {},
      dailyData: [],
      monthlyData: [],
      warehouseData: []
      warehouseNames: ['FJSC1', 'ZJSC1', 'GWSC1', 'CWSC1', 'HCSC1']
    };
  },
  mounted() {
@@ -54,212 +37,190 @@
    },
    initCharts() {
      this.charts.monthlyTrend = echarts.init(document.getElementById("chart-monthly-trend"));
      this.charts.daily = echarts.init(document.getElementById("chart-daily"));
      this.charts.warehouse = echarts.init(document.getElementById("chart-warehouse"));
      this.charts.warehouseMonthly = echarts.init(document.getElementById("chart-warehouse-monthly"));
    },
    async loadData() {
      await this.loadMonthlyStats();
      await this.loadDailyStats();
      await this.loadStockByWarehouse();
    },
    async loadMonthlyStats() {
      try {
        const res = await this.http.get("/api/Dashboard/MonthlyStats", { months: 12 });
        if (res.status && res.data) {
          console.log("每月统计数据:", res.data);
          this.monthlyData = res.data;
          this.updateMonthlyTrendChart();
        }
        const promises = this.warehouseNames.map(warehouse =>
          this.http.get("/api/Dashboard/MonthlyStats", {
            months: 6,
            Roadway: warehouse
          })
        );
        const results = await Promise.all(promises);
        this.monthlyData = results.map((res, index) => ({
          warehouse: this.warehouseNames[index],
          warehouseName: this.getWarehouseName(this.warehouseNames[index]),
          data: res.data || []
        }));
        this.updateWarehouseMonthlyChart();
      } catch (e) {
        console.error("加载每月统计失败", e);
      }
    },
    async loadDailyStats() {
      try {
        const res = await this.http.get("/api/Dashboard/DailyStats", { days: 30 });
        if (res.status && res.data) {
          console.log("每日统计数据:", res.data);
          this.dailyData = res.data;
          this.updateDailyChart();
        }
      } catch (e) {
        console.error("加载每日统计失败", e);
      }
    },
    async loadStockByWarehouse() {
      try {
        const res = await this.http.get("/api/Dashboard/StockByWarehouse");
        if (res.status && res.data) {
          console.log("仓库分布数据:", res.data);
          this.warehouseData = res.data.data || res.data;
          this.updateWarehouseChart();
        }
      } catch (e) {
        console.error("加载仓库分布失败", e);
      }
    },
    updateMonthlyTrendChart() {
      const option = {
        tooltip: { trigger: "axis" },
        legend: { data: ["入库", "出库"], textStyle: { color: "#fff" } },
        xAxis: {
          type: "category",
          data: this.monthlyData.map(m => m.month),
          axisLabel: { color: "#fff", rotate: 45 }
        },
        yAxis: [
          {
            type: "value",
            name: "数量",
            axisLabel: { color: "#fff" }
          }
        ],
        series: [
          { name: "入库", type: "bar", data: this.monthlyData.map(m => m.inbound), itemStyle: { color: "#5470c6" } },
          { name: "出库", type: "line", data: this.monthlyData.map(m => m.outbound), itemStyle: { color: "#91cc75" } }
        ]
    getWarehouseName(code) {
      const nameMap = {
        'FJSC1': '负极卷1号仓库',
        'ZJSC1': '正极卷1号仓库',
        'GWSC1': '高温1号仓库',
        'CWSC1': '常温1号仓库',
        'HCSC1': '分容1号仓库'
      };
      this.charts.monthlyTrend.setOption(option, true);
      return nameMap[code] || code;
    },
    updateDailyChart() {
      const option = {
        tooltip: { trigger: "axis" },
        legend: { data: ["入库", "出库"], textStyle: { color: "#fff" } },
        xAxis: {
          type: "category",
          data: this.dailyData.map(d => d.date),
          axisLabel: {
            color: "#fff",
            interval: 0,
            rotate: 45,
            fontSize: 12,
            margin: 10
    updateWarehouseMonthlyChart() {
      // 获取所有月份
      const months = this.monthlyData[0]?.data.map(d => `${d.month}月`) || [];
      // 为每个仓库生成系列数据
      const series = [];
      this.monthlyData.forEach((warehouseData, index) => {
        const data = warehouseData.data;
        series.push({
          name: warehouseData.warehouseName,
          type: 'bar',
          data: data.map(d => ({
            value: (d.inbound || 0) + (d.outbound || 0),
            inbound: d.inbound || 0,
            outbound: d.outbound || 0,
            label: {
              show: true,
              position: 'top',
              formatter: function(params) {
                return `入:${params.data.inbound}\n出:${params.data.outbound}`;
          },
          axisTick: {
            alignWithLabel: true
              fontSize: 10,
              color: '#fff',
              lineHeight: 15
          }
        },
        yAxis: {
          type: "value",
          axisLabel: { color: "#fff" }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '15%',
          top: '10%',
          containLabel: true
        },
        series: [
          { name: "入库", type: "bar", data: this.dailyData.map(d => d.inbound), itemStyle: { color: "#5470c6" } },
          { name: "出库", type: "bar", data: this.dailyData.map(d => d.outbound), itemStyle: { color: "#91cc75" } }
        ]
      };
      this.charts.daily.setOption(option, true);
    },
    updateWarehouseChart() {
      const warehouseNames = this.warehouseData.map(w => w.warehouse);
      const totalStocks = this.warehouseData.map(w => w.total);
      const hasStocks = this.warehouseData.map(w => w.hasStock);
      const noStocks = this.warehouseData.map(w => w.noStock);
      const hasStockPercentages = this.warehouseData.map(w => w.hasStockPercentage);
      const noStockPercentages = this.warehouseData.map(w => w.noStockPercentage);
          })),
          barWidth: '15%',
          barGap: '10%',
          itemStyle: {
            color: this.getBarColor(index),
            borderRadius: [3, 3, 0, 0]
          }
        });
      });
      
      const option = {
        title: {
          text: '各仓库月度出入库对比',
          textStyle: {
            color: '#00ffff',
            fontSize: 16
          },
          left: 'center',
          top: 10
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          },
          formatter: function(params) {
            let tip = params[0].name + '<br/>';
            let tip = `<strong>${params[0].axisValue}</strong><br/>`;
            params.forEach(param => {
              const dataIndex = param.dataIndex;
              const warehouse = window.homeComponent.warehouseData[dataIndex];
              if (param.seriesName === '已用容量') {
                tip += `${param.marker}${param.seriesName}: ${param.value} (${warehouse.hasStockPercentage})<br/>`;
                tip += `有库存: ${warehouse.hasStock}<br/>`;
                tip += `无库存: ${warehouse.noStock}<br/>`;
                tip += `总容量: ${warehouse.total}`;
              } else if (param.seriesName === '剩余容量') {
                tip += `${param.marker}${param.seriesName}: ${param.value} (${warehouse.noStockPercentage})<br/>`;
                tip += `有库存: ${warehouse.hasStock}<br/>`;
                tip += `无库存: ${warehouse.noStock}<br/>`;
                tip += `总容量: ${warehouse.total}`;
              }
              tip += `<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${param.color};margin-right:5px;"></span>`;
              tip += `${param.seriesName}: `;
              tip += `入库:${param.data.inbound} | 出库:${param.data.outbound} | 总计:${param.value}<br/>`;
            });
            return tip;
          }
        },
        legend: {
          data: ['已用容量', '剩余容量'],
          textStyle: { color: '#fff' }
          data: this.monthlyData.map(d => d.warehouseName),
          textStyle: { color: '#fff', fontSize: 11 },
          top: 45,
          left: 'center',
          type: 'scroll'
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '10%',
          top: '20%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: warehouseNames,
          axisLabel: { color: '#fff', rotate: 30 }
          data: months,
          axisLabel: {
            color: '#fff',
            fontSize: 11
          },
          axisLine: {
            lineStyle: { color: 'rgba(255,255,255,0.3)' }
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: 'rgba(255,255,255,0.1)',
              type: 'dashed'
            }
          }
        },
        yAxis: {
          type: 'value',
          axisLabel: { color: '#fff' }
          name: '数量',
          nameTextStyle: { color: '#fff' },
          axisLabel: { color: '#fff' },
          splitLine: {
            lineStyle: {
              color: 'rgba(255,255,255,0.1)',
              type: 'dashed'
            }
          }
        },
        series: [
        dataZoom: [
          {
            name: '已用容量',
            type: 'bar',
            data: hasStocks.map((value, index) => ({
              value: value,
              label: {
                show: true,
                position: 'top',
                formatter: '{c} {a|' + hasStockPercentages[index] + '}',
                rich: {
                  a: {
                    lineHeight: 20,
                    borderColor: '#91cc75',
                    color: '#91cc75'
                  }
                }
              }
            })),
            itemStyle: { color: '#91cc75' }
            type: 'inside',
            start: 0,
            end: 100
          },
          {
            name: '剩余容量',
            type: 'bar',
            data: noStocks.map((value, index) => ({
              value: value,
              label: {
                show: true,
                position: 'top',
                formatter: '{c} {a|' + noStockPercentages[index] + '}',
                rich: {
                  a: {
                    lineHeight: 20,
                    borderColor: '#fac858',
                    color: '#fac858'
            start: 0,
            end: 100,
            height: 20,
            bottom: 0,
            borderColor: 'rgba(255,255,255,0.3)',
            fillerColor: 'rgba(0,255,255,0.1)',
            handleStyle: {
              color: '#00ffff',
              borderColor: '#00ffff'
            },
            textStyle: {
              color: '#fff'
                  }
                }
              }
            })),
            itemStyle: { color: '#fac858' }
          }
        ]
        ],
        series: series
      };
      
      window.homeComponent = this;
      this.charts.warehouseMonthly.setOption(option, true);
    },
      
      this.charts.warehouse.setOption(option, true);
    getBarColor(index) {
      const colors = [
        '#5470c6', // 蓝
        '#fac858', // 黄
        '#73c0de', // 天蓝
        '#fc8452', // 橙
        '#ea7ccc'  // 粉
      ];
      return colors[index] || '#5470c6';
    }
  }
};
@@ -331,22 +292,6 @@
  box-shadow: 2px -2px 10px #00ffff, 0 0 10px rgba(0, 255, 255, 0.7);
}
.chart-card::before,
.chart-card::after {
  animation: neon-flicker 2s infinite alternate;
}
@keyframes neon-flicker {
  0%, 100% {
    opacity: 1;
    box-shadow: -2px -2px 10px #00ffff, 0 0 10px rgba(0, 255, 255, 0.7);
  }
  50% {
    opacity: 0.8;
    box-shadow: -2px -2px 5px #00ffff, 0 0 5px rgba(0, 255, 255, 0.5);
  }
}
.card-title {
  color: #00ffff;
  font-size: 16px;
@@ -357,21 +302,19 @@
}
.chart-content {
  height: 280px;
  height: 500px;
  width: 100%;
}
/* 全宽图表 */
.full-width .chart-card {
  flex: none;
  width: 100%;
}
.full-width .chart-content {
  height: 350px;
  height: 500px;
}
/* 添加网格线效果 */
.dashboard-container::before {
  content: "";
  position: fixed;
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_TaskStatus.cs
@@ -1,6 +1,10 @@
using System.Threading.Tasks;
using WIDESEA_Common.TaskEnum;
using WIDESEA_Core;
using WIDESEA_Core.Enums;
using WIDESEA_DTO.Task;
using WIDESEA_IStockService;
using WIDESEA_Model.Models;
namespace WIDESEA_TaskInfoService
{
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs
@@ -71,10 +71,10 @@
        }
        /// <summary>
        /// 每日统计
        /// 每日统计(按巷道号分组,指定仓库)
        /// </summary>
        [HttpGet("DailyStats"), AllowAnonymous]
        public async Task<WebResponseContent> DailyStats([FromQuery] int days = 30)
        public async Task<WebResponseContent> DailyStats([FromQuery] int days = 10)
        {
            try
            {
@@ -84,9 +84,16 @@
                var startDate = DateTime.Today.AddDays(-days + 1);
                var endDate = DateTime.Today; // 包含今天
                // 指定要统计的仓库(巷道号)
                var specifiedRoadways = new List<string>
        {
            "GWSC1", "CWSC1", "HCSC1", "ZJSC1", "FJSC1"
        };
                var query = await _db.Queryable<Dt_Task_Hty>()
                    .Where(t => t.InsertTime >= startDate && t.InsertTime <= endDate)
                    .Select(t => new { t.InsertTime, t.TaskType })
                    .Where(t => specifiedRoadways.Contains(t.Roadway)) // 只查询指定巷道号的数据
                    .Select(t => new { t.InsertTime, t.TaskType, t.Roadway })
                    .ToListAsync();
                // 生成日期范围
@@ -96,21 +103,30 @@
                    allDates.Add(date);
                }
                // 按日期分组统计
                // 按巷道号和日期分组统计
                var groupedData = query
                    .GroupBy(t => t.InsertTime.Date)
                    .GroupBy(t => new { t.Roadway, Date = t.InsertTime.Date })
                    .Select(g => new
                    {
                        Date = g.Key,
                        Roadway = g.Key.Roadway,
                        Date = g.Key.Date,
                        Inbound = g.Count(t => t.TaskType >= 200 && t.TaskType < 300),
                        Outbound = g.Count(t => t.TaskType >= 100 && t.TaskType < 200)
                    })
                    .ToList();
                // 构建结果:每个指定仓库对应一个日期列表
                var result = specifiedRoadways.Select(roadway =>
                {
                    // 获取该巷道号的分组数据字典
                    var roadwayData = groupedData
                        .Where(g => g.Roadway == roadway)
                    .ToDictionary(x => x.Date, x => x);
                // 补全缺失日期
                var result = allDates.Select(date =>
                    // 补全缺失日期,确保每天都有数据(默认为0)
                    var dailyStats = allDates.Select(date =>
                {
                    if (groupedData.TryGetValue(date, out var data))
                        if (roadwayData.TryGetValue(date, out var data))
                    {
                        return new
                        {
@@ -130,6 +146,14 @@
                    }
                })
                .OrderBy(x => x.Date)
                    .ToList();
                    return new
                    {
                        Roadway = roadway,
                        DailyStats = dailyStats
                    };
                })
                .ToList();
                return WebResponseContent.Instance.OK(null, result);
@@ -190,14 +214,11 @@
            return $"{monday.Year}-W{weekNum:D2}";
        }
        /// <summary>
        /// 每月统计
        /// </summary>
        /// <remarks>
        /// 按年月统计入站和出站任务数量
        /// </remarks>
        [HttpGet("MonthlyStats"), AllowAnonymous]
        public async Task<WebResponseContent> MonthlyStats([FromQuery] int months = 12)
        public async Task<WebResponseContent> MonthlyStats([FromQuery] int months = 12, string Roadway = null)
        {
            try
            {
@@ -206,8 +227,27 @@
                var startDate = DateTime.Today.AddMonths(-months + 1);
                startDate = new DateTime(startDate.Year, startDate.Month, 1);
                var monthlyStats = await _db.Queryable<Dt_Task_Hty>()
                    .Where(t => t.InsertTime >= startDate)
                // 仓库名称映射
                var roadwayNames = new Dictionary<string, string>
        {
            { "FJSC1", "负极卷1号仓库" },
            { "ZJSC1", "正极卷1号仓库" },
            { "GWSC1", "高温1号仓库" },
            { "CWSC1", "常温1号仓库" },
            { "HCSC1", "分容1号仓库" }
        };
                // 构建查询
                var query = _db.Queryable<Dt_Task_Hty>()
                    .Where(t => t.InsertTime >= startDate);
                // 如果指定了道路,添加道路过滤条件
                if (!string.IsNullOrEmpty(Roadway))
                {
                    query = query.Where(t => t.Roadway == Roadway);
                }
                var monthlyStats = await query
                    .GroupBy(t => new { t.InsertTime.Year, t.InsertTime.Month })
                    .Select(t => new
                    {
@@ -253,7 +293,11 @@
                        {
                            Month = monthKey,
                            Inbound = stat.Inbound,
                            Outbound = stat.Outbound
                            Outbound = stat.Outbound,
                            Roadway = Roadway,
                            RoadwayName = !string.IsNullOrEmpty(Roadway) && roadwayNames.ContainsKey(Roadway)
                                ? roadwayNames[Roadway]
                                : null
                        });
                    }
                    else
@@ -262,7 +306,11 @@
                        {
                            Month = monthKey,
                            Inbound = 0,
                            Outbound = 0
                            Outbound = 0,
                            Roadway = Roadway,
                            RoadwayName = !string.IsNullOrEmpty(Roadway) && roadwayNames.ContainsKey(Roadway)
                                ? roadwayNames[Roadway]
                                : null
                        });
                    }
                }
@@ -271,13 +319,9 @@
            }
            catch (Exception ex)
            {
                // 记录异常日志(实际项目中建议使用日志框架)
                // _logger.LogError(ex, "每月统计获取失败");
                return WebResponseContent.Instance.Error($"每月统计获取失败: {ex.Message}");
            }
        }
        /// <summary>
        /// 库存库龄分布
        /// </summary>
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
@@ -55,6 +55,7 @@
    "EnableConsoleOutput": false, //是否输出到控制台
    "EnableFloderByLevel": true //是否按日志级别生成不同的文件夹
  },
  "ApiLogIgnore": "Export,Get,get",
  "LogAopEnable": false,
  "PrintSql": false, //打印SQL语句
  "ApiName": "WIDESEA",