188 lines
6.5 KiB
C#
188 lines
6.5 KiB
C#
namespace SimpleAdmin.Application;
|
|
|
|
/// <summary>
|
|
/// 统一校验任务合同变量,确保最终提交的数据可以安全用于合同生成。
|
|
/// </summary>
|
|
public class OnboardingContractVariableValidationService
|
|
: IOnboardingContractVariableValidationService
|
|
{
|
|
private readonly SqlSugarScope _db;
|
|
|
|
public OnboardingContractVariableValidationService()
|
|
{
|
|
_db = DbContext.DB;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task Validate(long taskId)
|
|
{
|
|
var contracts = await _db.Queryable<ObTaskContract>()
|
|
.Where(item => item.TaskId == taskId)
|
|
.ToListAsync();
|
|
if (contracts.Count == 0)
|
|
return;
|
|
|
|
var contractIds = contracts
|
|
.Select(item => item.Id)
|
|
.ToList();
|
|
var templateVersionIds = contracts
|
|
.Select(item => item.TemplateVersionId)
|
|
.Distinct()
|
|
.ToList();
|
|
var variables = await _db.Queryable<ObTaskContractVariable>()
|
|
.Where(item => contractIds.Contains(item.TaskContractId))
|
|
.ToListAsync();
|
|
var definitions = await _db.Queryable<ObTemplateVariable>()
|
|
.Where(item => templateVersionIds.Contains(item.TemplateVersionId))
|
|
.ToListAsync();
|
|
|
|
foreach (var contract in contracts)
|
|
{
|
|
var contractDefinitions = definitions
|
|
.Where(item => item.TemplateVersionId == contract.TemplateVersionId)
|
|
.OrderBy(item => item.SortCode);
|
|
|
|
foreach (var definition in contractDefinitions)
|
|
{
|
|
var variable = variables.FirstOrDefault(item =>
|
|
item.TaskContractId == contract.Id
|
|
&& item.VariableCode == definition.VariableCode);
|
|
var value = variable?.VariableValue?.Trim();
|
|
|
|
if (definition.Required && string.IsNullOrWhiteSpace(value))
|
|
{
|
|
throw Oops.Bah(
|
|
$"合同“{contract.ContractName}”的必填变量“{definition.VariableName}”尚未填写");
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(value)
|
|
|| definition.VariableType != ContractVariableType.Employee)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
ValidateDataType(contract.ContractName, definition, value);
|
|
ValidateOptions(contract.ContractName, definition, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void ValidateDataType(
|
|
string contractName,
|
|
ObTemplateVariable definition,
|
|
string value)
|
|
{
|
|
var dataType = definition.DataType?.Trim().ToLowerInvariant() ?? "string";
|
|
switch (dataType)
|
|
{
|
|
case "string":
|
|
return;
|
|
case "number":
|
|
var numberIsValid = decimal.TryParse(
|
|
value,
|
|
global::System.Globalization.NumberStyles.Number,
|
|
global::System.Globalization.CultureInfo.InvariantCulture,
|
|
out _);
|
|
if (!numberIsValid)
|
|
{
|
|
throw Oops.Bah(
|
|
$"合同“{contractName}”的变量“{definition.VariableName}”必须填写数字");
|
|
}
|
|
|
|
return;
|
|
case "date":
|
|
var dateIsValid = DateTime.TryParseExact(
|
|
value,
|
|
"yyyy-MM-dd",
|
|
global::System.Globalization.CultureInfo.InvariantCulture,
|
|
global::System.Globalization.DateTimeStyles.None,
|
|
out _);
|
|
if (!dateIsValid)
|
|
{
|
|
throw Oops.Bah(
|
|
$"合同“{contractName}”的变量“{definition.VariableName}”必须填写正确日期");
|
|
}
|
|
|
|
return;
|
|
default:
|
|
throw Oops.Bah(
|
|
$"合同“{contractName}”的变量“{definition.VariableName}”数据类型配置不正确");
|
|
}
|
|
}
|
|
|
|
private static void ValidateOptions(
|
|
string contractName,
|
|
ObTemplateVariable definition,
|
|
string value)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(definition.OptionsJson))
|
|
return;
|
|
|
|
var options = ParseOptions(contractName, definition);
|
|
if (options.Contains(value))
|
|
return;
|
|
|
|
throw Oops.Bah(
|
|
$"合同“{contractName}”的变量“{definition.VariableName}”必须从配置选项中选择");
|
|
}
|
|
|
|
private static HashSet<string> ParseOptions(
|
|
string contractName,
|
|
ObTemplateVariable definition)
|
|
{
|
|
try
|
|
{
|
|
using var document = global::System.Text.Json.JsonDocument.Parse(
|
|
definition.OptionsJson);
|
|
if (document.RootElement.ValueKind != global::System.Text.Json.JsonValueKind.Array)
|
|
throw new global::System.Text.Json.JsonException();
|
|
|
|
var options = document.RootElement
|
|
.EnumerateArray()
|
|
.Select(GetOptionValue)
|
|
.Where(item => !string.IsNullOrWhiteSpace(item))
|
|
.ToHashSet(StringComparer.Ordinal);
|
|
|
|
if (options.Count == 0)
|
|
throw new global::System.Text.Json.JsonException();
|
|
|
|
return options;
|
|
}
|
|
catch (global::System.Text.Json.JsonException)
|
|
{
|
|
throw Oops.Bah(
|
|
$"合同“{contractName}”的变量“{definition.VariableName}”可选项配置不正确");
|
|
}
|
|
}
|
|
|
|
private static string GetOptionValue(
|
|
global::System.Text.Json.JsonElement option)
|
|
{
|
|
if (option.ValueKind == global::System.Text.Json.JsonValueKind.String)
|
|
return option.GetString()?.Trim();
|
|
|
|
if (option.ValueKind == global::System.Text.Json.JsonValueKind.Object)
|
|
{
|
|
if (option.TryGetProperty("value", out var value))
|
|
return GetJsonText(value);
|
|
if (option.TryGetProperty("label", out var label))
|
|
return GetJsonText(label);
|
|
}
|
|
|
|
return GetJsonText(option);
|
|
}
|
|
|
|
private static string GetJsonText(
|
|
global::System.Text.Json.JsonElement value)
|
|
{
|
|
return value.ValueKind switch
|
|
{
|
|
global::System.Text.Json.JsonValueKind.String => value.GetString()?.Trim(),
|
|
global::System.Text.Json.JsonValueKind.Number => value.ToString(),
|
|
global::System.Text.Json.JsonValueKind.True => bool.TrueString,
|
|
global::System.Text.Json.JsonValueKind.False => bool.FalseString,
|
|
_ => null
|
|
};
|
|
}
|
|
}
|