app接口传递的数据存储到数据库

This commit is contained in:
Hinse 2021-08-01 15:25:01 +08:00
parent aba7d04f81
commit b14de78b28
14 changed files with 488 additions and 83 deletions

View File

@ -192,7 +192,62 @@ namespace Nirvana.Common.File
return new byte[0];
}
public static async Task<ProcessData> ApiProcessStreamedFile(
MultipartSection section, ContentDispositionHeaderValue contentDisposition,
ModelStateDictionary modelState, string[] permittedExtensions, long sizeLimit)
{
try
{
using (var memoryStream = new MemoryStream())
{
await section.Body.CopyToAsync(memoryStream);
// Check if the file is empty or exceeds the size limit.
if (memoryStream.Length == 0)
{
modelState.AddModelError("File", "文件不可为空");
}
else if (memoryStream.Length > sizeLimit)
{
var megabyteSizeLimit = sizeLimit / 1048576;
modelState.AddModelError("File",
$"文件大小超过了{megabyteSizeLimit:N1} MB.");
}
else if (permittedExtensions !=null && permittedExtensions.Length>0 && !IsValidFileExtensionAndSignature(
contentDisposition.FileName.Value, memoryStream,
permittedExtensions))
{
modelState.AddModelError("File",
"此文件格式不支持");
}
else
{
return new ProcessData
{
data = memoryStream.ToArray(),
modelState = modelState
};
}
}
}
catch (Exception ex)
{
modelState.AddModelError("File",
$"上传失败,发生错误,请联系客服人员解决. Error: {ex.HResult}");
// Log the exception
LogFactory.InsertErrorLog($"上传失败,{ex.Message},{ex.HResult}");
}
return new ProcessData
{
data = new byte[0],
modelState = modelState
};
}
public class ProcessData
{
public byte[] data { get; set; }
public ModelStateDictionary modelState { get; set; }
}
private static bool IsValidFileExtensionAndSignature(string fileName, Stream data, string[] permittedExtensions)
{
if (string.IsNullOrEmpty(fileName) || data == null || data.Length == 0)

View File

@ -134,14 +134,14 @@ namespace Waste.Application
{
//查找设备
var device = await repository.Change<W_Device>().Context.Queryable<W_Device>().FirstAsync(x => myPackage.IMEI == x.Ecode);
_loggerService.AddLogger($"接收到的数据,参数:{myPackage.ToJson()}", 3);
// _loggerService.AddLogger($"接收到的数据,参数:{myPackage.ToJson()}", 3);
if (device == null)
{
//记录日志
_loggerService.AddLogger($"设备未找到,参数:{myPackage.ToJson()}", 3);
return new ResultInfo(ResultState.FAIL, "设备未找到");
}
var devicedata = await repository.Change<W_DeviceData>().Context.Queryable<W_DeviceData>().FirstAsync(x => x.DeviceId == device.Id);
var devicedata = await dbClient.Queryable<W_DeviceData>().FirstAsync(x => x.DeviceId == device.Id);
var resultid = IDGen.NextID();
DateTime time = DateTime.Now;
if (myPackage.IsHeart)

View File

@ -34,11 +34,11 @@ namespace Waste.Application.ThirdApiInfo
/// <summary>
/// 纬度
/// </summary>
public string Latitude { get; set; } = "";
public decimal Latitude { get; set; } = 0;
/// <summary>
/// 经度
/// </summary>
public string Longitude { get; set; } = "";
public decimal Longitude { get; set; } = 0;
}
/// <summary>
/// 注册注册信息返回值

View File

@ -1,8 +1,16 @@
using Furion.DynamicApiController;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Net.Http.Headers;
using Nirvana.Common;
using Nirvana.Common.File;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -17,9 +25,14 @@ namespace Waste.Application.ThirdApiInfo
public class OpenAppService : IDynamicApiController
{
private readonly IOpenService _openService;
public OpenAppService(IOpenService openService)
private static IWebHostEnvironment _hostingEnvironment;
private readonly IHttpContextAccessor _httpContextAccessor;
private static readonly FormOptions _defaultFormOptions = new FormOptions();
public OpenAppService(IOpenService openService, IWebHostEnvironment webHostEnvironment, IHttpContextAccessor httpContextAccessor)
{
_openService = openService;
_hostingEnvironment = webHostEnvironment;
_httpContextAccessor = httpContextAccessor;
}
/// <summary>
/// 获取设备上报相关信息
@ -53,5 +66,195 @@ namespace Waste.Application.ThirdApiInfo
{
return await _openService.RegInfoAsync(ecode);
}
/// <summary>
/// BUG上报
/// </summary>
/// <returns></returns>
[HttpPost]
[Route("api/reportbug/Post")]
public async Task<object> PostAsync([FromQuery]string ecode="")
{
var Request = _httpContextAccessor.HttpContext.Request;
//先保存上传的图片
if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
{
return new
{
status = new
{
code = 0,
name = "FAIL",
message = "上传失败"
}
};
}
var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
var reader = new MultipartReader(boundary, Request.Body);
var section = await reader.ReadNextSectionAsync();
while (section != null && section.Body.Position != section.Body.Length)
{
var hasContentDispositionHeader =
ContentDispositionHeaderValue.TryParse(
section.ContentDisposition, out var contentDisposition);
if (hasContentDispositionHeader)
{
if (!MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
{
}
else
{
string[] _permittedExtensions = {};
long _fileSizeLimit = 1048576 * 10;
string rootname = $"/bugs/{DateTime.Now.ToString("yyyyMMdd")}";
string savefolder = _hostingEnvironment.WebRootPath;
ModelStateDictionary modelState = new ModelStateDictionary();
var streameFileData = await FileHelpers.ApiProcessStreamedFile(
section, contentDisposition, modelState,
_permittedExtensions, _fileSizeLimit);
var streamedFileContent = streameFileData.data;
modelState = streameFileData.modelState;
if (!modelState.IsValid)
{
string msg = "上传失败";
if (modelState.Values.Count() > 0)
{
msg = modelState.Values.FirstOrDefault().Errors.FirstOrDefault().ErrorMessage;
}
return new
{
status = new
{
code = 0,
name = "FAIL",
message = msg
}
};
}
var name = $"{Path.GetRandomFileName()}{Path.GetExtension(contentDisposition.FileName.Value)}";
if (!string.IsNullOrEmpty(ecode))
{
name = $"{ecode}_{name}";
}
var thumbnailPath = Path.Combine(savefolder + "/" + rootname, name);
if (!Directory.Exists(Path.GetDirectoryName(thumbnailPath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(thumbnailPath));
}
else
{
//检查文件是否存在
if (System.IO.File.Exists(thumbnailPath))
{
return new
{
status = new
{
code = 0,
name = "FAIL",
message = "此文件已存在"
}
};
}
}
var filepath = Path.Combine("wwwroot" + rootname + "/", name);
var filename = contentDisposition.FileName.Value;
using (var targetStream = File.Create(filepath))
{
await targetStream.WriteAsync(streamedFileContent);
}
}
}
}
return new
{
status = new
{
code = 1,
name = "SUCCESS",
message = ""
}
};
}
/// <summary>
/// 正式升级
/// </summary>
/// <returns></returns>
[HttpGet]
[QueryParameters]
[Route("api/upgrade/get")]
public async Task<object> GetAsync(string type, string ecode = "")
{
string rootpath = _hostingEnvironment.WebRootPath;
//读取文件,返回升级信息
var path = $"{rootpath}/apks/upgrade/{type}.txt";
if (!File.Exists(path))
{
return new
{
status = new
{
code = 0,
name = "FAIL",
message = "不存在任何信息"
}
};
}
FileStream fileStream = new FileStream(path, FileMode.Open);
string result = string.Empty;
using (StreamReader reader = new StreamReader(fileStream))
{
result = await reader.ReadToEndAsync();
}
if (string.IsNullOrEmpty(result))
{
return new
{
status = new
{
code = 0,
name = "FAIL",
message = "不存在任何信息"
}
};
}
return result.ToJson();
}
/// <summary>
/// 获取机器到期时间
/// </summary>
/// <param name="ecode"></param>
/// <returns></returns>
[HttpGet]
[QueryParameters]
[Route("api/machine/getisenable")]
public Object GetIsEnable(string ecode)
{
if (string.IsNullOrEmpty(ecode))
{
return new
{
status = new
{
code = 0,
name = "FAIL",
message = "参数错误"
}
};
}
return new
{
status = new
{
code = 1,
name = "SUCCESS",
message = ""
}
};
}
}
}

View File

@ -37,54 +37,115 @@ namespace Waste.Application.ThirdApiInfo
/// <returns></returns>
public async Task<ResultInfo> GetDevInfoAsync(GetDevInfoRequestDto data)
{
var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == data.ECode);
if (device == null)
//更新上报记录结果
if (data.ResultId.HasValue && data.ResultId.Value != Guid.Empty)
{
return new ResultInfo(ResultState.FAIL, "设备未找到");
int status = data.data.ToInt();
if (await dbClient.Queryable<W_ResultExt>().AnyAsync(x => x.ResultId == data.ResultId.Value))
{
await dbClient.Updateable<W_ResultExt>().SetColumns(x => new W_ResultExt
{
Status = status
}).Where(x => x.ResultId == data.ResultId.Value).ExecuteCommandAsync();
}
else
{
var insertdata = new W_ResultExt
{
Id = IDGen.NextID(),
Status = status,
CreateTime = DateTime.Now,
ResultId = data.ResultId.Value
};
await dbClient.Insertable(insertdata).ExecuteCommandAsync();
}
return new ResultInfo(ResultState.SUCCESS, "success");
}
var devicesecret = await dbClient.Queryable<W_SZDevice>().FirstAsync(x => x.DeviceId == device.Id);
if (devicesecret == null || string.IsNullOrEmpty(devicesecret.Secret)
|| string.IsNullOrEmpty(devicesecret.SecretHash)
|| string.IsNullOrEmpty(devicesecret.DevId))
else
{
return new ResultInfo(ResultState.FAIL, "设备还未获取验证信息");
}
int timestamp = _suZhouService.GetTimestamp();
int noncestr = _suZhouService.GetNonce();
var returndata = new GetDevInfoResponseDto
{
DeviceId = devicesecret.DevId,
noncestr = noncestr,
timestamp = timestamp,
Secret = devicesecret.Secret,
SecretHash = devicesecret.SecretHash,
UserId = UserId,
PostUrl = ApiUrl,
ScanningTime = GetTimestamp(DateTime.Now),
ResultId = IDGen.NextID()
};
//解析协议,IC卡数据@垃圾桶编号@厨余垃圾@7.91
// 00000000003031 40 000F000002 40 C6E4CBFBC0ACBBF8 40 35312E300D0A
if (!string.IsNullOrEmpty(data.data) && data.data.Length> 52)
{
data.data = data.data.Replace(" ", "");
//收到的为16进制,对数据进行解析,0-4预留,5-垃圾种类,6-垃圾桶大小,7-@,8-12垃圾桶编号,13@,14-21垃圾种类汉子,22@,23-结束重量, OD OA 回车换行
data.data = data.data.Substring(0,data.data.Length-4);
var trashhex = data.data.Substring(16, 10);
var typehex = data.data.Substring(28, 16);
var weighthex = data.data.Substring(46, data.data.Length - 46);
returndata.trash = trashhex;
var type = GetChsFromHex(typehex);
var weight = GetChsFromHex(weighthex);
returndata.type = TrashType(type);
returndata.Weight = weight.ToDouble();
returndata.IsSuccessed = true;
string[] paramlist = new string[] {
var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == data.ECode);
if (device == null)
{
return new ResultInfo(ResultState.FAIL, "设备未找到");
}
var devicesecret = await dbClient.Queryable<W_SZDevice>().FirstAsync(x => x.DeviceId == device.Id);
if (devicesecret == null || string.IsNullOrEmpty(devicesecret.Secret)
|| string.IsNullOrEmpty(devicesecret.SecretHash)
|| string.IsNullOrEmpty(devicesecret.DevId))
{
return new ResultInfo(ResultState.FAIL, "设备还未获取验证信息");
}
int timestamp = _suZhouService.GetTimestamp();
int noncestr = _suZhouService.GetNonce();
var returndata = new GetDevInfoResponseDto
{
DeviceId = devicesecret.DevId,
noncestr = noncestr,
timestamp = timestamp,
Secret = devicesecret.Secret,
SecretHash = devicesecret.SecretHash,
UserId = UserId,
PostUrl = ApiUrl,
ScanningTime = GetTimestamp(DateTime.Now),
ResultId = IDGen.NextID()
};
//解析协议,IC卡数据@垃圾桶编号@厨余垃圾@7.91
// 00000000003031 40 000F000002 40 C6E4CBFBC0ACBBF8 40 35312E300D0A
if (!string.IsNullOrEmpty(data.data) && data.data.Length > 52)
{
data.data = data.data.Replace(" ", "");
//收到的为16进制,对数据进行解析,0-4预留,5-垃圾种类,6-垃圾桶大小,7-@,8-12垃圾桶编号,13@,14-21垃圾种类汉子,22@,23-结束重量, OD OA 回车换行
data.data = data.data.Substring(0, data.data.Length - 4);
var trashhex = data.data.Substring(16, 10);
var typehex = data.data.Substring(28, 16);
var weighthex = data.data.Substring(46, data.data.Length - 46);
returndata.trash = trashhex;
var type = GetChsFromHex(typehex);
var weight = GetChsFromHex(weighthex);
returndata.type = TrashType(type);
returndata.Weight = weight.ToDouble();
returndata.IsSuccessed = true;
string[] paramlist = new string[] {
returndata.Weight.ToString(),returndata.trash,returndata.type.ToString(),returndata.ScanningTime.ToString(),returndata.status.ToString()
};
returndata.sign = _suZhouService.GetUserApiSign(returndata.Secret, paramlist);
returndata.sign = _suZhouService.GetUserApiSign(returndata.Secret, paramlist);
//保存测量结果
var devicedata = await dbClient.Queryable<W_DeviceData>().FirstAsync(x => x.DeviceId == device.Id);
DateTime time = DateTime.Now;
//检查设备是否为今天第一次上报
bool isfrist = false;
if (device.LastHeartTime.HasValue && device.LastHeartTime.Value.Date != DateTime.Now.Date)
{
isfrist = true;
}
//记录数据
data.IMEI = data.IMEI.ToStr();
data.ICCID = data.ICCID.ToStr();
data.IMSI = data.IMSI.ToStr();
await dbClient.Ado.UseStoredProcedure().ExecuteCommandAsync("Proc_InsertResult", new
{
deviceid = device.Id,
businessid = device.Businessid,
resultid = returndata.ResultId,
imei = data.IMEI,
iccid = data.ICCID,
imsi = data.IMSI,
time = time,
latitude = data.Latitude,
longitude = data.Longitude,
sign = data.GSLQ,
city = "",
area = returndata.trash,
wastetype = type,
weigth = weight,
isheart = 0,
tare = device.Tare,
isfrist = isfrist
});
}
return new ResultInfo(ResultState.SUCCESS, "success", returndata);
}
return new ResultInfo(ResultState.SUCCESS, "success", returndata);
}
/// <summary>
/// 16进制转汉字
@ -114,7 +175,7 @@ namespace Waste.Application.ThirdApiInfo
}
}
// 获得 GB2312Chinese Simplified。
Encoding chs = Encoding.GetEncoding("gb2312");
Encoding chs = Encoding.GetEncoding("gb2312");
return chs.GetString(bytes);
}
/// <summary>
@ -129,6 +190,47 @@ namespace Waste.Application.ThirdApiInfo
{
return new ResultInfo(ResultState.FAIL, "设备未找到");
}
if (await dbClient.Queryable<W_DeviceData>().AnyAsync(x => x.DeviceId == device.Id))
{
//更新设备心跳信息
if (data.Latitude == 0 || data.Longitude == 0)
{
await dbClient.Updateable<W_DeviceData>()
.SetColumns(x => new W_DeviceData
{
LastBeatTime = DateTime.Now
})
.Where(x => x.DeviceId == device.Id).ExecuteCommandAsync();
}
else
{
string longitude = data.Longitude.ToString();
string Latitude = data.Latitude.ToString();
await dbClient.Updateable<W_DeviceData>()
.SetColumns(x => new W_DeviceData
{
LastBeatTime = DateTime.Now,
Longitude = longitude,
Latitude = Latitude
})
.Where(x => x.DeviceId == device.Id).ExecuteCommandAsync();
}
}
else
{
var insertdata = new W_DeviceData
{
DeviceId = device.Id,
Sign = data.GSLQ.ToString(),
IMSI = data.IMSI,
ICCID = data.ICCID,
IMEI = data.IMEI,
LastBeatTime = DateTime.Now,
Latitude = data.Latitude.ToString(),
Longitude = data.Longitude.ToString()
};
await dbClient.Insertable(insertdata).ExecuteCommandAsync();
}
return new ResultInfo(ResultState.SUCCESS, "success");
}
/// <summary>
@ -139,10 +241,35 @@ namespace Waste.Application.ThirdApiInfo
public async Task<ResultInfo> RegInfoAsync(string ecode)
{
var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == ecode);
//if (device == null)
//{
// return new ResultInfo(ResultState.FAIL, "设备未找到");
//}
if (device == null)
{
return new ResultInfo(ResultState.FAIL, "设备未找到", new DevRegInfoResponseDto());
}
//更新开机时间
if (await dbClient.Queryable<W_DeviceData>().AnyAsync(x => x.DeviceId == device.Id))
{
await dbClient.Updateable<W_DeviceData>()
.SetColumns(x => new W_DeviceData
{
LastStartTime = DateTime.Now
})
.Where(x => x.DeviceId == device.Id).ExecuteCommandAsync();
}
else
{
var insertdata = new W_DeviceData
{
DeviceId = device.Id,
Sign = "",
IMSI = "",
ICCID = "",
IMEI = "",
Latitude = "0",
Longitude = "0",
LastStartTime = DateTime.Now
};
await dbClient.Insertable(insertdata).ExecuteCommandAsync();
}
var data = new DevRegInfoResponseDto
{
status = 0
@ -157,7 +284,7 @@ namespace Waste.Application.ThirdApiInfo
else if (type == "其他垃圾") return 4;
else return 0;
}
private int GetTimestamp(DateTime time)
private int GetTimestamp(DateTime time)
{
DateTime dateTimeStart = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));
int timestamp = Convert.ToInt32((time - dateTimeStart).TotalSeconds);
@ -168,7 +295,7 @@ namespace Waste.Application.ThirdApiInfo
/// </summary>
/// <param name="bt"></param>
/// <returns></returns>
private string BytesToHexStr( byte[] bt)
private string BytesToHexStr(byte[] bt)
{
string returnStr = "";
if (bt != null)

View File

@ -1,28 +0,0 @@
using Furion.DynamicApiController;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Waste.Application.ThirdApiInfo
{
/// <summary>
/// BUG上报
/// </summary>
[ApiDescriptionSettings("DevApi")]
[NonUnify]
public class ReportBugAppService : IDynamicApiController
{
/// <summary>
/// BUG上报
/// </summary>
/// <returns></returns>
[HttpPost]
public void Post()
{
}
}
}

View File

@ -2152,6 +2152,25 @@
<param name="ecode"></param>
<returns></returns>
</member>
<member name="M:Waste.Application.ThirdApiInfo.OpenAppService.PostAsync(System.String)">
<summary>
BUG上报
</summary>
<returns></returns>
</member>
<member name="M:Waste.Application.ThirdApiInfo.OpenAppService.GetAsync(System.String,System.String)">
<summary>
正式升级
</summary>
<returns></returns>
</member>
<member name="M:Waste.Application.ThirdApiInfo.OpenAppService.GetIsEnable(System.String)">
<summary>
获取机器到期时间
</summary>
<param name="ecode"></param>
<returns></returns>
</member>
<member name="T:Waste.Application.ThirdApiInfo.OpenService">
<summary>
设备对接接口

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Waste.Domain
{
/// <summary>
/// 上报结果
/// </summary>
public class W_ResultExt
{
public Guid Id { get; set; }
/// <summary>
/// 记录ID
/// </summary>
public Guid ResultId { get; set; }
/// <summary>
/// 状态,0-成功,1-失败
/// </summary>
public int Status { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
}
}

View File

@ -5,6 +5,6 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_PublishTargetUrl>D:\webpublish\waste.ybhdmob.com</_PublishTargetUrl>
<History>True|2021-07-31T12:27:53.6583811Z;True|2021-07-31T18:35:23.4214441+08:00;True|2021-07-31T17:34:14.0712243+08:00;True|2021-07-31T14:50:43.2065556+08:00;True|2021-07-30T17:59:30.2223340+08:00;True|2021-07-30T17:57:35.9412910+08:00;True|2021-07-30T17:07:58.3305971+08:00;True|2021-07-30T17:04:10.9244859+08:00;True|2021-07-30T17:02:12.1943634+08:00;True|2021-07-30T16:16:22.2838331+08:00;True|2021-07-30T15:05:26.5664155+08:00;True|2021-07-30T14:57:59.1966108+08:00;True|2021-07-30T14:54:25.8172908+08:00;True|2021-07-30T14:52:20.9209995+08:00;True|2021-07-30T14:35:29.5239463+08:00;True|2021-07-30T09:32:38.2676032+08:00;True|2021-07-30T09:14:42.6170851+08:00;True|2021-07-29T19:06:09.1449349+08:00;True|2021-06-11T08:16:29.9542894+08:00;True|2021-06-04T14:46:02.2707457+08:00;True|2021-06-02T15:08:52.8245632+08:00;True|2021-06-02T15:05:50.3614099+08:00;True|2021-06-02T14:59:32.3690948+08:00;True|2021-06-02T14:10:25.1182836+08:00;True|2021-06-02T14:09:54.9215833+08:00;True|2021-06-01T10:41:54.9488501+08:00;True|2021-06-01T10:38:56.0283198+08:00;True|2021-05-28T13:59:02.2308877+08:00;True|2021-05-28T11:56:26.6796406+08:00;True|2021-05-28T11:28:00.4087907+08:00;True|2021-05-27T16:18:09.5993838+08:00;True|2021-05-27T16:07:31.3484951+08:00;True|2021-05-27T11:30:37.9119310+08:00;True|2021-05-27T11:28:35.5374674+08:00;True|2021-05-27T08:00:09.1625592+08:00;True|2021-05-26T20:42:17.0852150+08:00;True|2021-05-26T20:36:49.7527415+08:00;True|2021-05-25T17:57:31.8791293+08:00;True|2021-05-25T13:49:29.6488978+08:00;True|2021-05-25T13:48:24.6686105+08:00;True|2021-05-25T13:25:41.2512493+08:00;True|2021-05-24T17:55:33.3800078+08:00;True|2021-05-20T14:35:30.6957985+08:00;True|2021-05-20T13:17:22.6192995+08:00;True|2021-05-20T10:51:38.1268169+08:00;True|2021-05-19T19:50:03.7000224+08:00;True|2021-05-19T19:44:27.2518811+08:00;True|2021-05-19T19:43:26.5916681+08:00;True|2021-05-19T19:36:29.3197365+08:00;True|2021-05-19T19:30:00.3802430+08:00;True|2021-05-19T17:55:23.7939835+08:00;True|2021-05-19T11:05:17.9043392+08:00;True|2021-05-19T10:19:38.4839988+08:00;True|2021-05-19T10:17:19.7430612+08:00;True|2021-05-19T10:13:23.0031721+08:00;True|2021-05-19T10:06:03.9881599+08:00;True|2021-05-18T14:39:03.8876574+08:00;True|2021-05-18T14:23:46.9818836+08:00;True|2021-05-18T14:19:56.2382079+08:00;True|2021-05-18T11:29:53.5497590+08:00;True|2021-05-18T11:16:18.0123853+08:00;True|2021-05-17T18:59:52.4159105+08:00;True|2021-05-17T18:53:37.9438984+08:00;True|2021-05-17T18:48:14.9625161+08:00;True|2021-05-17T17:46:03.7723404+08:00;True|2021-05-17T17:14:20.2312990+08:00;True|2021-05-17T16:44:34.5837616+08:00;True|2021-05-17T16:25:20.1087804+08:00;True|2021-05-17T11:35:27.9388562+08:00;</History>
<History>True|2021-08-01T05:49:38.4071985Z;True|2021-08-01T13:36:45.5372120+08:00;True|2021-08-01T11:00:19.6165520+08:00;True|2021-08-01T10:38:51.4029710+08:00;True|2021-07-31T20:27:53.6583811+08:00;True|2021-07-31T18:35:23.4214441+08:00;True|2021-07-31T17:34:14.0712243+08:00;True|2021-07-31T14:50:43.2065556+08:00;True|2021-07-30T17:59:30.2223340+08:00;True|2021-07-30T17:57:35.9412910+08:00;True|2021-07-30T17:07:58.3305971+08:00;True|2021-07-30T17:04:10.9244859+08:00;True|2021-07-30T17:02:12.1943634+08:00;True|2021-07-30T16:16:22.2838331+08:00;True|2021-07-30T15:05:26.5664155+08:00;True|2021-07-30T14:57:59.1966108+08:00;True|2021-07-30T14:54:25.8172908+08:00;True|2021-07-30T14:52:20.9209995+08:00;True|2021-07-30T14:35:29.5239463+08:00;True|2021-07-30T09:32:38.2676032+08:00;True|2021-07-30T09:14:42.6170851+08:00;True|2021-07-29T19:06:09.1449349+08:00;True|2021-06-11T08:16:29.9542894+08:00;True|2021-06-04T14:46:02.2707457+08:00;True|2021-06-02T15:08:52.8245632+08:00;True|2021-06-02T15:05:50.3614099+08:00;True|2021-06-02T14:59:32.3690948+08:00;True|2021-06-02T14:10:25.1182836+08:00;True|2021-06-02T14:09:54.9215833+08:00;True|2021-06-01T10:41:54.9488501+08:00;True|2021-06-01T10:38:56.0283198+08:00;True|2021-05-28T13:59:02.2308877+08:00;True|2021-05-28T11:56:26.6796406+08:00;True|2021-05-28T11:28:00.4087907+08:00;True|2021-05-27T16:18:09.5993838+08:00;True|2021-05-27T16:07:31.3484951+08:00;True|2021-05-27T11:30:37.9119310+08:00;True|2021-05-27T11:28:35.5374674+08:00;True|2021-05-27T08:00:09.1625592+08:00;True|2021-05-26T20:42:17.0852150+08:00;True|2021-05-26T20:36:49.7527415+08:00;True|2021-05-25T17:57:31.8791293+08:00;True|2021-05-25T13:49:29.6488978+08:00;True|2021-05-25T13:48:24.6686105+08:00;True|2021-05-25T13:25:41.2512493+08:00;True|2021-05-24T17:55:33.3800078+08:00;True|2021-05-20T14:35:30.6957985+08:00;True|2021-05-20T13:17:22.6192995+08:00;True|2021-05-20T10:51:38.1268169+08:00;True|2021-05-19T19:50:03.7000224+08:00;True|2021-05-19T19:44:27.2518811+08:00;True|2021-05-19T19:43:26.5916681+08:00;True|2021-05-19T19:36:29.3197365+08:00;True|2021-05-19T19:30:00.3802430+08:00;True|2021-05-19T17:55:23.7939835+08:00;True|2021-05-19T11:05:17.9043392+08:00;True|2021-05-19T10:19:38.4839988+08:00;True|2021-05-19T10:17:19.7430612+08:00;True|2021-05-19T10:13:23.0031721+08:00;True|2021-05-19T10:06:03.9881599+08:00;True|2021-05-18T14:39:03.8876574+08:00;True|2021-05-18T14:23:46.9818836+08:00;True|2021-05-18T14:19:56.2382079+08:00;True|2021-05-18T11:29:53.5497590+08:00;True|2021-05-18T11:16:18.0123853+08:00;True|2021-05-17T18:59:52.4159105+08:00;True|2021-05-17T18:53:37.9438984+08:00;True|2021-05-17T18:48:14.9625161+08:00;True|2021-05-17T17:46:03.7723404+08:00;True|2021-05-17T17:14:20.2312990+08:00;True|2021-05-17T16:44:34.5837616+08:00;True|2021-05-17T16:25:20.1087804+08:00;True|2021-05-17T11:35:27.9388562+08:00;</History>
</PropertyGroup>
</Project>

View File

@ -0,0 +1 @@
{"status":{"code":100,"name":"新版本1.0.0","update_url":"http://waste.jt-sky.com/apks/upgrade/appr311-signed.apk"}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB