Browse Source

1.新增維修進/出統計報表REP013

2.修改WipAlarmsController增加PostWipAlarm4ErrorCode
PTD
Marvin 3 years ago
parent
commit
bdf068f827
  1. 17
      AMESCoreStudio.Web/Controllers/REPController.cs
  2. 7
      AMESCoreStudio.Web/HttpApis/AMES/IREP.cs
  3. 300
      AMESCoreStudio.Web/Views/REP/REP013.cshtml
  4. 145
      AMESCoreStudio.WebApi/Controllers/AMES/NgRepairsController.cs
  5. 127
      AMESCoreStudio.WebApi/Controllers/AMES/WipAlarmsController.cs

17
AMESCoreStudio.Web/Controllers/REPController.cs

@ -1108,5 +1108,22 @@ namespace AMESCoreStudio.Web.Controllers
return Json(new Table() { count = 0, data = null });
}
#endregion
public IActionResult REP013()
{
return View();
}
public async Task<IActionResult> REP013QueryAsync(string wipNO, string itemNO, string dateStart, string dateEnd, int page = 0, int limit = 10)
{
var result = await _repApi.GetRepairData4REP013(wipNO, itemNO, dateStart, dateEnd, page, limit);
if (result.DataTotal > 0)
{
return Json(new Table() { code = 0, msg = "", data = result.Data, count = result.DataTotal });
}
return Json(new Table() { count = 0, data = null });
}
}
}

7
AMESCoreStudio.Web/HttpApis/AMES/IREP.cs

@ -225,5 +225,12 @@ namespace AMESCoreStudio.Web
ITask<ResultModel<WipAlarm>> GetWipAlarmsByType(int id, int page = 0, int limit = 10);
#endregion
/// <summary>
/// 維修進/出統計報表
/// </summary>
/// <returns></returns>
[WebApiClient.Attributes.HttpGet("api/NgRepairs/GetRepairData4REP013")]
ITask<ResultModel<dynamic>> GetRepairData4REP013(string wipNo, string itemNo, string dateStart, string dateEnd, int page, int limit);
}
}

300
AMESCoreStudio.Web/Views/REP/REP013.cshtml

@ -0,0 +1,300 @@
@{
ViewData["Title"] = "維修進/出統計報表";
Layout = "~/Views/Shared/_AMESLayout.cshtml";
}
<style type="text/css">
.layui-table-main .layui-table-cell {
/*height: auto !important;*/
white-space: normal;
}
.layui-table img {
max-width: 60px;
max-height: 28px;
}
.layui-tree-main {
cursor: pointer;
padding-right: 10px;
float: left;
border-width: 1px;
border-style: solid;
border-color: #e6e6e6;
margin: 10px 0;
}
</style>
<div class="layui-card">
<div class="layui-card-header">
<div class="layui-form">
<div class="layui-form-item">
<div class="layui-inline"><i class="fa fa-file-text-o fa-fw"></i> @ViewBag.Title</div>
</div>
</div>
</div>
<div class="layui-card-body">
<div class="layui-form">
<div class="layui-row">
<div class="layui-form-item">
<div class="layui-col-sm3">
<div class="layui-inline">
<label class="layui-form-label">工單號碼:</label>
<div class="layui-input-inline" style="width:150px">
<input id="wipNO" name="wipNo" autocomplete="off" class="layui-input" placeholder="請輸入工單號碼">
</div>
</div>
</div>
<div class="layui-col-sm3">
<div class="layui-inline">
<label class="layui-form-label">料號:</label>
<div class="layui-input-inline" style="width:150px">
<input id="itemNO" name="itemNo" autocomplete="off" class="layui-input" placeholder="請輸入料號">
</div>
</div>
</div>
</div>
</div>
<div class="layui-row">
<div class="layui-form-item">
<div class="layui-col-sm5">
<div class="layui-inline">
<label class="layui-form-label">維修日期:</label>
<div class="layui-input-inline" style="width:150px">
<input id="dateStart" name="dateStart" autocomplete="off" class="layui-input" readonly="">
</div>
<div class="layui-form-mid">~</div>
<div class="layui-input-inline" style="width:150px">
<input id="dateEnd" name="dateEnd" autocomplete="off" class="layui-input" readonly="">
</div>
</div>
</div>
<div class="layui-col-sm1">
<div class="layui-inline layui-show-xs-block">
<button class="layui-btn layui-btn-sm layui-btn-normal" lay-submit lay-filter="querysubmit">
<i class="layui-icon layui-icon-sm">&#xe615;</i>
</button>
</div>
</div>
</div>
</div>
</div>
<table class="layui-hide" id="query" lay-filter="query"></table>
<div class="layui-inline">
<button type="button" id="btnExport" class="layui-btn layui-btn-normal layui-btn-sm"><i class="fa fa-file-excel-o"></i>導出全部數據</button>
</div>
</div>
</div>
@section Scripts{
<script type="text/javascript">
layui.config({
base: '../lib/layui_ext/',
}).extend({
excel: 'excel',
});
</script>
<script type="text/javascript">
function formatJSONDate(jsonDate) {
if (jsonDate == null) {
return "";
}
else {
var date = eval(jsonDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
var myDate = new Date(date);
var yy = myDate.getFullYear();
var mm = (myDate.getMonth() + 1 < 10 ? '0' : '') + (myDate.getMonth() + 1);
var dd = (myDate.getDate() < 10 ? '0' : '') + myDate.getDate();
var h = (myDate.getHours() < 10 ? '0' : '') + myDate.getHours();
var m = (myDate.getMinutes() < 10 ? '0' : '') + myDate.getMinutes();
var s = (myDate.getSeconds() < 10 ? '0' : '') + myDate.getSeconds();
//mm + "/" + dd + " " +
//var output = yy + "-" + mm + "-" + dd + " " + h + ":" + m + ":" + s;
var output = yy + mm + dd + h + m + s;
// myDate.getHours() + ":" + myDate.getMinutes() + ":" + myDate.getSeconds();
return output;
}
}
layui.use(['jquery', 'excel', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var excel = layui.excel;
$('#btnExport').on('click', function () {
$.ajax({
url: '@Url.Action("REP013Query", "REP")',
dataType: 'json',
success(res) {
var data = res.data;
data = excel.filterExportData(data, [
'unitNO',
'lineDesc',
'createDate',
'month',
'weekOfYearISO',
'stationName',
'wipNO',
'planQTY',
'barcodeNo',
'modelNO',
'itemNO',
'semiItemNo',
'oldPartNo',
'newPartNo',
'ngNo',
'reasonDesc',
'locationNo',
'changeMaterial',
'repairReason',
'repairType2',
'memo',
'repairDesc',
'ngType2',
'rrDesc',
'userNo',
'userName',
'replyDate',
'testDate',
'testUserNo',
'testUserName',
'testTypeName',
'qaTypeName',
'ngReasonDescEn',
'partNo',
'pinNo',
'reelNo',
'dateCode',
'vendorCode',
'replyReason',
'replyMeasure',
'replyUserNo',
'replyUserName',
'checkInUserName',
'checkInDate',
'checkOutUserName',
'checkOutDate',
'tat',
'stateDesc'
]);
data.unshift({
unitNO: "製程單位", lineDesc: "線別", createDate: "維修時間", month: "月份", weekOfYearISO: "第幾週", stationName: "站別", wipNO: "工單號碼", planQTY: "數量", barcodeNo: "條碼", modelNO: "機種", itemNO: "料號", semiItemNo: "半成品料號", oldPartNo: "舊料號", newPartNo: "新料號",
ngNo: "不良代碼", reasonDesc: "不良描述", locationNo: "維修位置", changeMaterial: "更換零件", repairReason: "維修原因", repairType2: "維修類別", memo: "維修備註", repairDesc: "維修描述",
ngType2: "不良類別", rrDesc: "不良責任類別", userNo: "維修工號", userName: "維修人員", replyDate: "回覆時間", testDate: "測試時間", testUserNo: "測試工號", testUserName: "測試人員"
, testTypeName: "測試類別", qaTypeName: "QA類別", ngReasonDescEn: "英文不良描述", partNo: "零件料號", pinNo: "腳位", reelNo: "料卷號"
, dateCode: "日期碼", vendorCode: "供應商代碼", replyReason: "回覆原因"
, replyMeasure: "回覆對策", replyUserNo: "回覆工號", replyUserName: "回覆人員"
, checkInUserName: "進站人員", checkInDate: "進站時間", checkOutUserName: "出站人員", checkOutDate: "出站時間", tat: "TAT(小時)", stateDesc: "狀態"
});
var timestart = Date.now();
excel.downloadExcel(data, '維修進出統計報表' + formatJSONDate(Date.now().toString()), 'xlsx');
var timeend = Date.now();
var spent = (timeend - timestart) / 1000;
layer.alert('導出全部數據耗時 ' + spent + ' s');
}
, error() {
layer.alert('導出全部數據失敗');
}
});
});
});
layui.use(['form', 'layer', 'laydate'], function () {
form = layui.form;
laydate = layui.laydate;
laydate.render({
elem: '#dateStart'
, trigger: 'click'
, format: 'yyyy/MM/dd'
, theme: 'grid'
});
laydate.render({
elem: '#dateEnd'
, trigger: 'click'
, format: 'yyyy/MM/dd'
, theme: 'grid'
});
});
//监听表单提交事件
hg.form.onsubmit('querysubmit', function (data) {
hg.msghide("重新載入資料..");
table && table.reload(data);
});
var tableCols = [[
{
field: 'barcodeNo',
title: '條碼',
sort: true
},
{
field: 'wipNO',
width: 200,
title: '工單號碼',
sort: true
},
{
field: 'itemNO',
title: '料號',
width: 200,
sort: true
},
{
field: 'stationName',
width: 160,
title: '站別',
sort: true
},
{
field: 'checkInUserName',
title: '進站人員',
width: 160,
sort: true
},
{
field: 'checkInDate',
title: '進站時間',
width: 160,
templet: '<div>{{ layui.util.toDateString(d.testDate, "yyyy/MM/dd HH:mm") }}</div>'
},
{
field: 'checkOutUserName',
title: '出站人員',
width: 160,
sort: true
},
{
field: 'checkOutDate',
title: '出站時間',
width: 160,
templet: '<div>{{ layui.util.toDateString(d.createDate, "yyyy/MM/dd HH:mm") }}</div>'
},
{
field: 'tat',
title: 'TAT(Hour)',
width: 160,
sort: true
},
{
field: 'stateDesc',
title: '狀態',
width: 100,
sort: true
}]
];
//var param = productTypeNo.value + '_' + testTypeNo.value + '_' + unitNo.value + '_' + lineID.value + '_' + stationID.value + '_' + wipNO.value + '_' + itemNO.value + '_' + dateStart.value + '_' + dateEnd.value;
//基本数据表格
var table = hg.table.datatable('query', '維修進/出統計報表', '/REP/REP013Query', {}, tableCols, toolbar, true, 'full-100', ['filter', 'print', 'exports']);
</script>
}

145
AMESCoreStudio.WebApi/Controllers/AMES/NgRepairsController.cs

@ -354,6 +354,151 @@ namespace AMESCoreStudio.WebApi.Controllers.AMES
return result;
}
/// <summary>
/// 維修進/出統計報表
/// </summary>
/// <param name="wipNo"></param>
/// <param name="itemNo"></param>
/// <param name="dateStart"></param>
/// <param name="dateEnd"></param>
/// <param name="page"></param>
/// <param name="limit"></param>
/// <returns></returns>
[Route("[action]")]
[HttpGet]
public async Task<ResultModel<dynamic>> GetRepairData4REP013(string wipNo, string itemNo, string dateStart, string dateEnd, int page = 0, int limit = 10)
{
ResultModel<dynamic> result = new ResultModel<dynamic>();
var q = from q1 in _context.NgRepairs
join q2 in _context.NgInfos on q1.NgID equals q2.NgID
join q3 in _context.BarcodeInfoes on q2.BarcodeID equals q3.BarcodeID
join q4 in _context.WipInfos on q3.WipID equals q4.WipID
join q5 in _context.WipAtts on q4.WipNO equals q5.WipNO
join q6 in _context.LineInfoes on q4.LineID equals q6.LineID
join q7 in _context.Stationses on q2.StationId equals q7.StationID
join q8 in _context.NgComponents on q2.NgID equals q8.NgID
join q9 in _context.RepairResponsibleUnitses on q1.RepairResponsibleID equals q9.RRID
join qa in _context.NGReasons on q8.NgNo equals qa.NGReasonNo
join qb in _context.RepairTypes on q1.RepairTypeNo equals qb.RepairTypeNo
join qc in _context.UserInfoes on q1.CreateUserID equals qc.UserID
join qd in _context.UserInfoes on q2.CreateUserID equals qd.UserID
join qe in _context.TestTypes on q2.TypeNo equals qe.TypeNo
join qf in _context.UserInfoes on q8.ReplyUserID equals qf.UserID
join qg in _context.RMAReasons on q1.RepairNo equals qg.RMAReasonNo
join qh in _context.QATypes on qg.QATypeId equals qh.QATypeID
join qi in _context.CalendarTables on q1.CreateDate.Date equals qi.TimeID
select new
{
q4.UnitNO,
q6.LineDesc,
q1.CreateDate,
qi.Month,
qi.WeekOfYearISO,
q7.StationName,
q4.WipNO,
q4.PlanQTY,
q3.BarcodeNo,
q5.ModelNO,
q5.ItemNO,
q8.SemiItemNo,
q8.OldPartNo,
q8.NewPartNo,
q8.NgNo,
ReasonDesc = q8.NgNo + '-' + qa.NGReasonDesc,
q8.LocationNo,
q8.ChangeMaterial,
RepairReason = q1.RepairNo + '-' + q1.RepairDesc,
RepairType2 = qb.RepairTypeNo + '-' + qb.RepairTypeDesc,
q1.Memo,
q1.RepairDesc,
NgType2 = qa.NGReasonNo + '-' + qa.NGReasonDesc,
ResponsibleUnit = q9.RRID + '-' + q9.RRDesc,
q9.RRDesc,
qc.UserNo,
qc.UserName,
q8.ReplyDate,
//RepairDays = (q8.ReplyDate-q2.CreateDate).TotalDays,
TestDate = q2.CreateDate,
TestUserNo = qd.UserNo,
TestUserName = qd.UserName,
TestTypeName = qe.TypeName,
qh.QATypeName,
qa.NGReasonDescEn,
q1.PartNo,
q8.PinNo,
q8.ReelNo,
q8.DateCode,
q8.VendorCode,
q8.ReplyReason,
q8.ReplyMeasure,
q8.ReplyUserID,
ReplyUserNo = qf.UserNo,
ReplyUserName = qf.UserName,
q4.LineID,
q2.TypeNo,
q2.StationId,
q1.RepairNo,
q2.ReasonNo,
CheckInDate = q2.CreateDate,
CheckInUserNo = qd.UserNo,
CheckInUserName = qd.UserName,
CheckOutUserNo = qc.UserNo,
CheckOutUserName = qc.UserName,
CheckOutDate = q1.CreateDate,
TAT = EF.Functions.DateDiffHour(q2.CreateDate, q1.CreateDate),
StateDesc = (qc.UserName != "" ? "出站" : "進站")
};
if (wipNo != null)
{
if (wipNo != "")
{
q = q.Where(w => w.WipNO == wipNo);
}
}
if (itemNo != null)
{
if (itemNo != "")
{
q = q.Where(w => w.ItemNO == itemNo);
}
}
if (dateStart != null && dateEnd != null)
{
if (dateStart != "" && dateEnd != "")
{
q = q.Where(w => w.CreateDate >= DateTime.Parse(dateStart) && w.CreateDate <= DateTime.Parse(dateEnd));
}
}
q = q.OrderBy(w => w.CreateDate);
//紀錄筆數
result.DataTotal = q.Count();
//Table 頁數
if (page > 0)
{
q = q.Skip((page - 1) * limit).Take(limit);
}
result.Data = await q.ToListAsync();
if (result == null)
{
result.Msg = "查無資料";
result.Success = false;
return result;
}
result.Success = true;
result.Msg = "OK";
return result;
}
/// <summary>
/// 維修資料統計by不良代碼
/// </summary>

127
AMESCoreStudio.WebApi/Controllers/AMES/WipAlarmsController.cs

@ -7,7 +7,11 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using AMESCoreStudio.WebApi;
using AMESCoreStudio.WebApi.Models.AMES;
using AMESCoreStudio.WebApi.Models.BAS;
using AMESCoreStudio.CommonTools.Result;
using Microsoft.Extensions.Configuration;
using System.Net;
using System.Net.Mail;
namespace AMESCoreStudio.WebApi.Controllers.AMES
{
@ -19,6 +23,7 @@ namespace AMESCoreStudio.WebApi.Controllers.AMES
public class WipAlarmsController : ControllerBase
{
private readonly AMESContext _context;
private readonly IConfiguration _config;
/// <summary>
///
@ -182,6 +187,128 @@ namespace AMESCoreStudio.WebApi.Controllers.AMES
return result;
}
/// <summary>
/// 判斷同一不良代碼累計預警
/// </summary>
/// <param name="wipNO">工單號碼</param>
/// <param name="errorCode">不良代碼</param>
/// <returns></returns>
[Route("[action]")]
[HttpPost]
public async Task<ResultModel<string>> PostWipAlarm4ErrorCode(string wipNO, string errorCode)
{
ResultModel<string> result = new ResultModel<string>();
//判断预警
var q1 = from a in _context.NgComponents
join b in _context.NgInfos on a.NgID equals b.NgID
join c in _context.BarcodeInfoes on b.BarcodeID equals c.BarcodeID
join d in _context.WipInfos on c.WipID equals d.WipID
select new
{
a.NgNo,
d.WipNO
};
q1 = q1.Where(w => w.WipNO.Equals(wipNO));
q1 = q1.Where(w => w.NgNo.Equals(errorCode));
var data1 = await q1.ToListAsync();
if (data1.Count > 3)
{
try
{
//保存警报资料
string alarmDesc = string.Format("工單號碼{0}不良代碼{1}累積超過{2}次", wipNO, errorCode, data1.Count);
Helper helper = new Helper(_context);
WipAlarm wipAlarm = new WipAlarm();
wipAlarm.WipAlarmID = helper.GetIDKey("WIP_ALARMID").Result;
wipAlarm.AlarmTypeID = 1;
wipAlarm.WipNO = wipNO;
wipAlarm.AlarmParam = errorCode;
wipAlarm.AlarmValue = data1.Count.ToString();
wipAlarm.AlarmDesc = alarmDesc;
wipAlarm.AlarmDateTime = DateTime.Now;
_context.WipAlarms.Add(wipAlarm);
await _context.SaveChangesAsync();
//发送警报资料
string mailSubject = "警報持續郵件" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string mailBody = "";
mailBody = mailBody + "警報工單:" + wipNO + "<br />";
mailBody = mailBody + "警報時間:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "<br />";
mailBody = mailBody + "警報原因:" + alarmDesc + "<br />";
string mailFrom = _config["MailForm"].ToString();
//string mailTo = _config["MailTo"].ToString();
string mailSmtpServer = _config["MailSmtpServer"].ToString();
int mailSmtpPort = int.Parse(_config["MailSmtpPort"].ToString());
string mailUser = _config["MailUser"].ToString();
string mailPassword = _config["MailUserPassword"].ToString();
MailMessage mesMail = new MailMessage();
mesMail.From = new MailAddress(mailFrom);
IQueryable<MailGroup> q3 = _context.MailGroups;
q3 = q3.Where(p => p.GroupNo.Equals("WIP_ALARM"));
var mail1 = await q3.ToListAsync();
if (mail1.Count > 0)
{
var q4 = from a in _context.MailGroups
join b in _context.MailGroupDetails on a.GroupID equals b.GroupID
join c in _context.UserInfoes on b.UserID equals c.UserID
select new
{
a.GroupID,
b.UserID,
c.UserEMail
};
q4 = q4.Where(w => w.GroupID.Equals(mail1[0].GroupID));
var mail2 = await q4.ToListAsync();
if (mail2.Count > 0)
{
for (int i = 0; i < mail2.Count; i++)
{
mesMail.To.Add(new MailAddress(mail2[i].UserEMail));
}
}
//mesMail.To.Add(new MailAddress(mailTo));
mesMail.Subject = mailSubject;
mesMail.SubjectEncoding = System.Text.Encoding.UTF8;
mesMail.Body = mailBody;
mesMail.IsBodyHtml = true;
mesMail.BodyEncoding = System.Text.Encoding.UTF8;
SmtpClient mailClient = new SmtpClient(mailSmtpServer, mailSmtpPort);
//mailClient.EnableSsl = true;
NetworkCredential nc = new NetworkCredential();
nc.UserName = mailUser;
nc.Password = mailPassword;
mailClient.Credentials = nc;
mailClient.Send(mesMail);
}
}
catch { }
}
result.Success = true;
result.Msg = "OK";
return result;
}
/// <summary>
///
/// </summary>

Loading…
Cancel
Save