chore: initial commit

This commit is contained in:
XingCheng3
2026-05-29 09:34:04 +08:00
commit 78ae9dcd2e
683 changed files with 68110 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Collections.Concurrent;
using Newtonsoft.Json.Linq;
using System.Threading;
using System.Net;
using System.Net.Http.Headers;
using System.IO;
using MisDataSaveDate;
namespace MisDataSaveDate
{
/// <summary>
/// AGV接口控制器
/// </summary>
public class AGVController : ApiController
{
readonly string headUrl = "agv/";
/// <summary>
/// AGV请求进入离开、下降举升接口接收方
/// 接收AGV的进入、离开、下降、举升请求并存储到数据库
/// </summary>
/// <param name="jobj">AGV请求数据</param>
/// <returns>处理结果</returns>
[HttpPost]
[Route("agv/agvReqInOut")]
public HttpResponseMessage agvReqInOut([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AGV_BusinessLogic.ProcessAGVEnterRequest(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
}
}

View File

@@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using System.Net.Http;
using System.Web.Http;
using ExternalDataSync.MOM;
namespace ExternalDataSync.WebAPI.Controller
{
public class CheckDataController : ApiController
{
private readonly string headUrl = "TestPlatform/";
[HttpPost]
[Route("TestPlatform/OnlineCheckData")]
public HttpResponseMessage OnlineCheckData([FromBody] JObject jobj)
{
var result = Other.OnlineCheckData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
return new HttpResponseMessage
{
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
};
}
[HttpPost]
[Route("TestPlatform/OnlineStatusData")]
public HttpResponseMessage OnlineStatusData([FromBody] JObject jobj)
{
var result = Other.OnlineStatusData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
return new HttpResponseMessage
{
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
};
}
[HttpPost]
[Route("TestPlatform/OnlineDewPointResultData")]
public HttpResponseMessage OnlineDewPointResultData([FromBody] JObject jobj)
{
var result = DewPointDataHandler.OnlineDewPointResultData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
return new HttpResponseMessage
{
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
};
}
[HttpPost]
[Route("TestPlatform/OnlineDewPointTechnologyData")]
public HttpResponseMessage OnlineDewPointTechnologyData([FromBody] JObject jobj)
{
var result = DewPointDataHandler.OnlineDewPointTechnologyData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
return new HttpResponseMessage
{
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
};
}
[HttpPost]
[Route("TestPlatform/OnlineDewPointUseData")]
public HttpResponseMessage OnlineDewPointUseData([FromBody] JObject jobj)
{
var result = DewPointDataHandler.OnlineDewPointUseData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
return new HttpResponseMessage
{
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
};
}
[HttpPost]
[Route("TestPlatform/OnlineDewPointStatusData")]
public HttpResponseMessage OnlineDewPointStatusData([FromBody] JObject jobj)
{
var result = DewPointDataHandler.OnlineDewPointStatusData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
return new HttpResponseMessage
{
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 获取位置待测试产品信息
/// </summary>
[HttpPost]
[Route("TestPlatform/GetWaitCheckProductData")]
public HttpResponseMessage GetWaitCheckProductData([FromBody] JObject jobj)
{
var result = Other.GetWaitCheckProductData(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj);
return new HttpResponseMessage
{
Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "application/json")
};
}
}
}

View File

@@ -0,0 +1,270 @@
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.RegularExpressions;
using System.Web.Http;
using DataLinkMesWork2;
namespace WebApi
{
[RoutePrefix("api/checkimage")]
public class CheckImageController : ApiController
{
private readonly string _defaultRoot = @"D:\\XDCheckImages";
public class ImageUploadRequest
{
public string ProductCode { get; set; }
public string Remark { get; set; }
public string ImageBase64 { get; set; }
public string FileExt { get; set; }
}
public class ImageDownloadRequest
{
public string Path { get; set; }
}
private string GetRootPath()
{
string root = null;
try
{
root = ConfigurationManager.AppSettings["XD_CheckImageRootPath"];
}
catch
{
}
if (string.IsNullOrWhiteSpace(root))
{
root = _defaultRoot;
}
return root;
}
private string SanitizeForPath(string input)
{
if (string.IsNullOrEmpty(input)) return string.Empty;
char[] invalid = Path.GetInvalidFileNameChars();
var value = input.Trim();
foreach (var c in invalid)
{
value = value.Replace(c.ToString(), string.Empty);
}
value = value.Replace("/", string.Empty).Replace("\\", string.Empty);
return value;
}
private string GetExtensionFromRequest(ImageUploadRequest request)
{
string ext = ".jpg";
if (request == null) return ext;
if (!string.IsNullOrWhiteSpace(request.FileExt))
{
ext = request.FileExt.Trim();
if (!ext.StartsWith("."))
{
ext = "." + ext;
}
return ext;
}
if (!string.IsNullOrWhiteSpace(request.ImageBase64) &&
request.ImageBase64.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
{
try
{
var match = Regex.Match(request.ImageBase64, "^data:(?<mime>[^;]+);base64,", RegexOptions.IgnoreCase);
if (match.Success)
{
var mime = match.Groups["mime"].Value.ToLowerInvariant();
if (mime == "image/png") return ".png";
if (mime == "image/gif") return ".gif";
if (mime == "image/bmp") return ".bmp";
if (mime == "image/webp") return ".webp";
if (mime == "image/tiff" || mime == "image/tif") return ".tif";
if (mime == "image/jpeg" || mime == "image/jpg") return ".jpg";
}
}
catch
{
}
}
return ext;
}
private string GetContentType(string fileName)
{
var extension = Path.GetExtension(fileName).ToLowerInvariant();
if (extension == ".bmp") return "image/bmp";
if (extension == ".jpg" || extension == ".jpeg") return "image/jpeg";
if (extension == ".png") return "image/png";
if (extension == ".gif") return "image/gif";
if (extension == ".tiff" || extension == ".tif") return "image/tiff";
if (extension == ".webp") return "image/webp";
return "application/octet-stream";
}
private bool IsPathSafe(string fullPath)
{
try
{
var basePath = Path.GetFullPath(GetRootPath());
var requestedPath = Path.GetFullPath(fullPath);
return requestedPath.StartsWith(basePath, StringComparison.OrdinalIgnoreCase);
}
catch
{
return false;
}
}
[HttpPost]
[Route("upload")]
public IHttpActionResult Upload([FromBody] ImageUploadRequest request)
{
try
{
if (request == null ||
string.IsNullOrWhiteSpace(request.ProductCode) ||
string.IsNullOrWhiteSpace(request.Remark) ||
string.IsNullOrWhiteSpace(request.ImageBase64))
{
return Ok(new { success = false, message = "产品编号、备注和图片不能为空" });
}
string productCode = SanitizeForPath(request.ProductCode);
string remark = SanitizeForPath(request.Remark);
if (string.IsNullOrEmpty(productCode))
{
return Ok(new { success = false, message = "产品编号无效" });
}
string ext = GetExtensionFromRequest(request);
string base64 = request.ImageBase64.Trim();
int commaIndex = base64.IndexOf(',');
if (base64.StartsWith("data:", StringComparison.OrdinalIgnoreCase) && commaIndex > 0)
{
base64 = base64.Substring(commaIndex + 1);
}
byte[] bytes;
try
{
bytes = Convert.FromBase64String(base64);
}
catch
{
return Ok(new { success = false, message = "图片数据格式错误" });
}
var now = DateTime.Now;
string datePart = now.ToString("yyyyMMdd");
string timePart = now.ToString("HHmmss");
string fileName = string.Format("{0}-{1}-{2}{3}", timePart, productCode, remark, ext);
string relativePath = string.Format("/{0}/{1}", datePart, fileName);
string root = GetRootPath();
string directory = Path.Combine(root, datePart);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
string fullPath = Path.Combine(directory, fileName);
if (!IsPathSafe(fullPath))
{
return Ok(new { success = false, message = "目标路径不安全" });
}
File.WriteAllBytes(fullPath, bytes);
string errorMessage;
var sqlParameters = new SqlParameter[4];
sqlParameters[0] = new SqlParameter("@产品编号", SqlDbType.NVarChar, 500) { Value = (object)request.ProductCode ?? DBNull.Value };
sqlParameters[1] = new SqlParameter("@备注", SqlDbType.NVarChar, 500) { Value = (object)request.Remark ?? DBNull.Value };
sqlParameters[2] = new SqlParameter("@图片路径", SqlDbType.NVarChar, 500) { Value = (object)relativePath ?? DBNull.Value };
sqlParameters[3] = new SqlParameter("@图片名称", SqlDbType.NVarChar, 500) { Value = (object)fileName ?? DBNull.Value };
bool dbOk = DataAccess2.ExecuteStoredProcedure("XD_检测图片上传_增加", ref sqlParameters, out errorMessage);
if (!dbOk)
{
return Ok(new { success = false, message = "图片已保存,但写入数据库失败:" + errorMessage });
}
return Ok(new
{
success = true,
message = "上传成功",
data = new
{
= request.ProductCode,
= request.Remark,
= relativePath,
= fileName
}
});
}
catch (Exception ex)
{
return Ok(new { success = false, message = "服务器错误:" + ex.Message });
}
}
[HttpPost]
[Route("download")]
public IHttpActionResult Download([FromBody] ImageDownloadRequest request)
{
try
{
if (request == null || string.IsNullOrWhiteSpace(request.Path))
{
return Ok(new { success = false, message = "文件路径不能为空" });
}
string root = GetRootPath();
string relative = request.Path.Replace("\\", "/").Trim();
if (relative.StartsWith("/"))
{
relative = relative.Substring(1);
}
string fullPath = Path.Combine(root, relative.Replace('/', Path.DirectorySeparatorChar));
if (!IsPathSafe(fullPath) || !File.Exists(fullPath))
{
return Ok(new { success = false, message = "文件不存在" });
}
var fileInfo = new FileInfo(fullPath);
var contentType = GetContentType(fileInfo.Name);
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline")
{
FileName = fileInfo.Name
};
return ResponseMessage(response);
}
catch (Exception ex)
{
return Ok(new { success = false, message = "下载文件失败:" + ex.Message });
}
}
}
}

View File

@@ -0,0 +1,458 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Net.Http.Headers;
using WinSCP;
namespace WebApi
{
[RoutePrefix("api/craftfile")]
public class CraftFileController : ApiController
{
// 本地缓存根目录
private readonly string _cacheRoot = @"D:\\CraftFilesCache";
private readonly string _sftpHost = "10.107.69.5";
private readonly string _sftpUser = "root";
private readonly string _sftpPassword = "XKYXmes@123!";
public class FileRequestDto
{
// 远程SFTP相对路径或绝对路径如 /root/PLM-MES/.../xxx.pdf
public string RelativePath { get; set; } = "";
}
[HttpPost]
[Route("browse")]
public IHttpActionResult Browse([FromBody] FileRequestDto request)
{
try
{
if (request == null || string.IsNullOrWhiteSpace(request.RelativePath))
return Ok(new { success = false, message = "路径不能为空" });
EnsureCacheRoot();
var remotePath = NormalizeRemotePath(request.RelativePath);
var localPath = ToLocalPath(remotePath);
var isFile = Path.HasExtension(remotePath);
if (isFile)
{
// 确保本地存在
if (!System.IO.File.Exists(localPath))
{
var ok = DownloadFileFromSftp(remotePath, localPath, out string err);
if (!ok) return Ok(new { success = false, message = $"下载失败: {err}" });
}
return GetFilePreviewLocal(localPath, remotePath);
}
else
{
// 目录:优先读取本地,没有则读取远程目录结构
if (Directory.Exists(localPath))
{
return GetDirectoryContentsLocal(localPath, remotePath);
}
else
{
return GetDirectoryContentsRemote(remotePath);
}
}
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"服务器错误: {ex.Message}" });
}
}
[HttpPost]
[Route("download")]
public IHttpActionResult Download([FromBody] FileRequestDto request)
{
try
{
if (request == null || string.IsNullOrWhiteSpace(request.RelativePath))
return Ok(new { success = false, message = "文件路径不能为空" });
EnsureCacheRoot();
var remotePath = NormalizeRemotePath(request.RelativePath);
var localPath = ToLocalPath(remotePath);
if (!Path.HasExtension(remotePath))
return Ok(new { success = false, message = "请传入文件路径" });
if (!System.IO.File.Exists(localPath))
{
var ok = DownloadFileFromSftp(remotePath, localPath, out string err);
if (!ok) return Ok(new { success = false, message = $"下载失败: {err}" });
}
var fileInfo = new FileInfo(localPath);
var contentType = GetContentType(fileInfo.Name);
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(new FileStream(localPath, FileMode.Open, FileAccess.Read, FileShare.Read))
};
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = fileInfo.Name
};
return ResponseMessage(response);
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"下载文件失败: {ex.Message}" });
}
}
// 新增浏览器直接预览文件支持PDF等支持Range分块
[HttpGet]
[Route("preview")]
public HttpResponseMessage Preview([FromUri] string path)
{
try
{
if (string.IsNullOrWhiteSpace(path))
{
return Request.CreateResponse(HttpStatusCode.BadRequest, new { success = false, message = "文件路径不能为空" });
}
EnsureCacheRoot();
var remotePath = NormalizeRemotePath(path);
var localPath = ToLocalPath(remotePath);
if (!Path.HasExtension(remotePath))
{
return Request.CreateResponse(HttpStatusCode.BadRequest, new { success = false, message = "请传入文件路径" });
}
if (!System.IO.File.Exists(localPath))
{
var ok = DownloadFileFromSftp(remotePath, localPath, out string err);
if (!ok)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, new { success = false, message = $"下载失败: {err}" });
}
}
var fileInfo = new FileInfo(localPath);
var contentType = GetContentType(fileInfo.Name);
var totalLength = fileInfo.Length;
var response = new HttpResponseMessage();
var range = Request.Headers.Range;
var stream = new FileStream(localPath, FileMode.Open, FileAccess.Read, FileShare.Read);
if (range != null && range.Ranges.Count > 0 && totalLength > 0)
{
// 处理 Range 请求
var from = range.Ranges.First().From ?? 0;
var to = range.Ranges.First().To ?? (totalLength - 1);
if (to >= totalLength) to = totalLength - 1;
var length = to - from + 1;
stream.Seek(from, SeekOrigin.Begin);
response.StatusCode = HttpStatusCode.PartialContent;
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
response.Content.Headers.ContentLength = length;
response.Content.Headers.ContentRange = new ContentRangeHeaderValue(from, to, totalLength);
response.Headers.AcceptRanges.Add("bytes");
}
else
{
// 全量流式
response.StatusCode = HttpStatusCode.OK;
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
response.Content.Headers.ContentLength = totalLength;
response.Headers.AcceptRanges.Add("bytes");
}
// inline 以支持浏览器内嵌预览
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline")
{
FileName = fileInfo.Name
};
// CORS 允许跨域及暴露必要头
if (!response.Headers.Contains("Access-Control-Allow-Origin"))
response.Headers.Add("Access-Control-Allow-Origin", "*");
if (!response.Headers.Contains("Access-Control-Expose-Headers"))
response.Headers.Add("Access-Control-Expose-Headers", "Accept-Ranges, Content-Range, Content-Length, Content-Type, Content-Disposition");
return response;
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError, new { success = false, message = $"预览失败: {ex.Message}" });
}
}
private IHttpActionResult GetFilePreviewLocal(string localPath, string remotePath)
{
try
{
var fileInfo = new FileInfo(localPath);
var extension = fileInfo.Extension.ToLowerInvariant();
var previewable = IsPreviewableFile(extension);
var contentType = GetContentType(fileInfo.Name);
bool tooLarge = fileInfo.Length > 500 * 1024 * 1024; // 500MB限制
string base64String = null;
string dataUrl = null;
bool canPreview = previewable && !tooLarge;
if (canPreview)
{
var fileBytes = System.IO.File.ReadAllBytes(localPath);
base64String = Convert.ToBase64String(fileBytes);
dataUrl = $"data:{contentType};base64,{base64String}";
}
var result = new
{
success = true,
type = "file",
path = remotePath,
name = fileInfo.Name,
size = fileInfo.Length,
extension = fileInfo.Extension,
contentType = contentType,
isPreviewable = canPreview,
base64Data = base64String,
dataUrl = dataUrl,
created = fileInfo.CreationTime,
modified = fileInfo.LastWriteTime,
message = tooLarge ? "文件过大,无法预览,可下载" : null
};
return Ok(result);
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"获取文件预览失败: {ex.Message}" });
}
}
private IHttpActionResult GetDirectoryContentsLocal(string localPath, string remotePath)
{
try
{
var items = new List<object>();
var directories = Directory.GetDirectories(localPath);
foreach (var dir in directories)
{
var dirInfo = new DirectoryInfo(dir);
var subPath = CombineRemotePath(remotePath, dirInfo.Name);
items.Add(new
{
name = dirInfo.Name,
type = "directory",
path = subPath,
created = dirInfo.CreationTime,
modified = dirInfo.LastWriteTime,
isPreviewable = false
});
}
var files = Directory.GetFiles(localPath);
foreach (var file in files)
{
var fileInfo = new FileInfo(file);
var filePath = CombineRemotePath(remotePath, fileInfo.Name);
var extension = fileInfo.Extension.ToLowerInvariant();
items.Add(new
{
name = fileInfo.Name,
type = "file",
path = filePath,
size = fileInfo.Length,
extension = fileInfo.Extension,
created = fileInfo.CreationTime,
modified = fileInfo.LastWriteTime,
isPreviewable = IsPreviewableFile(extension),
contentType = GetContentType(fileInfo.Name)
});
}
var result = new
{
success = true,
type = "directory",
path = remotePath,
items = items.OrderBy(x => ((dynamic)x).type == "directory" ? 0 : 1)
.ThenBy(x => ((dynamic)x).name)
.ToList()
};
return Ok(result);
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"读取目录失败: {ex.Message}" });
}
}
private IHttpActionResult GetDirectoryContentsRemote(string remotePath)
{
try
{
using (var session = OpenSftp())
{
var dir = session.ListDirectory(remotePath);
var items = new List<object>();
foreach (var subdir in dir.Files.Where(e => e.IsDirectory && e.Name != "." && e.Name != ".."))
{
var subPath = CombineRemotePath(remotePath, subdir.Name);
items.Add(new
{
name = subdir.Name,
type = "directory",
path = subPath,
created = subdir.LastWriteTime,
modified = subdir.LastWriteTime,
isPreviewable = false
});
}
foreach (var file in dir.Files.Where(e => !e.IsDirectory))
{
var filePath = CombineRemotePath(remotePath, file.Name);
var extension = Path.GetExtension(file.Name).ToLowerInvariant();
items.Add(new
{
name = file.Name,
type = "file",
path = filePath,
size = file.Length,
extension = Path.GetExtension(file.Name),
created = file.LastWriteTime,
modified = file.LastWriteTime,
isPreviewable = IsPreviewableFile(extension),
contentType = GetContentType(file.Name)
});
}
var result = new
{
success = true,
type = "directory",
path = remotePath,
items = items.OrderBy(x => ((dynamic)x).type == "directory" ? 0 : 1)
.ThenBy(x => ((dynamic)x).name)
.ToList()
};
return Ok(result);
}
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"读取远程目录失败: {ex.Message}" });
}
}
private bool DownloadFileFromSftp(string remotePath, string localPath, out string error)
{
error = null;
try
{
var localDir = Path.GetDirectoryName(localPath);
if (!Directory.Exists(localDir)) Directory.CreateDirectory(localDir);
using (var session = OpenSftp())
{
var result = session.GetFiles(remotePath, localPath, false);
result.Check();
}
return true;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
private Session OpenSftp()
{
var options = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = _sftpHost,
UserName = _sftpUser,
Password = _sftpPassword,
SshHostKeyPolicy = SshHostKeyPolicy.GiveUpSecurityAndAcceptAny
};
var session = new Session();
session.Open(options);
return session;
}
private void EnsureCacheRoot()
{
if (!Directory.Exists(_cacheRoot)) Directory.CreateDirectory(_cacheRoot);
}
private string NormalizeRemotePath(string p)
{
if (string.IsNullOrWhiteSpace(p)) return "/";
var s = p.Trim();
// 统一使用正斜杠
s = s.Replace('\\', '/');
return s;
}
private string ToLocalPath(string remotePath)
{
// 去掉开头的 '/'
var relative = remotePath.Trim().TrimStart('/');
var localRelative = relative.Replace('/', Path.DirectorySeparatorChar);
return Path.Combine(_cacheRoot, localRelative);
}
private string CombineRemotePath(string basePath, string name)
{
if (string.IsNullOrEmpty(basePath) || basePath == "/") return $"/{name}";
if (basePath.EndsWith("/")) return basePath + name;
return basePath + "/" + name;
}
private bool IsPreviewableFile(string extension)
{
var previewableExtensions = new[]
{
".bmp", ".jpg", ".jpeg", ".png", ".gif", ".tiff", ".tif", ".webp",
".txt", ".json", ".xml", ".csv", ".log", ".md", ".pdf"
};
return previewableExtensions.Contains(extension);
}
private string GetContentType(string fileName)
{
var extension = Path.GetExtension(fileName).ToLowerInvariant();
if (extension == ".bmp") return "image/bmp";
if (extension == ".jpg" || extension == ".jpeg") return "image/jpeg";
if (extension == ".png") return "image/png";
if (extension == ".gif") return "image/gif";
if (extension == ".tiff" || extension == ".tif") return "image/tiff";
if (extension == ".webp") return "image/webp";
if (extension == ".pdf") return "application/pdf";
if (extension == ".txt") return "text/plain";
if (extension == ".json") return "application/json";
if (extension == ".xml") return "application/xml";
if (extension == ".csv") return "text/csv";
if (extension == ".md") return "text/markdown";
if (extension == ".log") return "text/plain";
if (extension == ".zip") return "application/zip";
if (extension == ".rar") return "application/x-rar-compressed";
return "application/octet-stream";
}
}
}

View File

@@ -0,0 +1,277 @@
using System.Net.Http;
using System.Net;
using System.Web.Http;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System;
/////http://127.0.0.1:9981/api/file/browse
/// <summary>
///
/// </summary>
namespace WebApi
{
/// <summary>
///
/// </summary>
[RoutePrefix("api/file")]
public class IFileController : ApiController
{
// 基础路径配置
private readonly string _basePath = @"D:\CameraImg";
/// <summary>
/// 请求DTO
/// </summary>
public class FileRequestDto
{
public string RelativePath { get; set; } = "";
}
/// <summary>
/// 浏览文件或文件夹,前端传相对路径,返回文件夹内容或文件流(图片等可预览)
/// </summary>
[HttpPost]
[Route("browse")]
public IHttpActionResult BrowsePath([FromBody] FileRequestDto request)
{
try
{
if (request == null)
request = new FileRequestDto();
if (string.IsNullOrEmpty(request.RelativePath) || request.RelativePath == "/")
{
request.RelativePath = "";
}
string fullPath = Path.Combine(_basePath, request.RelativePath.Replace('/', Path.DirectorySeparatorChar));
if (!IsPathSafe(fullPath))
{
return Ok(new { success = false, message = "无效的路径" });
}
if (!Directory.Exists(fullPath) && !System.IO.File.Exists(fullPath))
{
return Ok(new { success = false, message = "路径不存在" });
}
if (System.IO.File.Exists(fullPath))
{
return GetFilePreview(fullPath, request.RelativePath);
}
if (Directory.Exists(fullPath))
{
return GetDirectoryContents(fullPath, request.RelativePath);
}
return Ok(new { success = false, message = "路径不存在" });
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"服务器错误: {ex.Message}" });
}
}
/// <summary>
/// 获取文件预览数据(图片/文本base64前端可直接预览
/// </summary>
private IHttpActionResult GetFilePreview(string fullPath, string relativePath)
{
try
{
var fileInfo = new FileInfo(fullPath);
var extension = fileInfo.Extension.ToLowerInvariant();
var previewable = IsPreviewableFile(extension);
var contentType = GetContentType(fileInfo.Name);
bool tooLarge = fileInfo.Length > 10 * 1024 * 1024; // 10MB限制
string base64String = null;
string dataUrl = null;
bool canPreview = previewable && !tooLarge;
if (canPreview)
{
var fileBytes = System.IO.File.ReadAllBytes(fullPath);
base64String = Convert.ToBase64String(fileBytes);
dataUrl = $"data:{contentType};base64,{base64String}";
}
var result = new
{
success = true,
type = "file",
path = relativePath,
name = fileInfo.Name,
size = fileInfo.Length,
extension = fileInfo.Extension,
contentType = contentType,
isPreviewable = canPreview,
base64Data = base64String,
dataUrl = dataUrl,
created = fileInfo.CreationTime,
modified = fileInfo.LastWriteTime,
message = tooLarge ? "文件过大,无法预览,可下载" : null
};
return Ok(result);
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"获取文件预览失败: {ex.Message}" });
}
}
/// <summary>
/// 判断文件是否可预览
/// </summary>
private bool IsPreviewableFile(string extension)
{
var previewableExtensions = new[]
{
".bmp", ".jpg", ".jpeg", ".png", ".gif", ".tiff", ".tif", ".webp",
".txt", ".json", ".xml", ".csv", ".log", ".md"
};
return previewableExtensions.Contains(extension);
}
/// <summary>
/// 安全检查:确保路径在基础目录内,防止路径遍历攻击
/// </summary>
private bool IsPathSafe(string fullPath)
{
try
{
var basePath = Path.GetFullPath(_basePath);
var requestedPath = Path.GetFullPath(fullPath);
return requestedPath.StartsWith(basePath, StringComparison.OrdinalIgnoreCase);
}
catch
{
return false;
}
}
/// <summary>
/// 根据文件扩展名获取MIME类型兼容C# 7.3
/// </summary>
private string GetContentType(string fileName)
{
var extension = Path.GetExtension(fileName).ToLowerInvariant();
if (extension == ".bmp") return "image/bmp";
if (extension == ".jpg" || extension == ".jpeg") return "image/jpeg";
if (extension == ".png") return "image/png";
if (extension == ".gif") return "image/gif";
if (extension == ".tiff" || extension == ".tif") return "image/tiff";
if (extension == ".webp") return "image/webp";
if (extension == ".pdf") return "application/pdf";
if (extension == ".txt") return "text/plain";
if (extension == ".json") return "application/json";
if (extension == ".xml") return "application/xml";
if (extension == ".csv") return "text/csv";
if (extension == ".md") return "text/markdown";
if (extension == ".log") return "text/plain";
if (extension == ".zip") return "application/zip";
if (extension == ".rar") return "application/x-rar-compressed";
return "application/octet-stream";
}
private IHttpActionResult GetDirectoryContents(string fullPath, string relativePath)
{
try
{
var items = new List<object>();
var directories = Directory.GetDirectories(fullPath);
foreach (var dir in directories)
{
var dirInfo = new DirectoryInfo(dir);
var subPath = string.IsNullOrEmpty(relativePath)
? dirInfo.Name
: $"{relativePath}/{dirInfo.Name}";
items.Add(new
{
name = dirInfo.Name,
type = "directory",
path = subPath,
created = dirInfo.CreationTime,
modified = dirInfo.LastWriteTime,
isPreviewable = false
});
}
var files = Directory.GetFiles(fullPath);
foreach (var file in files)
{
var fileInfo = new FileInfo(file);
var filePath = string.IsNullOrEmpty(relativePath)
? fileInfo.Name
: $"{relativePath}/{fileInfo.Name}";
var extension = fileInfo.Extension.ToLowerInvariant();
items.Add(new
{
name = fileInfo.Name,
type = "file",
path = filePath,
size = fileInfo.Length,
extension = fileInfo.Extension,
created = fileInfo.CreationTime,
modified = fileInfo.LastWriteTime,
isPreviewable = IsPreviewableFile(extension),
contentType = GetContentType(fileInfo.Name)
});
}
var result = new
{
success = true,
type = "directory",
path = relativePath,
items = items.OrderBy(x => ((dynamic)x).type == "directory" ? 0 : 1)
.ThenBy(x => ((dynamic)x).name)
.ToList()
};
return Ok(result);
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"读取目录失败: {ex.Message}" });
}
}
[HttpPost]
[Route("download")]
public IHttpActionResult DownloadFile([FromBody] FileRequestDto request)
{
try
{
if (request == null || string.IsNullOrEmpty(request.RelativePath))
return Ok(new { success = false, message = "文件路径不能为空" });
string fullPath = Path.Combine(_basePath, request.RelativePath.Replace('/', Path.DirectorySeparatorChar));
if (!IsPathSafe(fullPath) || !System.IO.File.Exists(fullPath))
return Ok(new { success = false, message = "文件不存在" });
var fileInfo = new FileInfo(fullPath);
var contentType = GetContentType(fileInfo.Name);
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
};
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = fileInfo.Name
};
return ResponseMessage(response);
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"下载文件失败: {ex.Message}" });
}
}
}
}

View File

@@ -0,0 +1,252 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Collections.Concurrent;
using Newtonsoft.Json.Linq;
using System.Threading;
using PLMTEST;
using System.Net;
using System.Net.Http.Headers;
using System.IO;
using MisDataSaveDate;
/////http://127.0.0.1:9981/api/IOrder/InsertOrder
/// <summary>
///
/// </summary>
namespace WebApi
{
/// <summary>
///
/// </summary>
public class MomController : ApiController
{
readonly string headUrl = "/";
/// <summary>
/// 工艺信息接口
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("ProcessInfo")]
public HttpResponseMessage ProcessInfo([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.ProcessInfo(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 生产任务接口
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("DispatchOrder")]
public HttpResponseMessage DispatchOrder([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.DispatchOrder(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 生产工单接口
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("ProductionOrder")]
public HttpResponseMessage ProductionOrder([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.ProductionOrder(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 员工信息下发接口
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("EmployeeSave")]
public HttpResponseMessage EmployeeSave([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_Employee(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 生产组织信息下发
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("OrgInfoSave")]
public HttpResponseMessage OrgInfoSave([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_OrgInfo(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 工作中心信息下发
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("WorkCenterSave")]
public HttpResponseMessage WorkCenterSave([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_WorkCenterSave(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 物料信息下发
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("MaterialSave")]
public HttpResponseMessage MaterialSave([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_MaterialSave(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 计量单位下发
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("UnitInfoSave")]
public HttpResponseMessage UnitInfoSave([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_UnitInfoSave(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 员工排班信息下发
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("ShiftScheduleSave")]
public HttpResponseMessage ShiftScheduleSave([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_ShiftScheduleSave(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 报警关闭
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("AlarmClosed")]
public HttpResponseMessage AlarmClosed([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.MES_To_AMS_AlarmClosed(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// AGV送料交互接口
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("AGV_To_AMS_InterAction")]
public HttpResponseMessage AGV_To_AMS_InterAction([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.AGV_To_AMS_Interaction(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 缓存位置查询
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("LineSideStock")]
public HttpResponseMessage LineSideStock([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.AGV_To_AMS_LineSideStock(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 点检计划下发
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("InspectionPlan")]
public HttpResponseMessage InspectionPlan([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.InspectionPlan(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
[HttpPost]
[Route("QTTemplateInfo")]
public HttpResponseMessage QTTemplateInfo([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.QTItemTemplateInfo(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
[HttpPost]
[Route("QTStandardInfo")]
public HttpResponseMessage QTStandardInfo([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.QTStandardInfo(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 删除派工订单接口
/// </summary>
/// <param name="jobj"></param>
/// <returns></returns>
[HttpPost]
[Route("DeleteDispatchOrder")]
public HttpResponseMessage DeleteDispatchOrder([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(AnalysisMomMsg.DeleteDispatchOrder(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
}
}

View File

@@ -0,0 +1,134 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Collections.Concurrent;
using Newtonsoft.Json.Linq;
using System.Threading;
using System.Net;
using System.Net.Http.Headers;
using System.IO;
using MisDataSaveDate;
using WebApi;
namespace MisDataSaveDate
{
/// <summary>
/// AGV接口控制器
/// </summary>
public class WebController : ApiController
{
readonly string headUrl = "/";
/// <summary>
/// AGV请求进入接口接收方
/// 接收AGV的进入请求并存储到数据库
/// </summary>
/// <param name="jobj">AGV请求数据</param>
/// <returns>处理结果</returns>
[HttpPost]
[Route("web/WEB_Request")]
public HttpResponseMessage WEB_Request([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(WEB_BusinessLogic.WEB_Request(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// AGV请求进入接口接收方
/// 接收AGV的进入请求并存储到数据库
/// </summary>
/// <param name="jobj">AGV请求数据</param>
/// <returns>处理结果</returns>
[HttpPost]
[Route("web/WEB_SpotCheckResultUpload")]
public HttpResponseMessage WEB_SpotCheckResultUpload([FromBody] SpotCheckResult request)
{
var result = new MsgResHeader<object>
{
code = 200,
message = "",
Data = null
};
try
{
if (request == null)
{
throw new Exception("请求体不能为空");
}
var response = CALL_Inerface_DataHandle.CALL_Inerface_SpotCheckResultUpload(request);
int.TryParse(response["code"]?.ToString() ?? "500", out int remoteCode);
result.code = remoteCode;
result.message = response["message"]?.ToString() ?? "";
result.Data = response["data"];
}
catch (Exception ex)
{
result.code = 500;
result.message = ex.Message;
}
return new HttpResponseMessage
{
Content = new StringContent(JsonConvert.SerializeObject(result), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 磨合转序接口
/// 调用AGV转序接口成功后执行转序存储过程
/// </summary>
/// <param name="jobj">转序请求数据</param>
/// <returns>处理结果</returns>
[HttpPost]
[Route("web/WEB_RunningInTransfer")]
public HttpResponseMessage WEB_RunningInTransfer([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(WEB_BusinessLogic.WEB_RunningInTransfer(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 批量读取PLC点位值接口
/// 前端传递TagTypeCodeID数组和工位号返回对应点位的值
/// </summary>
/// <param name="jobj">请求数据包含OpName和TagTypeCodeIDs数组</param>
/// <returns>返回对应TagTypeCodeID的值列表</returns>
[HttpPost]
[Route("web/WEB_ReadPLCValues")]
public HttpResponseMessage WEB_ReadPLCValues([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(WEB_BusinessLogic.WEB_ReadPLCValues(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
/// <summary>
/// 写入PLC接口
/// 前端传递TagTypeCodeID、工位号和值写入到PLC
/// </summary>
/// <param name="jobj">请求数据包含TagTypeCodeID、OpName和TagValue</param>
/// <returns>写入结果</returns>
[HttpPost]
[Route("web/WEB_WritePLC")]
public HttpResponseMessage WEB_WritePLC([FromBody] JObject jobj)
{
return new HttpResponseMessage
{
Content = new StringContent(WEB_BusinessLogic.WEB_WritePLC(headUrl + System.Reflection.MethodBase.GetCurrentMethod().Name, jobj), Encoding.GetEncoding("UTF-8"), "application/json")
};
}
}
}