Merge branch 'dev' of https://git.tuotong-tech.com/tnb/tnb.server into dev
This commit is contained in:
@@ -163,6 +163,11 @@ public static class DictConst
|
|||||||
/// andon状态已完成
|
/// andon状态已完成
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string AndonStatusYWC = "5";
|
public const string AndonStatusYWC = "5";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 产成品入库单
|
||||||
|
/// </summary>
|
||||||
|
public const string CHANCHENGPINRUKUDAN = "40";
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Tnb.BasicData.Entities.Dto;
|
|||||||
using Tnb.BasicData.Entitys.Dto.BasProcess;
|
using Tnb.BasicData.Entitys.Dto.BasProcess;
|
||||||
using Tnb.BasicData.Interfaces;
|
using Tnb.BasicData.Interfaces;
|
||||||
using Tnb.EquipMgr.Entities;
|
using Tnb.EquipMgr.Entities;
|
||||||
|
using Tnb.WarehouseMgr.Entities;
|
||||||
|
|
||||||
namespace Tnb.BasicData
|
namespace Tnb.BasicData
|
||||||
{
|
{
|
||||||
@@ -41,8 +42,10 @@ namespace Tnb.BasicData
|
|||||||
.LeftJoin<OrganizeEntity>((a, b) => a.source_id == b.Id)
|
.LeftJoin<OrganizeEntity>((a, b) => a.source_id == b.Id)
|
||||||
.LeftJoin<EqpEquipment>((a, b, c) => a.source_id == c.id)
|
.LeftJoin<EqpEquipment>((a, b, c) => a.source_id == c.id)
|
||||||
.LeftJoin<ToolLocation>((a, b, c, d) => a.source_id == d.id)
|
.LeftJoin<ToolLocation>((a, b, c, d) => a.source_id == d.id)
|
||||||
|
.LeftJoin<BasLocation>((a,b,c,d,e)=>a.source_id==e.id)
|
||||||
|
.LeftJoin<WmsCarryH>((a,b,c,d,e,f)=>a.source_id==f.id)
|
||||||
.Where((a, b, c, d) => a.code == code)
|
.Where((a, b, c, d) => a.code == code)
|
||||||
.Select((a, b, c, d) => new
|
.Select((a, b, c, d,e,f) => new
|
||||||
{
|
{
|
||||||
id = a.id,
|
id = a.id,
|
||||||
source_id = a.source_id,
|
source_id = a.source_id,
|
||||||
@@ -52,6 +55,10 @@ namespace Tnb.BasicData
|
|||||||
equip_code = a.code,
|
equip_code = a.code,
|
||||||
equip_name = c.name,
|
equip_name = c.name,
|
||||||
tool_location_code = d.location_code,
|
tool_location_code = d.location_code,
|
||||||
|
bas_location_name = e.location_name,
|
||||||
|
bas_location_code = e.location_code,
|
||||||
|
carry_name = f.carry_name,
|
||||||
|
carry_code = f.carry_code,
|
||||||
}).FirstAsync();
|
}).FirstAsync();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,5 +212,15 @@ public partial class EqpEquipment : BaseEntity<string>
|
|||||||
/// 挤出件类型
|
/// 挤出件类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? tube { get; set; }
|
public string? tube { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 入库库位id
|
||||||
|
/// </summary>
|
||||||
|
public string? as_location_id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 第三方平台设备编号
|
||||||
|
/// </summary>
|
||||||
|
public string? third_equip_code { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Tnb.ProductionMgr.Entities.Dto
|
||||||
|
{
|
||||||
|
public class InstockInput
|
||||||
|
{
|
||||||
|
public string equip_code { get; set; }
|
||||||
|
public string as_location_code { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
namespace Tnb.ProductionMgr.Entities.Dto
|
||||||
|
{
|
||||||
|
public class KittingOutNewInput
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标库位编号
|
||||||
|
/// </summary>
|
||||||
|
public string location_code { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 齐套搭配方案ID
|
||||||
|
/// </summary>
|
||||||
|
public string collocation_scheme_id { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// 所属工位
|
||||||
|
/// </summary>
|
||||||
|
public string? workstation_id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 任务单
|
||||||
|
/// </summary>
|
||||||
|
public string? mo_task_id { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
namespace Tnb.ProductionMgr.Entities.Dto.PrdManage
|
||||||
|
{
|
||||||
|
public class MaterialPreparationPlanOutput
|
||||||
|
{
|
||||||
|
public string mo_task_id { get; set; }
|
||||||
|
public string mo_task_code { get; set; }
|
||||||
|
public string material_id { get; set; }
|
||||||
|
public string material_code { get; set; }
|
||||||
|
public int? num { get; set; }
|
||||||
|
public List<MaterialPreparationPlanDOutput> children { get; set; } = new List<MaterialPreparationPlanDOutput>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MaterialPreparationPlanDOutput
|
||||||
|
{
|
||||||
|
public int? rate_num { get; set; }
|
||||||
|
public string mo_task_id { get; set; }
|
||||||
|
public string mo_task_code { get; set; }
|
||||||
|
public string parent_id { get; set; }
|
||||||
|
public string material_id { get; set; }
|
||||||
|
public string material_code { get; set; }
|
||||||
|
public List<MaterialPreparationPlanDDOutput> children { get; set; } = new List<MaterialPreparationPlanDDOutput>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MaterialPreparationPlanDDOutput
|
||||||
|
{
|
||||||
|
public string material_id { get; set; }
|
||||||
|
public string material_code { get; set; }
|
||||||
|
public decimal? num { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -144,5 +144,15 @@ namespace Tnb.ProductionMgr.Entities.Dto.PrdManage
|
|||||||
/// 副单位数量(kg)
|
/// 副单位数量(kg)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? deputy_num { get; set; }
|
public string? deputy_num { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 第三方平台设备编号
|
||||||
|
/// </summary>
|
||||||
|
public string? third_equip_code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 称重点位名称
|
||||||
|
/// </summary>
|
||||||
|
public string? weight_name { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,8 +126,8 @@ public partial class PrdReport : BaseEntity<string>
|
|||||||
public string? process_id { get; set; }
|
public string? process_id { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 料箱二维码
|
/// 料箱编号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string material_box_qrcode { get; set; }
|
public string material_box_code { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,5 +21,12 @@ namespace Tnb.ProductionMgr.Interfaces
|
|||||||
/// <param name="dic">source_id</param>
|
/// <param name="dic">source_id</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task<dynamic> SyncInstock(Dictionary<string, string> dic);
|
public Task<dynamic> SyncInstock(Dictionary<string, string> dic);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注塑满箱到位后入库申请
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<dynamic> InstockTypeOne(InstockInput inut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,5 +19,12 @@ namespace Tnb.ProductionMgr.Interfaces
|
|||||||
/// <param name="eqpId"></param>
|
/// <param name="eqpId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<List<PrdMoTask>> GetListByEqpId(string eqpId);
|
Task<List<PrdMoTask>> GetListByEqpId(string eqpId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取备料计划
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<dynamic> GetMaterialPreparationPlan();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Tnb.ProductionMgr.Interfaces
|
||||||
|
{
|
||||||
|
public interface IRedisDataService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 根据机号获取重量
|
||||||
|
/// </summary>
|
||||||
|
Task<dynamic> GetWeight(string key, string field);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ using JNPF.Common.Filter;
|
|||||||
using JNPF.Common.Security;
|
using JNPF.Common.Security;
|
||||||
using JNPF.Systems.Entitys.Permission;
|
using JNPF.Systems.Entitys.Permission;
|
||||||
using JNPF.Systems.Interfaces.Permission;
|
using JNPF.Systems.Interfaces.Permission;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using SQLitePCL;
|
using SQLitePCL;
|
||||||
using SqlSugar.Extensions;
|
using SqlSugar.Extensions;
|
||||||
|
|
||||||
@@ -261,5 +262,132 @@ namespace Tnb.ProductionMgr
|
|||||||
|
|
||||||
return result.IsSuccess;
|
return result.IsSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注塑满箱到位后入库申请
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inut"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="AppFriendlyException"></exception>
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<dynamic> InstockTypeOne(InstockInput inut)
|
||||||
|
{
|
||||||
|
string equip_code = inut.equip_code;
|
||||||
|
string as_location_code = inut.as_location_code;
|
||||||
|
if (!string.IsNullOrEmpty(equip_code)) throw Oops.Bah("请传机台号");
|
||||||
|
var db = _repository.AsSugarClient();
|
||||||
|
EqpEquipment equipment = await db.Queryable<EqpEquipment>().Where(x => x.code == equip_code).FirstAsync();
|
||||||
|
if(equipment==null ) throw Oops.Bah("未找到机台");
|
||||||
|
if(string.IsNullOrEmpty(equipment.as_location_id)) throw Oops.Bah("未找到入库库位");
|
||||||
|
BasLocation basLocation = await db.Queryable<BasLocation>().SingleAsync(x=>x.id==equipment.as_location_id);
|
||||||
|
if(basLocation==null) throw Oops.Bah("未找到入库库位");
|
||||||
|
PrdReport prdReport = await db.Queryable<PrdReport>()
|
||||||
|
.Where(x => x.equip_id == equipment.id && x.status == 0).OrderByDescending(x => x.create_time)
|
||||||
|
.FirstAsync();
|
||||||
|
if(prdReport==null) throw Oops.Bah("未找到提报记录");
|
||||||
|
|
||||||
|
PrdInstockH prdInstockH = null;
|
||||||
|
List<PrdInstockD> prdInstockDs = new List<PrdInstockD>() { };
|
||||||
|
DbResult<bool> result2 = new DbResult<bool>();
|
||||||
|
BasMaterial basMaterial = await db.Queryable<BasMaterial>().SingleAsync(x=>x.id==prdReport.material_id);
|
||||||
|
DbResult<bool> result = await db.Ado.UseTranAsync(async () =>
|
||||||
|
{
|
||||||
|
OrganizeEntity workline = await _organizeService.GetAnyParentByWorkstationId(prdReport.station, DictConst.RegionCategoryWorklineCode);
|
||||||
|
OrganizeEntity workshop = await _organizeService.GetAnyParentByWorkstationId(prdReport.station, DictConst.RegionCategoryWorkshopCode);
|
||||||
|
|
||||||
|
prdInstockH = new PrdInstockH()
|
||||||
|
{
|
||||||
|
bill_type = DictConst.CHANCHENGPINRUKUDAN,
|
||||||
|
bill_date = DateTime.Now,
|
||||||
|
create_id = _userManager.UserId,
|
||||||
|
location_code = basLocation.location_code,
|
||||||
|
carry_code = prdReport.material_box_code,
|
||||||
|
is_check = 1,
|
||||||
|
station_id = prdReport.station,
|
||||||
|
workline_id = workline?.Id ?? "",
|
||||||
|
workshop_id = workshop?.Id ?? "",
|
||||||
|
org_id = _userManager.GetUserInfo().Result.organizeId,
|
||||||
|
warehouse_id = basLocation?.wh_id,
|
||||||
|
status = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
prdInstockDs.Add(new PrdInstockD()
|
||||||
|
{
|
||||||
|
instock_id = prdInstockH.id,
|
||||||
|
report_id = prdReport.create_id,
|
||||||
|
material_id = prdReport.material_id,
|
||||||
|
material_code = basMaterial.code,
|
||||||
|
unit_id = prdReport.unit_id,
|
||||||
|
barcode = prdReport.barcode,
|
||||||
|
code_batch = prdReport.barcode+"0001",
|
||||||
|
quantity = (int)prdReport.reported_qty,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.IsSuccess)
|
||||||
|
{
|
||||||
|
MESCreateInstockInput mesCreateInstockInput = new MESCreateInstockInput();
|
||||||
|
mesCreateInstockInput.instock = new MESWmsInstockHInput()
|
||||||
|
{
|
||||||
|
org_id = _userManager.GetUserInfo().Result.organizeId,
|
||||||
|
bill_date = DateTime.Now,
|
||||||
|
bill_type = DictConst.CHANCHENGPINRUKUDAN,
|
||||||
|
warehouse_id = basLocation?.wh_id,
|
||||||
|
source_id = prdInstockH.id,
|
||||||
|
create_id = _userManager.UserId,
|
||||||
|
carry_code = prdReport.material_box_code,
|
||||||
|
location_code = basLocation.location_code,
|
||||||
|
is_check = 1,
|
||||||
|
};
|
||||||
|
mesCreateInstockInput.instockds = new List<MESWmsInstockDInput>();
|
||||||
|
mesCreateInstockInput.instockcodes = new List<MESWmsInstockCodeInput>();
|
||||||
|
mesCreateInstockInput.instockds.Add(new MESWmsInstockDInput()
|
||||||
|
{
|
||||||
|
material_id = prdReport.material_id,
|
||||||
|
material_code = basMaterial.code,
|
||||||
|
unit_id = prdReport.unit_id,
|
||||||
|
code_batch = prdReport.barcode,
|
||||||
|
pr_qty = (int)prdReport.reported_qty,
|
||||||
|
});
|
||||||
|
|
||||||
|
mesCreateInstockInput.instockcodes.Add(new MESWmsInstockCodeInput()
|
||||||
|
{
|
||||||
|
material_id = prdReport.material_id,
|
||||||
|
material_code = basMaterial.code,
|
||||||
|
unit_id = prdReport.unit_id,
|
||||||
|
barcode = prdReport.barcode,
|
||||||
|
code_batch = prdReport.barcode+"0001",
|
||||||
|
codeqty = (int)prdReport.reported_qty,
|
||||||
|
});
|
||||||
|
string domain = (App.HttpContext.Request.IsHttps ? "https://" : "http://") + App.HttpContext.Request.Host;
|
||||||
|
Dictionary<string, object> header = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
["Authorization"] = App.HttpContext.Request.Headers["Authorization"]
|
||||||
|
};
|
||||||
|
var sendResult = HttpUtils.RequestPost(domain + WebApiConst.MES_CREATE_INSTOCK,JsonConvert.SerializeObject(mesCreateInstockInput),header);
|
||||||
|
Log.Information(sendResult);
|
||||||
|
AuthResponse authResponse = JsonConvert.DeserializeObject<AuthResponse>(sendResult);
|
||||||
|
if (authResponse.code != 200 || !authResponse.data.ObjToBool())
|
||||||
|
{
|
||||||
|
throw Oops.Bah(authResponse.msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result2 = await db.Ado.UseTranAsync(async () =>
|
||||||
|
{
|
||||||
|
await _repository.InsertAsync(prdInstockH);
|
||||||
|
|
||||||
|
if (prdInstockDs.Count > 0)
|
||||||
|
{
|
||||||
|
await db.Insertable<PrdInstockD>(prdInstockDs).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!result2.IsSuccess) throw Oops.Oh(ErrorCode.COM1008);
|
||||||
|
return result2.IsSuccess ? "申请成功" : result2.ErrorMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ using JNPF.Extras.CollectiveOAuth.Utils;
|
|||||||
using JNPF.FriendlyException;
|
using JNPF.FriendlyException;
|
||||||
using JNPF.Logging;
|
using JNPF.Logging;
|
||||||
using JNPF.Systems.Entitys.Permission;
|
using JNPF.Systems.Entitys.Permission;
|
||||||
|
using JNPF.Systems.Entitys.System;
|
||||||
using JNPF.Systems.Interfaces.Permission;
|
using JNPF.Systems.Interfaces.Permission;
|
||||||
using JNPF.Systems.Interfaces.System;
|
using JNPF.Systems.Interfaces.System;
|
||||||
using JNPF.VisualDev;
|
using JNPF.VisualDev;
|
||||||
@@ -23,11 +24,12 @@ using Tnb.ProductionMgr.Entities;
|
|||||||
using Tnb.ProductionMgr.Interfaces;
|
using Tnb.ProductionMgr.Interfaces;
|
||||||
using Tnb.WarehouseMgr.Entities.Dto.Inputs;
|
using Tnb.WarehouseMgr.Entities.Dto.Inputs;
|
||||||
using Tnb.ProductionMgr.Entities.Dto;
|
using Tnb.ProductionMgr.Entities.Dto;
|
||||||
|
using Tnb.WarehouseMgr.Entities;
|
||||||
|
|
||||||
namespace Tnb.ProductionMgr
|
namespace Tnb.ProductionMgr
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生产领料
|
/// 齐套出库
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ApiDescriptionSettings(Tag = ModuleConst.Tag, Area = ModuleConst.Area, Order = 700)]
|
[ApiDescriptionSettings(Tag = ModuleConst.Tag, Area = ModuleConst.Area, Order = 700)]
|
||||||
[Route("api/[area]/[controller]/[action]")]
|
[Route("api/[area]/[controller]/[action]")]
|
||||||
@@ -184,7 +186,6 @@ namespace Tnb.ProductionMgr
|
|||||||
collocation_scheme_id = kittingOutInput.collocation_scheme_id,
|
collocation_scheme_id = kittingOutInput.collocation_scheme_id,
|
||||||
collocation_scheme_code = kittingOutInput.collocation_scheme_code,
|
collocation_scheme_code = kittingOutInput.collocation_scheme_code,
|
||||||
source_id = prdKittingOutH.id,
|
source_id = prdKittingOutH.id,
|
||||||
seq = !string.IsNullOrEmpty(kittingOutInput.seq) ? Convert.ToInt32(kittingOutInput.seq) : 0,
|
|
||||||
create_id = _userManager.UserId,
|
create_id = _userManager.UserId,
|
||||||
wmsKittingoutDs = new List<MESKittingOutStkDInput>(),
|
wmsKittingoutDs = new List<MESKittingOutStkDInput>(),
|
||||||
});
|
});
|
||||||
@@ -262,5 +263,142 @@ namespace Tnb.ProductionMgr
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 齐套出库申请
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="kittingOutInput"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="AppFriendlyException"></exception>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<dynamic> KittingOutNew(KittingOutNewInput kittingOutInput)
|
||||||
|
{
|
||||||
|
PrdKittingOutH prdKittingOutH = new PrdKittingOutH();
|
||||||
|
string warehouse_id = "26103348825381";//二楼缓存仓
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var db = _repository.AsSugarClient();
|
||||||
|
PrdMoTask prdMoTask = await db.Queryable<PrdMoTask>().SingleAsync(x=>x.id==kittingOutInput.mo_task_id);
|
||||||
|
BasMaterial basMaterial = await db.Queryable<BasMaterial>().SingleAsync(x=>x.id==prdMoTask.material_id);
|
||||||
|
WmsCollocationSchemeH wmsCollocationSchemeH = await db.Queryable<WmsCollocationSchemeH>().SingleAsync(x=>x.id==kittingOutInput.collocation_scheme_id);
|
||||||
|
List<WmsCollocationSchemeD> wmsCollocationSchemeDs = await db.Queryable<WmsCollocationSchemeD>().Where(x=>x.bill_id==kittingOutInput.collocation_scheme_id).ToListAsync();
|
||||||
|
List<string> materialIds = wmsCollocationSchemeDs.Select(x => x.material_id).ToList();
|
||||||
|
List<BasMaterial> basMaterials = await db.Queryable<BasMaterial>().Where(x=>materialIds.Contains(x.id)).ToListAsync();
|
||||||
|
Dictionary<string,object> unitIdDic = await db.Queryable<BasMaterial>()
|
||||||
|
.LeftJoin<DictionaryTypeEntity>((a, b) => b.EnCode == DictConst.MeasurementUnit)
|
||||||
|
.LeftJoin<DictionaryDataEntity>((a, b, c) => b.Id == c.DictionaryTypeId && a.unit_id == c.EnCode)
|
||||||
|
.Where((a,b,c)=>materialIds.Contains(a.id))
|
||||||
|
.Select((a, b, c) => new
|
||||||
|
{
|
||||||
|
key = a.id,
|
||||||
|
value = c.Id
|
||||||
|
})
|
||||||
|
.ToDictionaryAsync(x => x.key, x => x.value);
|
||||||
|
Dictionary<string, string> unitCodeDic = basMaterials.ToDictionary(x => x.id, x => x.unit_id);
|
||||||
|
OrganizeEntity workline = await _organizeService.GetAnyParentByWorkstationId(kittingOutInput.workstation_id, DictConst.RegionCategoryWorklineCode);
|
||||||
|
|
||||||
|
List<MESKittingOutStkInput> input = new List<MESKittingOutStkInput>();
|
||||||
|
input.Add(new MESKittingOutStkInput()
|
||||||
|
{
|
||||||
|
org_id = _userManager.GetUserInfo().Result.organizeId,
|
||||||
|
bill_date = DateTime.Now,
|
||||||
|
warehouse_id = warehouse_id,
|
||||||
|
location_code = kittingOutInput.location_code,
|
||||||
|
material_id = prdMoTask.material_id,
|
||||||
|
material_code = basMaterial.code,
|
||||||
|
collocation_scheme_id = kittingOutInput.collocation_scheme_id,
|
||||||
|
collocation_scheme_code = wmsCollocationSchemeH.bill_code,
|
||||||
|
source_id = prdKittingOutH.id,
|
||||||
|
create_id = _userManager.UserId,
|
||||||
|
wmsKittingoutDs = new List<MESKittingOutStkDInput>(),
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var item in wmsCollocationSchemeDs)
|
||||||
|
{
|
||||||
|
input[0].wmsKittingoutDs.Add(new MESKittingOutStkDInput()
|
||||||
|
{
|
||||||
|
material_id = item.material_id,
|
||||||
|
material_code = item.material_code,
|
||||||
|
unit_id = unitIdDic.ContainsKey(item.material_id) ? unitIdDic[item.material_id].ToString() : "",
|
||||||
|
unit_code = unitCodeDic.ContainsKey(item.material_id) ? unitCodeDic[item.material_id].ToString() : "",
|
||||||
|
pr_qty = item.qty,
|
||||||
|
code_batch = "",
|
||||||
|
box = item.box,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
string domain = (App.HttpContext.Request.IsHttps ? "https://" : "http://") + App.HttpContext.Request.Host;
|
||||||
|
Dictionary<string, object> header = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
["Authorization"] = App.HttpContext.Request.Headers["Authorization"]
|
||||||
|
};
|
||||||
|
var sendResult = HttpUtils.RequestPost(domain + WebApiConst.MES_KITTING_OUT_STK,JsonConvert.SerializeObject(input),header);
|
||||||
|
Log.Information(sendResult);
|
||||||
|
|
||||||
|
AuthResponse authResponse = JsonConvert.DeserializeObject<AuthResponse>(sendResult);
|
||||||
|
if (authResponse.code != 200)
|
||||||
|
{
|
||||||
|
throw Oops.Bah(authResponse.msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prdKittingOutH.code = await _billRullService.GetBillNumber(CodeTemplateConst.PRDKITTINGOUTSTOCK_CODE);
|
||||||
|
prdKittingOutH.warehouse_id = warehouse_id;
|
||||||
|
prdKittingOutH.location_code = kittingOutInput.location_code;
|
||||||
|
prdKittingOutH.material_id = basMaterial.id;
|
||||||
|
prdKittingOutH.material_code = basMaterial.code;
|
||||||
|
prdKittingOutH.collocation_scheme_id = kittingOutInput.collocation_scheme_id;
|
||||||
|
prdKittingOutH.collocation_scheme_code = wmsCollocationSchemeH.bill_code;
|
||||||
|
prdKittingOutH.workline_id = workline?.Id ?? "";
|
||||||
|
prdKittingOutH.workstation_id = kittingOutInput.workstation_id;
|
||||||
|
prdKittingOutH.mo_task_id = kittingOutInput.mo_task_id;
|
||||||
|
prdKittingOutH.seq = "0";
|
||||||
|
prdKittingOutH.create_id = _userManager.UserId;
|
||||||
|
prdKittingOutH.create_time = DateTime.Now;
|
||||||
|
prdKittingOutH.org_id = _userManager.GetUserInfo().Result.organizeId;
|
||||||
|
List<PrdKittingOutD> prdKittingOutDs = new List<PrdKittingOutD>();
|
||||||
|
foreach (var item in wmsCollocationSchemeDs)
|
||||||
|
{
|
||||||
|
prdKittingOutDs.Add(new PrdKittingOutD()
|
||||||
|
{
|
||||||
|
material_id = item.material_id,
|
||||||
|
material_code = item.material_code,
|
||||||
|
unit_id = unitIdDic.ContainsKey(item.material_id) ? unitIdDic[item.material_id].ToString() : "",
|
||||||
|
unit_code = unitCodeDic.ContainsKey(item.material_id) ? unitCodeDic[item.material_id].ToString() : "",
|
||||||
|
pr_qty = item.qty,
|
||||||
|
code_batch = "",
|
||||||
|
box = item.box,
|
||||||
|
kitting_out_id = prdKittingOutH.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleId, true);
|
||||||
|
// await _runService.Create(templateEntity, visualDevModelDataCrInput);
|
||||||
|
|
||||||
|
DbResult<bool> result = await _repository.AsSugarClient().Ado.UseTranAsync(async () =>
|
||||||
|
{
|
||||||
|
await _repository.InsertAsync(prdKittingOutH);
|
||||||
|
if (prdKittingOutDs.Count > 0)
|
||||||
|
{
|
||||||
|
await db.Insertable<PrdKittingOutD>(prdKittingOutDs).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.IsSuccess)
|
||||||
|
{
|
||||||
|
throw Oops.Bah(result.ErrorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return await Task.FromResult(true);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
Log.Error(e.Message);
|
||||||
|
throw Oops.Bah(e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2121,7 +2121,7 @@ namespace Tnb.ProductionMgr
|
|||||||
return await _db.Queryable<PrdMoTask>().Where(it => it.eqp_id == eqpId && it.mo_task_status == DictConst.InProgressEnCode).ToListAsync();
|
return await _db.Queryable<PrdMoTask>().Where(it => it.eqp_id == eqpId && it.mo_task_status == DictConst.InProgressEnCode).ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 计算预计结束日期
|
/// 计算预计结束日期
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -2607,6 +2607,70 @@ namespace Tnb.ProductionMgr
|
|||||||
count = SqlFunc.AggregateCount(c.mo_status)
|
count = SqlFunc.AggregateCount(c.mo_status)
|
||||||
}).ToListAsync();
|
}).ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取备料计划
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<dynamic> GetMaterialPreparationPlan()
|
||||||
|
{
|
||||||
|
string now = DateTime.Now.ToString("yyyy-MM-dd");
|
||||||
|
var childrenList = await _db.Queryable<PrdMoTask>()
|
||||||
|
.LeftJoin<PrdMoTask>((a, b) => a.id == b.parent_id)
|
||||||
|
.LeftJoin<BasMaterial>((a, b, c) => b.material_id == c.id)
|
||||||
|
.Where((a, b) => a.schedule_type == 2 && string.IsNullOrEmpty(a.parent_id) && a.estimated_start_date.Value.ToString("yyyy-MM-dd") == now)
|
||||||
|
.Select((a, b, c) => new MaterialPreparationPlanDOutput
|
||||||
|
{
|
||||||
|
mo_task_id = b.id,
|
||||||
|
mo_task_code = b.mo_task_code,
|
||||||
|
rate_num = SqlFunc.Subqueryable<BasMbom>().Where(o => o.id == a.bom_id)
|
||||||
|
.OrderByDesc(o => o.create_time).Select(o => o.num),
|
||||||
|
parent_id = b.parent_id,
|
||||||
|
material_id = b.material_id,
|
||||||
|
material_code = c.code,
|
||||||
|
children = SqlFunc.Subqueryable<BasMbomInput>()
|
||||||
|
.LeftJoin<BasMaterial>((x, y) => x.material_id == y.id)
|
||||||
|
.Where((x, y) => x.mbom_process_id == b.mbom_process_id)
|
||||||
|
.ToList((x, y) => new MaterialPreparationPlanDDOutput()
|
||||||
|
{
|
||||||
|
material_id = x.material_id,
|
||||||
|
material_code = y.code,
|
||||||
|
num = x.num
|
||||||
|
})
|
||||||
|
|
||||||
|
}).ToListAsync();
|
||||||
|
|
||||||
|
var prdMoTaskList = await _db.Queryable<PrdMoTask>()
|
||||||
|
.LeftJoin<BasMaterial>((a, b) => a.material_id == b.id)
|
||||||
|
.Where(a => a.schedule_type == 2 && string.IsNullOrEmpty(a.parent_id) && a.estimated_start_date.Value.ToString("yyyy-MM-dd") == now)
|
||||||
|
.Select((a,b)=>new MaterialPreparationPlanOutput()
|
||||||
|
{
|
||||||
|
mo_task_id = a.id,
|
||||||
|
mo_task_code = a.mo_task_code,
|
||||||
|
material_id = b.id,
|
||||||
|
material_code = b.code,
|
||||||
|
num = a.scheduled_qty,
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
foreach (var item in prdMoTaskList)
|
||||||
|
{
|
||||||
|
item.children = childrenList.Where(x => x.parent_id == item.mo_task_id).ToList();
|
||||||
|
foreach (var itemChild in item.children)
|
||||||
|
{
|
||||||
|
foreach (var itemChildChild in itemChild.children)
|
||||||
|
{
|
||||||
|
if (itemChildChild.num > 0 && itemChild.rate_num != null && itemChild.rate_num>0)
|
||||||
|
{
|
||||||
|
itemChildChild.num = item.num * itemChildChild.num / itemChild.rate_num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prdMoTaskList;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -401,13 +401,14 @@ namespace Tnb.ProductionMgr
|
|||||||
.LeftJoin<BasStandardTime>((a,b,c,d,e,f,g,h,i)=>a.process_id==i.process_id && i.enabled==1)
|
.LeftJoin<BasStandardTime>((a,b,c,d,e,f,g,h,i)=>a.process_id==i.process_id && i.enabled==1)
|
||||||
.LeftJoin<PrdMo>((a,b,c,d,e,f,g,h,i,j)=>a.mo_id==j.id)
|
.LeftJoin<PrdMo>((a,b,c,d,e,f,g,h,i,j)=>a.mo_id==j.id)
|
||||||
.LeftJoin<BasMaterialUnit>((a,b,c,d,e,f,g,h,i,j,k)=>a.material_id==k.material_id && k.auxiliary_unit_id=="kg")
|
.LeftJoin<BasMaterialUnit>((a,b,c,d,e,f,g,h,i,j,k)=>a.material_id==k.material_id && k.auxiliary_unit_id=="kg")
|
||||||
|
.LeftJoin<EqpDaq>((a,b,c,d,e,f,g,h,i,j,k,l)=>a.eqp_id==l.equip_id && l.enabled==1 && l.label_point=="提报装箱称重点位")
|
||||||
.Where((a, b) => a.workstation_id == input.stationId && (a.mo_task_status == DictConst.ToBeStartedEnCode || a.mo_task_status == DictConst.MoStatusPauseCode || a.mo_task_status == DictConst.ComplatedEnCode || a.mo_task_status == DictConst.InProgressEnCode) )
|
.Where((a, b) => a.workstation_id == input.stationId && (a.mo_task_status == DictConst.ToBeStartedEnCode || a.mo_task_status == DictConst.MoStatusPauseCode || a.mo_task_status == DictConst.ComplatedEnCode || a.mo_task_status == DictConst.InProgressEnCode) )
|
||||||
.WhereIF(!string.IsNullOrEmpty(mo_task_code),a=>a.mo_task_code.Contains(mo_task_code))
|
.WhereIF(!string.IsNullOrEmpty(mo_task_code),a=>a.mo_task_code.Contains(mo_task_code))
|
||||||
//.WhereIF(!string.IsNullOrEmpty(mo_task_status),a=>a.mo_task_status==mo_task_status)
|
//.WhereIF(!string.IsNullOrEmpty(mo_task_status),a=>a.mo_task_status==mo_task_status)
|
||||||
.WhereIF(statusList.Count>0,a=>statusList.Contains(a.mo_task_status))
|
.WhereIF(statusList.Count>0,a=>statusList.Contains(a.mo_task_status))
|
||||||
.WhereIF(status=="3" && start_time!=null,a=>a.act_end_date>=start_time)
|
.WhereIF(status=="3" && start_time!=null,a=>a.act_end_date>=start_time)
|
||||||
.WhereIF(status=="3" && end_time!=null,a=>a.act_end_date<=end_time)
|
.WhereIF(status=="3" && end_time!=null,a=>a.act_end_date<=end_time)
|
||||||
.Select((a, b, c, d, e,f,g,h,i,j,k) => new PADPackageTaskPageOutput
|
.Select((a, b, c, d, e,f,g,h,i,j,k,l) => new PADPackageTaskPageOutput
|
||||||
{
|
{
|
||||||
id = a.id,
|
id = a.id,
|
||||||
mo_task_code = a.mo_task_code,
|
mo_task_code = a.mo_task_code,
|
||||||
@@ -448,6 +449,8 @@ namespace Tnb.ProductionMgr
|
|||||||
minpacking = b.minpacking,
|
minpacking = b.minpacking,
|
||||||
main_num = k.number_of_primary_unit,
|
main_num = k.number_of_primary_unit,
|
||||||
deputy_num = k.number_of_auxiliary_unit,
|
deputy_num = k.number_of_auxiliary_unit,
|
||||||
|
third_equip_code = f.third_equip_code,
|
||||||
|
weight_name = l.label_name
|
||||||
})
|
})
|
||||||
.MergeTable()
|
.MergeTable()
|
||||||
.OrderBy($"{input.sidx} {input.sort}")
|
.OrderBy($"{input.sidx} {input.sort}")
|
||||||
|
|||||||
77
ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs
Normal file
77
ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using JNPF.Common.Cache;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using UAParser;
|
||||||
|
using Tnb.ProductionMgr.Interfaces;
|
||||||
|
using Tnb.ProductionMgr.Entities.Dto;
|
||||||
|
|
||||||
|
namespace Tnb.ProductionMgr
|
||||||
|
{
|
||||||
|
//redis定时获取数采数据
|
||||||
|
public class RedisBackGround : IHostedService, IDisposable
|
||||||
|
{
|
||||||
|
private Timer? packtimer;
|
||||||
|
private Timer? limittimer;
|
||||||
|
private readonly RedisCache _redisCache;
|
||||||
|
private readonly IPrdInstockService _prdInstockService;
|
||||||
|
public RedisBackGround(RedisCache redisCache, IPrdInstockService prdInstockService)
|
||||||
|
{
|
||||||
|
_redisCache = redisCache;
|
||||||
|
_prdInstockService = prdInstockService;
|
||||||
|
}
|
||||||
|
//获取装箱状态
|
||||||
|
private void GetPackStatus(object state)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
||||||
|
Console.WriteLine($"获取装箱状态");
|
||||||
|
/*
|
||||||
|
var data = _redisCache.GetHash("TY4C-JICHU", "weight_4").Result;
|
||||||
|
var res = JsonConvert.DeserializeObject<JObject>(data);
|
||||||
|
if (res != null && res["Value"] != null)
|
||||||
|
{
|
||||||
|
InstockInput instockInput = new InstockInput();
|
||||||
|
instockInput.equip_code = res["Value"]!.ToString();
|
||||||
|
_prdInstockService.InstockTypeOne(instockInput);
|
||||||
|
Console.WriteLine(decimal.Parse(res["Value"]!.ToString()));
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
//获取限位状态
|
||||||
|
private void GetLimitStatus(object state)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
||||||
|
Console.WriteLine($"获取限位状态");
|
||||||
|
/*
|
||||||
|
var data = _redisCache.GetHash("TY4C-JICHU", "weight_4").Result;
|
||||||
|
var res = JsonConvert.DeserializeObject<JObject>(data);
|
||||||
|
if (res != null && res["Value"] != null)
|
||||||
|
{
|
||||||
|
InstockInput instockInput = new InstockInput();
|
||||||
|
instockInput.equip_code = res["Value"]!.ToString();
|
||||||
|
_prdInstockService.InstockTypeOne(instockInput);
|
||||||
|
Console.WriteLine(decimal.Parse(res["Value"]!.ToString()));
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
packtimer?.Dispose();
|
||||||
|
limittimer?.Dispose();
|
||||||
|
}
|
||||||
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// packtimer = new Timer(GetPackStatus, null, TimeSpan.Zero, TimeSpan.FromSeconds(2));
|
||||||
|
// limittimer = new Timer(GetLimitStatus, null, TimeSpan.Zero, TimeSpan.FromSeconds(2));
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
public Task StopAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
67
ProductionMgr/Tnb.ProductionMgr/RedisDataService.cs
Normal file
67
ProductionMgr/Tnb.ProductionMgr/RedisDataService.cs
Normal file
File diff suppressed because one or more lines are too long
@@ -81,11 +81,6 @@ namespace Tnb.WarehouseMgr.Entities.Dto.Inputs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string source_code { get; set; }
|
public string source_code { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 顺序号
|
|
||||||
/// </summary>
|
|
||||||
public int seq { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建用户ID
|
/// 创建用户ID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -71,7 +71,8 @@
|
|||||||
"txt",
|
"txt",
|
||||||
"rar",
|
"rar",
|
||||||
"zip",
|
"zip",
|
||||||
"csv"
|
"csv",
|
||||||
|
"json"
|
||||||
],
|
],
|
||||||
//过滤上传文件名称特殊字符
|
//过滤上传文件名称特殊字符
|
||||||
"SpecialString": [
|
"SpecialString": [
|
||||||
@@ -188,5 +189,5 @@
|
|||||||
"DoMainApp": "http://localhost:8081", // 前端App外网能访问的地址(域名), 回调的时候拼接接口地址用
|
"DoMainApp": "http://localhost:8081", // 前端App外网能访问的地址(域名), 回调的时候拼接接口地址用
|
||||||
"AppPushUrl": "https://8e84eea8-6922-4033-8e86-67ad7442e692.bspapp.com/unipush"
|
"AppPushUrl": "https://8e84eea8-6922-4033-8e86-67ad7442e692.bspapp.com/unipush"
|
||||||
},
|
},
|
||||||
"IsStartTimeJob": true //是否开启定时任务
|
"IsStartTimeJob": false //是否开启定时任务
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,7 @@ using Senparc.Weixin;
|
|||||||
using Senparc.Weixin.Entities;
|
using Senparc.Weixin.Entities;
|
||||||
using Senparc.Weixin.RegisterServices;
|
using Senparc.Weixin.RegisterServices;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
using Tnb.ProductionMgr;
|
||||||
using Tnb.WarehouseMgr;
|
using Tnb.WarehouseMgr;
|
||||||
|
|
||||||
namespace JNPF.API.Entry;
|
namespace JNPF.API.Entry;
|
||||||
@@ -66,7 +67,7 @@ public class Startup : AppStartup
|
|||||||
|
|
||||||
//定时任务
|
//定时任务
|
||||||
services.AddHostedService<TimedTaskBackgroundService>();
|
services.AddHostedService<TimedTaskBackgroundService>();
|
||||||
|
services.AddHostedService<RedisBackGround>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -224,4 +224,20 @@ public class RedisCache : ICache, ISingleton
|
|||||||
long second = RedisHelper.PTtl(key);
|
long second = RedisHelper.PTtl(key);
|
||||||
return DateTime.Now.AddMilliseconds(second);
|
return DateTime.Now.AddMilliseconds(second);
|
||||||
}
|
}
|
||||||
|
public Task<string> GetHash(string key, string field)
|
||||||
|
{
|
||||||
|
return RedisHelper.HGetAsync(key, field);
|
||||||
|
}
|
||||||
|
public Task<bool> HashExist(string key, string field)
|
||||||
|
{
|
||||||
|
return RedisHelper.HExistsAsync(key, field);
|
||||||
|
}
|
||||||
|
public Task<Dictionary<string, string>> HGetAll(string key)
|
||||||
|
{
|
||||||
|
return RedisHelper.HGetAllAsync(key);
|
||||||
|
}
|
||||||
|
public Task<bool> HSet(string key, string field, string value)
|
||||||
|
{
|
||||||
|
return RedisHelper.HSetAsync(key, field,value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using JNPF.Common.Extension;
|
using JNPF.Common.Extension;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
|
||||||
namespace System;
|
namespace System;
|
||||||
|
|
||||||
@@ -183,4 +184,17 @@ public static class StringExtensions
|
|||||||
public static string ToCamel(this string str) => str.SplitWord().Select((a, i) => i == 0 ? a : a.UpperFirst()).JoinAsString("");
|
public static string ToCamel(this string str) => str.SplitWord().Select((a, i) => i == 0 ? a : a.UpperFirst()).JoinAsString("");
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public static (string, string) LastSplit(this string str, char seperate)
|
||||||
|
{
|
||||||
|
int n = str.LastIndexOf(seperate);
|
||||||
|
if(n > 0)
|
||||||
|
{
|
||||||
|
return (str.Substring(0, n), str.Substring(n + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (str, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Security.Cryptography.Xml;
|
||||||
using JNPF;
|
using JNPF;
|
||||||
using JNPF.Common.Core.Manager;
|
using JNPF.Common.Core.Manager;
|
||||||
|
using JNPF.Common.Extension;
|
||||||
using JNPF.DependencyInjection;
|
using JNPF.DependencyInjection;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
@@ -15,7 +17,7 @@ namespace Tnb.Vengine.DataAccess;
|
|||||||
public class DataAccess : IDataAccess, ITransient, IDisposable
|
public class DataAccess : IDataAccess, ITransient, IDisposable
|
||||||
{
|
{
|
||||||
private const int MAX_PAGE_SIZE = 1000;
|
private const int MAX_PAGE_SIZE = 1000;
|
||||||
private ISqlSugarClient? _db;
|
private static ISqlSugarClient? _db;
|
||||||
|
|
||||||
protected ISqlSugarClient Db
|
protected ISqlSugarClient Db
|
||||||
{
|
{
|
||||||
@@ -170,14 +172,18 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
|||||||
private async Task LoadVmodelNavigateAsync(Vmodel vm)
|
private async Task LoadVmodelNavigateAsync(Vmodel vm)
|
||||||
{
|
{
|
||||||
Dictionary<string, Vmodel> dictVm = new();
|
Dictionary<string, Vmodel> dictVm = new();
|
||||||
|
var vmids = vm.navProps.Select(a => a.vmid).Distinct().ToList();
|
||||||
|
var ls = await Db.Queryable<Vmodel>().Where(a => vmids.Contains(a.id)).ToListAsync();
|
||||||
|
var navs = ls.ToDictionary(a => a.id);
|
||||||
foreach (var navProp in vm.navProps)
|
foreach (var navProp in vm.navProps)
|
||||||
{
|
{
|
||||||
if (!dictVm.ContainsKey(navProp.vmid))
|
navProp.naviModel = (Vmodel)navs.GetOrDefault(navProp.vmid);
|
||||||
{
|
//if (!dictVm.ContainsKey(navProp.vmid))
|
||||||
var navModel = await GetVmodelAsync(navProp.vmid);
|
//{
|
||||||
dictVm.Add(navProp.vmid, navModel);
|
// var navModel = await GetVmodelAsync(navProp.vmid);
|
||||||
}
|
// dictVm.Add(navProp.vmid, navModel);
|
||||||
navProp.naviModel = dictVm[navProp.vmid];
|
//}
|
||||||
|
//navProp.naviModel = dictVm[navProp.vmid];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,10 +197,8 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
|||||||
var selProps = vm.GetVmSelectProps(input.o);
|
var selProps = vm.GetVmSelectProps(input.o);
|
||||||
//处理导航属性联表
|
//处理导航属性联表
|
||||||
List<JoinInfoParameter> joins = vm.GetJoinInfos(selProps);
|
List<JoinInfoParameter> joins = vm.GetJoinInfos(selProps);
|
||||||
query.AddJoinInfo(joins);
|
|
||||||
//if (joins.Count > 0)
|
//if (joins.Count > 0)
|
||||||
//{
|
query.AddJoinInfo(joins);
|
||||||
//}
|
|
||||||
List<IConditionalModel> wheres = vm.GetConditionalModels(input.q);
|
List<IConditionalModel> wheres = vm.GetConditionalModels(input.q);
|
||||||
if (!string.IsNullOrEmpty(input.k))
|
if (!string.IsNullOrEmpty(input.k))
|
||||||
{
|
{
|
||||||
@@ -208,10 +212,8 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
|||||||
wheres.Add(new ConditionalCollections() { ConditionalList = lsCondition });
|
wheres.Add(new ConditionalCollections() { ConditionalList = lsCondition });
|
||||||
}
|
}
|
||||||
//处理查询参数
|
//处理查询参数
|
||||||
query.Where(wheres);
|
|
||||||
//if (wheres.Count > 0)
|
//if (wheres.Count > 0)
|
||||||
//{
|
query.Where(wheres);
|
||||||
//}
|
|
||||||
if (!string.IsNullOrEmpty(input.sort))
|
if (!string.IsNullOrEmpty(input.sort))
|
||||||
{
|
{
|
||||||
query.OrderBy(input.sort);
|
query.OrderBy(input.sort);
|
||||||
@@ -229,7 +231,7 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
|||||||
//组装输出对象
|
//组装输出对象
|
||||||
foreach (var data in ls)
|
foreach (var data in ls)
|
||||||
{
|
{
|
||||||
DObject ret = await NestedOutputAsync(vm, new DObject(data), selProps);
|
DObject ret = await CombineOutputAsync(vm, new DObject(data), selProps);
|
||||||
result.items.Add(ret);
|
result.items.Add(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,11 +245,12 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
|||||||
/// <param name="src"></param>
|
/// <param name="src"></param>
|
||||||
/// <param name="selProps"></param>
|
/// <param name="selProps"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<DObject> NestedOutputAsync(Vmodel vm, DObject src, List<VmSelectProp> selProps)
|
private async Task<DObject> CombineOutputAsync(Vmodel vm, DObject src, List<VmSelectProp> selProps)
|
||||||
{
|
{
|
||||||
DObject ret = new();
|
DObject ret = new();
|
||||||
foreach (var prop in selProps)
|
foreach (var prop in selProps)
|
||||||
{
|
{
|
||||||
|
// 加载主表字段
|
||||||
if (prop.navType == eNavigateType.None || prop.navCode == VmSelectProp.MAIN_ALIES)
|
if (prop.navType == eNavigateType.None || prop.navCode == VmSelectProp.MAIN_ALIES)
|
||||||
{
|
{
|
||||||
if (src.ContainsKey(prop.code))
|
if (src.ContainsKey(prop.code))
|
||||||
@@ -257,40 +260,14 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// 加载关联表字段
|
||||||
if (prop.navType == eNavigateType.OneToOne)
|
if (prop.navType == eNavigateType.OneToOne)
|
||||||
{
|
{
|
||||||
//以 nav_prop的形式返回
|
NestedOutput(vm, src, ret, prop);
|
||||||
var key = prop.navCode + "_" + prop.code;
|
|
||||||
ret.Add(key, src[key]);
|
|
||||||
//以 nav.prop的形式返回
|
|
||||||
//if (!ret.ContainsKey(prop.navCode))
|
|
||||||
//{
|
|
||||||
// ret.Add(prop.navCode, new DObject());
|
|
||||||
//}
|
|
||||||
//var key = prop.navCode + "_" + prop.code;
|
|
||||||
//if (src.ContainsKey(key))
|
|
||||||
//{
|
|
||||||
// ((DObject)ret[prop.navCode]).Add(prop.code, src[key]);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
else if (prop.navType == eNavigateType.OneToMany)
|
else if (prop.navType == eNavigateType.OneToMany)
|
||||||
{
|
{
|
||||||
if (!ret.ContainsKey(prop.navCode))
|
await NestedOneToManyAsync(vm, src, ret, prop, selProps);
|
||||||
{
|
|
||||||
ret.Add(prop.navCode, new List<DObject>());
|
|
||||||
}
|
|
||||||
var navProp = vm.navProps.First(a => a.code == prop.navCode);
|
|
||||||
if (navProp != null && navProp.naviModel != null && src.ContainsKey(navProp.refField))
|
|
||||||
{
|
|
||||||
VmListInput input = new VmListInput();
|
|
||||||
var fkProp = navProp.naviModel.FieldCodeToPropCode(navProp.fkField);
|
|
||||||
if (!string.IsNullOrEmpty(fkProp))
|
|
||||||
{
|
|
||||||
input.q = new DObject(fkProp, src[navProp.refField]);
|
|
||||||
input.o = string.Join(',', selProps.Where(a => a.navCode == prop.navCode).Select(a => a.code));
|
|
||||||
ret[prop.navCode] = (await QueryDataAsync(navProp.naviModel, input)).items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (prop.navType == eNavigateType.ManyToMany)
|
else if (prop.navType == eNavigateType.ManyToMany)
|
||||||
{
|
{
|
||||||
@@ -304,6 +281,50 @@ public class DataAccess : IDataAccess, ITransient, IDisposable
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将一对一的关联表字段嵌入到返回值中
|
||||||
|
/// </summary>
|
||||||
|
private void NestedOutput(Vmodel vm, DObject src, DObject ret, VmSelectProp prop)
|
||||||
|
{
|
||||||
|
// 以 nav_prop的形式返回
|
||||||
|
var key = prop.navCode + "_" + prop.code;
|
||||||
|
ret.Add(key, src[key]);
|
||||||
|
// 以 nav.prop的形式返回
|
||||||
|
//if (!ret.ContainsKey(prop.navCode))
|
||||||
|
//{
|
||||||
|
// ret.Add(prop.navCode, new DObject());
|
||||||
|
//}
|
||||||
|
//var key = prop.navCode + "_" + prop.code;
|
||||||
|
//if (src.ContainsKey(key))
|
||||||
|
//{
|
||||||
|
// ((DObject)ret[prop.navCode]).Add(prop.code, src[key]);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task NestedOneToManyAsync(Vmodel vm, DObject src, DObject ret, VmSelectProp prop, List<VmSelectProp> selProps)
|
||||||
|
{
|
||||||
|
// 在返回值中增加导航属性
|
||||||
|
if (ret.ContainsKey(prop.navCode))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ret.Add(prop.navCode, new List<DObject>());
|
||||||
|
|
||||||
|
// 找到导航属性的配置
|
||||||
|
var navCfg = vm.navProps.First(a => a.code == prop.navCode);
|
||||||
|
if (navCfg != null && navCfg.naviModel != null && src.ContainsKey(navCfg.refField) && navCfg.refCode == VmSelectProp.MAIN_ALIES)
|
||||||
|
{
|
||||||
|
VmListInput input = new VmListInput();
|
||||||
|
var fkProp = navCfg.naviModel.FieldCodeToPropCode(navCfg.fkField);
|
||||||
|
if (!string.IsNullOrEmpty(fkProp))
|
||||||
|
{
|
||||||
|
input.q = new DObject(fkProp, src[navCfg.refField]);
|
||||||
|
input.o = string.Join(',', selProps.Where(a => a.navCode == prop.navCode).Select(a => a.code));
|
||||||
|
ret[prop.navCode] = (await QueryDataAsync(navCfg.naviModel, input)).items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 新增数据 默认方法
|
/// 新增数据 默认方法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
97
visualdev/Tnb.Vengine/Domain/OutputParser.cs
Normal file
97
visualdev/Tnb.Vengine/Domain/OutputParser.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using JNPF.Common.Extension;
|
||||||
|
using Tnb.Vengine.DataAccess;
|
||||||
|
|
||||||
|
namespace Tnb.Vengine.Domain
|
||||||
|
{
|
||||||
|
public class OutputParser
|
||||||
|
{
|
||||||
|
private readonly IDataAccess _dataAccess;
|
||||||
|
private readonly Vmodel _root;
|
||||||
|
private List<string> _outputs;
|
||||||
|
private Dictionary<string, OutputSelect> _selectProps = new Dictionary<string, OutputSelect>();
|
||||||
|
private Dictionary<string, Vmodel?> _navModels = new Dictionary<string, Vmodel?>();
|
||||||
|
public OutputParser(IDataAccess dataAccess, Vmodel rootModel, string output)
|
||||||
|
{
|
||||||
|
_dataAccess = dataAccess;
|
||||||
|
_root = rootModel;
|
||||||
|
_outputs = output.Split(',').Distinct().ToList();
|
||||||
|
ParseOutputStr();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 按模型组织要输出的属性
|
||||||
|
/// </summary>
|
||||||
|
private void ParseOutputStr()
|
||||||
|
{
|
||||||
|
foreach (var outStr in _outputs)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(outStr))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
string vmPath;
|
||||||
|
int n = outStr.LastIndexOf('.');
|
||||||
|
if (n < 1)
|
||||||
|
{
|
||||||
|
vmPath = Vmodel.MAIN_ALIES;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vmPath = outStr.Substring(0, n);
|
||||||
|
}
|
||||||
|
if (!_selectProps.ContainsKey(vmPath))
|
||||||
|
{
|
||||||
|
_selectProps.Add(vmPath, new OutputSelect { navPaths = vmPath.Split(',').ToList(), vmPath = vmPath });
|
||||||
|
}
|
||||||
|
var outSelect = _selectProps[vmPath];
|
||||||
|
outSelect.propCodes.Add(outStr.Substring(n + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadNavModel()
|
||||||
|
{
|
||||||
|
var navProps = _root.navProps.Where(a => _selectProps.Values.Any(b => b.vmPath.StartsWith(a.code + "."))).ToList();
|
||||||
|
await LoadVmodelNavigateAsync(navProps);
|
||||||
|
}
|
||||||
|
private async Task LoadVmodelNavigateAsync(List<VmNavProp> navProps)
|
||||||
|
{
|
||||||
|
var db = _dataAccess.GetSqlSugar();
|
||||||
|
|
||||||
|
var vmids = navProps.Select(a => a.vmid).Distinct().ToList();
|
||||||
|
var navs = await db.Queryable<Vmodel>().Where(a => vmids.Contains(a.id)).ToDictionaryAsync(a => a.id, a => a);
|
||||||
|
foreach (var navProp in navProps)
|
||||||
|
{
|
||||||
|
navProp.naviModel = (Vmodel)navs.GetOrDefault(navProp.vmid);
|
||||||
|
navProp.naviModel.navProps.Where(a => _selectProps.Values.Any(b => b.vmPath.StartsWith(a.code + "."))).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class OutputSelect
|
||||||
|
{
|
||||||
|
public string vmId { get; set; } = string.Empty;
|
||||||
|
public string vmCode { get; set; } = string.Empty;
|
||||||
|
public string vmPath { get; set; } = string.Empty;
|
||||||
|
public eNavigateType navType { get; set; } = eNavigateType.None;
|
||||||
|
public List<string> navPaths { get; set; } = new List<string>();
|
||||||
|
|
||||||
|
public List<string> propCodes { get; set; } = new List<string>();
|
||||||
|
public List<string> fieldCodes { get; set; } = new List<string>();
|
||||||
|
|
||||||
|
public OutputSelect()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public OutputSelect(Vmodel model)
|
||||||
|
{
|
||||||
|
vmId = model.id;
|
||||||
|
vmCode = model.vmCode;
|
||||||
|
vmPath = Vmodel.MAIN_ALIES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -164,6 +164,7 @@ public class VmSelectProp
|
|||||||
public const string MAIN_ALIES = "m";
|
public const string MAIN_ALIES = "m";
|
||||||
public string code { get; set; } = string.Empty;
|
public string code { get; set; } = string.Empty;
|
||||||
public string field { get; set; } = string.Empty;
|
public string field { get; set; } = string.Empty;
|
||||||
|
public List<string> navPath { get; set; } = new List<string>();
|
||||||
public string navCode { get; set; } = MAIN_ALIES;
|
public string navCode { get; set; } = MAIN_ALIES;
|
||||||
public ePropType propType { get; set; }
|
public ePropType propType { get; set; }
|
||||||
public eNavigateType navType { get; set; }
|
public eNavigateType navType { get; set; }
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public class VmDbProp : VmBaseProp
|
|||||||
/// 获取默认值文本
|
/// 获取默认值文本
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public object? GetDefaultValueString()
|
public string? GetDefaultValueString()
|
||||||
{
|
{
|
||||||
string val = "";
|
string val = "";
|
||||||
if (!required) return val;
|
if (!required) return val;
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ namespace Tnb.Vengine.Domain;
|
|||||||
[SugarTable("sys_vmodel")]
|
[SugarTable("sys_vmodel")]
|
||||||
public partial class Vmodel : Entity
|
public partial class Vmodel : Entity
|
||||||
{
|
{
|
||||||
|
public const string MAIN_ALIES = "m";
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -146,7 +148,8 @@ public partial class Vmodel : Entity
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion Properties
|
#endregion Properties
|
||||||
|
//private Dictionary<string, string>? _mapField2Prop = null;
|
||||||
|
//private Dictionary<string, string>? _mapProp2Field = null;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 通过实体创建模型
|
/// 通过实体创建模型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -351,11 +354,30 @@ public partial class Vmodel : Entity
|
|||||||
if (filter == null) return wheres;
|
if (filter == null) return wheres;
|
||||||
foreach (var item in filter)
|
foreach (var item in filter)
|
||||||
{
|
{
|
||||||
|
VmDbProp? prop = null;
|
||||||
// TODO 按子表条件查询
|
// TODO 按子表条件查询
|
||||||
if (item.Key.Contains("."))
|
if (item.Key.Contains("."))
|
||||||
{
|
{
|
||||||
|
var codes = item.Key.Split('.');
|
||||||
|
if (codes.Length >= 2)
|
||||||
|
{
|
||||||
|
var navProp = navProps.FirstOrDefault(a => a.code == codes[0]);
|
||||||
|
if (navProp != null && navProp.naviModel != null)
|
||||||
|
{
|
||||||
|
var dbProp = navProp.naviModel.dbProps.FirstOrDefault(a => a.code == codes[1]);
|
||||||
|
if (dbProp != null)
|
||||||
|
{
|
||||||
|
prop = new VmDbProp();
|
||||||
|
prop.field = codes[0] + "." + dbProp.field;
|
||||||
|
prop.csType = dbProp.csType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prop = dbProps.FirstOrDefault(a => a.code == item.Key);
|
||||||
}
|
}
|
||||||
var prop = dbProps.FirstOrDefault(a => a.code == item.Key);
|
|
||||||
if (prop == null) continue;
|
if (prop == null) continue;
|
||||||
if (item.Value is JArray val)
|
if (item.Value is JArray val)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user