一、layUI+JQuery
@using AMes.Domain.Entity.SystemManage;
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>不合格品处置申请</title>
<link href="~/Scripts/layui-v2.8.2/layui/css/layui.css" rel="stylesheet" />
<style>
body, html {
height: 100%;
margin: 10px;
}
/*弹窗右上角关闭按钮*/
.layui-layer-setwin span {
font-size: 30px;
}
.layui-form-label {
width: 120px !important; /* 或者具体宽度如 120px */
white-space: nowrap; /* 防止文本换行 */
overflow: visible; /* 确保内容不会溢出被隐藏 */
}
/* 强制禁用样式 */
.disabled-input {
background-color: #f6f6f6 !important;
border-color: #e6e6e6 !important;
opacity: 0.7;
cursor: not-allowed !important;
}
</style>
</head>
<body>
<from class="layui-form layui-form-pane">
@*第一行*@
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">项目号</label>
<div class="layui-input-inline">
<input id="PROJN" type="text" name="PROJN" autocomplete="off" class="layui-input disabled-input " disabled>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">订单号</label>
<div class="layui-input-inline">
<input id="WorkOrderNumber" type="text" name="WorkOrderNumber" autocomplete="off" class="layui-input disabled-input" disabled>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">工位</label>
<div class="layui-input-inline">
<input id="WorkUnit" type="text" name="WorkUnit" autocomplete="off" class="layui-input disabled-input" disabled>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">产品型号</label>
<div class="layui-input-inline">
<input id="ProductModel" type="text" name="ProductModel" autocomplete="off" class="layui-input disabled-input" disabled>
</div>
</div>
</div>
@*第二行*@
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">物料编码</label>
<div class="layui-input-inline">
<input id="MaterialCode" type="text" name="MaterialCode" autocomplete="off" class="layui-input disabled-input" disabled>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">物料名称</label>
<div class="layui-input-inline">
<input id="MaterialName" type="text" name="MaterialName" autocomplete="off" class="layui-input disabled-input" disabled>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">内码</label>
<div class="layui-input-inline">
<input id="SerialNumberIn" type="text" name="SerialNumberIn" autocomplete="off" class="layui-input disabled-input" disabled>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">外码</label>
<div class="layui-input-inline">
<input id="SerialNumberOut" type="text" name="SerialNumberOut" autocomplete="off" class="layui-input disabled-input" disabled>
</div>
</div>
</div>
@*第三行*@
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">生产车间</label>
<div class="layui-input-inline">
<input id="ProductArea" type="text" name="ProductArea" autocomplete="off" class="layui-input disabled-input" disabled>
@*<select id="ProductArea" name="ProductArea" lay-filter="Industry-select-filter" lay-verify="required">
<option value="" selected>请选择车间</option>
@foreach (var item in (List<ItemsDetailEntity>)ViewData["Dis_Workshop"])
{
<option value="@item.F_Id">@item.F_ItemName</option>
}
</select>*@
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">产业</label>
<div class="layui-input-inline">
<select id="Industry" name="Industry" lay-filter="Industry-select-filter" lay-verify="required">
<option value="" selected>请选择产业</option>
@foreach (var item in (List<ItemsDetailEntity>)ViewData["Industry"])
{
<option value="@item.F_Id">@item.F_ItemName</option>
}
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">物料类别</label>
<div class="layui-input-inline">
<select id="MaterialCategory" name="MaterialCategory" lay-filter="MaterialCategory-select-filter" lay-verify="required">
<option value="" selected>请选择物料类别</option>
@foreach (var item in (List<ItemsDetailEntity>)ViewData["MaterialCategory"])
{
<option value="@item.F_Id">@item.F_ItemName</option>
}
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">不合格数</label>
<div class="layui-input-inline">
<input id="NonConformanceQty" type="number" name="NonConformanceQty" lay-verify="required" autocomplete="off" class="layui-input">
</div>
</div>
</div>
@*第四行*@
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">产品归类</label>
<div class="layui-input-inline">
<select id="ProductCategorization" name="ProductCategorization" lay-filter="ProductCategorization-select-filter">
<option value="" selected>请选择产品归类</option>
@foreach (var item in (List<ItemsDetailEntity>)ViewData["ProductCategorization"])
{
<option value="@item.F_Id">@item.F_ItemName</option>
}
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">不合格类别</label>
<div class="layui-input-inline">
<select id="NonConformanceCategory" name="NonConformanceCategory" lay-filter="NonConformanceCategory-select-filter">
<option value="" selected>请选择不合格类别</option>
@foreach (var item in (List<ItemsDetailEntity>)ViewData["NonConformanceCategory"])
{
<option value="@item.F_Id">@item.F_ItemName</option>
}
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">不合格程度</label>
<div class="layui-input-inline">
<select id="NonConformanceDegree" name="NonConformanceDegree" lay-filter="NonConformanceDegree-select-filter" lay-verify="required">
<option value="" selected>请选择不合格程度</option>
@foreach (var item in (List<ItemsDetailEntity>)ViewData["NonConformanceDegree"])
{
<option value="@item.F_Id">@item.F_ItemName</option>
}
</select>
</div>
</div>
</div>
@*第五行*@
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">问题发生时间</label>
<div class="layui-input-inline">
<input id="OccurrenceTime" type="text" name="OccurrenceTime" lay-filter="OccurrenceTime" lay-verify="required" autocomplete="off" class="layui-input" placeholder="yyyy-MM-dd HH:mm:ss">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">一级物料分类</label>
<div class="layui-input-inline">
<select id="OneMaterialCode" name="OneMaterialCode" lay-filter="OneMaterialCode"></select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">二级物料分类</label>
<div class="layui-input-inline">
<select id="TwoMaterialCode" name="TwoMaterialCode" lay-filter="TwoMaterialCode"></select>
</div>
</div>
</div>
@*第六行*@
<div class="layui-form-item">
<div class="layui-upload">
<div>
<table class="layui-hide" id="InspectionItems" lay-filter="InspectionItems"></table>
</div>
<div style="text-align:right;padding:10px;">
<button class="layui-btn" lay-submit lay-filter="table-submit" style="background-color:#006487">
提交 <i class="layui-icon layui-icon-ok layui-font-12"></i>
</button>
</div>
</div>
</div>
</from>
<script type="text/html" id="TPL-select-DefectType">
<select name="DefectType" class="layui-border DefectType" data-rowid="{{d.Id}}" lay-ignore>
<option value="">请选择</option>
@foreach (var item in (List<Base_DefectType_Entity>)ViewData["DefectType"])
{
<option value="@item.DefectTypeCode" {{ d.DefectType == '@item.DefectTypeCode' ? 'selected' : '' }}>@item.DefectTypeName</option>
}
</select>
</script>
<script type="text/html" id="TPL-select-DefectDes">
<select name="DefectDes" class="layui-border DefectDes" data-rowid="{{d.Id}}" lay-ignore style="width:115px;">
<option value="">请选择</option>
{{# layui.each(d._defectDesOptions || [], function(index, item){ }}
<option value="{{ item.DefectDesCode }}" {{ d.DefectDes == item.DefectDesCode ? 'selected' : '' }}>{{ item.DefectDesName }}</option>
{{# }); }}
</select>
</script>
<!-- 操作列模板 -->
<script type="text/html" id="actionTpl">
<div class="action-cell">
<button class="layui-btn layui-btn-sm upload-btn" lay-event="upload">
<i class="layui-icon"></i> 上传文件
</button>
</div>
</script>
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script src="~/Scripts/layui-v2.11.4/layui/layui.js"></script>
<script>
var form;
var loginUserCode = "@ViewData["LoginUserCode"]";//当前登录人编号
var loginUserName = "@ViewData["LoginUserName"]";//当前登录人名称
var List_UploadFile = [];//文件结果列表中
var workOrderOperationInfo = new Object();
var edit = function (data) {
workOrderOperationInfo = data;
console.log("workOrderOperationInfo ===========================================", JSON.stringify(workOrderOperationInfo));
$("#PROJN").val(workOrderOperationInfo.ProjectNo);//项目号
$("#WorkOrderNumber").val(workOrderOperationInfo.OrderNo);//订单号
$("#WorkUnit").val(workOrderOperationInfo.Ps_Ppr);//工位
$("#ProductModel").val(workOrderOperationInfo.Model);//型号
$("#MaterialCode").val(workOrderOperationInfo.ProductCode);//物料编码
$("#MaterialName").val(workOrderOperationInfo.ProductDesc);//物料名称
$("#SerialNumberIn").val(workOrderOperationInfo.ProductBarCode);//内码
$("#SerialNumberOut").val(workOrderOperationInfo.outCode);//外码
$("#ProductArea").val(workOrderOperationInfo.WorkshopCode);//车间名称
}
layui.use(function () {
//得到各种内置组件
var $ = layui.jquery;
var layer = layui.layer //弹层
, laypage = layui.laypage //分页
, laydate = layui.laydate //日期
, table = layui.table //表格
, upload = layui.upload //上传
element = layui.element;//元素操作
form = layui.form;
//时间控件
laydate.render({
elem: '#OccurrenceTime',
type: 'datetime',
fullPanel: true //
});
// 使用事件委托处理缺陷类型变更
$(document).on('change', '.DefectType', function () {
var value = this.value;
var text = this.options[this.selectedIndex].text;
var rowId = $(this).data('rowid');
var tr = $(this).closest('tr');
var index = tr.data('index');
if (rowId) {
var rowData = table.cache.InspectionItems[index];
if (rowData) {
rowData.DefectType = value;
rowData.DefectTypeName = text;
// 清空缺陷描述的值和选项
rowData.DefectDes = '';
rowData.DefectDesName = '';
rowData._defectDesOptions = []; // 先清空,等加载完再设置
GetDefectDes(value, rowId, function (defectDesList) {
// 将缺陷描述列表保存到行数据的临时属性中
rowData._defectDesOptions = defectDesList;
// 更新行数据,以便重新渲染缺陷描述下拉框
table.updateRow('InspectionItems', {
index: index,
data: rowData
});
});
}
}
});
// 使用事件委托处理缺陷描述变更
$(document).on('change', '.DefectDes', function () {
var value = this.value;
var text = this.options[this.selectedIndex].text;
var rowId = $(this).data('rowid');
var tr = $(this).closest('tr');
var index = tr.data('index');
if (rowId) {
var rowData = table.cache.InspectionItems[index];
if (rowData) {
rowData.DefectDes = value;
rowData.DefectDesName = text;
}
}
});
setTimeout(() => {
//不合格检验项列表
table.render({
elem: '#InspectionItems'
,id: 'InspectionItems'// 添加这行
, url: '/ProcessInspectionManage/NonconformDispositionApplication/GetInspectionItemsTablePage'//数据接口
, height: '400px'
, method: 'post'
, title: '不合格检验项列表'
//, toolbar: '#toolbarDemo'
, cellMinWidth: 'auto'
, where: {
QualityInspectionId: workOrderOperationInfo.F_Id
}
, page: true//开启分页
, limit: 200//页面大小
, limits: [30, 50, 100, 200, 500]
, cols: [[ //表头
{ field: 'Id', title: 'ID', hide: true }
,{ field: 'CheckNo', title: '检验项编码', align: 'center', width: 150, hide: false }
, { field: 'CheckName', title: '检验项名称', align: 'center', width: 150, hide: false }
, { field: 'CheckContent', title: '检验内容', align: 'center', width: 150, hide: false }
, { field: 'DefectType', title: '缺陷类型', align: 'center', width: 150, hide: false, templet: '#TPL-select-DefectType' }
, { field: 'DefectDes', title: '缺陷描述', align: 'center', width: 150, hide: false, templet: '#TPL-select-DefectDes' }
, { field: 'ProblemDes', title: '问题描述', align: 'center', width: 300, hide: false, edit: 'textarea' }
, { field: 'FileName', title: '文件名称', align: 'center', width: 150, hide: false }
, { field: 'FileType', title: '文件类型', align: 'center', width: 150, hide: true }
, { field: 'FileUrl', title: '文件地址', align: 'center', width: 150, hide: true }
, { fixed: 'right', title: '操作', width: 134, minWidth: 125, templet: '#actionTpl' }
]]
, done: function (res, curr, count) {
//初始化上传按钮
// 在表格渲染完成后绑定上传按钮
$('.upload-btn').each(function () {
var elem = $(this);
var tr = elem.closest('tr');
var index = tr.data('index');
if (!elem.data('upload-initialized')) {
initUpload(elem, index);
elem.data('upload-initialized', true);
}
});
}
});
}, 500);
//提交
form.on('submit(table-submit)', function (data) {
console.log("table-submit-----------------" + JSON.stringify(data.field));
var field = data.field; // 获得表单字段
field.ProductCategorizationName = $("#ProductCategorization option:selected").text();
field.NonConformanceCategoryName = $("#NonConformanceCategory option:selected").text();
field.NonConformanceDegreeName = $("#NonConformanceDegree option:selected").text();
field.MaterialCategoryName = $("#MaterialCategory option:selected").text();
field.IndustryName = $("#Industry option:selected").text();
field.OneMaterialName = $("#OneMaterialCode option:selected").text();
field.TwoMaterialName = $("#TwoMaterialCode option:selected").text();
field.ReworkTaskNumber = workOrderOperationInfo.ReworkTaskNumber;
field.ProductAreaName = $("#ProductArea option:selected").text();
//field.List_UploadFile = List_UploadFile;
var currentData = table.getData('InspectionItems');
field.List_UploadFile = currentData;
let postData = {
createdUserCode: loginUserCode,
createdUserName: loginUserName,
F_Id: workOrderOperationInfo.F_Id,
entity: JSON.stringify(field)
}
console.log("postData-----------------" + JSON.stringify(postData));
$.ajax({
async: false, //true 异步 false为同步请求
type: 'POST'
, url: '/ProcessInspectionManage/NonconformDispositionApplication/SaveNonconformDispositionOrder'
, data: postData
, beforeSend: function () {
//console.log("加载中...");
},
complete: function () {
// console.log("加载更多");
},
success: function (data) {
var res = data;
if (res.code != 200) {
layer.msg(res.msg, { icon: 5 });
} else {
layer.msg(res.msg, { icon: 1 });
//当在iframe页面关闭自身时,在iframe页执行以下js脚本
var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
//parent.layer.close(index); //再执行关闭
setTimeout(function () { parent.layer.close(index) }, 1000);
}
}
});
});
//监听一级物料分类下拉选择
form.on('select(OneMaterialCode)', function (data) {
console.log(data)
GetTwoMaterialCode(data.value)
});
// 初始化上传函数
function initUpload(elem, index) {
var tr = elem.closest('tr');
upload.render({
elem: elem[0],
url: '/ProcessInspectionManage/NonconformDispositionApplication/FileUpload',
accept: 'file',
size: 10 * 1024,
auto: true, // 自动上传
choose: function (obj) {
// 仅修改文本,不替换整个DOM
elem.addClass('layui-btn-disabled').html('<i class="layui-icon"></i> 上传中...');
},
before: function () {
var progress = $('<div class="upload-status"></div>');
progress.append('<div class="layui-progress progress" lay-filter="progress-' + index + '">' +
'<div class="layui-progress-bar layui-bg-blue" lay-percent="0%"></div></div>');
tr.find('.file-info').html(progress);
element.render('progress');
},
progress: function (n) {
var percent = n + '%';
element.progress('progress-' + index, percent);
},
done: function (res) {
console.log("上传结果==========================", JSON.stringify(res));
if (res.success) {
//let tableId = 'InspectionItems';
//var allData = table.cache.InspectionItems;
var allData = table.cache.InspectionItems;
console.log("allData ==========================", JSON.stringify(allData));
console.log("index ==========================", JSON.stringify(index));
// 确保索引有效
if (allData && allData[index]) {
// 更新数据
allData[index].FileName = res.data.fileName;
allData[index].FileType = res.data.fileType;
allData[index].FileUrl = res.data.filePath;
console.log("allData[index]._defectDesOptions ==========================", JSON.stringify(allData[index]._defectDesOptions));
console.log("allData[index] ==========================", JSON.stringify(allData[index]));
console.log("allData =====after=====================", JSON.stringify(allData));
// 更新指定行数据
table.updateRow("InspectionItems", {
index: index,
data: allData[index]
});
let DefectTypeValue = allData[index].DefectType;
let rowId = allData[index].Id;
// GetDefectDes(DefectTypeValue, rowId);
GetDefectDes(DefectTypeValue, rowId, function (defectDesList) {
// 将缺陷描述列表保存到行数据的临时属性中
allData[index]._defectDesOptions = defectDesList;
// 更新行数据,以便重新渲染缺陷描述下拉框
table.updateRow('InspectionItems', {
index: index,
data: allData[index]
});
// 重新渲染表单
// layui.form.render();
});
layer.msg('上传成功');
}
} else {
layer.msg('上传失败');
}
elem.removeClass('layui-btn-disabled').html('<i class="layui-icon"></i> 上传文件');
},
error: function () {
elem.removeClass('layui-btn-disabled').html('<i class="layui-icon"></i> 上传文件');
layer.msg('上传失败');
}
});
}
});
$(function () {
GetOneMaterialCode();
});
//获取一级物料分类数据
function GetOneMaterialCode() {
$.post("/ProcessInspectionManage/NonconformDispositionApplication/GetMaterialClassA", "", function (res) {
if (res.code == 1) {
$("#OneMaterialCode").empty();
var str = '<option value="">请选择一级物料分类</option>';
$.each(res.data, function (index, item) {
str += '<option value="' + item.MaterialCode + '" >' + item.MaterialName + '</option>';
})
$("#OneMaterialCode").append(str);
//重新渲染下拉框
layui.use('form', function () {
form.render();
form.render('select', 'OneMaterialCode'); //刷新select选择框渲染
});
}
})
}
//获取二级物料分类数据
function GetTwoMaterialCode(_MaterialCode) {
$.post("/ProcessInspectionManage/NonconformDispositionApplication/GetMaterialClassB", "MaterialCode=" + _MaterialCode, function (res) {
if (res.code == 1) {
$("#TwoMaterialCode").empty();
var str = '<option value="">请选择二级物料分类</option>';
$.each(res.data, function (index, item) {
str += '<option value="' + item.MaterialCode + '" >' + item.MaterialName + '</option>';
})
$("#TwoMaterialCode").append(str);
//重新渲染下拉框
layui.use('form', function () {
form.render();
form.render('select', 'TwoMaterialCode'); //刷新select选择框渲染
});
}
});
}
// 获取缺陷描述数据(带回调)
function GetDefectDes(defectTypeCode, rowId, callback) {
$.post("/ProcessInspectionManage/NonconformDispositionApplication/GetDefectDes",
{ DefectTypeCode: defectTypeCode },
function (res) {
if (res.code == 1) {
if (callback) {
callback(res.data);
}
}
}
);
}
// 获取缺陷描述数据(使用行ID)
function GetDefectDes2(defectTypeCode, rowId) {
$.post("/ProcessInspectionManage/NonconformDispositionApplication/GetDefectDes",
{ DefectTypeCode: defectTypeCode },
function (res) {
if (res.code == 1) {
// 使用行ID查找对应的缺陷描述下拉框
var $defectDes = $('select.DefectDes[data-rowid="' + rowId + '"]');
$defectDes.empty();
$defectDes.append('<option value="">请选择</option>');
$.each(res.data, function (index, item) {
$defectDes.append(
$('<option></option>').val(item.DefectDesCode).text(item.DefectDesName)
);
});
// 重新渲染下拉框
layui.form.render($defectDes.parent());
}
}
);
}
</script>
</body>
</html>
二、C# MVC
// 文件上传API
[HttpPost]
public ActionResult FileUpload()
{
try
{
if (Request.Files.Count == 0)
return Json(new { success = false, message = "没有接收到文件" });
HttpPostedFileBase file = Request.Files[0];
if (file.ContentLength == 0)
return Json(new { success = false, message = "文件为空" });
// 创建上传目录(如果不存在)
string uploadPath = Server.MapPath("~/Uploads/");
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
// 生成唯一文件名
string fileName = $"{Guid.NewGuid().ToString()}_{Path.GetFileName(file.FileName)}";
string filePath = Path.Combine(uploadPath, fileName);
// 保存文件
file.SaveAs(filePath);
// 返回文件信息
return Json(new
{
success = true,
data = new
{
fileName = file.FileName,
fileType = Path.GetExtension(file.FileName).ToUpper().TrimStart('.'),
filePath = $"/Uploads/{fileName}"
}
});
}
catch (Exception ex)
{
return Json(new { success = false, message = ex.Message });
}
}