<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="com.sjsemi.prms.constants.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><%=Global.WEB_TITLE %>
</title>
<%
request.setCharacterEncoding("UTF-8");
%>
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="stylesheet" type="text/css" href="lib/bootstrap/css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="custom/global.css">
<link rel="stylesheet" type="text/css" href="stylesheets/theme.css">
<link rel="stylesheet" href="lib/font-awesome/css/font-awesome.css">
<link rel="stylesheet" type="text/css" href="stylesheets/jquery-ui.css">
<script src="lib/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="lib/jquery-ui-1.10.4.js" type="text/javascript"></script>
<style type="text/css">
.brand {
font-family: georgia, serif;
}
.brand .first {
color: #FF5C0D;
font-style: italic;
}
.brand .second {
color: #fff;
font-weight: bold;
}
.table td {
padding: 5px;
line-height: 20px;
border-top: 1px solid #dddddd;
}
</style>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="lib/html5.js"></script>
<![endif]-->
<!-- Le fav and touch icons -->
<link rel="shortcut icon" href="../assets/ico/favicon.ico">
</head>
<%
String scanIdType = FormatUtils.parseString(request.getParameter("scanIdType"));
%>
<body>
<%@ include file="navBar.jsp" %>
<%@ include file="sideBar.jsp" %>
<div class="content">
<div class="header">
<h1 class="page-title">库位绑定</h1>
</div>
<div class="container-fluid">
<div class="raw-fluid">
<div class="block span6" style="width: 100%;">
<a href="#tablewidget" class="block-heading" data-toggle="collapse">Search</a>
<div id="tablewidget" class="block-body collapse in">
<form id="frmQuery">
<input type="hidden" name="pageIndex"/>
<input type="hidden" id="savedScanIdType" name="savedScanIdType" value="<%=scanIdType%>"/>
<table class="table">
<thead>
<tr>
<td style="width: 10%">Scan ID:</td>
<td><input type="text" style="width: 130px;" id="scanId" name="scanId"
autocomplete="off"></td>
<td style="width: 10%">Scan ID 类型:</td>
<td colspan="3" style="text-align: left;"><select name="scanIdType">
</select></td>
<td style="width: 10%">Rack ID:</td>
<td><input type="text" style="width: 130px;" id="rackId" name="rackId" readonly/></td>
<td><input type="text" id="countId" name="countId"
style="color: red; font-size: 14px; width: 50px;" value="0" readonly/></td>
<td style="width: 30%"></td>
</thead>
</table>
</form>
</div>
</div>
</div>
</div>
<div class="container-fluid">
<form id="frmResult">
<div class="raw-fluid">
<div class="block span6" style="width: 100%;">
<div>
<a href="#tablewidget1" class="block-heading" data-toggle="collapse">Search Result List</a>
</div>
<div id="tablewidget1" class="block-body collapse in" style="width: 100%;">
<table border="1" cellpadding="10" style="width: 85%;" id="searchResult">
<thead>
<tr>
<th rowspan="2" style="width: 5%"></th>
<th rowspan="2" style="width: 21%">Cabinet ID(Rack ID)</th>
<th rowspan="2" style="width: 19%">Scan ID</th>
<th rowspan="2" style="width: 19%">Scan ID 类型</th>
<th rowspan="2" style="width: 19%">CTM</th>
<th rowspan="2" style="width: 19%">Product ID</th>
</tr>
</thead>
<tbody id="q"></tbody>
</tbody>
</table>
<div style="text-align: center;">
<button id="btn_submit" style="display:none;" type="button" class="btn btn-primary"
onclick="rmsSubmit();">Submit
</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
<script src="lib/bootstrap/js/bootstrap.js"></script>
<script language="Javascript">
$(document).ready(function () {
setScanIdType();
});
var sequence = 1;
window.onload = function () {
document.getElementById("scanId").focus();
}
document.onkeydown = function enterserach() {
if (isEnter(event)) {
checkRms();
}
}
function isEnter(e) {
var keynum = 0;
if (window.event) // IE
{
keynum = e.keyCode
} else if (e.which) // Netscape/Firefox/Opera
{
keynum = e.which
}
if (keynum == 13) {
return true;
} else {
return false;
}
}
function trim(str) {
return str.replace(/\s+/g, "");
}
function getScanIdTypeDisplayName(value) {
var map = {
"LOTID": "Lot ID",
"WAFERID": "Wafer ID",
"REELID": "Reel ID",
"CARRIERID": "Carrier ID"
};
return map[value] || value;
}
function setScanIdType() {
$.ajax({
type: "POST",
url: "RmsAction?accessMethod=<%=AccessMethod.AJAX %>",
data: {
'actionCode': '<%=ActionCode.GET_RMS_SCAN_ID_TYPE %>',
},
dataType: "json",
success: function (data) {
if (data.return_code == "0") {
var values = data.return_value.split(',');
var selectBox = $("select[name='scanIdType']");
selectBox.empty(); // 清空原有选项
// 遍历数组,生成下拉选项
$.each(values, function (index, value) {
var displayName = getScanIdTypeDisplayName(value);
selectBox.append(
$("<option></option>")
.attr("value", value)
.text(displayName || value)
);
});
var savedScanIdType = '<%=scanIdType%>';
if (savedScanIdType && values.includes(savedScanIdType)) {
selectBox.val(savedScanIdType);
getRmsConfig();
} else if (values.length > 0) {
// 默认加载第一个选项
selectBox.val(values[0]);
getRmsConfig();
}
// 绑定 change 事件,动态加载配置
selectBox.on('change', function () {
var selectedType = $(this).val();
$("#savedScanIdType").val(selectedType); // 保存当前选择
getRmsConfig();
});
}
},
error: function () {
alert("Ajax HTTP访问失败, 请联系IT处理!");
}
});
}
// 全局变量,用于存储从后台获取的配置
var lotIdConfig = {
rackIdKeyword: null,
lengthRequirement: 16,
container: null
};
// 获取 RMS 配置
function getRmsConfig() {
let hasRackIdConfig = false;
var scanIdInput = document.getElementById("scanId");
// 清除旧的配置
lotIdConfig.rackIdKeyword = null;
lotIdConfig.lengthRequirement = 16;
lotIdConfig.lengthRequirement = 16;
$.ajax({
type: "POST",
url: "RmsAction?accessMethod=<%=AccessMethod.AJAX %>",
data: {
'actionCode': '<%=ActionCode.GET_RMS_CONFIG_LIST %>',
'rmsType': 'RACKID'
},
dataType: "json",
success: function (data) {
if (data.return_code == "0") {
if (data.return_value.length == 0) {
alert("请联系Sa维护Rack ID的命名规则!");
if (scanIdInput) scanIdInput.disabled = true;
return;
}
// 更新全局配置
for (var i = 0; i < data.return_value.length; i++) {
var item = data.return_value[i];
if (item.key === "CONTAIN") {
hasRackIdConfig = true;
lotIdConfig.rackIdKeyword = item.value;
if (scanIdInput) scanIdInput.disabled = false;
} else if (item.key === "CONTAINER") {
hasRackIdConfig = true;
lotIdConfig.container = item.value;
}
}
if (!hasRackIdConfig) {
alert("请联系Sa维护Rack ID的命名规则!");
if (scanIdInput) scanIdInput.disabled = true;
}
} else {
alert(data.return_value);
}
},
error: function () {
alert("Ajax HTTP访问失败, 请联系IT处理!");
}
});
}
var j = 1;
function checkRms() {
var scanIdObj = document.getElementById("scanId");
var rackIdObj = document.getElementById("rackId");
var scanIdType = $("select[name='scanIdType']").val();
var scanId = trim(scanIdObj.value.toUpperCase());
if (scanId.length == 0) return;
// 获取配置
var rackIdKeyword = lotIdConfig.rackIdKeyword;
var lengthRequirement = lotIdConfig.lengthRequirement;
var container = lotIdConfig.container;
// 判断是否为 Rack ID
if (scanId.indexOf(rackIdKeyword) >= 0) {
if (scanId.length === lengthRequirement) {
// 获取从右往左的第4个字符
const fourthCharFromRight = scanId[scanId.length - 4];
// 拆分 container 字符
const allowedChars = container.split('&');
// 判断是否符合要求
if (allowedChars.includes(fourthCharFromRight)) {
rackIdObj.value = scanId;
scanIdObj.value = '';
scanIdObj.focus();
} else {
alert("Rack ID从右往左的第4码只能是 " + allowedChars.join(' 或 '));
scanIdObj.value = '';
scanIdObj.focus();
return;
}
} else {
alert("库位当前不满足" + lengthRequirement + "位字符!");
scanIdObj.value = '';
scanIdObj.focus();
return;
}
} else {
// 格式校验逻辑
let isValid = true;
if (scanIdType === "WAFERID") {
// 格式要求:任意字符(至少一个) + "-" + 两位数字
const waferPattern = /^[A-Za-z0-9]+-\d{2}$/;
if (!waferPattern.test(scanId)) {
alert("Wafer ID 格式不正确,请输入类似 XXX-XX 的格式('-' 后必须为两位数字)");
isValid = false;
}
}
if (!isValid) {
scanIdObj.value = '';
scanIdObj.focus();
return;
}
document.getElementById("btn_submit").style.display = "";
scanIdObj.value = '';
scanIdObj.focus();
// 定义并获取 objTable
var objTable = document.getElementById("searchResult");
if (!objTable) {
alert("表格 searchResult 未找到,请检查页面结构!");
return;
}
var countIdObj = document.getElementById("countId");
countIdObj.value = objTable.rows.length;
$.ajax({
type: "POST",
url: "RmsAction?accessMethod=<%=AccessMethod.AJAX %>",
data: {
'actionCode': '<%=ActionCode.GET_RMS_MES_FW_LOT %>',
'scanId': scanId,
'type': scanIdType,
'rackId': rackId.value,
'count': countIdObj.value
},
dataType: "json",
success: function (data) {
if (data.return_code == "0") {
if (data.return_value.length > 1) {
alert("获取到2个或以上的CTM,Product ID!");
return;
}
let vendorId = '';
let productId = '';
if (data.return_value && Array.isArray(data.return_value) && data.return_value.length > 0) {
vendorId = data.return_value[0].vendorId || '';
productId = data.return_value[0].productName || '';
}
q.innerHTML += '<tr id="button' + j + '">' +
'<td style="width: 20px;text-align: center;">' +
'<button type="button" class="btn btn-primary" id=' + j + ' onclick="rmsRemove(this);">Remove</button>' +
'</td>' +
'<td style="width: 40px;text-align: center;" id="rackId' + j + '" name="rackId">' + rackId.value + '</td>' +
'<td style="width: 40px;text-align: center;" id="scanId' + j + '" name="scanId">' + scanId + '</td>' +
'<td style="width: 40px;text-align: center;" id="scanIdType' + j + '" name="scanIdType">' + scanIdType + '</td>' +
'<td style="width: 40px;text-align: center;" id="vendorId' + j + '" name="vendorId">' + vendorId + '</td>' +
'<td style="width: 40px;text-align: center;" id="productId' + j + '" name="productId">' + productId + '</td>' +
'</tr>';
j++;
} else {
alert(data.return_value);
var countIdObj = document.getElementById("countId");
countIdObj.value = countIdObj.value - 1;
}
},
error: function () {
alert("Ajax HTTP访问失败, 请联系IT处理!");
$('#butSend').attr("disabled", false);
}
});
}
}
function rmsRemove(obj) {
var tb = document.getElementById("searchResult");
var id = obj.id;
var row = document.getElementById("button" + id);
var index = row.rowIndex;
tb.deleteRow(index);
var countIdObj = document.getElementById("countId");
countIdObj.value = tb.rows.length - 1;
}
function rmsSubmit() {
var selectedType = $("#frmQuery select[name='scanIdType']").val();
var countId = document.getElementById("countId").value;
var count = parseInt(countId);
var dataList = [];
var searchResult = document.getElementById("searchResult");
var rows = searchResult.rows;
for (var i = 1; i < rows.length; i++) {
var row = rows[i];
var cabinetId = row.cells[1].innerText.trim();
var scanId = row.cells[2].innerText.trim();
var scanIdType = row.cells[3].innerText.trim();
var vendorId = row.cells[4].innerText.trim();
var productId = row.cells[5].innerText.trim();
dataList.push({
cabinetId: cabinetId,
scanId: scanId,
scanIdType: scanIdType,
vendorId: vendorId,
productId: productId,
});
}
if (count <= 0) {
alert("请输入数据后再提交!");
return;
}
if (dataList.length !== count) {
alert("数据数量与输入的次数不匹配,请检查!");
return;
}
// 将数据转换为 JSON 字符串
var jsonData = JSON.stringify({
dataList: dataList,
});
$.ajax({
type: "POST",
url: "RmsAction?accessMethod=<%=AccessMethod.AJAX %>",
data: {
'actionCode': '<%=ActionCode.CREATE_RMS_STORAGE_BINDING_DETAIL %>',
jsonData: jsonData,
count: count,
},
dataType: "json",
success: function (data) {
if (data.return_code == "0") {
var results = data.return_value;
var successBind = [];
var failBind = [];
var successUnbind = [];
var failUnbind = [];
results.forEach(function (item) {
if (item.status === "success") {
if (item.action === "bind") {
successBind.push(item.scanId);
} else if (item.action === "unbind") {
successUnbind.push(item.scanId);
}
} else if (item.status === "fail") {
if (item.action === "bind") {
failBind.push(item.scanId + " (" + item.reason + ")");
} else if (item.action === "unbind") {
failUnbind.push(item.scanId + " (" + item.reason + ")");
} else {
failBind.push(item.scanId + " (" + item.reason + ")");
}
}
});
let message = "";
if (successBind.length > 0) {
message += "✅ 成功绑定:" + successBind.join(", ") + "\n";
}
if (successUnbind.length > 0) {
message += "🔓 成功解绑:" + successUnbind.join(", ") + "\n";
}
if (failBind.length > 0) {
message += "❌ 绑定失败:" + failBind.join("\n") + "\n";
}
if (failUnbind.length > 0) {
message += "⚠ 解绑失败:" + failUnbind.join("\n") + "\n";
}
alert(message);
location.href = "tdRmsLotId.jsp?scanIdType=" + selectedType;
} else {
alert("操作失败: " + data.return_value);
}
},
error: function () {
alert("Ajax HTTP访问失败, 请联系IT处理!");
$('#butSend').attr("disabled", false);
}
});
}
</script>
</body>
</html>
checkRms时,需要判断一下,
如果时解绑,那么就不能有绑定,如果是绑定,那么就只能绑定且不能有其他的绑定
解绑: document.getElementById("rackId"); 没有值
绑定:document.getElementById("rackId"); 有值,如果当前绑定SJ2A-DOI-004N002,那么后续只能绑定SJ2A-DOI-004N002,除非
q.innerHTML += '<tr id="button' + j + '">' +
'<td style="width: 20px;text-align: center;">' +
'<button type="button" class="btn btn-primary" id=' + j + ' onclick="rmsRemove(this);">Remove</button>' +
'</td>' +
'<td style="width: 40px;text-align: center;" id="rackId' + j + '" name="rackId">' + rackId.value + '</td>' +
'<td style="width: 40px;text-align: center;" id="scanId' + j + '" name="scanId">' + scanId + '</td>' +
'<td style="width: 40px;text-align: center;" id="scanIdType' + j + '" name="scanIdType">' + scanIdType + '</td>' +
'<td style="width: 40px;text-align: center;" id="vendorId' + j + '" name="vendorId">' + vendorId + '</td>' +
'<td style="width: 40px;text-align: center;" id="productId' + j + '" name="productId">' + productId + '</td>' +
'</tr>';
j++;
添加的内容没有了
最新发布