283 lines
12 KiB
C#
283 lines
12 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using Lskj.Business;
|
||
using Lskj.Business.Impl;
|
||
using Lskj.Core;
|
||
using Lskj.Data;
|
||
|
||
namespace Lskj.Control.Model
|
||
{
|
||
/// <summary>
|
||
/// 审核改动日志处理类。
|
||
/// 用来比较单据主表原始数据和当前表头控件值,并把发生变化的字段写入 P_SystemAuditChangeLog。
|
||
/// </summary>
|
||
public class AuditChangeLog
|
||
{
|
||
private const string TableName = "P_SystemAuditChangeLog";
|
||
private const int MaxOrderNumberLength = 50;
|
||
private const int MaxTextLength = 500;
|
||
|
||
|
||
/// <summary>
|
||
/// 比较表头字段是否发生变化,并保存审核改动日志。
|
||
/// 返回 false 时,errorMessage 会一次性返回所有未记录成功的字段。
|
||
/// </summary>
|
||
/// <param name="drBillInfoMsg">改动前数据(单表数据或者单据主表数据)</param>
|
||
/// <param name="controlObj">控件 mycontrol</param>
|
||
/// <param name="orderNumber">单号</param>
|
||
/// <param name="stepCode">步骤号</param>
|
||
/// <param name="operatorId">登录人id</param>
|
||
/// <returns></returns>
|
||
public static bool SaveHeaderChangeLog(DataRow drBillInfoMsg, MyControl controlObj, string orderNumber, string stepCode, string operatorId)
|
||
{
|
||
if (SystemInfo.Instance.AuditChangeRecord)
|
||
{
|
||
CreateModificationRecordTable();
|
||
string errorMessage = string.Empty;
|
||
|
||
// 原始主表数据或控件对象为空时,没有可比较的数据,直接返回成功。
|
||
if (drBillInfoMsg == null || controlObj == null || controlObj.ControlModels == null)
|
||
return true;
|
||
|
||
List<string> errorFields = new List<string>();
|
||
|
||
// 遍历当前界面的表头控件模型,逐个比较可保存字段。
|
||
foreach (ControlModel model in controlObj.ControlModels)
|
||
{
|
||
string currentFieldName = model == null ? string.Empty : model.FieldName;
|
||
try
|
||
{
|
||
// 只比较可保存、界面真实存在、原始主表行中也存在的普通字段。
|
||
if (!CanCompare(model, drBillInfoMsg, controlObj))
|
||
continue;
|
||
|
||
// 旧值来自打开审核界面时加载出来的主表原始行。
|
||
string oldValue = GetRowValue(drBillInfoMsg, model.FieldName);
|
||
|
||
// 新值来自当前界面控件值,也就是用户修改后的值。
|
||
string newValue = controlObj.GetControlValue(model);
|
||
if (newValue == "****")
|
||
continue;
|
||
|
||
// 日期、数字、空值先做统一处理,避免显示格式不同造成误判。
|
||
if (IsSameValue(oldValue, newValue))
|
||
continue;
|
||
|
||
// 字段确实发生变化后写入日志;相同单号、步骤、字段已存在时执行更新。
|
||
SaveChangeLog(orderNumber, model.FieldName, oldValue, newValue, stepCode, operatorId);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 单个字段记录失败时先收集错误,继续处理后续字段,最后一次性提示。
|
||
errorFields.Add(GetErrorFieldName(model, currentFieldName) + "(" + ex.Message + ")");
|
||
}
|
||
}
|
||
|
||
if (errorFields.Count > 0)
|
||
{
|
||
errorMessage = "以下字段审核改动日志未记录:" + Environment.NewLine + string.Join(Environment.NewLine, errorFields.ToArray());
|
||
MessageUtil.Show(errorMessage);
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 判断控件字段是否需要参与改动比较。
|
||
/// </summary>
|
||
private static bool CanCompare(ControlModel model, DataRow drBillInfoMsg, MyControl controlObj)
|
||
{
|
||
if (model == null)
|
||
return false;
|
||
|
||
// 不保存的字段和图片控件不参与本次表头改动日志记录。
|
||
if (!model.IsSave ||
|
||
model.FieldType == ControlType.LabPic ||
|
||
model.FieldType == ControlType.LabPicEx)
|
||
return false;
|
||
|
||
if (string.IsNullOrWhiteSpace(model.FieldName))
|
||
return false;
|
||
|
||
// 当前界面上没有真实控件的字段不参与比较。
|
||
if (controlObj.FindControl(model) == null)
|
||
return false;
|
||
|
||
// 原始主表行里必须存在同名数据库字段。
|
||
return drBillInfoMsg.Table != null && drBillInfoMsg.Table.Columns.Contains(model.FieldName);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 保存单个字段的改动记录。
|
||
/// 如果相同单号、相同步骤、相同字段已存在记录,则更新;否则新增。
|
||
/// </summary>
|
||
private static void SaveChangeLog(string orderNumber, string fieldName, string oldValue, string newValue, string stepCode, string operatorId)
|
||
{
|
||
//orderNumber = orderNumber == null ? string.Empty : orderNumber;
|
||
//fieldName = fieldName == null ? string.Empty : fieldName;
|
||
//oldValue = oldValue == null ? string.Empty : oldValue;
|
||
//newValue = newValue == null ? string.Empty : newValue;
|
||
|
||
//orderNumber = orderNumber.Length > MaxOrderNumberLength ? orderNumber.Substring(0, MaxOrderNumberLength) : orderNumber;
|
||
//fieldName = fieldName.Length > MaxTextLength ? fieldName.Substring(0, MaxTextLength) : fieldName;
|
||
//oldValue = oldValue.Length > MaxTextLength ? oldValue.Substring(0, MaxTextLength) : oldValue;
|
||
//newValue = newValue.Length > MaxTextLength ? newValue.Substring(0, MaxTextLength) : newValue;
|
||
|
||
//orderNumber = orderNumber.Replace("'", "''");
|
||
//fieldName = fieldName.Replace("'", "''");
|
||
//oldValue = oldValue.Replace("'", "''");
|
||
//newValue = newValue.Replace("'", "''");
|
||
|
||
string sql = string.Format(@"if exists (select 1 from {0} where orderNumber = '{1}' and stepCode = {2} and fieldName = N'{3}')
|
||
begin
|
||
update {0}
|
||
set oldValue = N'{4}',
|
||
newValue = N'{5}',
|
||
operatorId = N'{6}'
|
||
where orderNumber =N'{1}'
|
||
and stepCode = N'{2}'
|
||
and fieldName = N'{3}'
|
||
end
|
||
else
|
||
begin
|
||
insert into {0} (orderNumber, fieldName, oldValue, newValue, stepCode, operatorId)
|
||
values (N'{1}', N'{3}', N'{4}', N'{5}', N'{2}', N'{6}')
|
||
end",
|
||
TableName,
|
||
orderNumber,
|
||
stepCode,
|
||
fieldName,
|
||
oldValue,
|
||
newValue,
|
||
operatorId);
|
||
|
||
SqlHelper.ExecuteNonQuery(sql);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从原始主表行中读取字段旧值,数据库 NULL 统一按空字符串处理。
|
||
/// </summary>
|
||
private static string GetRowValue(DataRow row, string fieldName)
|
||
{
|
||
if (row[fieldName] == DBNull.Value || row[fieldName] == null)
|
||
return string.Empty;
|
||
|
||
return row[fieldName] + "";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取错误提示中展示的字段名称,优先显示控件标题,没有标题时显示字段名。
|
||
/// </summary>
|
||
private static string GetErrorFieldName(ControlModel model, string fieldName)
|
||
{
|
||
if (model != null && !string.IsNullOrWhiteSpace(model.LabelText))
|
||
return model.LabelText + "[" + model.FieldName + "]";
|
||
|
||
return string.IsNullOrWhiteSpace(fieldName) ? "未知字段" : fieldName;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 判断两个值是否相同。
|
||
/// 优先按日期、数字进行值比较,最后再按普通字符串比较。
|
||
/// </summary>
|
||
/// <param name="oldValue">原始值</param>
|
||
/// <param name="newValue">当前值</param>
|
||
/// <returns>两个值在统一格式后是否相同</returns>
|
||
public static bool IsSameValue(string oldValue, string newValue)
|
||
{
|
||
oldValue = NormalizeValue(oldValue);
|
||
newValue = NormalizeValue(newValue);
|
||
|
||
if (oldValue == string.Empty && newValue == string.Empty)
|
||
return true;
|
||
|
||
DateTime oldDate;
|
||
DateTime newDate;
|
||
if (DateTime.TryParse(oldValue, out oldDate) && DateTime.TryParse(newValue, out newDate))
|
||
return oldDate == newDate;
|
||
|
||
decimal oldDecimal;
|
||
decimal newDecimal;
|
||
if (decimal.TryParse(oldValue, out oldDecimal) && decimal.TryParse(newValue, out newDecimal))
|
||
return oldDecimal == newDecimal;
|
||
|
||
return oldValue == newValue;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 比较前统一处理 NULL 和首尾空格。
|
||
/// </summary>
|
||
private static string NormalizeValue(string value)
|
||
{
|
||
return value == null ? string.Empty : value.Trim();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据单号获取所有审核改动字段名。
|
||
/// </summary>
|
||
/// <param name="orderNumber">单号</param>
|
||
/// <returns>当前单号对应的审核改动字段名集合</returns>
|
||
public static List<string> GetChangeLogFields(string orderNumber)
|
||
{
|
||
List<string> fields = new List<string>();
|
||
if (SystemInfo.Instance.AuditChangeRecord)
|
||
{
|
||
CreateModificationRecordTable();
|
||
orderNumber = orderNumber == null ? string.Empty : orderNumber.Replace("'", "''");
|
||
|
||
string sqlValue = string.Format(@"
|
||
select distinct fieldName
|
||
from {0}
|
||
where orderNumber = N'{1}'
|
||
order by fieldName", TableName, orderNumber);
|
||
|
||
DataTable dataTable = SqlHelper.ExecuteDataTable(sqlValue);
|
||
|
||
if (dataTable == null)
|
||
return fields;
|
||
|
||
foreach (DataRow row in dataTable.Rows)
|
||
{
|
||
string fieldName = row["fieldName"] + "";
|
||
if (!string.IsNullOrWhiteSpace(fieldName))
|
||
fields.Add(fieldName);
|
||
}
|
||
|
||
|
||
}
|
||
return fields;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建修改记录表
|
||
/// </summary>
|
||
public static void CreateModificationRecordTable()
|
||
{
|
||
if (!Lskj.Business.Impl.BaseImpl.HasExistsTable("P_SystemAuditChangeLog"))
|
||
{
|
||
string sqlValue = string.Format(@"CREATE TABLE P_SystemAuditChangeLog (
|
||
id BIGINT IDENTITY(1,1) NOT NULL PRIMARY KEY,
|
||
orderNumber VARCHAR(50) NOT NULL, -- 单号
|
||
fieldName NVARCHAR(500) NOT NULL, -- 字段名称
|
||
oldValue NVARCHAR(500) NULL, -- 旧值(改动前)
|
||
newValue NVARCHAR(500) NULL, -- 新值(改动后)
|
||
stepCode INT NOT NULL, -- 步骤号
|
||
operatorId int NOT NULL -- 人员id(改动人)
|
||
);");
|
||
BaseImpl.ExecSqlValue(sqlValue);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
}
|
||
}
|