var obj=function(id){return document.getElementById?document.getElementById(id):id};

本文介绍了一种使用JavaScript获取DOM元素的方法,并展示了如何设置元素的透明度效果,包括对于旧版IE浏览器的支持。

var obj=function(id){return document.getElementById?document.getElementById(id):id};

filter:Alpha(opacity=50);opacity:0.5;

document.getElementById("projectDecisionPlace").addEventListener("change", function () { const provinceId = this.value; // 清空旧数据 if (!provinceId) { clearOrgFields(); return; } // 发起 AJAX 请求 fetch(`/api/department/by-province?provinceId=${provinceId}`) .then(response => response.json()) .then(data => { if (data && data.orgId && data.orgName) { document.getElementById("orgId").value = data.orgId; document.getElementById("orgName").value = data.orgName; document.getElementById("topSaleOrgId").value = data.topOrgId; document.getElementById("topSaleOrgName").value = data.topOrgName; } else { clearOrgFields(); } }) .catch(error => { console.error("请求失败:", error); clearOrgFields(); }); }); function clearOrgFields() { document.getElementById("orgId").value = ""; document.getElementById("orgName").value = ""; document.getElementById("topSaleOrgId").value = ""; document.getElementById("topSaleOrgName").value = ""; }根据后面代码的格式重新生成$("#selectStoreMember").click(function(){ $("#selectStoreMember").bindQueryBtn({ type:'selectStoreMember', title:'${message("查询用户")}', bindClick:false, url:'/crm/v2/storeMember/select_member.jhtml', callback:function(rows){ if(rows.length>0){ var row = rows[0]; $(".storeMemberName").val(row.name); $(".storeMemberId").val(row.id); $(".orgName").val(row.default_sale_org_name); $(".orgId").val(row.org_id); ajaxSubmit('', { method: 'post', url: '/crm/v2/storeMember/getOrgInfo.jhtml', data: {"id": row.id}, callback: function (data) { var obj = data.objx; $(".topSaleOrgName").val(obj.topSaleOrgName); $(".topSaleOrgId").val(obj.topSaleOrgId); } }); } } }); });
09-17
<%@ 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" action="<%=Page.TD_MATERIAL_INFO%>"> <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> </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="saveRackLot();">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)) { checkLotInfo(); } } 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", "SCANID": "Scan 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(savedScanIdType); } else if (values.length > 0) { // 默认加载第一个选项 selectBox.val(values[0]); getRmsConfig(values[0]); } // 绑定 change 事件,动态加载配置 selectBox.on('change', function () { var selectedType = $(this).val(); $("#savedScanIdType").val(selectedType); // 保存当前选择 getRmsConfig(selectedType); }); } }, error: function () { alert("Ajax HTTP访问失败, 请联系IT处理!"); } }); } // 全局变量,用于存储从后台获取的配置 var lotIdConfig = { rackIdKeyword: null, lengthRequirement: 16 }; // 获取 RMS 配置 function getRmsConfig(rmsType) { let hasRackIdConfig = false; var scanIdInput = document.getElementById("scanId"); // 清除旧的配置 lotIdConfig.rackIdKeyword = null; lotIdConfig.lengthRequirement = 16; $.ajax({ type: "POST", url: "RmsAction?accessMethod=<%=AccessMethod.AJAX %>", data: { 'actionCode': '<%=ActionCode.GET_RMS_CONFIG_LIST %>', 'rmsType': rmsType }, dataType: "json", success: function (data) { if (data.return_code == "0") { if (data.return_value.length == 0) { alert("请在RMS配置维护中维护RMS配置名称:RACKID的条件!"); 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 === "LENGTH") { if (item.value === undefined || item.value === null || item.value === "NA") { lotIdConfig.lengthRequirement = 16; } else { var parsedValue = parseInt(item.value, 10); lotIdConfig.lengthRequirement = isNaN(parsedValue) ? 16 : parsedValue; } } else if (item.key === "CONTAIN") { hasRackIdConfig = true; lotIdConfig.rackIdKeyword = item.value; if (scanIdInput) scanIdInput.disabled = false; } } if (!hasRackIdConfig) { alert("请在RMS配置维护中维护RACKID的包含条件!"); if (scanIdInput) scanIdInput.disabled = true; } } else { alert(data.return_value); } }, error: function () { alert("Ajax HTTP访问失败, 请联系IT处理!"); } }); } var j = 1; function checkLotInfo() { var lotIdObj = document.getElementById("scanId"); lotId = trim(lotIdObj.value.toUpperCase()); if (lotId.length == 0) return; var rackIdObj = document.getElementById("rackId"); rackId = trim(rackIdObj.value.toUpperCase()); var objTable = document.getElementById("searchResult"); var rackIdKeyword = lotIdConfig.rackIdKeyword; var lengthRequirement = lotIdConfig.lengthRequirement; if (lotId.indexOf(rackIdKeyword) >= 0) { if (lotId.length === lengthRequirement) { rackIdObj.value = lotId; lotIdObj.value = ''; lotIdObj.focus(); } else { alert("库位当前不满足" + lengthRequirement + "码!"); lotIdObj.value = ''; lotIdObj.focus(); return; } } else { document.getElementById("btn_submit").style.display = ""; lotIdObj.value = ''; lotIdObj.focus(); var countIdObj = document.getElementById("countId"); countIdObj.value = objTable.rows.length; q.innerHTML = q.innerHTML + '<tr id="button' + j + '"><td style="width: 20px;text-align: center;">' + '<button type="button" class="btn btn-primary" id=' + j + ' onclick="removeLot(this);" >Remove</button></td>' + '<td style="width: 40px;text-align: center;" id="rackId' + j + '" Name="rackId" >' + rackId + '</td>' + '<td style="width: 40px;text-align: center;" id="scanId' + j + '" Name="scanId" >' + lotId + '</td></tr>'; j++; } } function removeLot(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 saveRackLot() { var selectedType = $("#frmQuery select[name='scanIdType']").val(); //获取循环次数 var countId = document.getElementById("countId").value; var count = parseInt(countId); //判断次数 var isCount = parseInt(0); var strs1 = []; var strs2 = []; for (i = 1; i <= count; i++) { var scanId = ""; var rackId = ""; var searchResult = document.getElementById("searchResult"); var rows = searchResult.rows;//获取所有行 for (var i = 1; i < rows.length; i++) { var row = rows[i];//获取每一行 scanId = row.cells[1].id; rackId = row.cells[2].id; var scanIds = document.getElementById(rackId).innerHTML; var rackIds = document.getElementById(scanId).innerHTML; strs1 = strs1 + "," + scanIds; strs2 = strs2 + "," + rackIds; isCount++ } } if (count > 0) { if (isCount == count) { $.ajax({ type: "POST", url: "RmsAction?accessMethod=<%=AccessMethod.AJAX %>", data: { 'actionCode': '<%=ActionCode.CREATE_RMS_LOT %>', 'scanIdType': selectedType, 'scanId': strs1, 'rackId': strs2, 'count': count }, dataType: "json", success: function (data) { if (data.return_code == "0") { alert(data.return_value); location.href = "tdRmsLotId.jsp?scanIdType=" + selectedType; } else { alert(data.return_value); } }, error: function () { alert("Ajax HTTP访问失败, 请联系IT处理!"); $('#butSend').attr("disabled", false); } }); } } else { alert("请输入数据后再提交!") } } </script> </body> </html> 增加Scan ID 类型:的判断,例如: waferID是lot 的片号带一个“-”符号,CARRIER ID固定为”YF(两位数字)-A-(三位数字)“比如“YF25-A-028 ” Scan ID:回车时触发判断
最新发布
12-12
自动更新传出一个时间参数,获取最新数据并更新贝蒂数据 /** 数据管理器类,负责与后端API通信并管理数据 */ class DataManager { constructor(baseUrl) { this.baseUrl = baseUrl; this.data = { bancais: [], dingdans: [], mupis: [], chanpins: [], kucuns: [], dingdan_bancais:[], chanpin_zujians: [], zujians: [], caizhis: [], dingdan_chanpins: [], users: [], jinhuos: [] }; this.isSyncing = false; this.lastSync = null; this.callbacks = { all: [], bancais: [], dingdan: [], mupi: [], chanpin: [], kucun: [], chanpin_zujian: [], dingdan_bancai:[], zujian: [], caizhi: [], dingdan_chanpin: [], user: [], jinhuo: [] }; this.syncQueue = Promise.resolve(); this.syncInterval = 5 * 60 * 1000; // 5分钟 this.startAutoSync(); this.registerCallback('dingdan_bancai', async (operation, data) => { if (operation === 'add' || operation === 'update') { try { // 构造进货记录数据 const jinhuoData = { dingdan_bancai:{id:data?.id}, shuliang: data.shuliang, date: new Date().toISOString(), user: { id: localStorage.getItem("userId") } }; // 创建进货记录 await this.addEntity('jinhuo', jinhuoData); } catch (error) { console.error('进货记录创建失败:', error); } } }); } // 启动自动同步 startAutoSync() { if (this.autoSyncTimer) clearInterval(this.autoSyncTimer); this.autoSyncTimer = setInterval(() => { if (!this.isSyncing) this.syncData(); }, this.syncInterval); } // 停止自动同步 stopAutoSync() { clearInterval(this.autoSyncTimer); } /** 获取所有数据 @returns {Promise} 是否成功 */ async fetchAll() { console.log(this) try { const response = await fetch(${this.baseUrl}/app/all); if (!response.ok) throw new Error(‘Network response was not ok’); const result = await response.json(); if (result.status !== 200) throw new Error(result.text || ‘API error’); console.log(result.data) const resolvedData = resolveDataReferences(result.data); // 更新本地数据 Object.keys(this.data).forEach(key => { if (resolvedData[key]) { this.data[key] = resolvedData[key]; } }); this.lastSync = new Date(); // 关键改进:数据更新后触发刷新回调 this.triggerCallbacks(‘refresh’, ‘all’, this.data); return true; } catch (error) { console.error(‘Fetch error:’, error); // 触发错误回调 this.triggerCallbacks(‘fetch_error’, ‘all’, { error }); return false; } } /** 注册回调函数 @param {string} entity - 实体类型(如’bancai’)或’all’表示全局回调 @param {Function} callback - 回调函数,参数为(operation, data) */ registerCallback(entity, callback) { if (!this.callbacks[entity]) { this.callbacks[entity] = []; } this.callbacks[entity].push(callback); } /** 移除回调函数 @param {string} entity - 实体类型单数性质 @param {Function} callback - 要移除的回调函数 */ unregisterCallback(entity, callback) { if (!this.callbacks[entity]) return; const index = this.callbacks[entity].indexOf(callback); if (index !== -1) { this.callbacks[entity].splice(index, 1); } } /** 触发回调 @param {string} operation - 操作类型(‘add’, ‘update’, ‘delete’) @param {string} entity - 实体类型单数性质 @param {Object} data - 相关数据 */ triggerCallbacks(operation, entity, data) { // 触发全局回调 this.callbacks.all.forEach(cb => cb(operation, entity, data)); // 触发特定实体回调 if (this.callbacks[entity]) { this.callbacks[entity].forEach(cb => cb(operation, data)); } } checkDuplicate(entity, data) { switch (entity) { case ‘bancai’: return this.data.bancais.some(b => b.houdu === data.houdu && b.caizhi?.id === data.caizhi?.id && b.mupi1?.id === data.mupi1?.id && b.mupi2?.id === data.mupi2?.id ); case ‘caizhi’: return this.data.caizhis.some(c => c.name === data.name); case ‘mupi’: return this.data.mupis.some(m => m.name === data.name); case ‘chanpin’: return this.data.chanpins.some(c => c.bianhao === data.bianhao); case ‘zujian’: return this.data.zujians.some(z => z.name === data.name); case ‘dingdan’: return this.data.dingdans.some(d => d.number === data.number); case ‘chanpin_zujian’: return this.data.chanpin_zujians.some(cz => cz.chanpin?.id === data.chanpin?.id && cz.zujian?.id === data.zujian?.id ); case ‘dingdan_chanpin’: return this.data.dingdan_chanpins.some(dc => dc.dingdan?.id === data.dingdan?.id && dc.chanpin?.id === data.chanpin?.id ); case ‘dingdan_bancai’: return this.data.dingdan_bancais.some(db => db.dingdan?.id === data.dingdan?.id && db.chanpin?.id === data.chanpin?.id && db.zujian?.id === data.zujian?.id && db.bancai?.id === data.bancai?.id ); case ‘user’: return this.data.users.some(u => u.name === data.name); default: return false; // 其他实体类型不检查重复 } } /** 执行CRUD操作 @param {string} operation - ‘add’, ‘delete’, ‘update’ @param {string} entity - 实体名称单数性质(小写) @param {Object} data - 要发送的数据 后端要求数据格式为{属性: “值”, 关联对象: {id:0}, 关联对象集: [{id:0}]} @returns {Promise} 响应结果 */ async crudOperation(operation, entity, data) { try { const response = await fetch(${this.baseUrl}/app/${operation}/${entity}, { method: ‘POST’, headers: {‘Content-Type’: ‘application/json’}, body: JSON.stringify(data) }); if (!response.ok) throw new Error('Network response was not ok'); const result = await response.json(); if (result.status !== 200) throw new Error(result.text || 'API error'); console.log(data)//这了就没有id了 this. updateLocalData(operation, entity, result.data||data) // 自动同步数据 // 同步完成后触发操作回调 this.triggerCallbacks(operation, entity, result.data||data); return result; } catch (error) { console.error(‘CRUD error:’, error); // 触发操作失败的回调 this.triggerCallbacks(${operation}_error, entity, { data, error: error.message }); throw error; } } updateLocalData(operation, entity, newData) { var key=entity+“s”; var entitys= this.data[key] switch (operation) { case ‘add’: entitys.push(resolveDataReference(newData,this.data)) break; case ‘update’: const index = entitys.findIndex(item => item.id === newData.id); if (index !== -1) { if(entitys[index].id==newData.id){ for(var an in entitys[index]){ entitys[index][an]=newData[an] } } /*报错DataManager.js:312 CRUD error: ReferenceError: collection is not defined at DataManager.updateLocalData (DataManager.js:335:32) at DataManager.crudOperation (DataManager.js:303:13) at async HTMLButtonElement.<anonymous> (tianjia.js:325:21)*/ } else { entitys.push(resolveDataReference(newData,this.data)); } break; case 'delete': const deleteIndex = entitys.findIndex(item => item.id === newData.id); if (deleteIndex !== -1) { entitys.splice(deleteIndex, 1); } break; default: break; } } /** 自动同步数据(防止频繁请求) */ async syncData() { if (this.isSyncing) { this.pendingSync = true; return; } this.isSyncing = true; try { await this.fetchAll(); } catch (error) { console.error(‘Sync failed:’, error); } finally { this.isSyncing = false; // 处理等待中的同步请求 if (this.pendingSync) { this.pendingSync = false; setTimeout(() => this.syncData(), 1000); } } } /** 添加实体 @param {string} entity - 实体名称单数性质 @param {Object} data - 实体数据 / async addEntity(entity, data) { // 检查重复数据 if (this.checkDuplicate(entity, data)) { const errorMsg = ${entity}数据重复; this.triggerCallbacks(‘duplicate_error’, entity, { data, error: errorMsg }); throw new Error(errorMsg); } return this.crudOperation(‘add’, entity, data); } /* 更新实体 @param {string} entity - 实体名称单数性质 @param {Object} data - 实体数据(必须包含id) */ async updateEntity(entity, data) { return this.crudOperation(‘update’, entity, data); } /** 删除实体 @param {string} entity - 实体名称单数性质 @param {number} id - 实体ID */ async deleteEntity(entity, id) { return this.crudOperation(‘delete’, entity, {id}); } /** 新增方法:手动触发数据刷新 */ async refreshData() { return this.syncQueue = this.syncQueue.then(() => this.syncData()); } /** 获取订单的可用板材信息 @param {number} dingdanId - 订单ID @returns {Object} 可用板材信息 */ getAvailableBancaisForOrder(dingdanId) { const dingdan = this.data.dingdans.find(d => d?.id == dingdanId); if (!dingdan) return {}; return dingdan.availableBancais || {}; } /** 获取产品的组件列表 @param {number} chanpinId - 产品ID @returns {Array} 组件列表 */ getZujiansForChanpin(chanpinId) { const chanpin = this.data.chanpins.find(c => c?.id == chanpinId); if (!chanpin) return []; return (chanpin.chanpin_zujian_list || []) .map(cz => cz.zujian) .filter(z => z); } /** 获取组件的板材信息 @param {number} zujianId - 组件ID @returns {Array} 板材列表 */ getBancaisForZujian(zujianId) { return (this.data.chanpin_zujians || []) .filter(cz => cz.zujian && cz.zujian?.id == zujianId) .map(cz => cz.bancai) .filter(b => b); } /** 创建进货记录 @param {Object} jinhuoData - 进货数据 @returns {Promise} 操作结果 */ async createJinhuo(jinhuoData) { return this.addEntity(‘jinhuo’, jinhuoData); } /** 获取订单列表 @returns {Array} 订单列表 */ getDingdans() { return this.data.dingdans || []; } /** 获取订单的产品列表 @param {number} dingdanId - 订单ID @returns {Array} 产品列表 */ getChanpinsForDingdan(dingdanId) { const dingdan = this.data.dingdans.find(d => d?.id == dingdanId); if (!dingdan) return []; return (dingdan.dingdan_chanpin_list || []) .map(dc => dc.chanpin) .filter(c => c); } } export { DataManager };
06-30
//这个函数不许改,也禁止废话,属性名和其他命名都哼规范不会出现意外, function resolveDataReferences(data) { console.log(data) // 获取 data 对象的所有顶层键 const keys = Object.keys(data); // 遍历每个顶层键(如 users, posts 等) for (const key of keys) { const entities = data[key]; // 遍历该顶层键下的每个实体(如每个 user 或 post) for (const entity of entities) { // 遍历实体的每个属性 for (const attribute in entity) { if (entity?.hasOwnProperty(attribute)) { var trpe=attribute?.replace(/\d/g, ''); // 确保属性属于当前实体 if (Array.isArray(entity[attribute])) { if(data[trpe]==null){ trpe+="s" } // 如果属性是一个数组,则将数组中的每个 ID 替换为对应的实际对象 entity[attribute] = entity[attribute].map(item => data[trpe ]?.find(updateItem => updateItem?.id === item?.id) || item ); } else if (typeof entity[attribute] === "object" && entity[attribute] !== null) { // 如果属性是一个对象,则将其替换为对应的实际对象 entity[attribute] = data[trpe + "s"]?.find(updateItem => updateItem?.id === entity[attribute]?.id); } } } } } return data; } /** 数据管理器类,负责与后端API通信并管理数据 */ class DataManager { constructor(baseUrl) { this.baseUrl = baseUrl; this.data = { bancais: [], dingdans: [], mupis: [], chanpins: [], kucuns: [], dingdan_bancais:[], chanpin_zujians: [], zujians: [], caizhis: [], dingdan_chanpins: [], users: [], jinhuos: [] }; this.isSyncing = false; this.lastSync = null; this.callbacks = { all: [], bancais: [], dingdan: [], mupi: [], chanpin: [], kucun: [], chanpin_zujian: [], dingdan_bancai:[], zujian: [], caizhi: [], dingdan_chanpin: [], user: [], jinhuo: [] }; this.syncQueue = Promise.resolve(); this.registerCallback('dingdan_bancai', async (operation, data) => { if (operation === 'add' || operation === 'update') { try { // 构造进货记录数据 const jinhuoData = { dingdan_bancai:data, shuliang: data.shuliang, date: new Date().toISOString(), user: { id: localStorage.getItem("userId") } }; // 创建进货记录 await this.addEntity('jinhuo', jinhuoData); } catch (error) { console.error('进货记录创建失败:', error); } } }); } /** 获取所有数据 @returns {Promise} 是否成功 */ async fetchAll() { console.log(this) try { const response = await fetch(${this.baseUrl}/app/all); if (!response.ok) throw new Error(‘Network response was not ok’); const result = await response.json(); if (result.status !== 200) throw new Error(result.text || ‘API error’); console.log(result.data) const resolvedData = resolveDataReferences(result.data); // 更新本地数据 Object.keys(this.data).forEach(key => { if (resolvedData[key]) { this.data[key] = resolvedData[key]; } }); this.lastSync = new Date(); // 关键改进:数据更新后触发刷新回调 this.triggerCallbacks(‘refresh’, ‘all’, this.data); return true; } catch (error) { console.error(‘Fetch error:’, error); // 触发错误回调 this.triggerCallbacks(‘fetch_error’, ‘all’, { error }); return false; } } /** 注册回调函数 @param {string} entity - 实体类型(如’bancai’)或’all’表示全局回调 @param {Function} callback - 回调函数,参数为(operation, data) */ registerCallback(entity, callback) { if (!this.callbacks[entity]) { this.callbacks[entity] = []; } this.callbacks[entity].push(callback); } /** 移除回调函数 @param {string} entity - 实体类型单数性质 @param {Function} callback - 要移除的回调函数 */ unregisterCallback(entity, callback) { if (!this.callbacks[entity]) return; const index = this.callbacks[entity].indexOf(callback); if (index !== -1) { this.callbacks[entity].splice(index, 1); } } /** 触发回调 @param {string} operation - 操作类型(‘add’, ‘update’, ‘delete’) @param {string} entity - 实体类型单数性质 @param {Object} data - 相关数据 */ triggerCallbacks(operation, entity, data) { // 触发全局回调 this.callbacks.all.forEach(cb => cb(operation, entity, data)); // 触发特定实体回调 if (this.callbacks[entity]) { this.callbacks[entity].forEach(cb => cb(operation, data)); } } checkDuplicate(entity, data) { switch (entity) { case ‘bancai’: return this.data.bancais.some(b => b.houdu === data.houdu && b.caizhi?.id === data.caizhi?.id && b.mupi1?.id === data.mupi1?.id && b.mupi2?.id === data.mupi2?.id ); case ‘caizhi’: return this.data.caizhis.some(c => c.name === data.name); case ‘mupi’: return this.data.mupis.some(m => m.name === data.name); case ‘chanpin’: return this.data.chanpins.some(c => c.bianhao === data.bianhao); case ‘zujian’: return this.data.zujians.some(z => z.name === data.name); case ‘dingdan’: return this.data.dingdans.some(d => d.number === data.number); case ‘chanpin_zujian’: return this.data.chanpin_zujians.some(cz => cz.chanpin?.id === data.chanpin?.id && cz.zujian?.id === data.zujian?.id ); case ‘dingdan_chanpin’: return this.data.dingdan_chanpins.some(dc => dc.dingdan?.id === data.dingdan?.id && dc.chanpin?.id === data.chanpin?.id ); case ‘dingdan_bancai’: return this.data.dingdan_bancais.some(db => db.dingdan?.id === data.dingdan?.id && db.chanpin?.id === data.chanpin?.id && db.zujian?.id === data.zujian?.id && db.bancai?.id === data.bancai?.id ); case ‘user’: return this.data.users.some(u => u.name === data.name); default: return false; // 其他实体类型不检查重复 } } /** 执行CRUD操作 @param {string} operation - ‘add’, ‘delete’, ‘update’ @param {string} entity - 实体名称单数性质(小写) @param {Object} data - 要发送的数据 后端要求数据格式为{属性: “值”, 关联对象: {id:0}, 关联对象集: [{id:0}]} @returns {Promise} 响应结果 */ async crudOperation(operation, entity, data) { try { const response = await fetch(${this.baseUrl}/app/${operation}/${entity}, { method: ‘POST’, headers: {‘Content-Type’: ‘application/json’}, body: JSON.stringify(data) }); if (!response.ok) throw new Error('Network response was not ok'); const result = await response.json(); if (result.status !== 200) throw new Error(result.text || 'API error'); console.log(data)//这了就没有id了 // 自动同步数据 this.syncQueue = this.syncQueue.then(async () => { await this.syncData(); // 同步完成后触发操作回调 this.triggerCallbacks(operation, entity, result.data); }); return result; } catch (error) { console.error(‘CRUD error:’, error); // 触发操作失败的回调 this.triggerCallbacks(${operation}_error, entity, { data, error: error.message }); throw error; } } /** 自动同步数据(防止频繁请求) */ async syncData() { if (this.isSyncing) { this.pendingSync = true; return; } this.isSyncing = true; try { await this.fetchAll(); } catch (error) { console.error(‘Sync failed:’, error); } finally { this.isSyncing = false; // 处理等待中的同步请求 if (this.pendingSync) { this.pendingSync = false; setTimeout(() => this.syncData(), 1000); } } } /** 添加实体 @param {string} entity - 实体名称单数性质 @param {Object} data - 实体数据 / async addEntity(entity, data) { // 检查重复数据 if (this.checkDuplicate(entity, data)) { const errorMsg = ${entity}数据重复; this.triggerCallbacks(‘duplicate_error’, entity, { data, error: errorMsg }); throw new Error(errorMsg); } return this.crudOperation(‘add’, entity, data); } /* 更新实体 @param {string} entity - 实体名称单数性质 @param {Object} data - 实体数据(必须包含id) */ async updateEntity(entity, data) { return this.crudOperation(‘update’, entity, data); } /** 删除实体 @param {string} entity - 实体名称单数性质 @param {number} id - 实体ID */ async deleteEntity(entity, id) { return this.crudOperation(‘delete’, entity, {id}); } /** 新增方法:手动触发数据刷新 */ async refreshData() { return this.syncQueue = this.syncQueue.then(() => this.syncData()); } /** 获取订单的可用板材信息 @param {number} dingdanId - 订单ID @returns {Object} 可用板材信息 */ getAvailableBancaisForOrder(dingdanId) { const dingdan = this.data.dingdans.find(d => d?.id == dingdanId); if (!dingdan) return {}; return dingdan.availableBancais || {}; } /** 获取产品的组件列表 @param {number} chanpinId - 产品ID @returns {Array} 组件列表 */ getZujiansForChanpin(chanpinId) { const chanpin = this.data.chanpins.find(c => c?.id == chanpinId); if (!chanpin) return []; return (chanpin.chanpin_zujian_list || []) .map(cz => cz.zujian) .filter(z => z); } /** 获取组件的板材信息 @param {number} zujianId - 组件ID @returns {Array} 板材列表 */ getBancaisForZujian(zujianId) { return (this.data.chanpin_zujians || []) .filter(cz => cz.zujian && cz.zujian?.id == zujianId) .map(cz => cz.bancai) .filter(b => b); } /** 创建进货记录 @param {Object} jinhuoData - 进货数据 @returns {Promise} 操作结果 */ async createJinhuo(jinhuoData) { return this.addEntity(‘jinhuo’, jinhuoData); } /** 获取订单列表 @returns {Array} 订单列表 */ getDingdans() { return this.data.dingdans || []; } /** 获取订单的产品列表 @param {number} dingdanId - 订单ID @returns {Array} 产品列表 */ getChanpinsForDingdan(dingdanId) { const dingdan = this.data.dingdans.find(d => d?.id == dingdanId); if (!dingdan) return []; return (dingdan.dingdan_chanpin_list || []) .map(dc => dc.chanpin) .filter(c => c); } } export { DataManager }; // 创建单例实例 //const dataManager = new DataManager(‘http://127.0.0.1:8080/KuCun2’); //// 初始化时获取所有数据 //dataManager.fetchAll().then(() => { // console.log(‘Initial data loaded’); //}); // 导出数据对象,外部可以直接访问 data.bancais, data.dingdans 等 //export const data = dataManager.data; //// 导出操作方法 //export const addEntity = dataManager.addEntity.bind(dataManager); //export const updateEntity = dataManager.updateEntity.bind(dataManager); //export const deleteEntity = dataManager.deleteEntity.bind(dataManager); //export const fetchAll = dataManager.fetchAll.bind(dataManager); -----------------------------------------------------------------------------------数据添加同步请求时,返回的数据要立马更行数据集合,获取全部数据要固定时间间隔更新,
06-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值