Commit 4897a0e0 by Neo Turing

森马升级

parent f1f173f9
......@@ -8,14 +8,36 @@ namespace Njhg.Third.Semir
{
public static class Configs
{
public const string _defaultUrl = "https://scm.semir.com";
public const string _pdfUrl = "http://njhg.lims.kivii.org";
public const string _token = "eE9ZeUhodXpRS0djRUFCZ2R2Z2FmMk5ENjFoNFE1aUs=";
//public const string _defaultUrl = "https://scm.semir.com";//正式
//public const string _token = "eE9ZeUhodXpRS0djRUFCZ2R2Z2FmMk5ENjFoNFE1aUs=";//正式
public const string _defaultUrl = "https://scmtest.semirapp.com";//测试
public const string _token = "dVRKbW1NMXNtbVlHVmdjYm9CTHl2TmhtRUpSbDNodjI=";//测试
public const string _ownerName = "浙江森马电子商务有限公司";
public const string _ownerKvid = "5A6EC61D-63BE-41AE-AAD9-03DD3FF92095";
public const string RouteGenerateQcResult = "/thirdpartyapi/qc-wts/generate-qc-result";
/// <summary>
/// 检测结果接口(回写检测结果并关闭委托书)
/// </summary>
public const string RouteGenerateWtsResult = "/thirdpartyapi/qc-wts/generate-qc-result";
/// <summary>
/// 检测结果接口(更新检测结果,但不会关闭委托书,每次调用都会将之前的结果清除,更新为最新传入的结果)
/// </summary>
public const string RouteUpdateWtsResult = "/thirdpartyapi/qc-wts/update-qc-result";
/// <summary>
/// 关闭委托书接口
/// </summary>
public const string RouteCloseWts = "/thirdpartyapi/qc-wts/close-wts";
public const string RouteAcceptWts = "/thirdpartyapi/qc-wts/accept-wts";
public const string RouteGetWtsList = "/thirdpartyapi/qc-wts/get-wts-list";
public const string RouteGetWtsData = "/thirdpartyapi/qc-wts/get-wts-data";
public const string TableNameSemirRelation = "SMR_SemirRelations";
}
}
......@@ -54,6 +54,13 @@ namespace Njhg.Third.Semir.Entities
/// </summary>
[ApiMember(Description = "检测项⽬描述")]
public string ITEM_DESC { get; set; }
/// <summary>
/// 检测项目编码
/// </summary>
[ApiMember(Description = "检测项目编码")]
public string ITEM_CODE { get; set; }
/// <summary>
/// 检测项模板ID
/// </summary>
......@@ -69,6 +76,13 @@ namespace Njhg.Third.Semir.Entities
/// </summary>
[ApiMember(Description = "测试⽅法")]
public string ITEM_STANDARD { get; set; }
/// <summary>
/// 标准编码
/// </summary>
[ApiMember(Description = "标准编码")]
public string ITEM_STANDARD_CODE { get; set; }
/// <summary>
/// 检测指标,单位
/// </summary>
......
......@@ -184,51 +184,7 @@ namespace Njhg.Third.Semir.Entities
if (!report.TestNeedJudge) reportDetail.RPT_DESC = "此报告无需判定";
reportDetail.ITEMS = new List<Detail>();
foreach (var item in primaryAllReportItems)
{
var nodeItems = allReportItems.Where(o => o.ParentKvid == item.Kvid).ToList();
#region 拼接检测要求及检测值
var spec2List = new List<string>();
var resultList = new List<string>();
if (item.Type == ReportItemType.Test)
{
spec2List.Add($"{item.Title}({item.DetectionValueQualified})");
resultList.Add($"{item.Title}({item.TestValue})");
}
else if (!nodeItems.IsNullOrEmpty())
{
foreach (var node in nodeItems)
{
spec2List.Add($"{node.Title}({node.DetectionValueQualified})");
resultList.Add($"{node.Title}({node.TestValue})");
}
}
var spec2 = string.Join(", ", spec2List.ToArray());
var result = string.Join(", ", resultList.ToArray());
#endregion
var detail = new Detail();
detail.ITEM_NAME = item.Title;
detail.ITEM_DESC = item.Title;
detail.TEMP_ITEM_ID = "";
detail.F1_DISPLAY = item.PackageUnit;
detail.ITEM_STANDARD = item.DetectionCodeActual;
detail.ITEM_SPEC1 = "";
detail.ITEM_SPEC2 = spec2;
detail.CHECK_PART = item.TitlePart;
detail.CHECK_PART_DISPLAY = item.TitlePart;
detail.RESULT = 4;
if (item.Judgement == "合格") detail.RESULT = 1;
else if (item.Judgement == "不合格")
{
infoJudement = false;
detail.RESULT = 0;
}
else detail.RESULT_TEXT = "此项无需判定";
detail.RESULT_REMARK = result;
reportDetail.ITEMS.Add(detail);
}
reportDetail.ITEMS = primaryAllReportItems.ConverToDetails(allReportItems);
rpt_detail.Add(reportDetail);
#endregion
}
......@@ -248,9 +204,7 @@ namespace Njhg.Third.Semir.Entities
body.Add("result_info", info);
body.Add("rpt_detail", rpt);
Console.WriteLine($"result_info:{info}\n");
Console.WriteLine($"rpt_detail:{rpt}\n");
var resp = _client.Post<SemirOrderResponse>($"{Configs.RouteGenerateQcResult}?token={Configs._token}", body);
var resp = _client.Post<SemirOrderResponse>($"{Configs.RouteUpdateWtsResult}?token={Configs._token}", body);
Console.WriteLine($"Code:{resp.code}\n");
Console.WriteLine($"Message:{resp.message}\n");
Console.WriteLine($"resp_code:{resp.data.resp_code}\n");
......@@ -272,6 +226,17 @@ namespace Njhg.Third.Semir.Entities
log.Title = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
log.Remark = $"Code:{resp.code} Message:{resp.message}";
conn.Insert(log);
if (resp.code == 200)
{
try
{
var bodyClose = new Dictionary<string, string>();
bodyClose.Add("DOC_NO", result_info.DOC_NO);
_client.Post<SemirOrderResponse>($"{Configs.RouteCloseWts}?token={Configs._token}", bodyClose);
}
catch { }
}
return true;
}
else return false;
......
using Kivii.DataAnnotations;
using Kivii;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Njhg.Third.Semir.Entities
{
[Api(Description = "项目对应表")]
[Alias(Configs.TableNameSemirRelation)]
public class SemirRelation : EntityWithMetadata, IEntityInAssemblyDb
{
[ApiMember(Description = "项目名称")]
[StringLength(300)]
[Required, Unique("Semir")]
public string Title { get; set; }
[ApiMember(Description = "项目编码")]
[StringLength(300)]
[Required, Unique("Semir")]
public string Code { get; set; }
}
}
......@@ -74,39 +74,66 @@ namespace Njhg.Third.Semir.Extensions
if (thirdReportOrders.Exists(o => o == item.DOC_NO)) continue;
var third = new ThirdReportOrder();
if (ownerKvid != null) third.OwnerKvid = ownerKvid.Value;
if (!ownerName.IsNullOrEmpty()) third.OwnerName = ownerName;
third.SerialNumber = item.DOC_NO;
third.Name = item.MAT_NAME.Length > 100 ? item.MAT_NAME.Substring(0, 99) : item.MAT_NAME;
third.ThirdName = item.BRAND_DISPLAY;
third.ThirdType = typeof(SemirOrder).FullName;
third.IsAccepted = false;
third.IsUploaded = false;
third.OperateTime = item.CREATED_TIME;
third.ManufacturerName = item.APPLY_ORG_NAME;
third.ManufacturerContactName = item.PAYER_CONTACT_PERSON;
third.SampleName = item.MAT_NAME.Length > 100 ? item.MAT_NAME.Substring(0, 99) : item.MAT_NAME;
third.BatchNumber = item.FG_MAT_CODE;
third.Brand = item.BRAND_DISPLAY;
//thirdReportOrder.Content = JsonSerializer.SerializeToString(item);
try
{
if (ownerKvid != null) third.OwnerKvid = ownerKvid.Value;
if (!ownerName.IsNullOrEmpty()) third.OwnerName = ownerName;
third.SerialNumber = item.DOC_NO.RemoveControlCharacters();
third.Name = item.MAT_NAME.Length > 100 ? item.MAT_NAME.Substring(0, 99) : item.MAT_NAME.RemoveControlCharacters(); ;
third.ThirdName = item.BRAND_DISPLAY.RemoveControlCharacters(); ;
third.ThirdType = typeof(SemirOrder).FullName.RemoveControlCharacters(); ;
third.IsAccepted = false;
third.IsUploaded = false;
third.OperateTime = item.CREATED_TIME;
third.ManufacturerName = item.APPLY_ORG_NAME.RemoveControlCharacters(); ;
third.ManufacturerContactName = item.PAYER_CONTACT_PERSON.RemoveControlCharacters(); ;
third.SampleName = item.MAT_NAME.Length > 100 ? item.MAT_NAME.Substring(0, 99) : item.MAT_NAME.RemoveControlCharacters(); ;
third.BatchNumber = item.FG_MAT_CODE.RemoveControlCharacters(); ;
third.Brand = item.BRAND_DISPLAY.RemoveControlCharacters(); ;
//thirdReportOrder.Content = JsonSerializer.SerializeToString(item);
}
catch (Exception ex)
{
throw ex;
}
third.Metadata = new Dictionary<string, string>();
foreach (var propertyInfo in item.GetType().GetProperties())
{
if (propertyInfo.Name == "ITEMS")
try
{
var items = item.ITEMS;
if (items.IsNullOrEmpty()) items = new List<SemirOrderDetail>();
third.Metadata.Add(propertyInfo.Name, JsonSerializer.SerializeToString(items));
continue;
if (propertyInfo.Name == "ITEMS")
{
var items = item.ITEMS;
if (items.IsNullOrEmpty()) items = new List<SemirOrderDetail>();
third.Metadata.Add(propertyInfo.Name, JsonSerializer.SerializeToString(items).RemoveControlCharacters());
continue;
}
var value = propertyInfo.GetValue(item);
third.Metadata.Add(propertyInfo.Name, value == null ? string.Empty : value.ToString().RemoveControlCharacters());
}
var value = propertyInfo.GetValue(item);
third.Metadata.Add(propertyInfo.Name, value == null ? string.Empty : value.ToString());
catch (Exception ex)
{
throw ex;
}
}
try
{
conn.Insert(third);
//trans?.Commit();
third.RemoveAllOnlyProperties();
rtns.Add(third);
}
catch (Exception ex)
{
throw ex;
}
conn.Insert(third);
//trans?.Commit();
third.RemoveAllOnlyProperties();
rtns.Add(third);
}
}
catch (Exception ex)
......@@ -350,5 +377,117 @@ namespace Njhg.Third.Semir.Extensions
}
return md;
}
/// <summary>
/// 获取森马关系数据(带缓存,缓存10天)
/// </summary>
/// <param name="forceRefresh">是否强制刷新缓存</param>
/// <returns>森马关系数据列表</returns>
internal static List<SemirRelation> GetCachedSemirRelations(bool forceRefresh = false)
{
var cache = KiviiContext.GetCacheClient();
var cacheKey = KiviiContext.GetUrnKey("SemirRelationQuery:Cache10Days");
if (!forceRefresh)
{
var cacheValue = cache.Get<List<SemirRelation>>(cacheKey);
if (!cacheValue.IsNullOrEmpty())
{
return cacheValue;
}
}
// 缓存中没有数据或强制刷新,从数据库查询
var conn = KiviiContext.GetOpenedDbConnection<SemirRelation>();
var results = conn.Select<SemirRelation>();
// 将结果缓存10天
cache.Set(cacheKey, results, TimeSpan.FromDays(10));
return results;
}
public static List<Detail> ConverToDetails(this List<ReportItem> reportItems, List<ReportItem> allReportItems)
{
var rtns = new List<Detail>();
var exists = GetCachedSemirRelations();
foreach (var item in reportItems)
{
var nodeItems = allReportItems.Where(o => o.ParentKvid == item.Kvid).ToList();
#region 拼接检测要求及检测值
var spec2List = new List<string>();
var resultList = new List<string>();
if (item.Type == ReportItemType.Test)
{
spec2List.Add($"{item.Title}({item.DetectionValueQualified})");
resultList.Add($"{item.Title}({item.TestValue})");
}
else if (!nodeItems.IsNullOrEmpty())
{
foreach (var node in nodeItems)
{
spec2List.Add($"{node.Title}({node.DetectionValueQualified})");
resultList.Add($"{node.Title}({node.TestValue})");
}
}
var spec2 = string.Join(", ", spec2List.ToArray());
var result = string.Join(", ", resultList.ToArray());
#endregion
var detail = new Detail();
detail.ITEM_CODE = "H-9999";
detail.ITEM_STANDARD_CODE = "F-9999";
if (!exists.IsNullOrEmpty())
{
var title = item.Title.Replace(" ", "");
var code = item.DetectionCodeActual.Replace(" ", "").Replace("—", "-");
var existTitle = exists.FirstOrDefault(o => o.Title.Replace(" ", "").Contains(title) || title.Contains(o.Title.Replace(" ", "")));
if (existTitle != null)
{
detail.ITEM_CODE = existTitle.Code;
}
var existCode = exists.FirstOrDefault(o => o.Title.Replace(" ", "").Contains(code) || code.Contains(o.Title.Replace(" ", "")));
if (existCode != null)
{
detail.ITEM_STANDARD_CODE = existCode.Code;
}
}
detail.ITEM_NAME = item.Title;
detail.ITEM_DESC = item.Title;
detail.TEMP_ITEM_ID = "";
detail.F1_DISPLAY = item.PackageUnit;
detail.ITEM_STANDARD = item.DetectionCodeActual;
detail.ITEM_SPEC1 = "";
detail.ITEM_SPEC2 = spec2;
detail.CHECK_PART = item.TitlePart;
detail.CHECK_PART_DISPLAY = item.TitlePart;
detail.RESULT = 4;
if (item.Judgement == "合格") detail.RESULT = 1;
else if (item.Judgement == "不合格")
{
detail.RESULT = 0;
}
else detail.RESULT_TEXT = "此项无需判定";
detail.RESULT_REMARK = result;
rtns.Add(detail);
}
return rtns;
}
/// <summary>
/// 移除字符串中的所有不可打印的 Unicode 控制字符
/// </summary>
/// <param name="input">原始字符串</param>
/// <returns>移除控制字符后的字符串</returns>
public static string RemoveControlCharacters(this string input)
{
if (string.IsNullOrEmpty(input))
return input;
// 使用 LINQ 过滤掉控制字符
return new string(input.Where(c => !char.IsControl(c)).ToArray());
}
}
}
......@@ -37,9 +37,11 @@
<Reference Include="Kivii.Core.V4.5, Version=5.6.2024.11000, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Kivii.Core.5.6.2024.11000\lib\net45\Kivii.Core.V4.5.dll</HintPath>
</Reference>
<Reference Include="Kivii.Linq.V4.5, Version=5.6.2023.10000, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Kivii.Linq.5.6.2023.10000\lib\net45\Kivii.Linq.V4.5.dll</HintPath>
<Reference Include="Kivii.Linq.V4.5, Version=5.6.2024.11000, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Kivii.Linq.5.6.2024.11000\lib\net45\Kivii.Linq.V4.5.dll</HintPath>
</Reference>
<Reference Include="Kivii.Office.OpenXml.V4.5, Version=5.6.2025.3220, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Kivii.Office.OpenXml.5.6.2025.3220\lib\net45\Kivii.Office.OpenXml.V4.5.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
......@@ -55,14 +57,18 @@
<Compile Include="Entities\ReportDetail.cs" />
<Compile Include="Entities\SemirOrder.cs" />
<Compile Include="Entities\SemirOrderBase.cs" />
<Compile Include="Entities\SemirRelation.cs" />
<Compile Include="Extensions\SemirExtension.cs" />
<Compile Include="Jobs\SemirOrderJob.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Transforms\RestfulRelation.cs" />
<Compile Include="Transforms\SemirOrderResponse.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="Resources\南京海关森马质检接口描述.docx" />
<None Include="Resources\SCM系统检测项目梳理20250609.xlsx" />
<None Include="Resources\森马质检接口描述.docx" />
<None Include="Resources\森马质检接口描述20250605.docx" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Kivii.Biz.Lims.V1.0\Src\Kivii.Biz.Lims.V1.0.csproj">
......
......@@ -33,5 +33,5 @@ using System.Runtime.InteropServices;
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("5.4.2024.12240")]
[assembly: AssemblyFileVersion("5.4.2024.12240")]
[assembly: AssemblyVersion("5.4.2025.6130")]
[assembly: AssemblyFileVersion("5.4.2025.6130")]
using Kivii;
using Kivii.Linq;
using Kivii.Office.OpenXml.Excel;
using Kivii.Web;
using Njhg.Third.Semir.Entities;
using Njhg.Third.Semir.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Njhg.Third.Semir.Transforms
{
[RequiresAnyRole(MemberRoles.Everyone)]
public class SemirRelationCreate : RestfulCreate<SemirRelation>
{
}
[RequiresAnyRole(MemberRoles.Everyone)]
public class SemirRelationUpdate : RestfulUpdate<SemirRelation>
{
}
[RequiresAnyRole(MemberRoles.Everyone)]
public class SemirRelationRead : RestfulRead<SemirRelation>
{
}
[RequiresAnyRole(MemberRoles.Everyone)]
public class SemirRelationQuery : RestfulQuery<SemirRelation>
{
}
[RequiresAnyRole(MemberRoles.Everyone)]
public class SemirRelationDelete : RestfulDelete<SemirRelation>
{
}
public class SemirRelationImportResponse : RestfulQueryResponse<SemirRelation>
{
public bool success { get; set; }
}
[RequiresAnyRole(MemberRoles.Everyone)]
public class SemirRelationImport : RestfulExecution<SemirRelation>
{
public override object OnExecution(IRequest req, IResponse res)
{
(Request.Files.Count() < 1 || Request.Files == null).ThrowIfTrue("未找到excel文件!");
var httpFile = Request.Files[0];
ExcelPackage package = new ExcelPackage(Request.Files[0].InputStream);
(package.Workbook.Worksheets.Count == 0).ThrowIfTrue("未找到Sheet!");
var conn = KiviiContext.GetOpenedDbConnection<SemirRelation>();
var rtns = new SemirRelationImportResponse();
rtns.Results = new List<SemirRelation>();
var exists = SemirExtension.GetCachedSemirRelations();
try
{
var sheet = package.Workbook.Worksheets[1];
var end = sheet.Dimension.End.Row;
var results = new List<SemirRelation>();
for (int i = 2; i <= end; i++)
{
var title1 = sheet.Cells[i, 4].Value;
var code1 = sheet.Cells[i, 5].Value;
var title2 = sheet.Cells[i, 6].Value;
var code2 = sheet.Cells[i, 7].Value;
if (title1 != null && code1 != null)
{
var reltn1 = new SemirRelation();
reltn1.Title = title1.ToString().Trim();
reltn1.Code = code1.ToString().Trim();
if (!results.Exists(o => o.Title == reltn1.Title && o.Code == reltn1.Code)) results.Add(reltn1);
//conn.Insert(reltn1);
//rtns.Results.Add(reltn1);
}
if (title2 != null && code2 != null)
{
var reltn2 = new SemirRelation();
reltn2.Title = title2.ToString().Trim();
reltn2.Code = code2.ToString().Trim();
if (!results.Exists(o => o.Title == reltn2.Title && o.Code == reltn2.Code)) results.Add(reltn2);
//conn.Insert(reltn2);
//rtns.Results.Add(reltn2);
}
}
if (!results.IsNullOrEmpty())
{
var preInserts = new List<SemirRelation>();
foreach (var item in results)
{
var exist = false;
if (!exists.IsNullOrEmpty())
{
if (exists.Exists(o => o.Title == item.Title && o.Code == item.Code)) exist = true;
}
if (!exist)
{
preInserts.Add(item);
}
}
if (!preInserts.IsNullOrEmpty())
{
conn.InsertAll(preInserts);
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
SemirExtension.GetCachedSemirRelations(true);
}
rtns.success = true;
rtns.Total = rtns.Results.Count;
return rtns;
}
}
}
......@@ -2,5 +2,6 @@
<packages>
<package id="Kivii.Common" version="5.6.2024.11000" targetFramework="net45" />
<package id="Kivii.Core" version="5.6.2024.11000" targetFramework="net45" />
<package id="Kivii.Linq" version="5.6.2023.10000" targetFramework="net45" />
<package id="Kivii.Linq" version="5.6.2024.11000" targetFramework="net45" />
<package id="Kivii.Office.OpenXml" version="5.6.2025.3220" targetFramework="net45" />
</packages>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment