|
|
@@ -4073,7 +4073,7 @@ FROM
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
- return Ok(JsonView(false, "信息提取失败:"+ex.Message));
|
|
|
+ return Ok(JsonView(false, "信息提取失败:" + ex.Message));
|
|
|
}
|
|
|
|
|
|
#region 数据提交
|
|
|
@@ -6046,7 +6046,7 @@ FROM
|
|
|
|
|
|
if (!string.IsNullOrEmpty(url))
|
|
|
{
|
|
|
- return Ok(JsonView(true,"操作成功", url));
|
|
|
+ return Ok(JsonView(true, "操作成功", url));
|
|
|
}
|
|
|
|
|
|
return Ok(JsonView(false, "操作失败!"));
|
|
|
@@ -32060,6 +32060,268 @@ ORDER BY
|
|
|
return Ok(JsonView(true, "SUCCESS", backData));
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 会务成本从表图片文件上传
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="Dto"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPost]
|
|
|
+ public async Task<IActionResult> ConferenceAffairsChildImageUpload([FromForm] ConferenceAffairsChildImageUploadDto Dto)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (Dto == null || Dto.Files == null || Dto.Files.Count == 0)
|
|
|
+ {
|
|
|
+ return Ok(JsonView(false, "请选择要上传的图片文件!"));
|
|
|
+ }
|
|
|
+
|
|
|
+ var child = _sqlSugar.Queryable<Grp_ConferenceAffairsCostChild>()
|
|
|
+ .Where(x => x.IsDel == 0 && x.Id == Dto.childId)
|
|
|
+ .First();
|
|
|
+
|
|
|
+ if (child == null)
|
|
|
+ {
|
|
|
+ return Ok(JsonView(false, "会务成本从表不存在!"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 允许的图片类型
|
|
|
+ var allowedImageTypes = new[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp" };
|
|
|
+ var allowedContentTypes = new[] { "image/jpeg", "image/jpg", "image/png", "image/gif", "image/bmp" };
|
|
|
+
|
|
|
+ // 获取配置路径
|
|
|
+ string baseUrl = AppSettingsHelper.Get("ConferenceCostImageBaseUrl");
|
|
|
+ string basePath = AppSettingsHelper.Get("ConferenceCostImageBasePath");
|
|
|
+ string ftpPath = AppSettingsHelper.Get("ConferenceCostImageFtpPath");
|
|
|
+
|
|
|
+ // 确保路径以/结尾
|
|
|
+ if (!baseUrl.EndsWith("/"))
|
|
|
+ {
|
|
|
+ baseUrl = baseUrl.TrimEnd('/') + "/";
|
|
|
+ }
|
|
|
+ if (!basePath.EndsWith("\\") && !basePath.EndsWith("/"))
|
|
|
+ {
|
|
|
+ basePath = basePath.TrimEnd('\\', '/') + "\\";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建保存目录(按childId分目录)
|
|
|
+ string saveDir = Path.Combine(basePath, "child", child.Id.ToString());
|
|
|
+ if (!Directory.Exists(saveDir))
|
|
|
+ {
|
|
|
+ Directory.CreateDirectory(saveDir);
|
|
|
+ }
|
|
|
+
|
|
|
+ var uploadedImageUrls = new List<string>();
|
|
|
+ var existingImgs = string.IsNullOrWhiteSpace(child.Imgs)
|
|
|
+ ? new List<string>()
|
|
|
+ : child.Imgs.Split(',').Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
|
|
|
+
|
|
|
+ foreach (var file in Dto.Files)
|
|
|
+ {
|
|
|
+ if (file == null || file.Length == 0)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证文件扩展名
|
|
|
+ var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant();
|
|
|
+ if (string.IsNullOrEmpty(fileExtension) || !allowedImageTypes.Contains(fileExtension))
|
|
|
+ {
|
|
|
+ return Ok(JsonView(false, $"文件 {file.FileName} 不是支持的图片格式,仅支持:{string.Join("、", allowedImageTypes)}"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证ContentType
|
|
|
+ if (!string.IsNullOrEmpty(file.ContentType) && !allowedContentTypes.Contains(file.ContentType.ToLowerInvariant()))
|
|
|
+ {
|
|
|
+ return Ok(JsonView(false, $"文件 {file.FileName} 的ContentType不正确,不是图片类型"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取原始文件名(不含扩展名)和扩展名
|
|
|
+ string originalFileName = Path.GetFileNameWithoutExtension(file.FileName);
|
|
|
+ string fileName = file.FileName;
|
|
|
+ string filePath = Path.Combine(saveDir, fileName);
|
|
|
+
|
|
|
+ // 如果文件已存在,添加计数后缀
|
|
|
+ int count = 0;
|
|
|
+ while (System.IO.File.Exists(filePath))
|
|
|
+ {
|
|
|
+ count++;
|
|
|
+ fileName = $"{originalFileName}({count}){fileExtension}";
|
|
|
+ filePath = Path.Combine(saveDir, fileName);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存文件
|
|
|
+ using (var stream = new FileStream(filePath, FileMode.Create))
|
|
|
+ {
|
|
|
+ await file.CopyToAsync(stream);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成完整URL路径
|
|
|
+ string imageUrl = $"{baseUrl}{ftpPath}child/{child.Id}/{fileName}";
|
|
|
+ uploadedImageUrls.Add(imageUrl);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (uploadedImageUrls.Count == 0)
|
|
|
+ {
|
|
|
+ return Ok(JsonView(false, "没有成功上传任何图片!"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 合并现有图片路径和新上传的图片路径
|
|
|
+ existingImgs.AddRange(uploadedImageUrls);
|
|
|
+ string updatedImgs = string.Join(",", existingImgs);
|
|
|
+
|
|
|
+ // 更新数据库
|
|
|
+ _sqlSugar.Updateable<Grp_ConferenceAffairsCostChild>()
|
|
|
+ .SetColumns(x => new Grp_ConferenceAffairsCostChild { Imgs = updatedImgs })
|
|
|
+ .Where(x => x.Id == child.Id)
|
|
|
+ .ExecuteCommand();
|
|
|
+
|
|
|
+ return Ok(JsonView(true, $"成功上传 {uploadedImageUrls.Count} 张图片", uploadedImageUrls));
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ return Ok(JsonView(false, $"上传失败:{ex.Message}"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 根据文件名和从表id删除对应的图片
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="Dto"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ [HttpPost]
|
|
|
+ public async Task<IActionResult> ConferenceAffairsChildImageDelete(ConferenceAffairsChildImageDeleteDto Dto)
|
|
|
+ {
|
|
|
+ if (Dto == null || Dto.fileNames == null || Dto.fileNames.Count == 0)
|
|
|
+ {
|
|
|
+ return Ok(JsonView(false, "请提供要删除的文件名列表!"));
|
|
|
+ }
|
|
|
+
|
|
|
+ var child = _sqlSugar.Queryable<Grp_ConferenceAffairsCostChild>()
|
|
|
+ .Where(x => x.IsDel == 0 && x.Id == Dto.childId)
|
|
|
+ .First();
|
|
|
+
|
|
|
+ if (child == null)
|
|
|
+ {
|
|
|
+ return Ok(JsonView(false, "会务成本id有误!"));
|
|
|
+ }
|
|
|
+
|
|
|
+ var existingImgs = string.IsNullOrWhiteSpace(child.Imgs)
|
|
|
+ ? new List<string>()
|
|
|
+ : child.Imgs.Split(',').Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
|
|
|
+
|
|
|
+ // 获取配置路径
|
|
|
+ string baseUrl = AppSettingsHelper.Get("ConferenceCostImageBaseUrl");
|
|
|
+ string basePath = AppSettingsHelper.Get("ConferenceCostImageBasePath");
|
|
|
+ string ftpPath = AppSettingsHelper.Get("ConferenceCostImageFtpPath");
|
|
|
+
|
|
|
+ // 确保路径格式正确
|
|
|
+ if (!baseUrl.EndsWith("/"))
|
|
|
+ {
|
|
|
+ baseUrl = baseUrl.TrimEnd('/') + "/";
|
|
|
+ }
|
|
|
+ if (!basePath.EndsWith("\\") && !basePath.EndsWith("/"))
|
|
|
+ {
|
|
|
+ basePath = basePath.TrimEnd('\\', '/') + "\\";
|
|
|
+ }
|
|
|
+ if (!ftpPath.EndsWith("/"))
|
|
|
+ {
|
|
|
+ ftpPath = ftpPath.TrimEnd('/') + "/";
|
|
|
+ }
|
|
|
+
|
|
|
+ int deletedCount = 0;
|
|
|
+ var expectedUrlPrefix = $"{baseUrl}{ftpPath}child/{child.Id}/";
|
|
|
+ var fileDir = Path.Combine(basePath, "child", child.Id.ToString());
|
|
|
+
|
|
|
+ // 遍历要删除的文件名列表
|
|
|
+ foreach (var fileNameOrUrl in Dto.fileNames)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrWhiteSpace(fileNameOrUrl))
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ string fileName = fileNameOrUrl;
|
|
|
+ string fullUrl = fileNameOrUrl;
|
|
|
+
|
|
|
+ // 判断是完整URL还是文件名
|
|
|
+ if (fileNameOrUrl.StartsWith("http://") || fileNameOrUrl.StartsWith("https://"))
|
|
|
+ {
|
|
|
+ // 是完整URL,提取文件名
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var uri = new Uri(fileNameOrUrl);
|
|
|
+ fileName = Path.GetFileName(uri.AbsolutePath);
|
|
|
+ // 如果URL包含child/{childId}/路径,使用完整URL匹配
|
|
|
+ if (fileNameOrUrl.Contains($"/child/{child.Id}/"))
|
|
|
+ {
|
|
|
+ fullUrl = fileNameOrUrl;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // URL格式不匹配,尝试构造完整URL
|
|
|
+ fullUrl = $"{expectedUrlPrefix}{fileName}";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ // URL解析失败,当作文件名处理
|
|
|
+ fileName = Path.GetFileName(fileNameOrUrl);
|
|
|
+ fullUrl = $"{expectedUrlPrefix}{fileName}";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 是文件名,构造完整URL用于匹配
|
|
|
+ fullUrl = $"{expectedUrlPrefix}{fileName}";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从现有图片列表中移除(支持完整URL匹配或文件名匹配)
|
|
|
+ var removed = existingImgs.RemoveAll(img =>
|
|
|
+ img.Equals(fullUrl, StringComparison.OrdinalIgnoreCase) ||
|
|
|
+ img.Equals(fileNameOrUrl, StringComparison.OrdinalIgnoreCase) ||
|
|
|
+ img.EndsWith($"/{fileName}", StringComparison.OrdinalIgnoreCase));
|
|
|
+
|
|
|
+ if (removed > 0)
|
|
|
+ {
|
|
|
+ deletedCount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 删除磁盘上的文件
|
|
|
+ var filePath = Path.Combine(fileDir, fileName);
|
|
|
+ if (System.IO.File.Exists(filePath))
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ System.IO.File.Delete(filePath);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ _logger.LogError(ex, "删除图片失败:{fileName}", fileName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (deletedCount == 0)
|
|
|
+ {
|
|
|
+ return Ok(JsonView(false, "没有找到要删除的图片!"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新数据库
|
|
|
+ var updatedImgs = string.Join(",", existingImgs);
|
|
|
+ _sqlSugar.Updateable<Grp_ConferenceAffairsCostChild>()
|
|
|
+ .SetColumns(x => new Grp_ConferenceAffairsCostChild { Imgs = updatedImgs })
|
|
|
+ .Where(x => x.Id == child.Id)
|
|
|
+ .ExecuteCommand();
|
|
|
+
|
|
|
+ return Ok(JsonView(true, $"成功删除 {deletedCount} 张图片", updatedImgs));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 会务成本保存
|
|
|
/// </summary>
|