| | |
| | | // 获取当前明细行的GUID |
| | | Guid? _guid = UtilityHelper.ToGuid(row["guid"].ToString()); |
| | | // 添加明细项到请求对象 |
| | | // 说明: |
| | | // ① 旧逻辑使用 row["process"].ToString(),后台只要把列名改成 processName/gs003 或存在大小写差异,就会抛出 “Column 'process' does not belong to table” 异常; |
| | | // ② GetRowString 会在 DataTable 中按不区分大小写的方式逐个匹配候选列名,并把 DBNull/null 统一转换为空字符串,兼容不同接口与历史数据; |
| | | // ③ 字段列表提供多个候选值(process/processName/processDesc/processWay/gs003),确保后端字段命名调整时仍能成功保存。 |
| | | _obj.list.Add(new |
| | | { |
| | | Guid = _guid, |
| | | BatchQty = (row["batchQty"].ToString()), // 批次数量 |
| | | GfRkqty = (row["gfRkqty"].ToString()), // 合格入库数量 |
| | | LfRkqtyz = (row["lfRkqty"].ToString()), // 不合格入库数量 |
| | | HandResult = (row["handResult"].ToString()), // 选别类型 |
| | | ChooseType = (row["chooseType"].ToString()), // 处理意见 |
| | | Process = (row["process"].ToString()), // 退料方式 |
| | | |
| | | BatchQty = GetRowString(row, "batchQty"), // 批次数量 |
| | | GfRkqty = GetRowString(row, "gfRkqty"), // 合格入库数 |
| | | LfRkqtyz = GetRowString(row, "lfRkqty"), // 临放入库数 |
| | | HandResult = GetRowString(row, "handResult"), // 选别意见 |
| | | ChooseType = GetRowString(row, "chooseType"), // 异常类别 |
| | | Process = GetRowString(row, "process", "processName", "processDesc", "processWay", "gs003"), // 退料方式 |
| | | |
| | | }); |
| | | } |
| | | } |
| | |
| | | |
| | | // 将明细数据的JSON数组转换为DataTable(适合作为网格控件的数据源) |
| | | DataTable dt = JsonConvert.DeserializeObject<DataTable>(array.ToString()); |
| | | EnsureProcessColumn(dt); |
| | | |
| | | // 若明细数据存在(DataTable行数>0) |
| | | if (dt.Rows.Count > 0) |
| | |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// 统一封装 DataRow 字段读取逻辑:按照候选列名列表依次查找真实列,忽略大小写并规避 DBNull。 |
| | | /// </summary> |
| | | /// <param name="row">当前循环到的 DataRow,若为 null 直接返回空字符串。</param> |
| | | /// <param name="columnCandidates">按优先级排列的候选列名集合(例如 process/processName/gs003)。</param> |
| | | /// <returns>匹配到的列值;若所有候选列均不存在或值为 DBNull,则返回 string.Empty。</returns> |
| | | /// <remarks> |
| | | /// MesQcExceptional 的保存动作依赖该方法,以兼容后端接口字段改名或大小写差异,避免再次出现 “Column 'process' does not belong to table” 异常。 |
| | | /// </remarks> |
| | | private static string GetRowString(DataRow row, params string[] columnCandidates) |
| | | { |
| | | if (row == null || row.Table == null || columnCandidates == null) |
| | | return string.Empty; |
| | | |
| | | foreach (var candidate in columnCandidates) |
| | | { |
| | | if (string.IsNullOrEmpty(candidate)) |
| | | continue; |
| | | var match = FindMatchingColumn(row.Table, candidate); |
| | | if (!string.IsNullOrEmpty(match)) |
| | | return NormalizeValue(row[match]); |
| | | } |
| | | |
| | | return string.Empty; |
| | | } |
| | | |
| | | private static string FindMatchingColumn(DataTable table, string columnName) |
| | | { |
| | | if (table == null || string.IsNullOrEmpty(columnName)) |
| | | return null; |
| | | |
| | | foreach (DataColumn column in table.Columns) |
| | | { |
| | | if (string.Equals(column.ColumnName, columnName, StringComparison.OrdinalIgnoreCase)) |
| | | return column.ColumnName; |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | private static string FindFirstAvailableColumn(DataTable table, params string[] candidates) |
| | | { |
| | | if (table == null || candidates == null) |
| | | return null; |
| | | |
| | | foreach (var candidate in candidates) |
| | | { |
| | | var match = FindMatchingColumn(table, candidate); |
| | | if (!string.IsNullOrEmpty(match)) |
| | | return match; |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | private static bool HasColumnExact(DataTable table, string columnName) |
| | | { |
| | | if (table == null || string.IsNullOrEmpty(columnName)) |
| | | return false; |
| | | |
| | | foreach (DataColumn column in table.Columns) |
| | | { |
| | | if (string.Equals(column.ColumnName, columnName, StringComparison.Ordinal)) |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | private static void CopyColumn(DataTable table, string sourceColumnName, string targetColumnName) |
| | | { |
| | | if (table == null || string.IsNullOrEmpty(sourceColumnName) || string.IsNullOrEmpty(targetColumnName)) |
| | | return; |
| | | |
| | | if (!HasColumnExact(table, targetColumnName)) |
| | | table.Columns.Add(targetColumnName, typeof(string)); |
| | | |
| | | foreach (DataRow row in table.Rows) |
| | | { |
| | | row[targetColumnName] = NormalizeValue(row[sourceColumnName]); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 在绑定 gvMx1 明细前确保 DataTable 中存在名为 process 的列: |
| | | /// 1. 优先复用不区分大小写匹配到的同名列,保证 GridColumn23 的绑定不受影响; |
| | | /// 2. 若无同名列,则尝试使用常见别名(processName/processDesc/processWay/gs003)复制生成; |
| | | /// 3. 若仍无法定位有效列,则创建空的 process 列,避免前端访问时抛出列不存在异常。 |
| | | /// </summary> |
| | | /// <param name="table">接口返回的明细 DataTable。</param> |
| | | private static void EnsureProcessColumn(DataTable table) |
| | | { |
| | | if (table == null) |
| | | return; |
| | | |
| | | var existing = FindMatchingColumn(table, "process"); |
| | | if (!string.IsNullOrEmpty(existing)) |
| | | { |
| | | if (!HasColumnExact(table, "process")) |
| | | CopyColumn(table, existing, "process"); |
| | | return; |
| | | } |
| | | |
| | | var fallback = FindFirstAvailableColumn(table, "processName", "processDesc", "processWay", "gs003"); |
| | | if (string.IsNullOrEmpty(fallback)) |
| | | { |
| | | if (!HasColumnExact(table, "process")) |
| | | table.Columns.Add("process", typeof(string)); |
| | | return; |
| | | } |
| | | |
| | | CopyColumn(table, fallback, "process"); |
| | | } |
| | | |
| | | private static string NormalizeValue(object value) |
| | | { |
| | | return value == null || value == DBNull.Value ? string.Empty : value.ToString(); |
| | | } |
| | | /// <summary> |
| | | /// 工具条事件 |
| | | /// </summary> |
| | | /// <param name="inFieldValue"></param> |