@@ -1,2 +1,11 @@ | |||
# JTTools | |||
# JTTools | |||
JT808、JT809、JT1078、JTNE解析工具 | |||
[在线解析工具](http://jttools.smallchi.cn) | |||
使用nodejs的PM2托管应用程序 | |||
``` 1 | |||
pm2 start "dotnet JTTools.dll ASPNETCORE_ENVIRONMENT=Production" -n "JTTools.18888" -o "/home/Logs/JTTools/out.log" -e "/home/Logs/JTTools/error.log" | |||
``` |
@@ -0,0 +1,25 @@ | |||
| |||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||
# Visual Studio Version 16 | |||
VisualStudioVersion = 16.0.29123.88 | |||
MinimumVisualStudioVersion = 10.0.40219.1 | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JTTools", "JTTools\JTTools.csproj", "{4F7C65A6-85D2-4F32-AC00-B43D2C296618}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
Debug|Any CPU = Debug|Any CPU | |||
Release|Any CPU = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||
{4F7C65A6-85D2-4F32-AC00-B43D2C296618}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{4F7C65A6-85D2-4F32-AC00-B43D2C296618}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{4F7C65A6-85D2-4F32-AC00-B43D2C296618}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{4F7C65A6-85D2-4F32-AC00-B43D2C296618}.Release|Any CPU.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
EndGlobalSection | |||
GlobalSection(ExtensibilityGlobals) = postSolution | |||
SolutionGuid = {3C3239D7-6A1E-4D5B-ABB5-851786B72AED} | |||
EndGlobalSection | |||
EndGlobal |
@@ -0,0 +1,103 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
using JTTools.Dtos; | |||
using Microsoft.AspNetCore.Mvc; | |||
using JT1078.Protocol; | |||
using JT808.Protocol; | |||
using JT809.Protocol; | |||
using JT809.Protocol.Exceptions; | |||
using JT808.Protocol.Extensions.JT1078; | |||
using JT809.Protocol.Extensions.JT1078; | |||
using JT808.Protocol.Interfaces; | |||
using JT808.Protocol.Extensions; | |||
using JT808.Protocol.Exceptions; | |||
using Microsoft.AspNetCore.Cors; | |||
namespace JTTools.Controllers | |||
{ | |||
[Route("api/JTTools")] | |||
[ApiController] | |||
[EnableCors("Domain")] | |||
public class JTToolsController : ControllerBase | |||
{ | |||
private readonly IJT809Config jT809Config; | |||
private readonly IJT808Config jT808Config; | |||
private readonly JT808Serializer jT808Serializer; | |||
private readonly JT809Serializer jT809Serializer; | |||
public JTToolsController( | |||
IJT809Config jT809Config, | |||
IJT808Config jT808Config) | |||
{ | |||
this.jT809Config = jT809Config; | |||
this.jT808Config = jT808Config; | |||
jT808Serializer = jT808Config.GetSerializer(); | |||
jT809Serializer = jT809Config.GetSerializer(); | |||
} | |||
[Route("Parse808")] | |||
[HttpPost] | |||
public ActionResult<JTResultDto> Parse808([FromBody]JTRequestDto parameter) | |||
{ | |||
JTResultDto jTResultDto = new JTResultDto(); | |||
try | |||
{ | |||
jTResultDto.Code = 200; | |||
jTResultDto.Data = jT808Serializer.Deserialize(parameter.HexData.ToHexBytes()); | |||
} | |||
catch(JT808Exception ex) | |||
{ | |||
jTResultDto.Code = 500; | |||
jTResultDto.Message = $"{ex.ErrorCode}-{ex.Message}"; | |||
} | |||
catch (Exception ex) | |||
{ | |||
jTResultDto.Code = 500; | |||
jTResultDto.Message = ex.Message; | |||
} | |||
return jTResultDto; | |||
} | |||
[Route("Parse809")] | |||
[HttpPost] | |||
public ActionResult<JTResultDto> Parse809([FromBody]JTRequestDto parameter) | |||
{ | |||
JTResultDto jTResultDto = new JTResultDto(); | |||
try | |||
{ | |||
jTResultDto.Code = 200; | |||
jTResultDto.Data = jT809Serializer.Deserialize(parameter.HexData.ToHexBytes()); | |||
} | |||
catch (JT809Exception ex) | |||
{ | |||
jTResultDto.Code = 500; | |||
jTResultDto.Message = $"{ex.ErrorCode}-{ex.Message}"; | |||
} | |||
catch (Exception ex) | |||
{ | |||
jTResultDto.Code = 500; | |||
jTResultDto.Message = ex.Message; | |||
} | |||
return jTResultDto; | |||
} | |||
[Route("Parse1078")] | |||
[HttpPost] | |||
public ActionResult<JTResultDto> Parse1078([FromBody]JTRequestDto parameter) | |||
{ | |||
JTResultDto jTResultDto = new JTResultDto(); | |||
try | |||
{ | |||
jTResultDto.Code = 200; | |||
jTResultDto.Data = JT1078Serializer.Deserialize(parameter.HexData.ToHexBytes()); | |||
} | |||
catch (Exception ex) | |||
{ | |||
jTResultDto.Code = 500; | |||
jTResultDto.Message = ex.Message; | |||
} | |||
return jTResultDto; | |||
} | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace JTTools.Dtos | |||
{ | |||
public class JTRequestDto | |||
{ | |||
public string HexData { get; set; } | |||
public bool Skip { get; set; } | |||
public bool Custom { get; set; } | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
namespace JTTools.Dtos | |||
{ | |||
public class JTResultDto | |||
{ | |||
public int Code { get; set; } | |||
public string Message { get; set; } | |||
public object Data { get; set; } | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
<Project Sdk="Microsoft.NET.Sdk.Web"> | |||
<PropertyGroup> | |||
<TargetFramework>netcoreapp2.2</TargetFramework> | |||
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Content Remove="appsettings.json" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<PackageReference Include="JT1078" Version="1.0.0" /> | |||
<PackageReference Include="JT808" Version="2.1.2" /> | |||
<PackageReference Include="JT808.Protocol.Extensions.JT1078" Version="1.0.1" /> | |||
<PackageReference Include="JT809" Version="2.1.0" /> | |||
<PackageReference Include="JT809.Protocol.Extensions.JT1078" Version="1.0.0" /> | |||
<PackageReference Include="Microsoft.AspNetCore.App" /> | |||
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" /> | |||
<PackageReference Include="NLog.Extensions.Logging" Version="1.5.2" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="appsettings.json"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</None> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,29 @@ | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace JTTools | |||
{ | |||
public class ByteArrayHexConverter : JsonConverter | |||
{ | |||
public override bool CanConvert(Type objectType) => objectType == typeof(byte[]); | |||
public override bool CanRead => false; | |||
public override bool CanWrite => true; | |||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => throw new NotImplementedException(); | |||
private readonly string _separator; | |||
public ByteArrayHexConverter(string separator = " ") => _separator = separator; | |||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) | |||
{ | |||
var hexString = string.Join(_separator, ((byte[])value).Select(p => p.ToString("X2"))); | |||
writer.WriteValue(hexString); | |||
} | |||
} | |||
} |
@@ -0,0 +1,72 @@ | |||
using Microsoft.AspNetCore; | |||
using Microsoft.AspNetCore.Hosting; | |||
using Microsoft.AspNetCore.Builder; | |||
using Microsoft.AspNetCore.Mvc; | |||
using Microsoft.Extensions.DependencyInjection; | |||
using JT808.Protocol; | |||
using JT809.Protocol; | |||
using JT808.Protocol.Extensions.JT1078; | |||
using JT809.Protocol.Extensions.JT1078; | |||
using Newtonsoft.Json.Serialization; | |||
using System; | |||
using Microsoft.Extensions.Logging; | |||
using NLog.Extensions.Logging; | |||
using Microsoft.Extensions.Configuration; | |||
namespace JTTools | |||
{ | |||
public class Program | |||
{ | |||
public static void Main(string[] args) | |||
{ | |||
WebHost.CreateDefaultBuilder(args) | |||
.ConfigureAppConfiguration((hostingContext, config) => | |||
{ | |||
config.SetBasePath(AppDomain.CurrentDomain.BaseDirectory); | |||
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); | |||
}) | |||
.ConfigureKestrel(ksOptions=> | |||
{ | |||
ksOptions.ListenAnyIP(18888); | |||
}) | |||
.ConfigureLogging((context,logging) => { | |||
//if (Environment.OSVersion.Platform == PlatformID.Unix) | |||
//{ | |||
// NLog.LogManager.LoadConfiguration("Configs/nlog.unix.config"); | |||
//} | |||
//else | |||
//{ | |||
// NLog.LogManager.LoadConfiguration("Configs/nlog.win.config"); | |||
//} | |||
//logging.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true }); | |||
//logging.SetMinimumLevel(LogLevel.Trace); | |||
}) | |||
.ConfigureServices(services => | |||
{ | |||
services.AddMvc() | |||
.AddJsonOptions(jsonOptions => | |||
{ | |||
jsonOptions.SerializerSettings.Converters.Add(new ByteArrayHexConverter()); | |||
jsonOptions.SerializerSettings.ContractResolver = new DefaultContractResolver(); | |||
}) | |||
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2); | |||
services.AddCors(options => | |||
options.AddPolicy("Domain",builder => builder.WithOrigins("http://jttools.smallchi.cn") | |||
.AllowAnyMethod() | |||
.AllowAnyHeader() | |||
.AllowAnyOrigin() | |||
.AllowCredentials())); | |||
services.AddJT808Configure() | |||
.AddJT1078Configure(); | |||
services.AddJT809Configure() | |||
.AddJT1078Configure(); | |||
}) | |||
.Configure(app => { | |||
app.UseCors("Domain"); | |||
app.UseMvc(); | |||
}) | |||
.Build() | |||
.Run(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,9 @@ | |||
{ | |||
"Logging": { | |||
"LogLevel": { | |||
"Default": "Debug", | |||
"System": "Information", | |||
"Microsoft": "Information" | |||
} | |||
} | |||
} |
@@ -0,0 +1,8 @@ | |||
{ | |||
"Logging": { | |||
"LogLevel": { | |||
"Default": "Debug" //Warning | |||
} | |||
}, | |||
"AllowedHosts": "*" | |||
} |
@@ -0,0 +1,166 @@ | |||
<!DOCTYPE html> | |||
<html> | |||
<head> | |||
<meta charset="utf-8"> | |||
<title>JTTools解析工具</title> | |||
<!-- import Vue.js --> | |||
<script src="//vuejs.org/js/vue.min.js"></script> | |||
<!-- import stylesheet --> | |||
<link rel="stylesheet" href="//unpkg.com/iview/dist/styles/iview.css"> | |||
<!-- import iView --> | |||
<script src="//unpkg.com/iview/dist/iview.min.js"></script> | |||
<script type="text/javascript" src="https://unpkg.com/axios/dist/axios.min.js"></script> | |||
<script src="https://cdn.bootcss.com/dayjs/1.8.14/dayjs.min.js"></script> | |||
<style> | |||
.pane-content{ | |||
width: 100%; | |||
display: flex; | |||
display: -webkit-flex; | |||
align-items:center; | |||
justify-content:center; | |||
height: calc(100vh - 60px); | |||
padding: 10px 20px; | |||
} | |||
.left,.right{ | |||
width: 45%; | |||
height: 100%; | |||
display: inline-block; | |||
} | |||
.center{ | |||
width: 10%; | |||
display: flex; | |||
display: -webkit-flex; | |||
align-items: center; | |||
justify-content: center; | |||
} | |||
textarea.ivu-input { | |||
max-height: 100%; | |||
min-height: 32px; | |||
height: 100%; | |||
} | |||
.ivu-input-wrapper{ | |||
height: 100%; | |||
} | |||
@media (max-width:1024px){ | |||
.left,.right{ | |||
width: 40%; | |||
} | |||
.center{ | |||
width: 20%; | |||
} | |||
} | |||
</style> | |||
</head> | |||
<body> | |||
<div id="app"> | |||
<tabs value="name1"> | |||
<tab-pane label="JT808解析工具" name="name1" > | |||
<div class="pane-content" > | |||
<div class="left" > | |||
<i-input type="textarea" placeholder="Enter something..." /> | |||
</div> | |||
<div class="center" > | |||
<i-button type="primary">Primary</i-button> | |||
</div> | |||
<div class="right" > | |||
<i-input type="textarea" placeholder="Enter something..." /> | |||
</div> | |||
</div> | |||
</tab-pane> | |||
<tab-pane label="JT809解析工具" name="name2"> | |||
<div class="pane-content" > | |||
<div class="left" > | |||
<i-input type="textarea" placeholder="Enter something..." /> | |||
</div> | |||
<div class="center" > | |||
<i-button type="primary">Primary2</i-button> | |||
</div> | |||
<div class="right" > | |||
<i-input type="textarea" placeholder="Enter something..." /> | |||
</div> | |||
</div> | |||
</tab-pane> | |||
<tab-pane label="JT1078解析工具" name="name3"> | |||
<div class="pane-content" > | |||
<div class="left" > | |||
<i-input type="textarea" placeholder="Enter something..." /> | |||
</div> | |||
<div class="center" > | |||
<i-button type="primary">Primary3</i-button> | |||
</div> | |||
<div class="right" > | |||
<i-input type="textarea" placeholder="Enter something..." /> | |||
</div> | |||
</div> | |||
</tab-pane> | |||
</tabs> | |||
</div> | |||
<script> | |||
new Vue({ | |||
el: '#app', | |||
data: { | |||
loading: false, | |||
}, | |||
mounted:function(){ | |||
}, | |||
methods: { | |||
Api:{ | |||
parse808:function(){ | |||
this.loading=true; | |||
axios.post('http://jttools.smallchi.cn/api/JTTools/Parse808',this.queryParameter) | |||
.then((response)=>{ | |||
if(response.data=="" || response.data==null){ | |||
this.queryData=[]; | |||
this.loading=false; | |||
return; | |||
} | |||
this.queryData=response.data; | |||
this.loading=false; | |||
}) | |||
.catch((error)=>{ | |||
this.queryError=error; | |||
this.loading=false; | |||
}); | |||
}, | |||
parse809:function(){ | |||
this.loading=true; | |||
axios.post('http://jttools.smallchi.cn/api/JTTools/Parse809',this.queryParameter) | |||
.then((response)=>{ | |||
if(response.data=="" || response.data==null){ | |||
this.queryData=[]; | |||
this.loading=false; | |||
return; | |||
} | |||
this.queryData=response.data; | |||
this.loading=false; | |||
}) | |||
.catch((error)=>{ | |||
this.queryError=error; | |||
this.loading=false; | |||
}); | |||
}, | |||
parse1078:function(){ | |||
this.loading=true; | |||
axios.post('http://jttools.smallchi.cn/api/JTTools/Parse1078',this.queryParameter) | |||
.then((response)=>{ | |||
if(response.data=="" || response.data==null){ | |||
this.queryData=[]; | |||
this.loading=false; | |||
return; | |||
} | |||
this.queryData=response.data; | |||
this.loading=false; | |||
}) | |||
.catch((error)=>{ | |||
this.queryError=error; | |||
this.loading=false; | |||
}); | |||
} | |||
} | |||
} | |||
}) | |||
</script> | |||
</body> | |||
</html> |