LocationSupportAppService.cs
5.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using FoodLabeling.Application.Contracts;
using FoodLabeling.Application.Contracts.Dtos.LocationSupport;
using FoodLabeling.Application.Contracts.IServices;
using FoodLabeling.Application.Services.DbModels;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Guids;
using Volo.Abp.Uow;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace FoodLabeling.Application.Services;
/// <summary>
/// 全局 Support 联系方式(全门店共用;Web 可增改查,App JWT 仅可读)
/// </summary>
[Authorize]
public class LocationSupportAppService : ApplicationService, ILocationSupportAppService
{
private readonly ISqlSugarDbContext _dbContext;
private readonly IGuidGenerator _guidGenerator;
public LocationSupportAppService(ISqlSugarDbContext dbContext, IGuidGenerator guidGenerator)
{
_dbContext = dbContext;
_guidGenerator = guidGenerator;
}
/// <inheritdoc />
public async Task<LocationSupportGetOutputDto?> GetSupportAsync()
{
var rows = await _dbContext.SqlSugarClient.Queryable<FlLocationSupportDbEntity>()
.Where(x => !x.IsDeleted)
.ToListAsync();
var entity = rows.FirstOrDefault();
return MapOutput(entity);
}
/// <inheritdoc />
[UnitOfWork]
public async Task<LocationSupportGetOutputDto> CreateAsync(LocationSupportCreateInputVo input)
{
EnsureNotUsAppClient();
if (input is null)
{
throw new UserFriendlyException("Request body is required.");
}
var phone = NormalizeRequired(input.SupportPhone, "Support phone is required.");
var email = NormalizeRequired(input.SupportEmail, "Support email is required.");
EnsureEmailFormat(email);
var existed = await _dbContext.SqlSugarClient.Queryable<FlLocationSupportDbEntity>()
.AnyAsync(x => !x.IsDeleted);
if (existed)
{
throw new UserFriendlyException(
"Global support contact already exists. Use update instead.");
}
var now = Clock.Now;
var entity = new FlLocationSupportDbEntity
{
Id = _guidGenerator.Create().ToString(),
IsDeleted = false,
CreationTime = now,
CreatorId = CurrentUser?.Id?.ToString(),
LastModificationTime = now,
LastModifierId = CurrentUser?.Id?.ToString(),
SupportPhone = phone,
SupportEmail = email
};
await _dbContext.SqlSugarClient.Insertable(entity).ExecuteCommandAsync();
return MapOutput(entity)!;
}
/// <inheritdoc />
[UnitOfWork]
public async Task<LocationSupportGetOutputDto> UpdateAsync(string id, LocationSupportUpdateInputVo input)
{
EnsureNotUsAppClient();
var supportId = id?.Trim();
if (string.IsNullOrWhiteSpace(supportId))
{
throw new UserFriendlyException("Support record id is required.");
}
if (input is null)
{
throw new UserFriendlyException("Request body is required.");
}
var rows = await _dbContext.SqlSugarClient.Queryable<FlLocationSupportDbEntity>()
.Where(x => !x.IsDeleted && x.Id == supportId)
.ToListAsync();
var entity = rows.FirstOrDefault();
if (entity is null)
{
throw new UserFriendlyException("Support record not found.");
}
var phone = NormalizeRequired(input.SupportPhone, "Support phone is required.");
var email = NormalizeRequired(input.SupportEmail, "Support email is required.");
EnsureEmailFormat(email);
entity.SupportPhone = phone;
entity.SupportEmail = email;
entity.LastModificationTime = Clock.Now;
entity.LastModifierId = CurrentUser?.Id?.ToString();
await _dbContext.SqlSugarClient.Updateable(entity).ExecuteCommandAsync();
return MapOutput(entity)!;
}
private void EnsureNotUsAppClient()
{
if (CurrentUser.FindClaim(UsAppJwtClaims.ClientKind)?.Value == UsAppJwtClaims.ClientKindUsApp)
{
throw new UserFriendlyException(
"The mobile app can only view support contacts. Please use the web console to edit.");
}
}
private static string NormalizeRequired(string? value, string message)
{
var normalized = value?.Trim();
if (string.IsNullOrWhiteSpace(normalized))
{
throw new UserFriendlyException(message);
}
return normalized;
}
private static void EnsureEmailFormat(string email)
{
if (!email.Contains("@", StringComparison.Ordinal) || email.StartsWith("@", StringComparison.Ordinal) ||
email.EndsWith("@", StringComparison.Ordinal))
{
throw new UserFriendlyException("Support email format is invalid.");
}
}
private static LocationSupportGetOutputDto? MapOutput(FlLocationSupportDbEntity? entity)
{
if (entity is null)
{
return null;
}
return new LocationSupportGetOutputDto
{
Id = entity.Id,
SupportPhone = entity.SupportPhone,
SupportEmail = entity.SupportEmail
};
}
}