wms_base = require("wms_base") xml = require("oi_base_xml") mobox = require("OILua_JavelinExt") m3 = require("oi_base_mobox") -- XML特殊字符转义函数 local function xml_escape(str) if not str then return "" end return tostring(str):gsub("&", "&"):gsub("<", "<"):gsub(">", ">"):gsub("\"", """):gsub("'", "'") end -- 硬编码XML生成器 local function generate_raw_xml(result) local xml = [[ ]] .. xml_escape(result.flag) .. [[ ]] .. xml_escape(result.code) .. [[ ]] .. xml_escape(result.message) .. [[]] if result.data and #result.data > 0 then xml = xml .. [[ ]] for _, item in ipairs(result.data) do xml = xml .. [[ ]] .. xml_escape(item.productLine) .. [[ ]] .. xml_escape(item.storerId) .. [[ ]] .. xml_escape(item.cid) .. [[ ]] .. xml_escape(item.ownerId) .. [[ ]] .. xml_escape(item.skuId) .. [[ ]] .. xml_escape(item.boxCode) .. [[ ]] .. xml_escape(item.qty) .. [[ ]] .. xml_escape(item.registerNo) .. [[ ]] .. xml_escape(item.skuStatus) .. [[ ]] .. xml_escape(item.expiryDate) .. [[ ]] .. xml_escape(item.batchNo) .. [[ ]] .. xml_escape(item.productDate) .. [[ ]] .. xml_escape(item.produceCode) .. [[ ]] .. xml_escape(item.locationId) .. [[ ]] end xml = xml .. [[ ]] else xml = xml .. [[ ]] end xml = xml .. [[ ]] return xml end -- 创建统一返回结果 local function Create_result(flag, code, msg, data) return { flag = flag or "success", code = code or "0", message = msg or "", data = data or {} } end -- 深度遍历查找XML节点(最稳定的方法) local function deep_find_xml_node(data, node_names) if type(data) ~= "table" then return nil end -- 先尝试直接路径查找 local current = data for _, name in ipairs(node_names) do if type(current) ~= "table" then break end -- 尝试带v1命名空间和不带命名空间的节点 current = current["v1:" .. name] or current[name] if not current then break end end if current then return current end -- 深度遍历整个XML树查找 local function deep_search(t, names, index) if index > #names then return t end local current_name = names[index] for k, v in pairs(t) do if (k == current_name or k == "v1:" .. current_name) and type(v) == "table" then local result = deep_search(v, names, index + 1) if result then return result end elseif type(v) == "table" then local result = deep_search(v, names, index) if result then return result end end end return nil end return deep_search(data, node_names, 1) end -- 查询库存明细 local function query_inventory_detail(strLuaDEID, query_params) local strCondition = string.format(" S_STORER = '%s' AND S_OWNER = '%s' AND S_ITEM_CODE = '%s'", query_params.storerId, query_params.ownerId, query_params.skuId) if query_params.locationId and query_params.locationId ~= "" then strCondition = strCondition .. string.format(" AND S_LOC_CODE = '%s'", query_params.locationId) end if query_params.produceCode and query_params.produceCode ~= "" then strCondition = strCondition .. string.format(" AND S_BATCH_NO = '%s'", query_params.produceCode) end local nRet, data_objects = m3.QueryDataObject(strLuaDEID, "INV_Detail", strCondition) if nRet ~= 0 then return nRet, data_objects end local formatted_result = {} for n = 1, #data_objects do local obj_attrs = m3.KeyValueAttrsToObjAttr(data_objects[n].attrs) local stock = { storerId = obj_attrs.S_STORER or "", ownerId = obj_attrs.S_OWNER or "", skuId = obj_attrs.S_ITEM_CODE or "", skuStatus = obj_attrs.S_ITEM_STATE or "", qty = lua.Get_NumAttrValue(obj_attrs.F_QTY) or 0, locationId = obj_attrs.S_LOC_CODE or "", cid = obj_attrs.S_CNTR_CODE or "", boxCode = obj_attrs.S_CELL_NO or "", batchNo = obj_attrs.S_WMS_BN or "", produceCode = obj_attrs.S_BATCH_NO or "", productDate = obj_attrs.D_PRD_DATE or "", expiryDate = obj_attrs.D_EXP_DATE or "", productLine = obj_attrs.S_UDF01 or "", registerNo = obj_attrs.S_PROD_LINE or "" } table.insert(formatted_result, stock) end return 0, formatted_result end -- Main函数 function Stock_Query(strLuaDEID) m3.PrintLuaDEInfo(strLuaDEID) local FinalRes = Create_result() local xml_result = "" -- 使用pcall捕获所有可能的错误 local status, err = pcall(function() -- 1. 获取xml数据包 local nRet, soap_xml = mobox.getCurEditDataPacket(strLuaDEID) if nRet ~= 0 then FinalRes = Create_result("failure", "201", "无法获取数据包: " .. tostring(soap_xml)) error(FinalRes.message) end -- 2. 解析xml local nRet, parsed_data = xml.parse(soap_xml) if nRet ~= 0 then FinalRes = Create_result("failure", "202", "xml格式非法") error(FinalRes.message) end -- 3. 使用深度遍历查找关键节点 local inventory_input = deep_find_xml_node(parsed_data, {"Envelope", "Body", "InventoryReq", "Inventory_Input"}) if not inventory_input then FinalRes = Create_result("failure", "206", "XML结构错误: 缺少Inventory_Input节点") error(FinalRes.message) end local input_params = deep_find_xml_node(inventory_input, {"InputParameters"}) if not input_params then FinalRes = Create_result("failure", "207", "XML结构错误: 缺少InputParameters节点") error(FinalRes.message) end local inventory_tb = deep_find_xml_node(input_params, {"Inventory_TB"}) if not inventory_tb then FinalRes = Create_result("failure", "208", "XML结构错误: 缺少Inventory_TB节点") error(FinalRes.message) end -- 4. 提取查询参数 local query_params = { storerId = deep_find_xml_node(inventory_tb, {"storerId"}) or "", ownerId = deep_find_xml_node(inventory_tb, {"ownerId"}) or "", skuId = deep_find_xml_node(inventory_tb, {"skuId"}) or "", productLine = deep_find_xml_node(inventory_tb, {"productLine"}) or "", locationId = deep_find_xml_node(inventory_tb, {"locationId"}) or "", produceCode = deep_find_xml_node(inventory_tb, {"produceCode"}) or "" } -- 5. 参数校验 if query_params.storerId == "" then FinalRes = Create_result("failure", "203", "storerId不能为空") error(FinalRes.message) end if query_params.skuId == "" then FinalRes = Create_result("failure", "204", "skuId不能为空") error(FinalRes.message) end -- 6. 查询库存明细 local nRet, query_result = query_inventory_detail(strLuaDEID, query_params) if nRet ~= 0 then FinalRes = Create_result("failure", "205", "查询库存明细失败: " .. tostring(query_result)) error(FinalRes.message) end -- 7. 处理查询结果 if not query_result or #query_result == 0 then FinalRes = Create_result("success", "0", "未查询到符合条件的库存记录", {}) else FinalRes = Create_result("success", "0", "查询成功!", query_result) end end) -- 处理错误情况 if not status then if FinalRes.code == "0" then FinalRes = Create_result("failure", "299", "系统内部错误: " .. tostring(err)) end end -- 生成XML结果 xml_result = generate_raw_xml(FinalRes) -- 返回结果 mobox.returnValue(strLuaDEID, 0, xml_result, 0) -- 记录错误日志 if not status then lua.Stop(strLuaDEID, "处理过程中发生错误", FinalRes) end end