using Newtonsoft.Json.Linq; using NPOI.SS.UserModel; using PTMedicalInsurance.CardReaders; using PTMedicalInsurance.Common; using PTMedicalInsurance.Forms; using PTMedicalInsurance.Helper; using PTMedicalInsurance.Variables; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace PTMedicalInsurance.Forms { public partial class ChooseCardNew : Form { #region Windows API [DllImport("user32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll")] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll")] private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); private const int SW_MINIMIZE = 6; private const int SW_RESTORE = 9; private const int SW_SHOW = 5; private const int WM_SYSCOMMAND = 0x0112; private const int SC_MINIMIZE = 0xF020; private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); private static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); private const uint SWP_NOMOVE = 0x0002; private const uint SWP_NOSIZE = 0x0001; private const uint SWP_SHOWWINDOW = 0x0040; #endregion #region 属性定义 /// /// 证件类型:01 医保电子凭证 02 居民身份证 03 社会保障卡 05 终端扫脸 /// public string CertType { get; set; } /// /// 证件号码 /// public string CertNo { get; set; } /// /// 业务类型编码 /// public string BusinessType { get; set; } /// /// 是否工伤 /// public bool IsWorkInjury { get; set; } /// /// 读卡Invoker /// private readonly InvokeHelper _invoker = new InvokeHelper(); #endregion public ChooseCardNew() { InitializeComponent(); } private void ChooseCardNew_Load(object sender, EventArgs e) { // 初始化默认选项 rbSocialCard.Checked = true; rbMedicalInsurance.Checked = true; // 初始化患者信息表格 InitPatientInfoGrid(); InitBusinessType(); InitCertType(); // 初始化无卡结算控件状态 cbxNoCardTag_CheckedChanged(null, null); } private void InitBusinessType() { // 使用字典初始化业务类型 DictionaryHelper dicHelper = new DictionaryHelper(); dicHelper.SetComboxDatasource(cbBusinessType, "business_type"); } private void InitCertType() { // 使用字典初始化证件类型 DictionaryHelper dicHelper = new DictionaryHelper(); dicHelper.SetComboxDatasource(cbCertType, "psn_cert_type"); } /// /// 初始化患者信息表格(多行选择模式) /// private void InitPatientInfoGrid() { dgvPatientInfo.Columns.Clear(); dgvPatientInfo.Columns.Add("psnName", "姓名"); dgvPatientInfo.Columns.Add("gend", "性别"); dgvPatientInfo.Columns.Add("certno", "身份证号"); dgvPatientInfo.Columns.Add("psnNo", "人员编号"); dgvPatientInfo.Columns.Add("insuplcAdmdvs", "参保地"); dgvPatientInfo.Columns.Add("psnType", "人员类别"); // 设置列宽 dgvPatientInfo.Columns["psnName"].Width = 100; dgvPatientInfo.Columns["gend"].Width = 60; dgvPatientInfo.Columns["certno"].Width = 180; dgvPatientInfo.Columns["psnNo"].Width = 150; dgvPatientInfo.Columns["insuplcAdmdvs"].Width = 150; dgvPatientInfo.Columns["psnType"].Width = 100; // 设置表格属性 dgvPatientInfo.AllowUserToAddRows = false; dgvPatientInfo.AllowUserToDeleteRows = false; dgvPatientInfo.RowHeadersVisible = false; dgvPatientInfo.SelectionMode = DataGridViewSelectionMode.FullRowSelect; dgvPatientInfo.MultiSelect = false; dgvPatientInfo.ReadOnly = true; dgvPatientInfo.BackgroundColor = System.Drawing.Color.White; dgvPatientInfo.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; dgvPatientInfo.RowTemplate.Height = 35; } private void dgvPatientInfo_ColumnAdded(object sender, DataGridViewColumnEventArgs e) { e.Column.SortMode = DataGridViewColumnSortMode.NotSortable; } #region 读卡按钮事件 /// /// 读卡按钮 - 根据选择的证件类型读取 /// private void btnReadCard_Click(object sender, EventArgs e) { // 根据选择的证件类型确定证件类型码 string readType; if (rbSocialCard.Checked) { // 社会保障卡 Global.pat.mdtrtcertType = "03"; readType = "社会保障卡"; } else if (rbIDCard.Checked) { // 居民身份证 Global.pat.mdtrtcertType = "02"; readType = "居民身份证"; } else if (rbECToken.Checked) { // 医保电子凭证 Global.pat.mdtrtcertType = "01"; readType = "医保电子凭证"; } else if (rbFace.Checked) { // 终端扫脸 Global.pat.mdtrtcertType = "05"; readType = "终端扫脸"; } else { MessageBox.Show("请先选择证件类型!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 根据证件类型调用读卡 ReadCard(Global.pat.mdtrtcertType, "1001", readType); } /// /// 修改密码 /// private void btnPasswordModify_Click(object sender, EventArgs e) { try { string errorMsg = ""; string sInput = JsonHelper.setCenterInpar("1193", ""); JObject joRtn = _invoker.invokeCenterService("1193", sInput); if (JsonHelper.parseCenterRtnValue(joRtn, out errorMsg) != 0) { MessageBox.Show("修改卡密码失败:" + errorMsg, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { MessageBox.Show("修改卡密码成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (Exception ex) { MessageBox.Show("修改密码失败:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion #region 读卡核心方法 /// /// 读卡并获取信息 /// /// 证件类型 /// 交易码 /// 读卡类型描述 private void ReadCard(string certType, string tradeCode, string readType) { // 先禁用读卡按钮,防止重复点击 btnReadCard.Enabled = false; btnReadCard.Text = "读卡中..."; CertType = certType; // 根据证件类型选择不同的读卡方式 switch (certType) { case "01": case "02": case "03": // 电子凭证、身份证、社保卡:都走COM组件调用方式 ReadSocialCardNewTwo(certType); break; case "05": // 扫脸:使用 CardReader.FaceRecognition ReadFaceCard(); break; default: MessageBox.Show("不支持的证件类型!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); btnReadCard.Enabled = true; btnReadCard.Text = "读 卡"; break; } } /// /// 读取社保卡(使用COM控件) /// /// 证件类型:01电子凭证 02身份证 03社保卡 private void ReadSocialCard(string certType) { // 在后台线程执行COM控件调用,避免阻塞UI Task.Run(() => { try { string errorMsg = ""; // 从UI控件获取参数值(需要Invoke确保线程安全) string certNo = ""; string certTypeCode = ""; string betaFlag = ""; string noCardTag = ""; this.Invoke(new Action(() => { certNo = txtCertNo.Text.Trim(); certTypeCode = cbCertType.SelectedValue?.ToString() ?? ""; // 如果用户勾选了无卡结算,使用用户选择;否则根据证件类型自动判断 if (cbxNoCardTag.Checked) { noCardTag = "1"; } else { // 根据证件类型设置 no_card_tag // 01-电子凭证 02-身份证 03-社保卡 switch (certType) { case "01": noCardTag = "1"; break; case "02": noCardTag = "2"; break; default: noCardTag = ""; break; } } })); // COM控件调用需要在STA线程 string input = "{" + "\"begntime\": \"\"," + "\"no_card_tag\": \"" + noCardTag + "\"," + "\"certno\": \"" + certNo + "\"," + "\"psn_cert_typ\": \"" + certTypeCode + "\"," + "\"beta_flag\": \"" + betaFlag + "\"," + "\"cro_prov_flag\": \"\"" + "}"; int result = -1; InvokeComCenter2026 carder = new InvokeComCenter2026(); // 获取当前窗口句柄 IntPtr thisHandle = this.Handle; // 使用 STA 线程调用 COM 控件 Thread staThread = new Thread(() => { // 先将当前窗口最小化(使用 SendMessage 避免焦点问题) SendMessage(thisHandle, WM_SYSCOMMAND, (IntPtr)SC_MINIMIZE, IntPtr.Zero); // 等待最小化完成 Thread.Sleep(200); // 调用读卡 result = carder.Business("1001", ref input, ref errorMsg); // 读卡完成后恢复窗口 ShowWindow(thisHandle, SW_RESTORE); SetWindowPos(thisHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); }); staThread.SetApartmentState(ApartmentState.STA); staThread.Start(); staThread.Join(); // 回到UI线程更新界面 this.Invoke(new Action(() => { // 取消置顶 SetWindowPos(thisHandle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); this.BringToFront(); this.Activate(); btnReadCard.Enabled = true; btnReadCard.Text = "读 卡"; if (result != 0) { MessageBox.Show("读社保卡失败:" + errorMsg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 更新界面上的单选按钮 UpdateRadioButton(CertType); // 解析1001返回的多行数据 JObject joRtn = JObject.Parse(errorMsg); ParseAndShowPatientList(joRtn); })); } catch (Exception ex) { this.Invoke(new Action(() => { // 恢复窗口 ShowWindow(this.Handle, SW_RESTORE); this.BringToFront(); btnReadCard.Enabled = true; btnReadCard.Text = "读 卡"; MessageBox.Show("读社保卡失败:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); })); } }); } /// /// 读取社保卡(使用COM控件,支持CEF环境模态效果) /// 签名与ReadSocialCard相同 /// /// 证件类型:01电子凭证 02身份证 03社保卡 private void ReadSocialCardNew(string certType) { // 获取CEF Browser窗口句柄并禁用 IntPtr cefHwnd = IntPtr.Zero; try { cefHwnd = WinApi.GetWindowsHandle("prBrowser"); Global.writeLog("ReadSocialCardNew", "1-获取CEF窗口", $"hwnd={cefHwnd}"); } catch (Exception ex) { Global.writeLog("ReadSocialCardNew", "1-获取CEF窗口失败", ex.Message); } // 禁用CEF Browser窗口 if (cefHwnd != IntPtr.Zero) { WinApi.EnableWindow(cefHwnd, false); Global.writeLog("ReadSocialCardNew", "2-禁用CEF窗口", $"Enabled={WinApi.IsWindowEnabled(cefHwnd)}"); } // 禁用当前窗口 this.Enabled = false; Global.writeLog("ReadSocialCardNew", "3-禁用当前窗口", $"this.Enabled={this.Enabled}"); // 将当前窗口置顶并激活(确保COM窗口在它前面弹出) this.TopMost = true; this.BringToFront(); this.Activate(); Application.DoEvents(); Thread.Sleep(100); Global.writeLog("ReadSocialCardNew", "4-置顶当前窗口", $"hwnd={this.Handle}"); this.TopMost = false; // 临时置顶后立即取消,让COM窗口有机会置顶 // 在后台线程执行COM控件调用 Task.Run(() => { try { string errorMsg = ""; Global.writeLog("ReadSocialCardNew", "5-后台线程开始", ""); // 从UI控件获取参数值(需要Invoke确保线程安全) string certNo = ""; string certTypeCode = ""; string betaFlag = ""; string noCardTag = ""; this.Invoke(new Action(() => { certNo = txtCertNo.Text.Trim(); certTypeCode = cbCertType.SelectedValue?.ToString() ?? ""; if (cbxNoCardTag.Checked) { noCardTag = "1"; } else { switch (certType) { case "01": noCardTag = "1"; break; case "02": noCardTag = "2"; break; default: noCardTag = ""; break; } } })); // COM控件调用需要在STA线程 string input = "{" + "\"begntime\": \"\"," + "\"no_card_tag\": \"" + noCardTag + "\"," + "\"certno\": \"" + certNo + "\"," + "\"psn_cert_typ\": \"" + certTypeCode + "\"," + "\"beta_flag\": \"" + betaFlag + "\"," + "\"cro_prov_flag\": \"\"" + "}"; int result = -1; InvokeComCenter2026 carder = new InvokeComCenter2026(); // 使用 STA 线程调用 COM 控件 Global.writeLog("ReadSocialCardNew", "6-准备启动STA线程", input); Thread staThread = new Thread(() => { Global.writeLog("ReadSocialCardNew", "7-STA线程开始", ""); // 调用读卡 result = carder.Business("1001", ref input, ref errorMsg); Global.writeLog("ReadSocialCardNew", "8-读卡完成", $"result={result}"); }); staThread.SetApartmentState(ApartmentState.STA); staThread.Start(); staThread.Join(); Global.writeLog("ReadSocialCardNew", "9-后台线程结束", ""); // 回到UI线程更新界面 this.Invoke(new Action(() => { Global.writeLog("ReadSocialCardNew", "10-恢复窗口", ""); // 恢复CEF Browser窗口 if (cefHwnd != IntPtr.Zero) { WinApi.EnableWindow(cefHwnd, true); Global.writeLog("ReadSocialCardNew", "11-CEF窗口已恢复", $"Enabled={WinApi.IsWindowEnabled(cefHwnd)}"); } // 恢复当前窗口 this.Enabled = true; this.BringToFront(); this.Activate(); btnReadCard.Enabled = true; btnReadCard.Text = "读 卡"; if (result != 0) { MessageBox.Show("读社保卡失败:" + errorMsg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 更新界面上的单选按钮 UpdateRadioButton(CertType); // 解析1001返回的多行数据 JObject joRtn = JObject.Parse(errorMsg); ParseAndShowPatientList(joRtn); })); } catch (Exception ex) { this.Invoke(new Action(() => { // 恢复CEF Browser窗口 if (cefHwnd != IntPtr.Zero) { WinApi.EnableWindow(cefHwnd, true); } // 恢复当前窗口 this.Enabled = true; this.BringToFront(); btnReadCard.Enabled = true; btnReadCard.Text = "读 卡"; MessageBox.Show("读社保卡失败:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); })); } }); } /// /// 读取社保卡(方法二:找到COM窗口并置顶) /// /// 证件类型 private void ReadSocialCardNewTwo(string certType) { // 获取CEF Browser窗口句柄并禁用 IntPtr cefHwnd = IntPtr.Zero; try { cefHwnd = WinApi.GetWindowsHandle("prBrowser"); Global.writeLog("ReadSocialCardNewTwo", "1-获取CEF窗口", $"hwnd={cefHwnd}"); } catch (Exception ex) { Global.writeLog("ReadSocialCardNewTwo", "1-获取CEF窗口失败", ex.Message); } // 禁用CEF Browser窗口 if (cefHwnd != IntPtr.Zero) { WinApi.EnableWindow(cefHwnd, false); Global.writeLog("ReadSocialCardNewTwo", "2-禁用CEF窗口", ""); } // 禁用当前窗口 this.Enabled = false; Global.writeLog("ReadSocialCardNewTwo", "3-禁用当前窗口", ""); // 给系统时间完成禁用操作 Application.DoEvents(); Thread.Sleep(100); Global.writeLog("ReadSocialCardNewTwo", "4-准备调用COM", ""); // 在后台线程执行COM控件调用 Task.Run(() => { try { string errorMsg = ""; Global.writeLog("ReadSocialCardNewTwo", "5-后台线程开始", ""); // 从UI控件获取参数值 string certNo = ""; string certTypeCode = ""; string betaFlag = ""; string noCardTag = ""; this.Invoke(new Action(() => { certNo = txtCertNo.Text.Trim(); certTypeCode = cbCertType.SelectedValue?.ToString() ?? ""; if (cbxNoCardTag.Checked) { noCardTag = "1"; } else { switch (certType) { case "01": noCardTag = "1"; break; case "02": noCardTag = "2"; break; default: noCardTag = ""; break; } } })); string input = "{" + "\"begntime\": \"\"," + "\"no_card_tag\": \"" + noCardTag + "\"," + "\"certno\": \"" + certNo + "\"," + "\"psn_cert_typ\": \"" + certTypeCode + "\"," + "\"beta_flag\": \"" + betaFlag + "\"," + "\"cro_prov_flag\": \"\"" + "}"; int result = -1; InvokeComCenter2026 carder = new InvokeComCenter2026(); // 使用 STA 线程调用 COM 控件 Thread staThread = new Thread(() => { Global.writeLog("ReadSocialCardNewTwo", "6-STA线程开始", "开始调用COM"); // 在单独的线程中循环查找并置顶COM窗口(枚举所有窗口) Thread searchThread = new Thread(() => { int count = 0; while (count < 50) // 最多等待5秒 { IntPtr comHwnd = WinApi.FindAndSetTopComWindowAll(this.Handle); if (comHwnd != IntPtr.Zero) { string comTitle = WinApi.GetComWindowTitle(); Global.writeLog("ReadSocialCardNewTwo", "6.5-找到COM窗口", $"hwnd={comHwnd}, 窗口标题={comTitle}"); break; } Thread.Sleep(100); count++; } if (count >= 50) { Global.writeLog("ReadSocialCardNewTwo", "6.5-未找到COM窗口", "超时未找到"); } }); searchThread.IsBackground = true; searchThread.Start(); // 调用读卡 result = carder.Business("1001", ref input, ref errorMsg); Global.writeLog("ReadSocialCardNewTwo", "7-读卡完成", $"result={result}"); }); staThread.SetApartmentState(ApartmentState.STA); staThread.Start(); staThread.Join(); Global.writeLog("ReadSocialCardNewTwo", "8-后台线程结束", ""); // 回到UI线程更新界面 this.Invoke(new Action(() => { Global.writeLog("ReadSocialCardNewTwo", "9-恢复窗口", ""); // 恢复CEF Browser窗口 if (cefHwnd != IntPtr.Zero) { WinApi.EnableWindow(cefHwnd, true); Global.writeLog("ReadSocialCardNewTwo", "10-CEF窗口已恢复", ""); } // 恢复当前窗口 this.Enabled = true; this.BringToFront(); this.Activate(); btnReadCard.Enabled = true; btnReadCard.Text = "读 卡"; if (result != 0) { MessageBox.Show("读社保卡失败:" + errorMsg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } UpdateRadioButton(CertType); JObject joRtn = JObject.Parse(errorMsg); ParseAndShowPatientList(joRtn); })); } catch (Exception ex) { this.Invoke(new Action(() => { if (cefHwnd != IntPtr.Zero) { WinApi.EnableWindow(cefHwnd, true); } this.Enabled = true; this.BringToFront(); btnReadCard.Enabled = true; btnReadCard.Text = "读 卡"; MessageBox.Show("读社保卡失败:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); })); } }); } /// /// 读取扫脸 /// private void ReadFaceCard() { try { CardReader reader = new CardReader(); string msg; int result = reader.FaceRecognition(out msg); btnReadCard.Enabled = true; btnReadCard.Text = "读 卡"; if (result != 0) { MessageBox.Show("人脸识别失败:" + msg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 解析人脸识别返回的JSON数据 JObject joRtn = JObject.Parse(msg); string code = JsonHelper.getDestValue(joRtn, "code"); if (code != "0") { string errorMsg = JsonHelper.getDestValue(joRtn, "message"); MessageBox.Show("人脸识别失败:" + errorMsg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 获取 data 对象 JObject dataObj = joRtn.SelectToken("data") as JObject; if (dataObj == null) { MessageBox.Show("未获取到人脸识别数据!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 提取关键信息 string userName = JsonHelper.getDestValue(dataObj, "userName"); string idNo = JsonHelper.getDestValue(dataObj, "idNo"); string idType = JsonHelper.getDestValue(dataObj, "idType"); string insuOrg = JsonHelper.getDestValue(dataObj, "insuOrg"); string ecToken = JsonHelper.getDestValue(dataObj, "ecToken"); string birthday = JsonHelper.getDestValue(dataObj, "birthday"); string gender = JsonHelper.getDestValue(dataObj, "gender"); // 清空现有数据 dgvPatientInfo.DataSource = null; dgvPatientInfo.Rows.Clear(); dgvPatientInfo.Columns.Clear(); InitPatientInfoGrid(); // 添加人脸识别数据到表格(只显示单条) int rowIndex = dgvPatientInfo.Rows.Add(userName, gender, idNo, "", insuOrg, ""); // 保存原始数据到行标签 JObject rowData = new JObject(); rowData.Add("userName", userName); rowData.Add("idNo", idNo); rowData.Add("idType", idType); rowData.Add("insuOrg", insuOrg); rowData.Add("ecToken", ecToken); rowData.Add("birthday", birthday); rowData.Add("gender", gender); rowData.Add("certType", "05"); // 扫脸类型 dgvPatientInfo.Rows[rowIndex].Tag = rowData; // 设置证件类型 CertType = "05"; // 更新单选按钮 rbFace.Checked = true; MessageBox.Show("人脸识别成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { btnReadCard.Enabled = true; btnReadCard.Text = "读 卡"; MessageBox.Show("人脸识别失败:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// /// 解析并显示患者列表(多行) /// private void ParseAndShowPatientList(JObject joRtn) { try { // 清空现有数据 dgvPatientInfo.DataSource = null; dgvPatientInfo.Rows.Clear(); // 获取返回代码 string rtnCode = JsonHelper.getDestValue(joRtn, "code"); string message = JsonHelper.getDestValue(joRtn, "message"); // 检查返回状态 if (rtnCode != "1" && rtnCode != "0") { MessageBox.Show("读卡失败:" + message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 获取 data 对象 JObject dataObj = joRtn.SelectToken("data") as JObject; if (dataObj == null) { MessageBox.Show("未获取到数据!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 获取基本信息 string certno = JsonHelper.getDestValue(dataObj, "certno"); string psnName = JsonHelper.getDestValue(dataObj, "psn_name"); string insuinfoCnt = JsonHelper.getDestValue(dataObj, "insuinfo_cnt"); string cardSn = JsonHelper.getDestValue(dataObj, "card_sn"); // 获取参保信息列表(insuinfo) JArray insuinfoList = dataObj.SelectToken("insuinfo") as JArray; if (insuinfoList == null || insuinfoList.Count == 0) { MessageBox.Show("未获取到参保信息!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 清除现有列并重新设置 dgvPatientInfo.Columns.Clear(); InitPatientInfoGrid(); // 填充数据 - 根据实际的JSON字段名 foreach (JObject insuinfo in insuinfoList) { string insuplcAdmdvs = JsonHelper.getDestValue(insuinfo, "insuplc_admdvs"); string insuplcAdmdvsName = JsonHelper.getDestValue(insuinfo, "insuplc_admdvs_name"); string psnType = JsonHelper.getDestValue(insuinfo, "psn_type"); string psnNo = JsonHelper.getDestValue(insuinfo, "psn_insu_rlts_id"); string empName = JsonHelper.getDestValue(insuinfo, "emp_name"); // 合并参保地和名称 string insuplcFull = string.IsNullOrEmpty(insuplcAdmdvsName) ? insuplcAdmdvs : insuplcAdmdvs + " " + insuplcAdmdvsName; int rowIndex = dgvPatientInfo.Rows.Add(psnName, "", certno, psnNo, insuplcFull, psnType); // 保存原始数据到行标签 JObject rowData = new JObject(); rowData.Add("psn_name", psnName); rowData.Add("certno", certno); rowData.Add("card_sn", cardSn); rowData.Add("insuplc_admdvs", insuplcAdmdvs); rowData.Add("insuplc_admdvs_name", insuplcAdmdvsName); rowData.Add("psn_type", psnType); rowData.Add("psn_no", psnNo); rowData.Add("emp_name", empName); rowData.Add("insuinfo", insuinfo); rowData.Add("data", dataObj); dgvPatientInfo.Rows[rowIndex].Tag = rowData; } // 如果只有一条记录,自动选中 if (dgvPatientInfo.Rows.Count == 1) { dgvPatientInfo.Rows[0].Selected = true; SelectPatientAndFillInfo(0); } } catch (Exception ex) { MessageBox.Show("解析患者列表失败:" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// /// 选中患者并填充信息到全局变量 /// private void SelectPatientAndFillInfo(int rowIndex) { if (rowIndex < 0 || rowIndex >= dgvPatientInfo.Rows.Count) return; JObject item = dgvPatientInfo.Rows[rowIndex].Tag as JObject; if (item == null) return; // 根据证件类型选择不同的读卡方式 switch (CertType) { case "01": case "02": case "03": // 电子凭证、身份证、社保卡:都走COM组件调用方式 // 获取data对象(包含基础信息) JObject dataObj = item.SelectToken("data") as JObject; // 获取insuinfo对象(包含参保信息) JObject insuinfo = item.SelectToken("insuinfo") as JObject; // 填充基础信息 Global.pat.name = JsonHelper.getDestValue(item, "psn_name"); Global.pat.certNO = JsonHelper.getDestValue(item, "certno"); Global.pat.card.SN = JsonHelper.getDestValue(item, "card_sn"); Global.pat.card.NO = JsonHelper.getDestValue(item, "card_sn"); // 填充参保信息 Global.pat.insuplc_admdvs = JsonHelper.getDestValue(insuinfo, "insuplc_admdvs"); //Global.pat.psn_no = JsonHelper.getDestValue(insuinfo, "psn_insu_rlts_id"); // 填充证件类型(从data中获取) Global.pat.mdtrtcertType = JsonHelper.getDestValue(dataObj, "mdtrt_cert_type"); Global.pat.mdtrtcertNO = JsonHelper.getDestValue(dataObj, "mdtrt_cert_no"); Global.pat.certType = JsonHelper.getDestValue(dataObj, "psn_cert_type"); break; case "05": // 填充基础信息 Global.pat.name = JsonHelper.getDestValue(item, "userName"); Global.pat.certNO = JsonHelper.getDestValue(item, "idNo"); Global.pat.IDType = JsonHelper.getDestValue(item, "idType"); Global.pat.card.SN = ""; Global.pat.card.NO = ""; // 填充参保信息 Global.pat.insuplc_admdvs = JsonHelper.getDestValue(item, "insuOrg"); Global.pat.psn_no = ""; // 填充证件类型(从data中获取) Global.pat.mdtrtcertType = "05"; Global.pat.mdtrtcertNO = JsonHelper.getDestValue(item, "ecToken"); Global.pat.certType = JsonHelper.getDestValue(item, "idType"); break; default: MessageBox.Show("不支持的证件类型!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); break; } } /// /// 更新证件类型单选按钮 /// private void UpdateRadioButton(string certType) { switch (certType) { case "01": rbECToken.Checked = true; break; case "02": rbIDCard.Checked = true; break; case "03": rbSocialCard.Checked = true; break; case "05": rbFace.Checked = true; break; } } /// /// DataGridView行选择变化事件 /// private void dgvPatientInfo_SelectionChanged(object sender, EventArgs e) { if (dgvPatientInfo.SelectedRows.Count > 0) { int selectedIndex = dgvPatientInfo.SelectedRows[0].Index; SelectPatientAndFillInfo(selectedIndex); } } #endregion #region 确定取消按钮事件 /// /// 确定按钮 /// private void btnConfirm_Click(object sender, EventArgs e) { // 检查是否已选择患者 if (dgvPatientInfo.SelectedRows.Count == 0) { MessageBox.Show("请先读卡并选择患者信息!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 获取选中的患者信息 int selectedIndex = dgvPatientInfo.SelectedRows[0].Index; SelectPatientAndFillInfo(selectedIndex); // 获取业务类型编码(从ComboBox获取代码) if (cbBusinessType.SelectedItem != null) { DataRowView drv = cbBusinessType.SelectedItem as DataRowView; if (drv != null) { BusinessType = drv["code"].ToString(); } else { } } // 设置工伤标志 IsWorkInjury = rbWorkInjury.Checked; // 保存到全局变量 Global.pat.card.ecBizType = BusinessType; Global.pat.isWorkInjury = IsWorkInjury; this.DialogResult = DialogResult.OK; this.Close(); } /// /// 取消按钮 /// private void btnCancel_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.Cancel; this.Close(); } #endregion private void uiPanel5_Click(object sender, EventArgs e) { } private void rbFace_CheckedChanged(object sender, EventArgs e) { } private void cbxNoCardTag_CheckedChanged(object sender, EventArgs e) { // 根据无卡结算CheckBox状态控制证件号和证件类型控件的可用性 bool isEnabled = cbxNoCardTag.Checked; txtCertNo.Enabled = isEnabled; cbCertType.Enabled = isEnabled; Global.pat.isNoCardSettle = cbxNoCardTag.Checked; } private void dgvPatientInfo_CellContentClick(object sender, DataGridViewCellEventArgs e) { } } }