This commit is contained in:
wanghu
2026-09-02 10:23:24 +08:00
parent 5a414b14d2
commit ce436cbb32
117 changed files with 13768 additions and 0 deletions
@@ -0,0 +1,306 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Yh.Platform.Abstractions;
using YhCore.Common;
using YhCore.Common.Config;
using YhCore.Common.UserContext;
using YhCore.Entity;
using YhCore.Model.Dto;
using YhCore.Service.Interfaces;
namespace YhCore.WebApi.Controllers.Api.Common
{
/// <summary>
/// 公共字典 / 文件(对应旧 Areas/Common/CommonController,路由 api/base)。
/// 字典部分 8 接口 + 文件部分 4 接口(FileDown / FilePreview / FileUpload / FileUploadImage)已落地;
/// 旧 [NoAuth] 语义:无需用户上下文,schId 由前端传入或取当前用户。
/// </summary>
[ApiController]
[Route(ApiRoutes.ApiPath + "/base")]
public class CommonController : ControllerBase
{
private readonly IDictionaryService _dict;
private readonly IFileService _file;
public CommonController(IDictionaryService dict, IFileService file)
{
_dict = dict;
_file = file;
}
/// <summary>获取指定字典数据(Type 1~10)。</summary>
[HttpGet("GetSysDic")]
public async Task<List<DicOption>> GetSysDic([FromQuery] int type = 0)
{
var typeId = DictionaryTypeHelper.FromSysDicType(type);
if (typeId == null)
{
throw new DException("参数错误");
}
return await _dict.GetDictListAsync(typeId, SchSerID());
}
/// <summary>字典类别列表([NoAuth],排除部门)。</summary>
[HttpGet("GetDicTypeList")]
public async Task<List<DicOption>> GetDicTypeList() => await _dict.GetDicTypeListAsync();
/// <summary>字典列表管理(Type=0/DEPT 取全校;其他仅超管 bestsch)。</summary>
[HttpGet("GetDictMangeList")]
public async Task<List<DicManageItem>> GetDictMangeList([FromQuery] string type)
{
var typeId = DictionaryTypeHelper.ResolveTypeId(type);
if (typeId == null)
{
throw new DException("参数错误");
}
if (DictionaryTypeHelper.IsDept(typeId))
{
return await _dict.GetDictMangeListAsync("DEPT", SchSerID());
}
//if (UserContextHolder.Current.() =1 )
//{
// throw new DException("非超管不得操作!");
//}
return await _dict.GetDictMangeListAsync(typeId, "");
}
/// <summary>添加字典。</summary>
[HttpPost("AddDic")]
public async Task AddDic([FromBody] Common_Dictionary model)
{
if (model == null) throw new DException("参数错误!");
var info = new Common_Dictionary
{
typeID = model.typeID,
typeName = DictionaryTypeHelper.GetTypeName(model.typeID),
Name = model.Name,
Schserid = SchSerID()
};
await _dict.AddDicAsync(info);
}
/// <summary>更新字典。</summary>
[HttpPost("UpdateDic")]
public async Task UpdateDic([FromBody] Common_Dictionary model)
{
if (model == null) throw new DException("参数有误!");
model.Schserid = SchSerID();
await _dict.UpdateDicAsync(model);
}
/// <summary>编辑字典名称。</summary>
[HttpPost("EditDic")]
public async Task EditDic([FromBody] Common_Dictionary model)
{
if (model == null) throw new DException("参数有误!");
model.Schserid = SchSerID();
await _dict.EditDicAsync(model);
}
/// <summary>添加发文部门。</summary>
[HttpPost("AddDeptDic")]
public async Task AddDeptDic([FromBody] Common_Dictionary model)
{
if (model == null) throw new DException("参数有误!");
var info = new Common_Dictionary
{
typeID = "DEPT",
typeName = "部门类别",
Name = model.Name,
Schserid = SchSerID()
};
await _dict.AddDicAsync(info);
}
/// <summary>更新发文部门。</summary>
[HttpPost("UpdateDeptDic")]
public async Task UpdateDeptDic([FromBody] Common_Dictionary model)
{
if (model == null) throw new DException("参数有误!");
model.Schserid = SchSerID();
await _dict.UpdateDicAsync(model);
}
#region 文件:下载 / 预览 / 上传
/// <summary>
/// 公用下载文件(旧 FileDown,[NoAuth])。yl=true 且为图片/PDF 时重定向到文件 URL(webapp 预览),
/// 否则物理文件下载。
/// </summary>
[HttpGet("FileDown")]
public async Task<IActionResult> FileDown([FromQuery] int id, [FromQuery] bool yl = false)
{
if (id == 0)
return Ok();
var file = await _file.GetEnclosureAsync(id);
string[] previewArry = { ".jpg", ".gif", ".png", ".pdf", ".jpeg", ".bmp" };
if (yl)
{
// 旧 sch_weboa_url.Replace("notice/api", AppType + "/") + fileurl → 新 FileWebPath + fileurl
string fileUrl = (Config.FileWebPath ?? "") + file.fileurl;
string suffName = Path.GetExtension(fileUrl);
if (previewArry.Any(x => x == suffName.ToLower()))
return Redirect(fileUrl);
}
// WebHelper.DownFile:物理文件下载
string filePath = _file.MapPhysicalPath(file.fileurl);
if (!System.IO.File.Exists(filePath))
return Content("请求的文件不存在!");
string contentType = GetContentType(filePath);
string outputFileName = file.filename ?? "file";
return PhysicalFile(filePath, contentType, outputFileName);
}
/// <summary>
/// 公用预览 office 文件(旧 FilePreview / CommonPreview,[NoAuth])。
/// type=1 → 返回可用预览 url(本地 .pdf 存在优先);type=2 → 重定向本地 pdf 或 officeapps.live.com;
/// 其余 → 重定向替换后缀为 .pdf 的地址。跳转返回 RedirectResult(全局包装过滤器不拦截)。
/// </summary>
[HttpGet("FilePreview")]
public async Task<object> FilePreview([FromQuery] int id, [FromQuery] string type = null)
{
if (id == 0)
throw new DException("文件ID错误!");
var file = await _file.GetEnclosureAsync(id);
// 公文另做处理
if (file.fileurl != null && file.fileurl.IndexOf("gw.") > -1)
{
string fileUrl = "http://" + file.fileurl;
string suffName = Path.GetExtension(fileUrl);
string newName = fileUrl.Remove(fileUrl.LastIndexOf(suffName, StringComparison.Ordinal), suffName.Length) + ".pdf";
return Redirect(newName);
}
string fileUrl2 = (Config.FileWebPath ?? "") + file.fileurl;
string suffName2 = Path.GetExtension(fileUrl2);
if (!string.IsNullOrEmpty(type))
{
// 单独读取文件是否存在
string newFile = file.fileurl;
string pdfFile = newFile.Remove(newFile.LastIndexOf(suffName2, StringComparison.Ordinal), suffName2.Length) + ".pdf";
string outFile = _file.MapPhysicalPath(pdfFile);
if (type == "1")
{
if (System.IO.File.Exists(outFile)) return (Config.FileWebPath ?? "") + pdfFile;
return fileUrl2;
}
if (type == "2")
{
string pdfUrl = string.Empty;
if (System.IO.File.Exists(outFile)) pdfUrl = (Config.FileWebPath ?? "") + pdfFile;
else pdfUrl = "https://view.officeapps.live.com/op/view.aspx?src=" + fileUrl2;
return Redirect(pdfUrl);
}
return "";
}
string newName2 = fileUrl2.Remove(fileUrl2.LastIndexOf(suffName2, StringComparison.Ordinal), suffName2.Length) + ".pdf";
return Redirect(newName2);
}
/// <summary>
/// 公用附件上传(旧 FileUpload,[NoAuth])。
/// chunk 参数 → 分片保存返回 {code:1,type:"chunk",msg};fileName 参数 → 合并分片;否则单文件上传。
/// 落库 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"];
if (!string.IsNullOrEmpty(chunk))
{
var chunkFile = Request.Form.Files.FirstOrDefault(f => f.Name == "file") ?? Request.Form.Files.FirstOrDefault();
await _file.SaveChunkAsync(guid, chunk, chunkFile);
return new { code = 1, type = "chunk", msg = "分片上传成功!" };
}
FileObj url;
string errMsg = "上传失败!";
if (string.IsNullOrEmpty(fileName))
{
url = await _file.SaveFileAsync(apptype, Request.Form.Files.FirstOrDefault());
}
else
{
url = await _file.MergeSaveAsync(apptype, guid, fileName);
}
if (url == null)
throw new DException(errMsg);
// 旧 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>公用图片上传(旧 FileUploadImage,[NoAuth];多图,返回数组)。</summary>
[HttpPost("FileUploadImage")]
public async Task<object> UploadImg()
{
string apptype = "docprint";
var urlList = await _file.SaveFileImageAsync(apptype, Request.Form.Files);
if (urlList.Count == 0)
throw new DException("上传失败!");
var result = new List<object>();
foreach (var item in urlList)
{
int serid = await _file.SaveEnclosureAsync(item, DocPrintConstants.AppCode.ToString());
result.Add(new { fileurl = item.fileurl, host = item.host, fileid = serid, name = item.filename, type = item.filetype });
}
return result;
}
/// <summary>按扩展名取 ContentType(替代旧 MimeMapping.GetMimeMapping)。</summary>
private static string GetContentType(string filePath)
{
string ext = Path.GetExtension(filePath).ToLower();
return ext switch
{
".jpg" or ".jpeg" => "image/jpeg",
".gif" => "image/gif",
".png" => "image/png",
".bmp" => "image/bmp",
".pdf" => "application/pdf",
".txt" => "text/plain",
".doc" => "application/msword",
".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".xls" => "application/vnd.ms-excel",
".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
".ppt" => "application/vnd.ms-powerpoint",
".pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation",
".zip" => "application/zip",
".rar" => "application/x-rar-compressed",
".mp4" => "video/mp4",
_ => "application/octet-stream",
};
}
#endregion
private static string SchSerID() => UserContextHolder.Current.SchSerID;
}
}