This commit is contained in:
CortexCore 2024-05-31 01:19:55 +08:00
parent f77100bd56
commit c3517a2fe5
15 changed files with 452 additions and 45 deletions

View File

@ -20,6 +20,7 @@
<Routes @rendermode=RenderMode.InteractiveServer />
<script src="_framework/blazor.web.js"></script>
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
<script src="/_content/Ril.BlazorSignatureCanvas/BlazorSignatureCanvas.js"></script>
</body>
</html>

View File

@ -25,7 +25,7 @@
public Action<MudChip[]> OnSelectedChipsChanged { get; set; }
private List<string> values { get; set; }= new()
{
"oder","material","device","procedure","product"
"oder","material","product","device","procedure",
};
public void Add()
{

View File

@ -2,7 +2,9 @@
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.PlayCircleOutline">主页</MudNavLink>
<MudNavLink Href="/query" Match="NavLinkMatch.All" Icon="@Icons.Material.Outlined.DataObject">解析标识</MudNavLink>
<MudNavLink Href="template/register" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Outlined.AppRegistration">注册标识模板</MudNavLink>
<MudNavLink Href="/register" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Outlined.Assignment">注册标识</MudNavLink>
<MudNavLink Href="/register" Match="NavLinkMatch.All" Icon="@Icons.Material.Outlined.Assignment">注册标识</MudNavLink>
<MudNavLink Href="/signature" Match="NavLinkMatch.All" Icon="@Icons.Material.Outlined.Book">签名标识</MudNavLink>
<MudNavLink Href="/oneClickRegistration" Match="NavLinkMatch.All" Icon="@Icons.Material.Outlined.BatchPrediction">一键注册</MudNavLink>
<MudNavGroup Icon="@Icons.Material.Outlined.OtherHouses" Title="企业" Expanded="true">
<MudNavLink Match="NavLinkMatch.Prefix" Href="/enterprise/register" Icon="@Icons.Material.Outlined.Bookmark">注册企业</MudNavLink>
<MudNavLink Match="NavLinkMatch.Prefix" Href="/enterprise/query" Icon="@Icons.Material.Outlined.ScreenSearchDesktop">前缀查询</MudNavLink>

View File

@ -3,8 +3,20 @@
<MudDivider DividerType="DividerType.Middle" Class="my-6"/>
<MudStack Spacing="2">
<MudText Typo="Typo.h4">我从哪里开始?</MudText>
<MudAlert><MudLink Href="http://server.bitfall.icu:3000/root/IDIS_Server.Console.git">IDIS.Server.Console</MudLink></MudAlert>
<MudDivider DividerType="DividerType.Middle" Class="my-6"/>
<MudText Typo="Typo.h4">现在就给我文档</MudText>
<MudAlert><MudLink Href="https://docs.qq.com/document/DU09namRET25CZVZR">【腾讯文档】标识解析附件1 SNMS-API-1.2.6</MudLink></MudAlert>
<MudText>请注意该文档的版本是v1源自于冰河时期的文档</MudText>
<MudDivider DividerType="DividerType.Middle" Class="my-6"/>
<MudText Typo="Typo.h4">如何通过标签查询标识</MudText>
<MudAlert>http://host:port/api/GetQueryByTag?tags=tag1;tag2;tag3&today=false</MudAlert>
<MudAlert>http://host:port/api/query/by?tags=tag1;tag2;tag3&today=false</MudAlert>
<MudText><b>tags</b>使用<b>;</b>分隔多个标签</MudText>
<MudText><b>today</b>是可选参数</MudText>
<MudDivider DividerType="DividerType.Middle" Class="my-6"/>
@ -23,7 +35,10 @@
<MudText Typo="Typo.h4">我怎么知道这些Tag是啥子东西</MudText>
<MudAlert><MudLink Href="http://server.bitfall.icu:3000/root/IDIS.Model.YL106">YL106.Models</MudLink></MudAlert>
<MudDivider DividerType="DividerType.Middle" Class="my-6"/>
<MudDivider DividerType="DividerType.Middle" Class="my-6"/>
<MudText Typo="Typo.h4">非常方便的快捷方式</MudText>
<MudAlert>例如,在涉及到工单<b>PZK20240510</b>的所有标识下,注册的时候可以添加标签<b>oder_20240510</b>来方便查询该工单下的所有标识</MudAlert>
<MudText Typo="Typo.h4">仓库注册解析操作标识最新十条</MudText>
<MudText Typo="Typo.h5">注册记录</MudText>

View File

@ -0,0 +1,53 @@
@page "/OneClickRegistration"
@using IDIS.Client.Web.Data
@using IDIS.Models
@using IDIS.Services
@using Cysharp.Threading.Tasks
@inject IDIS_TemplateService templateService
@inject OneClickRegister register
@inject IDialogService dialogService
<MudText Typo="Typo.h3" GutterBottom="true">一键注册</MudText>
<MudText>选择需要的项目,对生产过程中产生的标识进行<b>一键注册</b></MudText>
<MudText>在生产过程中,更新对应的标识即可</MudText>
<MudGrid>
<MudItem xs="3">
<MudStack>
<MudAlert>快速注册</MudAlert>
<MudStack Row="true" Class="align-center">
<MudTextField @bind-Value="registerName" T="string" Label="输入名称"/>
<MudSelect @bind-Value="registerTemplate" T="string" Label="选择模板" AnchorOrigin="Origin.BottomCenter">
@foreach (var (name,template) in registerTemplates)
{
<MudSelectItem Value="template.Name"/>
}
</MudSelect>
</MudStack>
<MudButton OnClick="Register" Variant="Variant.Filled" Color="Color.Success">一键注册</MudButton>
</MudStack>
</MudItem>
</MudGrid>
@code {
private Dictionary<string,OneClickRegisterData> registerTemplates { get; set; }= new();
private string registerTemplate { get; set; }
private string registerName { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender) return;
await Rebuild();
await InvokeAsync(StateHasChanged);
}
private async UniTask Rebuild()
{
registerTemplates = await register.GetAllTemplate();
}
private async void Register()
{
await register.Register(registerTemplate,registerName);
dialogService.ShowMessageBox("注册成功", "注册成功").AndForget();
await InvokeAsync(StateHasChanged);
}
}

View File

@ -1,6 +1,85 @@
@page "/Enterprise/Query"
<h3>使用管理员账户登录查看</h3>
@using BITKit
@using IDIS.Models
@inject IDIS_EnterpriseService enterpriseService
<h3>企业查询</h3>
<MudStack Spacing="2">
<MudTextField
Disabled="@_isBusy.Allow"
T="string"
@bind-Value="@Prefix"
Label="查询前缀例如88.123.99"
Variant="Variant.Outlined"
Adornment="Adornment.End"
AdornmentIcon="@Icons.Material.Filled.Search"
OnAdornmentClick="QueryInternal"
/>
<MudAlert Severity="@Severity">@CurrentReport</MudAlert>
<MudPaper Class="pa-2">
<MudStack Row="true">
<MudStack>
<MudText>前缀名称</MudText>
<MudText>前缀创建时间</MudText>
<MudText>前缀注册服务机构</MudText>
<MudText>前缀状态</MudText>
<MudText>企业中文名称</MudText>
<MudText>企业官方地址</MudText>
<MudText>企业所属行业</MudText>
<MudText>企业中文地址</MudText>
<MudText>企业简介</MudText>
</MudStack>
<MudStack>
<MudText>@queryData.Prefix</MudText>
<MudText>@queryData.CreateDate</MudText>
<MudText>@queryData.GhrName</MudText>
<MudText>@queryData.Status</MudText>
<MudText>@queryData.EntNameCn</MudText>
<MudText>@queryData.EntSite</MudText>
<MudText>@queryData.EntIndustry</MudText>
<MudText>@queryData.EntAddrCn</MudText>
<MudText>@queryData.EntDesc</MudText>
</MudStack>
</MudStack>
</MudPaper>
</MudStack>
@code {
private string Prefix { get; set; } = "88.123.99";
private readonly ValidHandle _isBusy = new();
private IDIS_EnterpriseData queryData { get; set; } = new IDIS_EnterpriseData();
private string CurrentReport { get; set; } = "查询一个前缀开始";
private Severity Severity { get; set; } = Severity.Normal;
protected override void OnAfterRender(bool firstRender)
{
if(!firstRender)return;
_isBusy.AddListener(x=>InvokeAsync(StateHasChanged).AndForget());
}
private async void QueryInternal()
{
CurrentReport = "正在查询...";
Severity = Severity.Info;
_isBusy.AddElement(this);
try
{
queryData = await enterpriseService.GetEnterpriseAsync(Prefix);
CurrentReport = "查询成功";
Severity = Severity.Success;
}
catch (Exception e)
{
CurrentReport = e.Message;
Severity = Severity.Error;
}
_isBusy.RemoveElement(this);
}
}

View File

@ -1,4 +1,5 @@
@page "/Query"
@page "/query/{handle?}"
@inject IDIS_Service service
@inject IDIS_TemplateService templateService
@inject ISnackbar snackbar
@ -8,7 +9,7 @@
<MudStack>
<MudTextField
@bind-Value="@handle"
HelperText="例如:88.123.99/202402051710"
HelperText="例如:88.123.99/638509550657468460"
Label="在这里输入需要解析的标识"
Variant="Variant.Outlined"
Adornment="Adornment.End"
@ -30,10 +31,17 @@
<MudIcon Icon="@Icons.Material.Outlined.Info"/>
</MudItem>
<MudItem Style="min-width: 100px">
<MudText >@templateItem.Name</MudText>
<MudText >@templateItem.Name</MudText>
</MudItem>
<MudItem>
<MudText>@x.Data.Value</MudText>
@if (x.Data.Value.Contains("data:image"))
{
<MudImage Src="@x.Data.Value" Width="100" Fluid="true" />
}
else
{
<MudText>@x.Data.Value</MudText>
}
</MudItem>
</MudGrid>
}
@ -42,11 +50,21 @@
}
</MudStack>
@code {
private string handle { get; set; }
[Parameter]
public string handle { get; set; }
private IDIS_Query_Data queryData { get; set; }= new IDIS_Query_Data();
private IDIS_Template template { get; set; } = new IDIS_Template();
private string currentMessage { get; set; } = "从解析一个标识开始";
private Severity severity { get; set; } = Severity.Normal;
protected override void OnAfterRender(bool firstRender)
{
if (!firstRender) return;
if (string.IsNullOrEmpty(handle) is false)
{
QueryInternal();
}
}
private async void QueryInternal()
{
try
@ -58,13 +76,13 @@
currentMessage = "查询成功";
severity = Severity.Success;
await InvokeAsync(StateHasChanged);
}
catch (Exception e)
{
currentMessage = e.Message;
severity = Severity.Error;
}
await InvokeAsync(StateHasChanged);
}
}

View File

@ -11,8 +11,9 @@
@inject IDIS_EnterpriseService enterpriseService
@inject IDIS_Service service
@inherits OwningComponentBase
<MudText Typo="Typo.h3" GutterBottom="true">注册标识</MudText>
<MudText>当我们创建标识模板后<br/>我们就可以通过标识模板快速注册标识</MudText>
<MudText Typo="Typo.h3" GutterBottom="true">注册与更新标识</MudText>
<MudText>当我们创建标识模板后,我们就可以通过标识模板,快速注册与更新标识</MudText>
<MudText>如果需要更新标识,只需要填写需要更新的值</MudText>
<MudGrid>
<MudItem xs="3">
<TemplateSelector Reference="templateSelector" OnSelectTemplate="SelectTemplate"></TemplateSelector>
@ -42,42 +43,51 @@
<MudText Typo="Typo.h6">注册值</MudText>
<MudStack Spacing="0">
@for(var index=0;index<_valueInfo.Length;index++)
{
var i = index;
var templateInfo = this.template.Items[index];
@* @if (templateInfo.MetaData.Type is ("dateTime" or "DateTime")) *@
@* { *@
@* $1$ <MudDatePicker DateFormat="y" Label="@templateInfo.Name" @bind-Date="registerDateTimes[i].Value"/> #1# *@
@* <InputDate *@
@* Type="InputDateType.DateTimeLocal" *@
@* class="form-control" *@
@* id="ClockIn" *@
@* @bind-Value="registerDateTimes[i].Value" *@
@* @bind-Value:format="mm/dd/yyyy hh:mm tt" *@
@* placeholder="Clock In" /> *@
@* } *@
@* else *@
@for (var index = 0; index < _valueInfo.Length; index++)
{
<MudTextField Margin="@myMargin"
@bind-Value="@_valueInfo[i].Data.Value"
HelperText="@($"{templateInfo.IdType}:{templateInfo.MetaData.Type}")"
T="string"
Counter="25"
Immediate="true"
Label="@templateInfo.Name"
Variant="Variant.Outlined" />
var i = index;
var templateInfo = this.template.Items[index];
<MudStack Row="true">
@if (regOrUpdate)
{
<MudCheckBox @bind-Value="updateFlags[i]"/>
}
@if (templateInfo.MetaData.Type is ("dateTime" or "DateTime"))
{
<MudTextField
@bind-Value="@dateTimeProxies[i].Value"
T="DateTime?"
Format="s"
InputType="InputType.DateTimeLocal"
HelperText="@($"{templateInfo.IdType}:{templateInfo.MetaData.Type}")"
Margin="@myMargin"
Variant="Variant.Outlined"/>
}
else
{
<MudTextField Margin="@myMargin"
@bind-Value="@_valueInfo[i].Data.Value"
HelperText="@($"{templateInfo.IdType}:{templateInfo.MetaData.Type}")"
T="string"
Counter="25"
Immediate="true"
Label="@templateInfo.Name"
Variant="Variant.Outlined"/>
}
</MudStack>
}
}
</MudStack>
@if (string.IsNullOrEmpty(currentMessage) is false)
{
<MudAlert Severity="severity">@currentMessage</MudAlert>
}
<div class="d-flex">
<MudButton Class="d-flex flex-grow-1" Variant="Variant.Outlined" OnClick="Reg">注册标识:@handle</MudButton>
</div>
<MudStack Row="true">
<MudCheckBox @bind-Value="regOrUpdate">注册或更新</MudCheckBox>
<MudButton Class="d-flex flex-grow-1" Variant="Variant.Outlined" OnClick="Reg">@(regOrUpdate?"注册或更新标识":"注册标识") :@handle</MudButton>
</MudStack>
</MudStack>
</MudItem>
</MudGrid>
@ -86,7 +96,9 @@
{
public DateTime? Value { get; set; } = DateTime.Now;
}
private List<DateTimeProxy> dateTimeProxies { get; set; } = new();
private bool[] updateFlags { get; set; } = Array.Empty<bool>();
private Reference<TemplateSelector> templateSelector { get; set; } = new();
private IDIS_Template template = new IDIS_Template();
@ -98,6 +110,8 @@
private string handle_code { get; set; } = DateTime.Now.Ticks.ToString();
private string generatedHandleCode { get; set; } = DateTime.Now.Ticks.ToString();
private string handle=> $"{prefix_c}.{prefix_p}.{prefix_e.Split("(").Last().Split(")").First()}/{handle_code}";
private bool regOrUpdate { get; set; }
private string currentMessage { get; set; } = string.Empty;
private IDIS_Enterprise.EnterpriseInfo[] enterprises { get; set; } = Array.Empty<IDIS_Enterprise.EnterpriseInfo>();
@ -119,6 +133,8 @@
{
template = newValue;
_valueInfo = new IDIS_Register_Data.ValueInfo[template.Items.Length];
dateTimeProxies.Clear();
updateFlags = new bool[template.Items.Length];
for (var index = 0; index < template.Items.Length; index++)
{
var x = template.Items[index];
@ -135,6 +151,7 @@
if(x.MetaData.Type is ("dateTime" or "DateTime"))
info.Data.Value = DateTime.Now.ToString(CultureInfo.InvariantCulture);
_valueInfo[index] = info;
dateTimeProxies.Add(new DateTimeProxy());
}
InvokeAsync(StateHasChanged).AndForget();
}
@ -149,6 +166,14 @@
{
throw new Exception($"标识格式错误,正则表达式为{IDIS_Code.AddressRegex}");
}
for (var index = 0; index < template.Items.Length; index++)
{
var x = template.Items[index];
if (x.MetaData.Type is ("dateTime" or "DateTime"))
{
_valueInfo[index].Data.Value = dateTimeProxies[index].Value!.ToString()!;
}
}
await service.RegisterAsync(handle, template.Version, _valueInfo);
currentMessage = "注册成功,标识码为:\n" + handle;
severity=Severity.Success;
@ -170,7 +195,7 @@
{
try
{
enterprises = await enterpriseService.GetEnterpriseAsync();
enterprises = await enterpriseService.GetEnterprisesAsync();
return enterprises
.Select(x =>$"{x.NameCN}({x.Prefix.Split(".")[2]})")
.Where(x => x.Contains(arg))

View File

@ -0,0 +1,106 @@
@page "/Signature"
@using Ril.BlazorSignatureCanvas
@using IDIS.Services
@using SkiaSharp
@inject IDIS_Service service
<MudText Typo="Typo.h3" GutterBottom="true">在线签名</MudText>
<MudText>我们把签名写入标识中,用于其他应用通过解析标识,获取来自边缘终端的签名</MudText>
<SignatureCanvas
@ref="signatureCanvas"
width="256" height="512"
style="background-color: white; border: 1px solid black;"
MinLineWidth="0.5f"
MaxLineWidth="1"/>
<MudGrid>
<MudItem xs="3">
<MudPaper Class="pa-2">
<MudStack Spacing="2">
<MudTextField T="string" @bind-Value="@handle" Label="标识码"></MudTextField>
<MudTextField T="string" @bind-Value="@type" Label="值类型"></MudTextField>
<MudStack >
<MudStack Row="true">
<MudButton Variant="Variant.Outlined" @onclick=HandleClear>清除签名</MudButton>
<MudSpacer/>
<MudButton Variant="Variant.Outlined" Color="Color.Info" @onclick=HandleSave>保存签名</MudButton>
</MudStack>
</MudStack>
</MudStack>
<MudAlert Severity="@severity">@message</MudAlert>
</MudPaper>
</MudItem>
</MudGrid>
@code {
private string handle { get; set; } = string.Empty;
string type { get; set; } = "signature";
SignatureCanvas signatureCanvas { get; set; }
private string message { get; set; } = "等待注册中";
private Severity severity { get; set; } = Severity.Normal;
protected override void OnAfterRender(bool firstRender)
{
if(!firstRender)return;
{
if(BITKit.Data.TryGetValue<string>("Signature.DefaultHandle",out var value))
{
handle = value;
}
}
{
if(BITKit.Data.TryGetValue<string>("Signature.DefaultType",out var value))
{
type = value;
}
}
StateHasChanged();
}
async Task HandleClear()
{
await signatureCanvas.Clear();
}
async Task HandleSave()
{
message = "正在更新标识";
severity = Severity.Normal;
await InvokeAsync(StateHasChanged);
using var bitmap = SKBitmap.Decode(await signatureCanvas.ToByteArray());
using var signBitMap = SKBitmap.Decode(await signatureCanvas.ToByteArray());
using var canvas = new SKCanvas(bitmap);
canvas.Clear(SKColors.White);
canvas.DrawBitmap(signBitMap, new SKPoint());
using var rotatedData = bitmap.Encode(SKEncodedImageFormat.Png, 40);
using var newMs = new MemoryStream();
rotatedData.SaveTo(newMs);
var data = Convert.ToBase64String(newMs.ToArray());
data = "data:image/png;base64," + data;
try
{
await service.UpdateAsync(handle,new Dictionary<string, object>()
{
{type,data},
});
message = "更新成功";
severity = Severity.Success;
}
catch (Exception e)
{
message = e.Message;
severity = Severity.Error;
}
await InvokeAsync(StateHasChanged);
}
}

View File

@ -10,4 +10,4 @@
@using IDIS.Client.Web
@using IDIS.Client.Web.Components
@using MudBlazor
@using MudBlazor.Services
@using MudBlazor.Services

101
Data/OneClickRegister.cs Normal file
View File

@ -0,0 +1,101 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Net;
using System.Reflection.Metadata;
using System.Text.RegularExpressions;
using BITKit;
using Cysharp.Threading.Tasks;
using IDIS.Models;
using IDIS.Services;
using IDIS.Services.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Org.BouncyCastle.Security;
namespace IDIS.Client.Web.Data;
public record OneClickRegisterData
{
public string Name;
public string Prefix;
public Dictionary<string,string> Dictionary;
}
public class OneClickRegister:DbContext
{
[Keyless]
public class Info
{
public string Name { get; set; }
public string Json { get; set; }
}
[Keyless]
public class SavedInfo:Info
{
}
private readonly IDIS_Service _service;
public OneClickRegister(IDIS_Service service)
{
_service = service;
}
public DbSet<Info> oneClickTemplates { get; set; }
public DbSet<SavedInfo> oneClickRegisters { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connectionString = BITKit.Data.Get<string>("DefaultConnection");
optionsBuilder.UseMySQL(connectionString);
}
public async UniTask<Dictionary<string,OneClickRegisterData>> GetAllTemplate()
{
var array = await oneClickTemplates.ToArrayAsync();
return array.ToDictionary(info => info.Name, info => JsonConvert.DeserializeObject<OneClickRegisterData>(info.Json)!);
}
public async UniTask CreateTemplate(string name,string prefix,Dictionary<string,string> dictionary)
{
var _all =await GetAllTemplate();
if(_all.ContainsKey(name))
throw new ArgumentException("模板已存在");
oneClickTemplates.Add(new Info{Name = name,Json = JsonConvert.SerializeObject(new OneClickRegisterData{Name = name,Prefix = prefix,Dictionary = dictionary})});
await SaveChangesAsync();
}
public async UniTask DeleteTemplate(string name)
{
oneClickTemplates.RemoveRange(oneClickTemplates.Where(x => x.Name == name));
await SaveChangesAsync();
}
public async UniTask<OneClickRegisterData> Register(string templateName,string name)
{
if (string.IsNullOrEmpty(name))
{
name = DateTime.Now.ToString(CultureInfo.InvariantCulture);
}
var _all =await GetAllTemplate();
if(_all.TryGetValue(templateName,out var template) is false)
throw new ArgumentException($"未找到模板:{templateName}");
var tick = DateTime.Now.Ticks;
var export = new OneClickRegisterData
{
Name = name,
Prefix = template.Prefix,
Dictionary = new(),
};
foreach (var (entryName,templateVersion) in template.Dictionary)
{
var handle = $"{template.Prefix}/{tick++}";
await _service.RegisterAsync(handle,templateVersion,Array.Empty<IDIS_Register_Data.ValueInfo>());
export.Dictionary.Add(entryName,handle);
}
await oneClickRegisters.AddAsync(new SavedInfo{Name = name,Json = JsonConvert.SerializeObject(export)});
await SaveChangesAsync();
return export;
}
}

View File

@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using IDIS.Client.Web.Components;
using IDIS.Client.Web.Data;
using IDIS.Models;
using IDIS.Services;
using MudBlazor.Services;
@ -28,6 +29,7 @@ builder.Services.AddMudServices();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddTransient<OneClickRegister>();
builder.Services.AddTransient<QueryService>();
builder.Services.AddTransient<IDIS_Statistics_MySQLBased>();
builder.Services.AddTransient<IDIS_Service_MySQLBased>();

View File

@ -13,7 +13,7 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5150",
"applicationUrl": "http://localhost:5150;http://localhost:5151",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}

View File

@ -6,5 +6,10 @@
}
},
"DefaultConnection":"server=server.bitfall.icu;port=3306;database=ifactory;uid=ifactory;password=JdBfKR2dxhm76Ss2;",
"Urls":"http://+:5150",
"Signature": {
"DefaultHandle": "88.123.99/638514755153927653",
"DefaultType": "base64"
},
"AllowedHosts": "*"
}