@@ -214,9 +214,15 @@ namespace YhCore.Service.Impl
|
||||
if (string.IsNullOrEmpty(fileUrl))
|
||||
return "";
|
||||
|
||||
// 相对路径如 /upload/docprint/20260101/{guid}.jpg → Config.FilePath + 子路径
|
||||
// 新数据:fileurl 以 FILE_PATH 开头(如 /data/upload/docprint/20260101/{guid}.jpg)→ 剥前缀映射回 FILE_PATH。
|
||||
// 注意必须用未 TrimStart 的原始 fileUrl 比较(FILE_PATH 本身以 / 开头)
|
||||
string fp = Config.FilePath;
|
||||
if (!string.IsNullOrEmpty(fp) && fileUrl.StartsWith(fp, StringComparison.OrdinalIgnoreCase))
|
||||
return Path.Combine(fp, fileUrl.Substring(fp.Length).TrimStart('/').Replace('/', Path.DirectorySeparatorChar));
|
||||
|
||||
// 旧数据:相对路径如 /upload/docprint/20260101/{guid}.jpg(不含 FILE_PATH 前缀)→ StorageRoot + 子路径
|
||||
var relative = fileUrl.TrimStart('/');
|
||||
string prefix = Config.FilePath;
|
||||
const string prefix = "upload/";
|
||||
if (relative.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
relative = relative.Substring(prefix.Length);
|
||||
|
||||
@@ -229,7 +235,8 @@ namespace YhCore.Service.Impl
|
||||
if (!string.IsNullOrEmpty(Config.FilePath))
|
||||
return Config.FilePath;
|
||||
|
||||
return Path.Combine(AppContext.BaseDirectory,Config.FilePath);
|
||||
// 此分支仅在 FILE_PATH 未配置时执行(此时 Config.FilePath 为 null,不可再参与拼接)
|
||||
return Path.Combine(AppContext.BaseDirectory, "upload");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,42 +235,58 @@ namespace YhCore.WebApi.Controllers.Api.Common
|
||||
|
||||
/// <summary>
|
||||
/// 公用附件上传(旧 FileUpload,[NoAuth])。
|
||||
/// chunk 参数 → 分片保存返回 {code:1,type:"chunk",msg};fileName 参数 → 合并分片;否则单文件上传。
|
||||
/// 分片(chunk/chunkIndex + totalChunks>1)→ 分片保存返回 {code:1,type:"chunk",msg};
|
||||
/// 只带 fileName 不带文件 → 合并分片;带文件 → 单文件直传
|
||||
/// (前端单文件直传也会带 guid/chunkIndex=0/totalChunks=0/fileName,不得误入合并分支)。
|
||||
/// guid/chunk/fileName 兼容 query 与 form 两种形态(旧版读 Query)。
|
||||
/// 落库 Common_UpFiles(TopicType=AppCode),返回 {fileurl,host,fileid,name,type}。
|
||||
/// </summary>
|
||||
[HttpPost("FileUpload")]
|
||||
public async Task<object> Upload()
|
||||
{
|
||||
string apptype = "docprint"; // 旧 WebHelper.AppType 固定 docprint
|
||||
string guid = Request.Form["guid"];
|
||||
string chunk = Request.Form["chunk"];
|
||||
string fileName = Request.Form["fileName"];
|
||||
string guid = FormOrQuery("guid");
|
||||
string chunk = FormOrQuery("chunk"); // 旧契约分片序号
|
||||
string chunkIndex = FormOrQuery("chunkIndex"); // 前端现用分片序号
|
||||
string totalChunks = FormOrQuery("totalChunks");
|
||||
string fileName = FormOrQuery("fileName");
|
||||
|
||||
if (!string.IsNullOrEmpty(chunk))
|
||||
var file = Request.Form.Files.FirstOrDefault(f => f.Name == "file") ?? Request.Form.Files.FirstOrDefault();
|
||||
bool multiChunk = int.TryParse(totalChunks, out var total) && total > 1;
|
||||
bool isChunkReq = file != null
|
||||
&& (!string.IsNullOrEmpty(chunk) || (!string.IsNullOrEmpty(chunkIndex) && multiChunk));
|
||||
|
||||
if (isChunkReq)
|
||||
{
|
||||
var chunkFile = Request.Form.Files.FirstOrDefault(f => f.Name == "file") ?? Request.Form.Files.FirstOrDefault();
|
||||
await _file.SaveChunkAsync(guid, chunk, chunkFile);
|
||||
await _file.SaveChunkAsync(guid, string.IsNullOrEmpty(chunk) ? chunkIndex : chunk, file);
|
||||
return new { code = 1, type = "chunk", msg = "分片上传成功!" };
|
||||
}
|
||||
|
||||
FileObj url;
|
||||
string errMsg = "上传失败!";
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
if (!string.IsNullOrEmpty(fileName) && file == null)
|
||||
{
|
||||
url = await _file.SaveFileAsync(apptype, Request.Form.Files.FirstOrDefault());
|
||||
url = await _file.MergeSaveAsync(apptype, guid, fileName); // 合并分片
|
||||
}
|
||||
else
|
||||
{
|
||||
url = await _file.MergeSaveAsync(apptype, guid, fileName);
|
||||
url = await _file.SaveFileAsync(apptype, file); // 单文件直传
|
||||
}
|
||||
if (url == null)
|
||||
throw new DException(errMsg);
|
||||
throw new DException("上传失败!");
|
||||
|
||||
// 旧 WebHelper.AppCode == "1102" ? "1002" : AppCode → docprint 固定 1003
|
||||
int serid = await _file.SaveEnclosureAsync(url, DocPrintConstants.AppCode.ToString());
|
||||
return new { fileurl = url.fileurl, host = url.host, fileid = serid, name = url.filename, type = url.filetype };
|
||||
}
|
||||
|
||||
/// <summary>取表单/URL 参数(旧版读 Request["x"] 同时覆盖 Query+Form)。</summary>
|
||||
private string FormOrQuery(string name)
|
||||
{
|
||||
var v = Request.Form[name].ToString();
|
||||
if (!string.IsNullOrEmpty(v)) return v;
|
||||
return Request.Query[name].ToString();
|
||||
}
|
||||
|
||||
/// <summary>公用图片上传(旧 FileUploadImage,[NoAuth];多图,返回数组)。</summary>
|
||||
[HttpPost("FileUploadImage")]
|
||||
public async Task<object> UploadImg()
|
||||
|
||||
@@ -175,9 +175,17 @@ namespace YhCore.WebApi
|
||||
.Bind(Configuration.GetSection("Swagger"));
|
||||
services.AddOptions<YhCore.Common.Config.FileConfig>()
|
||||
.Bind(Configuration);
|
||||
// 静态门面(对齐 Java Config):文件路径由配置注入
|
||||
YhCore.Common.Config.Config.FilePath = Configuration["FILE_PATH"];
|
||||
YhCore.Common.Config.Config.FileWebPath = Configuration["FILE_WEB_PATH"];
|
||||
// 静态门面(对齐 Java Config):文件路径由配置注入。
|
||||
// FILE_PATH 必须以 / 结尾(旧约定:FileService 多处 FilePath + "{appType}/..." 直接拼接,缺斜杠会拼出坏路径);
|
||||
// FILE_WEB_PATH 不带尾 /(拼接目标 fileurl 均以 / 开头,带尾斜杠会产生 //)
|
||||
var configFilePath = Configuration["FILE_PATH"];
|
||||
YhCore.Common.Config.Config.FilePath = string.IsNullOrEmpty(configFilePath)
|
||||
? configFilePath
|
||||
: configFilePath.TrimEnd('/').Replace('\\', '/') + "/";
|
||||
var configFileWebPath = Configuration["FILE_WEB_PATH"];
|
||||
YhCore.Common.Config.Config.FileWebPath = string.IsNullOrEmpty(configFileWebPath)
|
||||
? configFileWebPath
|
||||
: configFileWebPath.TrimEnd('/');
|
||||
// 审批单 PDF:wkhtmltopdf 可执行文件路径(空则用 PATH)
|
||||
YhCore.Common.Config.Config.WkHtmlToPdfPath = Configuration["wkhtmltopdf_path"];
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"Redis": {
|
||||
"ConnectionString": "localhost:6379,defaultDatabase=0"
|
||||
},
|
||||
"FILE_PATH": "",
|
||||
"FILE_PATH": "/data/upload/",
|
||||
"FILE_WEB_PATH": "",
|
||||
"wkhtmltopdf_path": "",
|
||||
"yh": {
|
||||
|
||||
Reference in New Issue
Block a user