feat: 更新业务、控件及单据功能

This commit is contained in:
cyf
2026-08-10 09:59:46 +08:00
parent c07220bbf0
commit 000a69ce15
29 changed files with 919 additions and 359 deletions
+313 -28
View File
@@ -249,7 +249,10 @@ namespace Lskj.PubBill
/// 保存验证条件表
/// </summary>
public DataTable SaveCondTab = new DataTable();
/// <summary>
/// 明细对应字段(参数9中的明细sql对应的主表明细字段) Dictionary<sql中本身的字段名称, as 后对应明细的字段>
/// </summary>
public Dictionary<string, string> DetailMappingField = new Dictionary<string, string>();
public BillModule()
@@ -1363,7 +1366,11 @@ namespace Lskj.PubBill
if (!string.IsNullOrEmpty(this.SysModel.BillMasterSql))
{
// 处理单据明细数据
if (!this.SysModel.BillDetailSql.StartsWith("*")) this.AddMultiRowToGridView(BillImpl.GetDataTableResult(this.SysModel.BillDetailSql));
if (!this.SysModel.BillDetailSql.StartsWith("*"))
{
this.AddMultiRowToGridView(BillImpl.GetDataTableResult(this.SysModel.BillDetailSql));
this.DetailMappingField = GetFieldAliasMap(this.SysModel.BillDetailSql);
}
}
}
}
@@ -1378,7 +1385,16 @@ namespace Lskj.PubBill
BaseUserControl baseUserControl = ControlObj.FindControl("bom_rdm_tianshu");
if (baseUserControl != null)
{
int.TryParse(baseUserControl.EditText, out dayCount);
//int.TryParse(baseUserControl.EditText, out dayCount);
decimal value;
if (decimal.TryParse(baseUserControl.EditText, out value) &&
value == decimal.Truncate(value) &&
value > 0 &&
value <= int.MaxValue)
{
dayCount = (int)value;
}
}
if (dayCount <= 0)
{
@@ -1455,7 +1471,16 @@ namespace Lskj.PubBill
BaseUserControl baseUserControl = ControlObj.FindControl("bom_rdm_tianshu");
if (baseUserControl != null)
{
int.TryParse(baseUserControl.EditText, out dayCount);
//int.TryParse(baseUserControl.EditText, out dayCount);
decimal value;
if (decimal.TryParse(baseUserControl.EditText, out value) &&
value == decimal.Truncate(value) &&
value > 0 &&
value <= int.MaxValue)
{
dayCount = (int)value;
}
}
if (dayCount <= 0)
{
@@ -4607,6 +4632,9 @@ namespace Lskj.PubBill
int position = this.gcMain.GridView.FocusedRowHandle;
bool isLastRow = this.gcMain.GridView.IsLastVisibleRow;
bool onlyOne = true;
dataTable = CreateDetailMappingTable(dataTable);
foreach (DataRow rowItem in dataTable.Rows)
{
if (unionModel == null || ValidateDetailCond(rowItem, unionModel))
@@ -4615,18 +4643,6 @@ namespace Lskj.PubBill
AssociatedField = repeatProduct;
if ("1".Equals(this.BillModel.DetailDoubleClickTip) && this.gcMain.GridView.Columns[repeatProduct] != null && dataTable.Columns.Contains(repeatProduct))
{
// 需要提示编码重复
//GridView view = this.gcMain.GridView;
//bool result = (view.LocateByValue(repeatProduct, rowItem[repeatProduct], null) >= 0) |
// (view.LocateByValue(repeatProduct, rowItem[repeatProduct], null) >= 0) |
// (view.LocateByValue(repeatProduct, rowItem[repeatProduct], null) >= 0) |
// (view.LocateByValue(repeatProduct, rowItem[repeatProduct], null) >= 0);
//if (result)
//{
// DialogResult dialog = MessageUtil.Show(ResourceKeys.ProductIsRepet, MessageBoxButtons.YesNo);
// if (dialog != DialogResult.Yes)
// return;
//}
//上面方法无法处理大小写,改成搜索的形式
DataTable dt = this.gcMain.gridControl.DataSourceTable();
@@ -4732,22 +4748,13 @@ namespace Lskj.PubBill
{
// 插入数据行
gridTable.Rows.InsertAt(newRow, position);
//this.gcMain.GridView.ClearSelection();
//this.gcMain.GridView.SelectRowHandler(position);
}
else
{
// 添加数据行
gridTable.Rows.Add(newRow);
// this.gcMain.GridView.ClearSelection();
// this.gcMain.GridView.SelectRowHandler(gridTable.Rows.Count - 1);
}
position++;
//if (isLastRow)
//{
// this.gcMain.GridView.ClearSelection();
// this.gcMain.GridView.SelectRowHandler(position + 1);
//}
if (!string.IsNullOrEmpty(NumberMc) && gridTable.Columns.Contains(mRecordPrimaryField))
{
DataRow[] rt = gridTable.Rows.Cast<DataRow>().Where(x => (newRow[BillModel.DetailPreFix + "ProductId"] + "").Equals(x[BillModel.DetailPreFix + "ProductId"] + "") && !string.IsNullOrEmpty(x[mRecordPrimaryField] + "")).ToArray();
@@ -4906,13 +4913,18 @@ namespace Lskj.PubBill
if (unionModel != null)
{
bool onlyOne = true;
DataRow[] mappingRows = CreateDetailMappingRows(rowItems);
for (int i = 0; i < rowItems.Length; i++)
{
DataRow rowItem = rowItems[i]; //unionModel.GridDetailControlObj.GridView.GetDataRow(selectedRows[i]);
DataRow mappingRow = mappingRows[i];
// 检查当前记录是否满足条件
if (ValidateDetailCond(rowItem, unionModel))
{
this.AddRowToGridView(rowItem);
this.AddRowToGridView(mappingRow);
if (!string.IsNullOrWhiteSpace(this.BillModel.ChangeColColor))
{
if (rowItem.Table.Columns.Contains(this.BillModel.ChangeColColor))
@@ -6502,7 +6514,15 @@ namespace Lskj.PubBill
BaseUserControl baseUserControl = ControlObj.FindControl("bom_rdm_tianshu");
if (baseUserControl != null)
{
int.TryParse(baseUserControl.EditText, out dayCount);
decimal value;
if (decimal.TryParse(baseUserControl.EditText, out value) &&
value == decimal.Truncate(value) &&
value > 0 &&
value <= int.MaxValue)
{
dayCount = (int)value;
}
}
if (dayCount <= 0)
{
@@ -9698,7 +9718,8 @@ namespace Lskj.PubBill
try
{
if (string.IsNullOrWhiteSpace(cond)) return true;//如果值是空格或者空行,默认正确
cond = ReplaceHelper.ReplaceRowParam(dataRow, cond);
//cond = ReplaceHelper.ReplaceRowParam(dataRow, cond);
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(dataRow, cond);
if (cond.StartsWith("@") || cond.StartsWith("!"))
{
result = "1".Equals(BaseImpl.GetDefaultValue(cond));
@@ -10472,5 +10493,269 @@ namespace Lskj.PubBill
/// <summary>
/// 获取明细sql对应的字段
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public static Dictionary<string, string> GetFieldAliasMap(string sql)
{
Dictionary<string, string> result =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
try
{
if (string.IsNullOrWhiteSpace(sql))
return result;
string cleanSql = Regex.Replace(
sql,
@"/\*.*?\*/|--[^\r\n]*",
string.Empty,
RegexOptions.Singleline);
Match selectMatch = Regex.Match(
cleanSql,
@"\bSELECT\b(?<columns>.*?)\bFROM\b",
RegexOptions.IgnoreCase | RegexOptions.Singleline);
if (!selectMatch.Success)
return result;
string columns = selectMatch.Groups["columns"].Value;
const string identifier =
@"(?:\[[^\]]+\]|""[^""]+""|[\p{L}_@#][\p{L}\p{N}_@$#]*)";
string pattern =
@"(?:^|,)\s*" +
@"(?:(?:" + identifier + @")\s*\.\s*)*" +
@"(?<field>" + identifier + @")\s+" +
@"AS\s+" +
@"(?<alias>" + identifier + @")\s*" +
@"(?=,|$)";
MatchCollection matches = Regex.Matches(
columns,
pattern,
RegexOptions.IgnoreCase | RegexOptions.Multiline);
foreach (Match match in matches)
{
try
{
string fieldName = UnwrapSqlIdentifier(
match.Groups["field"].Value);
string aliasName = UnwrapSqlIdentifier(
match.Groups["alias"].Value);
if (string.IsNullOrWhiteSpace(fieldName) ||
string.IsNullOrWhiteSpace(aliasName))
{
continue;
}
// 相同字段重复配置时,以最后一个别名为准。
result[fieldName] = aliasName;
}
catch (Exception ex)
{
LogHelper.Instance.WriteError(ex);
continue;
}
}
}
catch (Exception ex)
{
LogHelper.Instance.WriteError(ex);
}
return result;
}
/// <summary>
/// 获取明细sql对应的字段
/// </summary>
private static string UnwrapSqlIdentifier(string value)
{
value = (value ?? string.Empty).Trim();
if (value.Length >= 2 &&
value[0] == '[' &&
value[value.Length - 1] == ']')
{
return value.Substring(1, value.Length - 2)
.Replace("]]", "]");
}
if (value.Length >= 2 &&
value[0] == '"' &&
value[value.Length - 1] == '"')
{
return value.Substring(1, value.Length - 2)
.Replace("\"\"", "\"");
}
return value;
}
/// <summary>
/// 根据参数9的字段映射转换DataTable。
/// 保留原字段,并添加AS后的目标字段。
/// </summary>
private DataTable CreateDetailMappingTable(DataTable sourceTable)
{
if (sourceTable == null ||
DetailMappingField == null ||
DetailMappingField.Count == 0)
{
return sourceTable;
}
DataTable result;
try
{
result = sourceTable.Copy();
}
catch (Exception ex)
{
LogHelper.Instance.WriteError(ex);
return sourceTable;
}
foreach (KeyValuePair<string, string> mapping in DetailMappingField)
{
try
{
string sourceField = mapping.Key;
string targetField = mapping.Value;
if (string.IsNullOrWhiteSpace(sourceField) ||
string.IsNullOrWhiteSpace(targetField) ||
sourceField.Equals(targetField, StringComparison.OrdinalIgnoreCase))
{
continue;
}
if (!result.Columns.Contains(sourceField))
continue;
// 已经存在目标字段时保留原值,兼容原来的SQL配置。
if (result.Columns.Contains(targetField))
continue;
DataColumn sourceColumn = result.Columns[sourceField];
result.Columns.Add(targetField, sourceColumn.DataType);
foreach (DataRow row in result.Rows)
{
try
{
if (row.RowState != DataRowState.Deleted)
row[targetField] = row[sourceField];
}
catch (Exception ex)
{
LogHelper.Instance.WriteError(ex);
}
}
}
catch (Exception ex)
{
LogHelper.Instance.WriteError(ex);
}
}
return result;
}
/// <summary>
/// 根据参数9的字段映射转换选中的DataRow数组。
/// 返回的行是临时副本,原始行仍用于变色、删除等来源操作。
/// </summary>
private DataRow[] CreateDetailMappingRows(DataRow[] sourceRows)
{
if (sourceRows == null ||
sourceRows.Length == 0 ||
DetailMappingField == null ||
DetailMappingField.Count == 0)
{
return sourceRows;
}
DataRow[] result = new DataRow[sourceRows.Length];
try
{
DataRow schemaRow = sourceRows.FirstOrDefault(
row => row != null && row.Table != null);
if (schemaRow == null)
return result;
DataTable temporaryTable = schemaRow.Table.Clone();
List<int> sourceIndexes = new List<int>();
for (int i = 0; i < sourceRows.Length; i++)
{
DataRow sourceRow = sourceRows[i];
if (sourceRow == null ||
sourceRow.Table == null ||
sourceRow.RowState == DataRowState.Deleted ||
sourceRow.RowState == DataRowState.Detached)
{
continue;
}
try
{
DataRow newRow = temporaryTable.NewRow();
foreach (DataColumn column in temporaryTable.Columns)
{
try
{
if (sourceRow.Table.Columns.Contains(column.ColumnName))
newRow[column.ColumnName] = sourceRow[column.ColumnName];
}
catch (Exception ex)
{
LogHelper.Instance.WriteError(ex);
}
}
temporaryTable.Rows.Add(newRow);
sourceIndexes.Add(i);
}
catch (Exception ex)
{
LogHelper.Instance.WriteError(ex);
}
}
DataTable mappingTable = CreateDetailMappingTable(temporaryTable);
for (int i = 0; i < mappingTable.Rows.Count &&
i < sourceIndexes.Count; i++)
{
result[sourceIndexes[i]] = mappingTable.Rows[i];
}
}
catch (Exception ex)
{
LogHelper.Instance.WriteError(ex);
}
return result;
}
}
}