DictionaryHelper.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. 
  2. using Newtonsoft.Json;
  3. using Newtonsoft.Json.Linq;
  4. using PTMedicalInsurance.Business;
  5. using PTMedicalInsurance.Variables;
  6. using System;
  7. using System.Collections.Concurrent;
  8. using System.Collections.Generic;
  9. using System.Data;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using System.Windows.Forms;
  15. namespace PTMedicalInsurance.Helper
  16. {
  17. class DictionaryHelper
  18. {
  19. private readonly ConcurrentDictionary<string, Dictionary<string, string>> _dictCache
  20. = new ConcurrentDictionary<string, Dictionary<string, string>>();
  21. public int SaveDicToJson(string dicType, out string error)
  22. {
  23. InsuServices iris = new InsuServices();
  24. JObject joRtn = iris.getSpecDictionary(Global.inf.interfaceDr.ToString(), dicType,false);
  25. DictionaryHelper dicHelper = new DictionaryHelper();
  26. return dicHelper.SaveDictionaryToFile(joRtn.ToString(), dicType,out error);
  27. }
  28. private int SaveDictionaryToFile(string jsonResponse, string dicType,out string error)
  29. {
  30. error = "";
  31. try
  32. {
  33. // 解析原始响应(只取 data 部分)
  34. var response = JsonConvert.DeserializeObject<DictResponse>(jsonResponse);
  35. var dictData = response?.Result?.Data;
  36. if (dictData == null || dictData.Count <= 1)
  37. {
  38. error = "无效的字典数据";
  39. return -1;
  40. }
  41. // 构建文件路径
  42. string directoryPath = Path.Combine(Global.curEvt.path, "Dictionary");
  43. string filePath = Path.Combine(directoryPath, $"{dicType}.json");
  44. // ✅ 关键:确保目录存在(不存在则创建)
  45. Directory.CreateDirectory(directoryPath);
  46. // 写入文件(只保存 code -> name 映射,更轻量)
  47. var simpleDict = dictData.ToDictionary(
  48. item => item.Code,
  49. item => item.Name,
  50. StringComparer.OrdinalIgnoreCase
  51. );
  52. string jsonContent = JsonConvert.SerializeObject(simpleDict, Formatting.Indented);
  53. File.WriteAllText(filePath, jsonContent, Encoding.UTF8);
  54. error = $"字典已保存至: {filePath}";
  55. return 0;
  56. }
  57. catch (Exception ex)
  58. {
  59. error = $"保存字典失败: {ex.Message}";
  60. return -1;
  61. }
  62. }
  63. /// <summary>
  64. /// 获取指定字典中代码对应的中文名称
  65. /// </summary>
  66. /// <param name="dicType">字典类型,如 "clr_type", "insu_type"</param>
  67. /// <param name="code">代码值,如 "11"</param>
  68. /// <param name="returnOriginalIfNotFound">未找到时是否返回原 code</param>
  69. /// <returns>中文名称或原值/空</returns>
  70. public string GetChineseName(string dicType, string code, bool returnOriginalIfNotFound = true)
  71. {
  72. if (string.IsNullOrEmpty(dicType) || string.IsNullOrEmpty(code))
  73. return returnOriginalIfNotFound ? code ?? "" : "";
  74. // 自动构建字典文件路径
  75. string dictFilePath = GetDictFilePath(dicType);
  76. var dict = _dictCache.GetOrAdd(dicType, key =>
  77. {
  78. //if (!File.Exists(dictFilePath))
  79. // throw new FileNotFoundException($"字典文件未找到: {dictFilePath}");
  80. if (!File.Exists(dictFilePath))
  81. {
  82. //此次报警只会一次,因为GetOrAdd方法只有当key不存在时才会执行,返回一个空数据集后,key已存在,lambda内不再执行
  83. MessageBox.Show($"字典文件未找到: {dictFilePath}");
  84. return new Dictionary<string, string>(); // 返回空字典,避免后续异常
  85. }
  86. var json = File.ReadAllText(dictFilePath, Encoding.UTF8);
  87. var parsed = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  88. return parsed ?? new Dictionary<string, string>();
  89. });
  90. return dict.TryGetValue(code, out var name) && !string.IsNullOrEmpty(name)
  91. ? name
  92. : returnOriginalIfNotFound ? code : "";
  93. }
  94. /// <summary>
  95. /// 根据字典名称生成完整文件路径
  96. /// </summary>
  97. public string GetDictFilePath(string dictName)
  98. {
  99. // 假设所有字典都存放在 Global.curEvt.path/Dictionary/ 下
  100. string baseDir = Global.curEvt.path;
  101. string dictDir = Path.Combine(baseDir, "Dictionary");
  102. return Path.Combine(dictDir, $"{dictName}.json");
  103. }
  104. /// <summary>
  105. /// 读取JSON文件并转换为DataTable
  106. /// </summary>
  107. /// <param name="filePath">JSON文件路径</param>
  108. /// <returns>DataTable</returns>
  109. public DataTable JsonFileToDataTable(string dictName)
  110. {
  111. string filePath = GetDictFilePath(dictName);
  112. if (!File.Exists(filePath))
  113. throw new FileNotFoundException($"文件未找到: {filePath}");
  114. string json = File.ReadAllText(filePath, Encoding.Default);
  115. return JsonToDataTable(json);
  116. }
  117. /// <summary>
  118. /// 将JSON字符串转换为DataTable
  119. /// </summary>
  120. /// <param name="json">JSON字符串(键值对格式,如 {"01": "挂号", "02": "住院"})</param>
  121. /// <returns>DataTable,包含 code 和 name 两列</returns>
  122. public static DataTable JsonToDataTable(string json, string arrayPath = null)
  123. {
  124. json = json.Trim();
  125. DataTable dt = new DataTable();
  126. dt.Columns.Add("code", typeof(string));
  127. dt.Columns.Add("name", typeof(string));
  128. if (!json.StartsWith("{"))
  129. throw new InvalidOperationException("JSON格式不正确,需要键值对格式");
  130. JObject jo = JObject.Parse(json);
  131. foreach (var prop in jo.Properties())
  132. {
  133. DataRow dr = dt.NewRow();
  134. dr["code"] = prop.Name;
  135. dr["name"] = prop.Value?.ToString() ?? "";
  136. dt.Rows.Add(dr);
  137. }
  138. return dt;
  139. }
  140. /// <summary>
  141. /// 批量转换整个 DataTable
  142. /// </summary>
  143. public void TranslateDataTable(DataTable table, List<ColumnDictMapping> mappings)
  144. {
  145. if (table == null || mappings == null || !mappings.Any())
  146. return;
  147. // 验证列是否存在
  148. foreach (var mapping in mappings)
  149. {
  150. if (!table.Columns.Contains(mapping.ColumnName))
  151. throw new ArgumentException($"DataTable 中不存在列: {mapping.ColumnName}");
  152. }
  153. // 遍历每一行
  154. foreach (DataRow row in table.Rows)
  155. {
  156. foreach (var mapping in mappings)
  157. {
  158. var currentValue = row[mapping.ColumnName]?.ToString();
  159. if (string.IsNullOrEmpty(currentValue)) continue;
  160. var chinese = GetChineseName(mapping.DicType, currentValue);
  161. row[mapping.ColumnName] = chinese;
  162. }
  163. }
  164. }
  165. /// <summary>
  166. /// 设置ComboBox的数据源为指定字典的DataTable
  167. /// </summary>
  168. /// <param name="comboBox">ComboBox控件(支持System.Windows.Forms.ComboBox和Sunny.UI.UIComboBox)</param>
  169. /// <param name="dicName">字典名称(不含.json后缀)</param>
  170. /// <param name="insertEmptyOption">是否插入空选项</param>
  171. public void SetComboxDatasource(object comboBox, string dicName, bool insertEmptyOption = false)
  172. {
  173. if (comboBox == null)
  174. throw new ArgumentNullException(nameof(comboBox));
  175. if (string.IsNullOrEmpty(dicName))
  176. throw new ArgumentNullException(nameof(dicName));
  177. DataTable dt = JsonFileToDataTable(dicName);
  178. if (insertEmptyOption)
  179. {
  180. DataRow dr = dt.NewRow();
  181. dr["code"] = "";
  182. dr["name"] = "请选择";
  183. dt.Rows.InsertAt(dr, 0);
  184. }
  185. // 使用dynamic避免类型转换问题
  186. dynamic cb = comboBox;
  187. cb.DataSource = dt;
  188. cb.DisplayMember = "name";
  189. cb.ValueMember = "code";
  190. }
  191. }
  192. public class ColumnDictMapping
  193. {
  194. /// <summary>
  195. /// DataTable 中的列名
  196. /// </summary>
  197. public string ColumnName { get; set; }
  198. /// <summary>
  199. /// 对应的字典类型
  200. /// </summary>
  201. public string DicType { get; set; }
  202. }
  203. public class DictItem
  204. {
  205. [JsonProperty("code")]
  206. public string Code { get; set; }
  207. [JsonProperty("name")]
  208. public string Name { get; set; }
  209. [JsonProperty("searchcode")]
  210. public string SearchCode { get; set; }
  211. }
  212. public class DictResponse
  213. {
  214. [JsonProperty("result")]
  215. public Result Result { get; set; }
  216. }
  217. public class Result
  218. {
  219. [JsonProperty("data")]
  220. public List<DictItem> Data { get; set; }
  221. }
  222. }