using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PTMedicalInsurance.Business; using PTMedicalInsurance.Variables; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace PTMedicalInsurance.Helper { class DictionaryHelper { private readonly ConcurrentDictionary> _dictCache = new ConcurrentDictionary>(); public int SaveDicToJson(string dicType, out string error) { InsuServices iris = new InsuServices(); JObject joRtn = iris.getSpecDictionary(Global.inf.interfaceDr.ToString(), dicType,false); DictionaryHelper dicHelper = new DictionaryHelper(); return dicHelper.SaveDictionaryToFile(joRtn.ToString(), dicType,out error); } private int SaveDictionaryToFile(string jsonResponse, string dicType,out string error) { error = ""; try { // 解析原始响应(只取 data 部分) var response = JsonConvert.DeserializeObject(jsonResponse); var dictData = response?.Result?.Data; if (dictData == null || dictData.Count <= 1) { error = "无效的字典数据"; return -1; } // 构建文件路径 string directoryPath = Path.Combine(Global.curEvt.path, "Dictionary"); string filePath = Path.Combine(directoryPath, $"{dicType}.json"); // ✅ 关键:确保目录存在(不存在则创建) Directory.CreateDirectory(directoryPath); // 写入文件(只保存 code -> name 映射,更轻量) var simpleDict = dictData.ToDictionary( item => item.Code, item => item.Name, StringComparer.OrdinalIgnoreCase ); string jsonContent = JsonConvert.SerializeObject(simpleDict, Formatting.Indented); File.WriteAllText(filePath, jsonContent, Encoding.UTF8); error = $"字典已保存至: {filePath}"; return 0; } catch (Exception ex) { error = $"保存字典失败: {ex.Message}"; return -1; } } /// /// 获取指定字典中代码对应的中文名称 /// /// 字典类型,如 "clr_type", "insu_type" /// 代码值,如 "11" /// 未找到时是否返回原 code /// 中文名称或原值/空 public string GetChineseName(string dicType, string code, bool returnOriginalIfNotFound = true) { if (string.IsNullOrEmpty(dicType) || string.IsNullOrEmpty(code)) return returnOriginalIfNotFound ? code ?? "" : ""; // 自动构建字典文件路径 string dictFilePath = GetDictFilePath(dicType); var dict = _dictCache.GetOrAdd(dicType, key => { //if (!File.Exists(dictFilePath)) // throw new FileNotFoundException($"字典文件未找到: {dictFilePath}"); if (!File.Exists(dictFilePath)) { //此次报警只会一次,因为GetOrAdd方法只有当key不存在时才会执行,返回一个空数据集后,key已存在,lambda内不再执行 MessageBox.Show($"字典文件未找到: {dictFilePath}"); return new Dictionary(); // 返回空字典,避免后续异常 } var json = File.ReadAllText(dictFilePath, Encoding.UTF8); var parsed = JsonConvert.DeserializeObject>(json); return parsed ?? new Dictionary(); }); return dict.TryGetValue(code, out var name) && !string.IsNullOrEmpty(name) ? name : returnOriginalIfNotFound ? code : ""; } /// /// 根据字典名称生成完整文件路径 /// public string GetDictFilePath(string dictName) { // 假设所有字典都存放在 Global.curEvt.path/Dictionary/ 下 string baseDir = Global.curEvt.path; string dictDir = Path.Combine(baseDir, "Dictionary"); return Path.Combine(dictDir, $"{dictName}.json"); } /// /// 读取JSON文件并转换为DataTable /// /// JSON文件路径 /// DataTable public DataTable JsonFileToDataTable(string dictName) { string filePath = GetDictFilePath(dictName); if (!File.Exists(filePath)) throw new FileNotFoundException($"文件未找到: {filePath}"); string json = File.ReadAllText(filePath, Encoding.Default); return JsonToDataTable(json); } /// /// 将JSON字符串转换为DataTable /// /// JSON字符串(键值对格式,如 {"01": "挂号", "02": "住院"}) /// DataTable,包含 code 和 name 两列 public static DataTable JsonToDataTable(string json, string arrayPath = null) { json = json.Trim(); DataTable dt = new DataTable(); dt.Columns.Add("code", typeof(string)); dt.Columns.Add("name", typeof(string)); if (!json.StartsWith("{")) throw new InvalidOperationException("JSON格式不正确,需要键值对格式"); JObject jo = JObject.Parse(json); foreach (var prop in jo.Properties()) { DataRow dr = dt.NewRow(); dr["code"] = prop.Name; dr["name"] = prop.Value?.ToString() ?? ""; dt.Rows.Add(dr); } return dt; } /// /// 批量转换整个 DataTable /// public void TranslateDataTable(DataTable table, List mappings) { if (table == null || mappings == null || !mappings.Any()) return; // 验证列是否存在 foreach (var mapping in mappings) { if (!table.Columns.Contains(mapping.ColumnName)) throw new ArgumentException($"DataTable 中不存在列: {mapping.ColumnName}"); } // 遍历每一行 foreach (DataRow row in table.Rows) { foreach (var mapping in mappings) { var currentValue = row[mapping.ColumnName]?.ToString(); if (string.IsNullOrEmpty(currentValue)) continue; var chinese = GetChineseName(mapping.DicType, currentValue); row[mapping.ColumnName] = chinese; } } } /// /// 设置ComboBox的数据源为指定字典的DataTable /// /// ComboBox控件(支持System.Windows.Forms.ComboBox和Sunny.UI.UIComboBox) /// 字典名称(不含.json后缀) /// 是否插入空选项 public void SetComboxDatasource(object comboBox, string dicName, bool insertEmptyOption = false) { if (comboBox == null) throw new ArgumentNullException(nameof(comboBox)); if (string.IsNullOrEmpty(dicName)) throw new ArgumentNullException(nameof(dicName)); DataTable dt = JsonFileToDataTable(dicName); if (insertEmptyOption) { DataRow dr = dt.NewRow(); dr["code"] = ""; dr["name"] = "请选择"; dt.Rows.InsertAt(dr, 0); } // 使用dynamic避免类型转换问题 dynamic cb = comboBox; cb.DataSource = dt; cb.DisplayMember = "name"; cb.ValueMember = "code"; } } public class ColumnDictMapping { /// /// DataTable 中的列名 /// public string ColumnName { get; set; } /// /// 对应的字典类型 /// public string DicType { get; set; } } public class DictItem { [JsonProperty("code")] public string Code { get; set; } [JsonProperty("name")] public string Name { get; set; } [JsonProperty("searchcode")] public string SearchCode { get; set; } } public class DictResponse { [JsonProperty("result")] public Result Result { get; set; } } public class Result { [JsonProperty("data")] public List Data { get; set; } } }