2025-09-04 18:28:02 +08:00
|
|
|
|
|
2025-10-09 18:08:19 +08:00
|
|
|
|
using Newtonsoft.Json;
|
2025-09-04 18:28:02 +08:00
|
|
|
|
using SWS.Commons;
|
|
|
|
|
using SWS.Model;
|
2025-10-09 18:08:19 +08:00
|
|
|
|
using System;
|
2025-09-04 18:28:02 +08:00
|
|
|
|
using System.Collections.Generic;
|
2025-10-09 18:08:19 +08:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Threading;
|
2025-09-04 18:28:02 +08:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace SWS.Service
|
|
|
|
|
{
|
|
|
|
|
public class IOModuleService : HttpService
|
|
|
|
|
{
|
|
|
|
|
public IOModuleService() : base()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取所有的信号
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
/// <param name="Assigned"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<List<Model.TreeModel>> GetPanelTree()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var res = await this.GetAsync<List<Model.TreeModel>>($"IOModuleApi/GetPanelTree?projectId={GlobalObject.curProject?.ProjectId}");
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 在IO分配界面,从左侧目录树中选择一个“端子排”后,进行查询
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="StripID"></param>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
/// <param name="OnlySelf">false时,带上下面的通道和端子。true时,就是返回端子排自己</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<ec_PanelStrip> GetPanelStrip(string StripID, bool OnlySelf = false, bool HaveChannel = true)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.GetAsync<ec_PanelStrip>($"IOModuleApi/GetPanelStrip?StripID={StripID}&projId={GlobalObject.curProject?.ProjectId}&OnlySelf={OnlySelf}&HaveChannel={HaveChannel}");
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 保存端子排 通道 端子的信息(不管信号和接线关系)。
|
|
|
|
|
/// 迁移通道也是这里。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="entity"></param>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
public async Task<object> SavePanelStrip(ec_PanelStrip entity)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<ec_PanelStrip, ec_PanelStrip>($"IOModuleApi/SavePanelStrip?projId={GlobalObject.curProject?.ProjectId}", entity);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
//return res.info;
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return res.info; // 返回错误信息
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 创建、修改 端子排和端子(一般是为非监测设备的端子排)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="entity"></param>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
public async Task<object> SavePanelStripNoChannel(ec_PanelStrip entity)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<ec_PanelStrip, ec_PanelStrip>($"IOModuleApi/SavePanelStripNoChannel?projId={GlobalObject.curProject?.ProjectId}", entity);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
//return res.info;
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return null; // 返回错误信息
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 查询所有的电缆
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
/// <param name="homerun">true或false</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<List<ec_Cable>> GetCables(bool homerun = true)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.GetAsync<List<ec_Cable>>($"IOModuleApi/GetCables?projId={GlobalObject.curProject?.ProjectId}&homerun={homerun}");
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据ID拿。只查询ec panel表本身
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="PanelID"></param>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<ec_Panel> GetPanel(string PanelID)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.GetAsync<ec_Panel>($"IOModuleApi/GetPanel?PanelID={PanelID}&projId={GlobalObject.curProject?.ProjectId}");
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 通过预设模式,批量创建端子排 通道 端子
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="entity"></param>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
public async Task<object> CreatePanelStripByProfile(ec_PanelStrip entity)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<ec_PanelStrip, ec_PanelStrip>($"IOModuleApi/CreatePanelStripByProfile?projId={GlobalObject.curProject?.ProjectId}", entity);
|
2025-09-12 12:03:20 +08:00
|
|
|
|
//if (res.code == 200)
|
|
|
|
|
//{
|
|
|
|
|
// //return res.info;
|
|
|
|
|
// return null;
|
|
|
|
|
//}
|
|
|
|
|
//else
|
|
|
|
|
//{
|
|
|
|
|
// return res.info; // 返回错误信息
|
|
|
|
|
//}
|
|
|
|
|
return res;
|
2025-09-04 18:28:02 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<string> DeletePanel(string PanelID)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<object,string>($"IOModuleApi/DeletePanel?PanelID={PanelID}&ProjectId={GlobalObject.curProject?.ProjectId}", null);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return res.info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<string> DeletePanelStrip(string StripID)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<object, string>($"IOModuleApi/DeletePanelStrip?StripID={StripID}&ProjectId={GlobalObject.curProject?.ProjectId}", null);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return res.info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据通道id来删除
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="keyValue"></param>
|
|
|
|
|
/// <param name="ProjectId"></param>
|
|
|
|
|
public async Task<string> DeletePanelChannel(string ChannelID)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<object, string>($"IOModuleApi/DeletePanelChannel?ProjectId={GlobalObject.curProject?.ProjectId}&ChannelID={ChannelID}", null);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return res.info;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据电缆id来删除
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="keyValue"></param>
|
|
|
|
|
/// <param name="ProjectId"></param>
|
|
|
|
|
public async Task<string> DeleteCableProfile(string CableID)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<object, string>($"IOModuleApi/DeleteCableProfile?CableID={CableID}&ProjectId={GlobalObject.curProject?.ProjectId}", null);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return res.info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据EngineerDataID拿。包括set wire,以及from to信息
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="EngineerDataID"></param>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
/// <param name="OnlySelf"></param>
|
|
|
|
|
/// <param name="PreAssign"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<ec_Cable> GetCableByEngID(string EngineerDataID,bool OnlySelf = false, bool PreAssign = false)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.GetAsync<ec_Cable>($"IOModuleApi/GetCableByEngID?EngineerDataID={EngineerDataID}&projId={GlobalObject.curProject?.ProjectId}&OnlySelf{OnlySelf}&PreAssign{PreAssign}");
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 新增或者修改。
|
|
|
|
|
/// 新建相当于强行,因为正常流程是和engineerdata一起新建出来的。
|
|
|
|
|
/// 改的话,只是改location和端子排数量这些。常规属性依旧通过objectTypeAPI去做
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="entity"></param>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<string> SavePanel(ec_Panel entity)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<object, ec_Panel>($"IOModuleApi/SavePanel?projId={GlobalObject.curProject?.ProjectId}", entity);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return res.info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 查询所有需要预分配的电缆
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<List<ec_Cable>> GetCablePreAssignPreview()
|
|
|
|
|
{
|
|
|
|
|
var res = await this.GetAsync<List<ec_Cable>>($"IOModuleApi/GetCablePreAssignPreview?projId={GlobalObject.curProject?.ProjectId}");
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// GetCableByEngID先去判断这个cable是否已经有了IO Module这边的记录
|
|
|
|
|
/// 电缆-端子连接,从图面上选择一个电缆对象
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
public async Task<string> CreateCableByProfile(ec_Cable entity)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<ec_Cable, ec_Cable>($"IOModuleApi/CreateCableByProfile?projId={GlobalObject.curProject?.ProjectId}", entity);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return res.info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<string> SaveCable(ec_Cable entity)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<ec_Cable, ec_Cable>($"IOModuleApi/SaveCable?projId={GlobalObject.curProject?.ProjectId}", entity);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return res.info;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 处理 接线关系,同时对cableset和wire的个别属性进行修改
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="projId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<List<ec_WireTerminal>> SaveConnections(Connections entity)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<List<ec_WireTerminal>, Connections>($"IOModuleApi/SaveConnections?projId={GlobalObject.curProject?.ProjectId}", entity);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<List<ec_Cable>> SaveCables(List<ec_Cable> entitys)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<List<ec_Cable>, List<ec_Cable>>($"IOModuleApi/SaveCables?projId={GlobalObject.curProject?.ProjectId}", entitys);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-22 10:02:17 +08:00
|
|
|
|
public async Task<object> AutoAssignCable2channel_step1(List<string> CableIds ,bool AcceptNearbyPanel)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<object,List<string>>($"IOModuleApi/AutoAssignCable2Channel_step1?projId={GlobalObject.curProject?.ProjectId}&AcceptNearbyPanel={AcceptNearbyPanel}", CableIds);
|
|
|
|
|
//if (res.code == 200)
|
|
|
|
|
//{
|
|
|
|
|
// return res.data;
|
|
|
|
|
//}
|
|
|
|
|
//else
|
|
|
|
|
//{
|
|
|
|
|
//}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<List<ec_Cable>> AutoAssignCable2channel_step2()
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<List<ec_Cable>, object>($"IOModuleApi/AutoAssignCable2Channel_step2?projId={GlobalObject.curProject?.ProjectId}", null);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<List<ec_Cable>> AutoAssignCable2channel_step3(List<ec_Cable> CableIds)
|
|
|
|
|
{
|
|
|
|
|
var res = await this.PostBodyAsync<List<ec_Cable>, object>($"IOModuleApi/AutoAssignCable2Channel_step3?projId={GlobalObject.curProject?.ProjectId}", CableIds);
|
|
|
|
|
if (res.code == 200)
|
|
|
|
|
{
|
|
|
|
|
return res.data;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-09 18:08:19 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 导出信号预分配结果
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="savePath"></param>
|
|
|
|
|
/// <param name="flg"></param>
|
|
|
|
|
/// <param name="progress"></param>
|
|
|
|
|
/// <param name="cancellationToken"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<string> AutoAssignCable2Channel_ResExport(
|
|
|
|
|
string savePath,
|
|
|
|
|
bool flg = true,
|
|
|
|
|
IProgress<double> progress = null,
|
|
|
|
|
CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var p = Path.GetDirectoryName(savePath);
|
|
|
|
|
if (!Directory.Exists(p))
|
|
|
|
|
Directory.CreateDirectory(p);
|
|
|
|
|
string url = $"IOModuleApi/AutoAssignCable2Channel_ResExport?projectId={GlobalObject.curProject?.ProjectId}&flg={flg}";
|
|
|
|
|
//url = Uri.EscapeDataString(url);
|
|
|
|
|
//url = Uri.UnescapeDataString(url);
|
|
|
|
|
// 发送请求并获取响应
|
|
|
|
|
using (var response = await GlobalObject.client.GetAsync(
|
|
|
|
|
url,
|
|
|
|
|
HttpCompletionOption.ResponseHeadersRead,
|
|
|
|
|
cancellationToken))
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (response.StatusCode != HttpStatusCode.OK)
|
|
|
|
|
{
|
|
|
|
|
string errorMsg = $"服务器地址 [{url}] 文件下载失败, 返回HTTP代码:" + response.StatusCode;
|
|
|
|
|
LoggerHelper.Current.Error(errorMsg);
|
|
|
|
|
throw new HttpRequestException(errorMsg);
|
|
|
|
|
}
|
|
|
|
|
response.EnsureSuccessStatusCode(); // 确保响应成功
|
|
|
|
|
var result = await response.Content.ReadAsStringAsync();
|
|
|
|
|
learunHttpRes<object> resultObj = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
resultObj = JsonConvert.DeserializeObject<learunHttpRes<object>>(result);
|
|
|
|
|
}
|
|
|
|
|
catch (JsonException)
|
|
|
|
|
{
|
|
|
|
|
//对下载文件来说,如果正常的话,这里反而是合理的,因为返回的就是stream的东西,不能被解析为learunHttpRes
|
|
|
|
|
await HandleStreamAsync();
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (resultObj.code != 200)
|
|
|
|
|
{
|
|
|
|
|
switch (resultObj.code)
|
|
|
|
|
{
|
|
|
|
|
case 400:
|
|
|
|
|
case 500:
|
|
|
|
|
return resultObj.info.ToString(); //业务错误,不是http本质错误
|
|
|
|
|
default:
|
|
|
|
|
string errorMsg = $"服务器地址 [{url}] Get失败, 返回自定义代码:" + resultObj.code;
|
|
|
|
|
LoggerHelper.Current.Error(errorMsg);
|
|
|
|
|
throw new HttpRequestException(errorMsg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
await HandleStreamAsync();
|
|
|
|
|
return "";
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async Task HandleStreamAsync()
|
|
|
|
|
{
|
|
|
|
|
#region core
|
|
|
|
|
// 获取文件总大小(可能为 null)
|
|
|
|
|
var totalBytes = response.Content.Headers.ContentLength;
|
|
|
|
|
|
|
|
|
|
// 创建文件流
|
|
|
|
|
using (var contentStream = await response.Content.ReadAsStreamAsync())
|
|
|
|
|
using (var fileStream = new FileStream(
|
|
|
|
|
savePath,
|
|
|
|
|
FileMode.Create,
|
|
|
|
|
FileAccess.Write,
|
|
|
|
|
FileShare.None,
|
|
|
|
|
bufferSize: 8192,
|
|
|
|
|
useAsync: true))
|
|
|
|
|
{
|
|
|
|
|
var buffer = new byte[8192];
|
|
|
|
|
var totalBytesRead = 0L;
|
|
|
|
|
var bytesRead = 0;
|
|
|
|
|
|
|
|
|
|
// 分块读取并写入文件
|
|
|
|
|
while ((bytesRead = await contentStream.ReadAsync(
|
|
|
|
|
buffer,
|
|
|
|
|
0,
|
|
|
|
|
buffer.Length,
|
|
|
|
|
cancellationToken)) > 0)
|
|
|
|
|
{
|
|
|
|
|
await fileStream.WriteAsync(
|
|
|
|
|
buffer,
|
|
|
|
|
0,
|
|
|
|
|
bytesRead,
|
|
|
|
|
cancellationToken);
|
|
|
|
|
|
|
|
|
|
totalBytesRead += bytesRead;
|
|
|
|
|
|
|
|
|
|
// 报告进度(如果有总大小)
|
|
|
|
|
if (totalBytes.HasValue)
|
|
|
|
|
{
|
|
|
|
|
var percent = (double)totalBytesRead / totalBytes.Value * 100;
|
|
|
|
|
progress?.Report(percent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (HttpRequestException ex)
|
|
|
|
|
{
|
|
|
|
|
return ex.Message;
|
|
|
|
|
//throw new Exception($"下载请求失败: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (TaskCanceledException ex2)
|
|
|
|
|
{
|
|
|
|
|
return ex2.Message;
|
|
|
|
|
// 取消操作时删除已下载的部分文件
|
|
|
|
|
//if (File.Exists(savePath)) File.Delete(savePath);
|
|
|
|
|
//throw;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex3)
|
|
|
|
|
{
|
|
|
|
|
return ex3.Message;
|
|
|
|
|
//throw new Exception($"下载失败: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-09-22 10:02:17 +08:00
|
|
|
|
|
2025-09-04 18:28:02 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// SaveConnections 专用
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class Connections
|
|
|
|
|
{
|
|
|
|
|
public string ID { get; set; }
|
|
|
|
|
public List<ec_WireTerminal> Conns { get; set; }
|
|
|
|
|
}
|
2025-09-22 10:02:17 +08:00
|
|
|
|
|
|
|
|
|
|
2025-09-04 18:28:02 +08:00
|
|
|
|
}
|
|
|
|
|
}
|