using System; using System.ArrayExtensions; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Aspose.Cells.Drawing; using JNPF.Common.Core.Manager; using JNPF.Common.Enums; using JNPF.DependencyInjection; using JNPF.DynamicApiController; using JNPF.FriendlyException; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Spire.Xls.Core; using SqlSugar; using Tnb.QcMgr.Entities; using Tnb.QcMgr.Entities.Entity; using Tnb.QcMgr.Interfaces; namespace Tnb.QcMgr { /// /// spc模块 /// [ApiDescriptionSettings(Tag = ModuleConsts.Tag, Area = ModuleConsts.Area, Order = 800)] public class QcSpcService : IQcSpcService, IDynamicApiController, ITransient { private readonly ISqlSugarRepository _repository; private readonly IUserManager _userManager; public QcSpcService(ISqlSugarRepository repository, IUserManager userManager) { _repository = repository; _userManager = userManager; } /// /// 获取spcd数据 /// /// /// [HttpPost] public async Task GetSpcItems(string id) { var datas= await _repository.AsSugarClient().Queryable().Where(p => p.mainid == id).ToListAsync(); List SpcDataInputs=new List(); datas.ForEach(p => { SpcDataInput SpcDataInput = new SpcDataInput(); SpcDataInput.mainid = p.mainid; SpcDataInput.checktime = p.checktime; SpcDataInput.batch = p.batch; SpcDataInput.data = Array.ConvertAll(p.data!.Split(","),float.Parse); SpcDataInput.checknum = p.checknum; SpcDataInput.defectivenum = p.defectivenum; SpcDataInputs.Add(SpcDataInput); }); return SpcDataInputs; } /// /// 保存spcd /// /// /// [HttpPost] public async Task SaveData(List SpcDataInput) { var db = _repository.AsSugarClient(); try { if (!string.IsNullOrEmpty(SpcDataInput.First().mainid)) await db.Deleteable(p => p.mainid == SpcDataInput.First().mainid).ExecuteCommandAsync(); List QcSpcDs = new List(); SpcDataInput.ForEach(p => { QcSpcD QcSpcD=new QcSpcD(); QcSpcD.mainid = p.mainid; QcSpcD.checktime = p.checktime; QcSpcD.batch = p.batch; QcSpcD.data = string.Join(",", p.data); QcSpcD.checknum = p.checknum; QcSpcD.defectivenum = p.defectivenum; QcSpcD.create_id = _userManager.UserId; QcSpcD.create_time=DateTime.Now; QcSpcDs.Add(QcSpcD); }); await db.Ado.BeginTranAsync(); await db.Insertable(QcSpcDs).ExecuteCommandAsync(); await db.Ado.CommitTranAsync(); } catch (Exception) { await db.Ado.RollbackTranAsync(); throw Oops.Oh(ErrorCode.COM1000); } } /// /// 获取spc图表 /// /// /// [HttpPost] public async Task GetSpcData(string id) { var QcSpcH = await _repository.AsSugarClient().Queryable().Where(p => p.id == id).FirstAsync(); var QcSpcDs = await _repository.AsSugarClient().Queryable().Where(p => p.mainid == id).ToListAsync(); var cinfigs = await _repository.AsSugarClient().Queryable().ToListAsync(); if (QcSpcH.graphtype == "X-R控制图") { XRchart XRchart = new XRchart(); XRchart.xcharts = new List(); XRchart.rcharts = new List(); foreach (var QcSpcD in QcSpcDs) { List datas = Array.ConvertAll(QcSpcD.data!.Split(",", StringSplitOptions.RemoveEmptyEntries), float.Parse).ToList(); XRxchart xchart = new XRxchart(); xchart.x = datas.Average(); xchart.jc = datas.Max() - datas.Min(); xchart.usl = QcSpcH.uplimit; xchart.cl = QcSpcH.target; xchart.lsl = QcSpcH.lowerlimit; XRrchart rchart = new XRrchart(); rchart.r = datas.Max() - datas.Min(); XRchart.xcharts.Add(xchart); XRchart.rcharts.Add(rchart); } var xAverage = XRchart.xcharts.Select(p => p.x).Average(); var num = XRchart.xcharts.Select(p => p.jc).Average() * cinfigs.Where(p => p.spctype == "X-R图" && p.spckey == "A2" && p.subcapacity == QcSpcH.samplesize).Select(p => p.spcdata).First(); XRchart.xcharts.ForEach(p => { p.uclx = xAverage + num; p.clx = xAverage; p.lclx = xAverage - num; }); var D4 = cinfigs.Where(p => p.spctype == "X-R图" && p.spckey == "D4" && p.subcapacity == QcSpcH.samplesize).Select(p => p.spcdata).First(); var D3 = cinfigs.Where(p => p.spctype == "X-R图" && p.spckey == "D3" && p.subcapacity == QcSpcH.samplesize).Select(p => p.spcdata).First(); var rAverage = XRchart.rcharts.Select(p => p.r).Average(); XRchart.rcharts.ForEach(p => { p.uclr = rAverage * D4; p.clr = rAverage; p.lclr = rAverage * D3; }); return XRchart; } if (QcSpcH.graphtype == "X-S控制图") { XSchart XSchart = new XSchart(); XSchart.xcharts = new List(); XSchart.scharts = new List(); foreach (var QcSpcD in QcSpcDs) { List datas = Array.ConvertAll(QcSpcD.data!.Split(",", StringSplitOptions.RemoveEmptyEntries), float.Parse).ToList(); XSxchart xchart = new XSxchart(); xchart.x = datas.Average(); xchart.bzc = CalculateStdDev(datas); xchart.usl = QcSpcH.uplimit; xchart.cl = QcSpcH.target; xchart.lsl = QcSpcH.lowerlimit; XSschart schart = new XSschart(); schart.s = CalculateStdDev(datas); XSchart.xcharts.Add(xchart); XSchart.scharts.Add(schart); } var xAverage = XSchart.xcharts.Select(p => p.x).Average(); var num = XSchart.xcharts.Select(p => p.bzc).Average() * cinfigs.Where(p => p.spctype == "X-S图" && p.spckey == "A3" && p.subcapacity == QcSpcH.samplesize).Select(p => p.spcdata).First(); XSchart.xcharts.ForEach(p => { p.uclx = xAverage + num; p.clx = xAverage; p.lclx = xAverage - num; }); var B4 = cinfigs.Where(p => p.spctype == "X-S图" && p.spckey == "B4" && p.subcapacity == QcSpcH.samplesize).Select(p => p.spcdata).First(); var B3 = cinfigs.Where(p => p.spctype == "X-S图" && p.spckey == "B3" && p.subcapacity == QcSpcH.samplesize).Select(p => p.spcdata).First(); var sAverage = XSchart.scharts.Select(p => p.s).Average(); XSchart.scharts.ForEach(p => { p.ucls = sAverage * B4; p.cls = sAverage; p.lcls = sAverage * B3; }); return XSchart; } if (QcSpcH.graphtype == "X中位数-R图") { XRchart XRchart = new XRchart(); XRchart.xcharts = new List(); XRchart.rcharts = new List(); foreach (var QcSpcD in QcSpcDs) { List datas = Array.ConvertAll(QcSpcD.data!.Split(",", StringSplitOptions.RemoveEmptyEntries), float.Parse).ToList(); XRxchart xchart = new XRxchart(); xchart.x = CalculateMedian(datas); xchart.jc = datas.Max() - datas.Min(); xchart.usl = QcSpcH.uplimit; xchart.cl = QcSpcH.target; xchart.lsl = QcSpcH.lowerlimit; XRrchart rchart = new XRrchart(); rchart.r = datas.Max() - datas.Min(); XRchart.xcharts.Add(xchart); XRchart.rcharts.Add(rchart); } var xAverage = XRchart.xcharts.Select(p => p.x).Average(); var num = XRchart.xcharts.Select(p => p.jc).Average() * cinfigs.Where(p => p.spctype == "中位数图" && p.spckey == "A2" && p.subcapacity == QcSpcH.samplesize).Select(p => p.spcdata).First(); XRchart.xcharts.ForEach(p => { p.uclx = xAverage + num; p.clx = xAverage; p.lclx = xAverage - num; }); var D4 = cinfigs.Where(p => p.spctype == "中位数图" && p.spckey == "D4" && p.subcapacity == QcSpcH.samplesize).Select(p => p.spcdata).First(); var D3 = cinfigs.Where(p => p.spctype == "中位数图" && p.spckey == "D3" && p.subcapacity == QcSpcH.samplesize).Select(p => p.spcdata).First(); var rAverage = XRchart.rcharts.Select(p => p.r).Average(); XRchart.rcharts.ForEach(p => { p.uclr = rAverage * D4; p.clr = rAverage; p.lclr = rAverage * D3; }); return XRchart; } if (QcSpcH.graphtype == "X-MR控制图") { XMRchart XMRchart = new XMRchart(); XMRchart.xmrxcharts = new List(); XMRchart.xmrmrcharts = new List(); foreach (var QcSpcD in QcSpcDs) { List datas = Array.ConvertAll(QcSpcD.data!.Split(",", StringSplitOptions.RemoveEmptyEntries), float.Parse).ToList(); XMRxchart xchart = new XMRxchart(); xchart.x = datas.Average(); xchart.usl = QcSpcH.uplimit; xchart.cl = QcSpcH.target; xchart.lsl = QcSpcH.lowerlimit; if (XMRchart.xmrxcharts.Count > 0) { XMRmrschart rchart = new XMRmrschart(); rchart.mr = Math.Abs((float)(xchart.x - XMRchart.xmrxcharts.Last().x)!); XMRchart.xmrmrcharts.Add(rchart); } XMRchart.xmrxcharts.Add(xchart); } var xAverage = XMRchart.xmrxcharts.Select(p => p.x).Average(); var mrAverage = XMRchart.xmrmrcharts.Select(p => p.mr).Average(); XMRchart.xmrxcharts.ForEach(p => { p.uclx = xAverage + (float)(2.66 * mrAverage)!; p.clx = xAverage; p.lclx = xAverage - (float)(2.66 * mrAverage)!; }); XMRchart.xmrmrcharts.ForEach(p => { p.uclmr = (float)(mrAverage * 3.267)!; p.clmr = mrAverage; p.lclmr = 0; }); return XMRchart; } if (QcSpcH.graphtype == "P图") { List pcharts = new List(); foreach (var QcSpcD in QcSpcDs) { Pchart pchart = new Pchart(); pchart.p = QcSpcD.defectivenum / QcSpcD.checknum; pchart.n = QcSpcD.checknum; pcharts.Add(pchart); } var pAverage = (pcharts.Select(p => p.n * p.p).Sum()) / (pcharts.Select(p => p.n).Sum()); var nAverage = pcharts.Select(p => p.n).Average(); pcharts.ForEach(p => { p.cl = pAverage; p.ucl = pAverage + (float)(3 * Math.Sqrt((double)(pAverage * (1 - pAverage))!) / Math.Sqrt((double)nAverage!)); p.lcl = pAverage - (float)(3 * Math.Sqrt((double)(pAverage * (1 - pAverage))!) / Math.Sqrt((double)nAverage!)) < 0 ? 0 : pAverage - (float)(3 * Math.Sqrt((double)(pAverage * (1 - pAverage))!) / Math.Sqrt((double)nAverage!)); }); return pcharts; } if (QcSpcH.graphtype == "U图") { List ucharts = new List(); foreach (var QcSpcD in QcSpcDs) { Uchart uchart = new Uchart(); uchart.u = QcSpcD.defectivenum / QcSpcD.checknum; uchart.n = QcSpcD.checknum; ucharts.Add(uchart); } var uAverage = (ucharts.Select(p => p.u).Sum()) / (ucharts.Count()); var nAverage = ucharts.Select(p => p.n).Average(); ucharts.ForEach(p => { p.cl = uAverage; p.ucl = uAverage + (float)(3 * Math.Sqrt((double)(uAverage / nAverage)!)); p.lcl = uAverage - (float)(3 * Math.Sqrt((double)(uAverage / nAverage)!)) < 0 ? 0 : uAverage - (float)(3 * Math.Sqrt((double)(uAverage / nAverage)!)); }); return ucharts; } if (QcSpcH.graphtype == "nP图") { List npcharts = new List(); foreach (var QcSpcD in QcSpcDs) { NPchart npchart = new NPchart(); npchart.np = QcSpcD.defectivenum; npcharts.Add(npchart); } var npAverage = (npcharts.Select(p => p.np).Sum()) / (npcharts.Count()); var pAverage = npcharts.Select(p => p.np).Sum() / (npcharts.Count() * QcSpcH.subcapacity); npcharts.ForEach(p => { p.cl = npAverage; p.ucl = npAverage + (float)(3 * Math.Sqrt((double)(npAverage * (1 - pAverage))!)); p.lcl = npAverage - (float)(3 * Math.Sqrt((double)(npAverage * (1 - pAverage))!)) < 0 ? 0 : npAverage - (float)(3 * Math.Sqrt((double)(npAverage * (1 - pAverage))!)); }); return npcharts; } if (QcSpcH.graphtype == "C图") { List ccharts = new List(); foreach (var QcSpcD in QcSpcDs) { Cchart cchart = new Cchart(); cchart.c = QcSpcD.defectivenum; ccharts.Add(cchart); } var cAverage = (ccharts.Select(p => p.c).Sum()) / (ccharts.Count()); ccharts.ForEach(p => { p.cl = cAverage; p.ucl = cAverage + (float)(3 * Math.Sqrt((double)cAverage!)); p.lcl = cAverage - (float)(3 * Math.Sqrt((double)cAverage!)) < 0 ? 0 : cAverage - (float)(3 * Math.Sqrt((double)cAverage!)); }); return ccharts; } return null; } //标准差计算 private static float CalculateStdDev(IEnumerable values) { double ret = 0; if (values.Count() > 0) { // 计算平均数 double avg = values.Average(); // 计算各数值与平均数的差值的平方,然后求和 double sum = values.Sum(d => Math.Pow(d - avg, 2)); // 除以数量,然后开方 ret = Math.Sqrt(sum / values.Count()); } return (float)ret; } //中位数计算 private static float CalculateMedian(IEnumerable values) { float ret = 0; var floats = values.OrderBy(d => d).ToArray(); if (floats.Count() % 2 == 0) { ret = (floats[floats.Count() / 2 - 1] + floats[(floats.Count() + 2) / 2 - 1]) / 2; } else { ret = floats[(floats.Count() + 1) / 2 - 1]; } return ret; } //移动极差平均值计算 private static float CalculateMovRange(IEnumerable values) { List floats = new List(); var arr=values.ToArray(); for (int i = 0; i < arr.Length-1; i++) { floats.Add(Math.Abs((arr[i + 1] - arr[i]))); } return floats.Average(); } } }