18 changed files with 608 additions and 17 deletions
-
90Shentun.Sms.Client/CreateSmsTaskDto.cs
-
18Shentun.Sms.Client/Shentun.Sms.Client.csproj
-
263Shentun.Sms.Client/SmsClientHelper.cs
-
14Shentun.Sms.Client/SmsLoginInputDto.cs
-
16Shentun.Sms.Client/SmsLoginOutDataDto.cs
-
17Shentun.Sms.Client/SmsWebApiOutDto.cs
-
7Shentun.WebPeis.sln
-
30src/Shentun.Utilities/JsonDateTimeConverter.cs
-
27src/Shentun.WebPeis.Application/Persons/PersonAppService.cs
-
1src/Shentun.WebPeis.Application/Shentun.WebPeis.Application.csproj
-
3src/Shentun.WebPeis.Domain/Models/AppointScheduleTemplate.cs
-
45src/Shentun.WebPeis.Domain/Models/AppointScheduleTemplateTime.cs
-
1src/Shentun.WebPeis.Domain/Shentun.WebPeis.Domain.csproj
-
48src/Shentun.WebPeis.EntityFrameworkCore/Configures/AppointScheduleTemplateTimeConfigure.cs
-
2src/Shentun.WebPeis.EntityFrameworkCore/EntityFrameworkCore/WebPeisDbContext.cs
-
10src/Shentun.WebPeis.HttpApi.Host/appsettings.json
-
23test/Shentun.WebPeis.Application.Tests/PersonAppServiceTest.cs
-
10test/Shentun.WebPeis.Application.Tests/appsettings.json
@ -0,0 +1,90 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Shentun.Sms.Client |
||||
|
{ |
||||
|
public class CreateSmsTaskDto |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 短信类别ID
|
||||
|
/// </summary>
|
||||
|
public Guid SmsTypeId { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 人员ID
|
||||
|
/// </summary>
|
||||
|
public string PersonId { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 姓名
|
||||
|
/// </summary>
|
||||
|
public string PersonName { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 手机号国家代码
|
||||
|
/// </summary>
|
||||
|
public string CountryCode { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 手机号
|
||||
|
/// </summary>
|
||||
|
public string MobileTelephone { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 短信内容
|
||||
|
/// </summary>
|
||||
|
public string Content { get; set; } |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 应用ID
|
||||
|
/// </summary>
|
||||
|
public Guid SmsAppId { get; set; } |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 第三方系统唯一ID
|
||||
|
/// </summary>
|
||||
|
public string? ThirdId { get; set; } |
||||
|
|
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 任务周期类别
|
||||
|
/// </summary>
|
||||
|
public char TaskCycleType { get; set; } |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 任务表达式
|
||||
|
/// </summary>
|
||||
|
public string? TaskCorn { get; set; } |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 停止执行时间
|
||||
|
/// </summary>
|
||||
|
public string? StopTime { get; set; } |
||||
|
|
||||
|
|
||||
|
///// <summary>
|
||||
|
///// 是否启用
|
||||
|
///// </summary>
|
||||
|
//public char IsActive { get; set; } = 'Y';
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 发送者用户ID
|
||||
|
/// </summary>
|
||||
|
public string? SenderId { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 发送者用户名
|
||||
|
/// </summary>
|
||||
|
public string? SenderName { get; set; } |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net8.0</TargetFramework> |
||||
|
<ImplicitUsings>enable</ImplicitUsings> |
||||
|
<Nullable>enable</Nullable> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" /> |
||||
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.6.0" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\src\Shentun.Utilities\Shentun.Utilities.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,263 @@ |
|||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Shentun.Utilities; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IdentityModel.Tokens.Jwt; |
||||
|
using System.Linq; |
||||
|
using System.Net.Http.Headers; |
||||
|
using System.Text; |
||||
|
using System.Text.Json; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Shentun.Sms.Client |
||||
|
{ |
||||
|
public class SmsClientHelper |
||||
|
{ |
||||
|
protected static IConfiguration? _appConfig; |
||||
|
private static string? _baseAddress; |
||||
|
private static string? _createSmsTaskUrl; |
||||
|
private static string? _accesToken; |
||||
|
private static string? _user; |
||||
|
private static string? _password; |
||||
|
private static string? _email; |
||||
|
static SmsClientHelper() |
||||
|
{ |
||||
|
_appConfig = new ConfigurationBuilder() |
||||
|
.SetBasePath(DirectoryHelper.GetAppDirectory()) // 设置基础路径为当前目录
|
||||
|
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) |
||||
|
.Build(); |
||||
|
_baseAddress = _appConfig.GetSection("Sms") |
||||
|
.GetSection("BaseAddress").Value; |
||||
|
_createSmsTaskUrl = _appConfig.GetSection("Sms") |
||||
|
.GetSection("CreateSmsTaskUrl").Value; |
||||
|
_user = _appConfig.GetSection("Sms") |
||||
|
.GetSection("User").Value; |
||||
|
_password = _appConfig.GetSection("Sms") |
||||
|
.GetSection("Password").Value; |
||||
|
} |
||||
|
|
||||
|
public async static Task CreateSmsTask(CreateSmsTaskDto createSmsTaskDto) |
||||
|
{ |
||||
|
if (createSmsTaskDto == null) |
||||
|
{ |
||||
|
throw new Exception("createSmsTaskDto参数不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (createSmsTaskDto.MobileTelephone.Length != 11) |
||||
|
{ |
||||
|
|
||||
|
throw new Exception("手机号长度必须为11位"); |
||||
|
} |
||||
|
if(string.IsNullOrWhiteSpace(createSmsTaskDto.PersonId)) |
||||
|
{ |
||||
|
throw new Exception("人员ID不能为空"); |
||||
|
|
||||
|
} |
||||
|
if (string.IsNullOrWhiteSpace(createSmsTaskDto.PersonName)) |
||||
|
{ |
||||
|
throw new Exception("姓名不能为空"); |
||||
|
|
||||
|
} |
||||
|
if (string.IsNullOrWhiteSpace(createSmsTaskDto.CountryCode)) |
||||
|
{ |
||||
|
throw new Exception("国家编码不能为空"); |
||||
|
|
||||
|
} |
||||
|
if (string.IsNullOrWhiteSpace(createSmsTaskDto.Content)) |
||||
|
{ |
||||
|
throw new Exception("短信内容不能为空"); |
||||
|
|
||||
|
} |
||||
|
if (createSmsTaskDto.SmsAppId == null || createSmsTaskDto.SmsAppId == Guid.Empty) |
||||
|
{ |
||||
|
var smsAppIdStr = _appConfig.GetSection("Sms") |
||||
|
.GetSection("SmsAppId").Value; |
||||
|
if (!Guid.TryParse(smsAppIdStr, out var smsAppId)) |
||||
|
{ |
||||
|
throw new Exception("解析短信应用ID错误"); |
||||
|
} |
||||
|
createSmsTaskDto.SmsAppId = smsAppId; |
||||
|
} |
||||
|
|
||||
|
var reslut = await CallAppServiceAsync<CreateSmsTaskDto, object>(_createSmsTaskUrl, createSmsTaskDto); |
||||
|
} |
||||
|
|
||||
|
public async static Task CreateVerifySmsTask(CreateSmsTaskDto smsDto) |
||||
|
{ |
||||
|
var verifySmsTypeIdStr = _appConfig.GetSection("Sms") |
||||
|
.GetSection("VerifySmsTypeId").Value; |
||||
|
if (!Guid.TryParse(verifySmsTypeIdStr, out var verifySmsTypeId)) |
||||
|
{ |
||||
|
throw new Exception("解析校验短信类别ID错误"); |
||||
|
} |
||||
|
smsDto.SmsTypeId = verifySmsTypeId; |
||||
|
await CreateSmsTask(smsDto); |
||||
|
} |
||||
|
public async static Task<TOut> CallAppServiceAsync<TInput, TOut>(string url, TInput data, string method = "post") |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(_baseAddress)) |
||||
|
{ |
||||
|
throw new Exception("_baseAddress不能为空"); |
||||
|
} |
||||
|
string baseAddress = _baseAddress; |
||||
|
await CheckLoginAsync(); |
||||
|
using (var httpClientHandler = new HttpClientHandler()) |
||||
|
{ |
||||
|
using (var httpClient = new HttpClient(httpClientHandler)) |
||||
|
{ |
||||
|
httpClient.BaseAddress = new Uri(baseAddress); |
||||
|
|
||||
|
httpClient.DefaultRequestHeaders.Accept.Add( |
||||
|
new MediaTypeWithQualityHeaderValue("application/json"));//设置accept标头,告诉JSON是可接受的响应类型
|
||||
|
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accesToken); |
||||
|
var jsonOptions = new JsonSerializerOptions |
||||
|
{ |
||||
|
WriteIndented = true, // 设置为true以便于可读性更好的JSON输出
|
||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, |
||||
|
// 如果你想要对日期进行格式化,可以使用JsonConverter
|
||||
|
Converters = { new JsonDateTimeConverter("yyyy-MM-dd HH:mm:ss") } |
||||
|
}; |
||||
|
|
||||
|
var sendData = System.Text.Json.JsonSerializer.Serialize(data, jsonOptions); |
||||
|
using (HttpContent httpContent = new StringContent(sendData)) |
||||
|
{ |
||||
|
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); |
||||
|
HttpResponseMessage response = null; |
||||
|
if (method == "post") |
||||
|
{ |
||||
|
response = await httpClient.PostAsync(url, httpContent); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
response = await httpClient.GetAsync(url); |
||||
|
} |
||||
|
|
||||
|
string result; |
||||
|
if (!response.IsSuccessStatusCode) |
||||
|
{ |
||||
|
result = response.Content.ReadAsStringAsync().Result; |
||||
|
throw new Exception("http通信错误:" + response.StatusCode + ",结果:" + result); |
||||
|
} |
||||
|
result = await response.Content.ReadAsStringAsync(); |
||||
|
|
||||
|
var resultDto = System.Text.Json.JsonSerializer.Deserialize<SmsWebApiOutDto<TOut>>(result,jsonOptions); |
||||
|
if (resultDto.Code == -1) |
||||
|
{ |
||||
|
throw new Exception($"调用WebApi失败,返回-1,消息:" + resultDto.Message); |
||||
|
} |
||||
|
return resultDto.Data; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
public async static Task<SmsWebApiOutDto<SmsLoginOutDataDto>> LoginAsync() |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(_user)) |
||||
|
{ |
||||
|
throw new Exception("SelfUser不能为空"); |
||||
|
} |
||||
|
if (string.IsNullOrWhiteSpace(_password)) |
||||
|
{ |
||||
|
throw new Exception("SelfPassword不能为空"); |
||||
|
} |
||||
|
var relult = await LoginAsync(_user, _password); |
||||
|
return relult; |
||||
|
} |
||||
|
public async static Task<SmsWebApiOutDto<SmsLoginOutDataDto>> LoginAsync(string userId, string password) |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(userId)) |
||||
|
{ |
||||
|
throw new Exception("用户ID不能为空"); |
||||
|
} |
||||
|
if (string.IsNullOrWhiteSpace(password)) |
||||
|
{ |
||||
|
throw new Exception("密码不能为空"); |
||||
|
} |
||||
|
using (var httpClientHandler = new HttpClientHandler()) |
||||
|
{ |
||||
|
using (var httpClient = new HttpClient(httpClientHandler)) |
||||
|
{ |
||||
|
httpClient.BaseAddress = new Uri(_baseAddress); |
||||
|
|
||||
|
httpClient.DefaultRequestHeaders.Accept.Add( |
||||
|
new MediaTypeWithQualityHeaderValue("application/json"));//设置accept标头,告诉JSON是可接受的响应类型
|
||||
|
var url = "api/app/CustomerUser/UserLogin"; |
||||
|
var jsonOptions = new JsonSerializerOptions |
||||
|
{ |
||||
|
WriteIndented = true, // 设置为true以便于可读性更好的JSON输出
|
||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, |
||||
|
// 如果你想要对日期进行格式化,可以使用JsonConverter
|
||||
|
Converters = { new JsonDateTimeConverter("yyyy-MM-dd HH:mm:ss") } |
||||
|
}; |
||||
|
var loginUser = new SmsLoginInputDto() |
||||
|
{ |
||||
|
UserName = userId, |
||||
|
Password = password |
||||
|
}; |
||||
|
var sendData = System.Text.Json.JsonSerializer.Serialize(loginUser); |
||||
|
using (HttpContent httpContent = new StringContent(sendData)) |
||||
|
{ |
||||
|
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); |
||||
|
HttpResponseMessage response = await httpClient.PostAsync(url, httpContent); |
||||
|
string result; |
||||
|
if (!response.IsSuccessStatusCode) |
||||
|
{ |
||||
|
result = response.Content.ReadAsStringAsync().Result; |
||||
|
throw new Exception("登录短信系统时http通信错误:" + response.StatusCode + ",结果:" + result); |
||||
|
} |
||||
|
result = await response.Content.ReadAsStringAsync(); |
||||
|
var restultDto = System.Text.Json.JsonSerializer.Deserialize<SmsWebApiOutDto<SmsLoginOutDataDto>>(result, jsonOptions); |
||||
|
if (restultDto == null) |
||||
|
{ |
||||
|
throw new Exception("返回结果是空"); |
||||
|
} |
||||
|
if (restultDto.Code != 1) |
||||
|
{ |
||||
|
throw new Exception($"短信登录失败{restultDto.Message}"); |
||||
|
} |
||||
|
_accesToken = restultDto.Data.access_token; |
||||
|
return restultDto; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private async static Task CheckLoginAsync() |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(_accesToken)) |
||||
|
{ |
||||
|
await LoginAsync(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var handler = new JwtSecurityTokenHandler(); |
||||
|
var payload = handler.ReadJwtToken(_accesToken).Payload; |
||||
|
var claims = payload.Claims; |
||||
|
var exp = claims.First(claim => claim.Type == "exp").Value; |
||||
|
if (exp == null) |
||||
|
{ |
||||
|
await LoginAsync(); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
if (long.TryParse(exp, out var expires)) |
||||
|
{ |
||||
|
var expireTime = DateTimeOffset.FromUnixTimeSeconds(expires).LocalDateTime; |
||||
|
if (expireTime <= DateTime.Now) |
||||
|
{ |
||||
|
await LoginAsync(); |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
await LoginAsync(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Shentun.Sms.Client |
||||
|
{ |
||||
|
public class SmsLoginInputDto |
||||
|
{ |
||||
|
public string UserName { get; set; } |
||||
|
public string Password { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Shentun.Sms.Client |
||||
|
{ |
||||
|
public class SmsLoginOutDataDto |
||||
|
{ |
||||
|
public string access_token { get; set; } |
||||
|
public string token_type { get; set; } |
||||
|
public int expires_in { get; set; } |
||||
|
public string refresh_token { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using NPOI.SS.Formula.Functions; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Shentun.Sms.Client |
||||
|
{ |
||||
|
public class SmsWebApiOutDto<T> |
||||
|
{ |
||||
|
public int Code { get; set; } |
||||
|
public string Message { get; set; } |
||||
|
public T? Data { get; set; } |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Text.Json; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Shentun.Utilities |
||||
|
{ |
||||
|
public class JsonDateTimeConverter : System.Text.Json.Serialization.JsonConverter<DateTime> |
||||
|
{ |
||||
|
private readonly string _dateFormat; |
||||
|
|
||||
|
public JsonDateTimeConverter(string dateFormat) |
||||
|
{ |
||||
|
_dateFormat = dateFormat; |
||||
|
} |
||||
|
|
||||
|
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) |
||||
|
{ |
||||
|
return DateTime.ParseExact(reader.GetString(), _dateFormat, null); |
||||
|
} |
||||
|
|
||||
|
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) |
||||
|
{ |
||||
|
writer.WriteStringValue(value.ToUniversalTime().ToString(_dateFormat)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Domain.Entities.Auditing; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
|
||||
|
namespace Shentun.WebPeis.Models |
||||
|
{ |
||||
|
public class AppointScheduleTemplateTime : AuditedEntity, IHasConcurrencyStamp |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 主键
|
||||
|
/// </summary>
|
||||
|
public Guid AppointScheduleTemplateTimeId { get; set; } |
||||
|
public Guid AppointScheduleTemplateId { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 数量限制
|
||||
|
/// </summary>
|
||||
|
|
||||
|
public int NumberLimit { get; set; } |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 开始时间
|
||||
|
/// </summary>
|
||||
|
|
||||
|
public TimeOnly StartTime { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 结束时间
|
||||
|
/// </summary>
|
||||
|
|
||||
|
public TimeOnly StopTime { get; set; } |
||||
|
|
||||
|
public string? ConcurrencyStamp { get; set; } |
||||
|
|
||||
|
public virtual AppointScheduleTemplate AppointScheduleTemplate { get; set; } = null!; |
||||
|
|
||||
|
public override object[] GetKeys() |
||||
|
{ |
||||
|
return [AppointScheduleTemplateTimeId]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,48 @@ |
|||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
||||
|
using Shentun.WebPeis.Models; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
|
||||
|
namespace Shentun.WebPeis.Configures |
||||
|
{ |
||||
|
public class AppointScheduleTemplateTimeConfigure : IEntityTypeConfiguration<AppointScheduleTemplateTime> |
||||
|
{ |
||||
|
public void Configure(EntityTypeBuilder<AppointScheduleTemplateTime> entity) |
||||
|
{ |
||||
|
entity.HasKey(e => e.AppointScheduleTemplateTimeId).HasName("appoint_schedule_template_time_pkey"); |
||||
|
|
||||
|
entity.ToTable("appoint_schedule_template_time"); |
||||
|
|
||||
|
entity.HasIndex(e =>new object[] {e.AppointScheduleTemplateId,e.StartTime }, "ix_appoint_schedule_template_time").IsUnique(); |
||||
|
|
||||
|
entity.Property(e => e.AppointScheduleTemplateTimeId) |
||||
|
.ValueGeneratedNever() |
||||
|
.HasColumnName("appoint_schedule_template_time_id"); |
||||
|
entity.Property(e => e.StartTime).HasColumnName("start_time"); |
||||
|
entity.Property(e => e.StopTime).HasColumnName("stop_time"); |
||||
|
entity.Property(e => e.ConcurrencyStamp) |
||||
|
.HasMaxLength(40) |
||||
|
.HasColumnName("concurrency_stamp"); |
||||
|
entity.Property(e => e.CreationTime) |
||||
|
.HasColumnType("timestamp without time zone") |
||||
|
.HasColumnName("creation_time"); |
||||
|
entity.Property(e => e.CreatorId).HasColumnName("creator_id"); |
||||
|
entity.Property(e => e.LastModificationTime) |
||||
|
.HasColumnType("timestamp without time zone") |
||||
|
.HasColumnName("last_modification_time"); |
||||
|
entity.Property(e => e.LastModifierId).HasColumnName("last_modifier_id"); |
||||
|
entity.Property(e => e.NumberLimit).IsRequired().HasColumnName("number_limit"); |
||||
|
entity.HasOne(d => d.AppointScheduleTemplate).WithMany(p => p.AppointScheduleTemplateTimes) |
||||
|
.HasForeignKey(d => d.AppointScheduleTemplateId) |
||||
|
.OnDelete(DeleteBehavior.Cascade) |
||||
|
.HasConstraintName("fk_appoint_schedule_template_time"); |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue