// pages/sale_order/sale_order.js const convert = require('xml-js'); const app = getApp(); Page({ /** * 页面的初始数据 */ data: { odooUrl: '', db: '', username: '', password: '', partners: [], userId: null // 用于存储用户ID }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { // Odoo 服务器配置 const { odooUrl, db, username, password } = app.globalData; this.setData({ odooUrl: odooUrl, db: db, username: username, password: password }); // 登录到 Odoo const loginUrl = `${this.data.odooUrl}/xmlrpc/2/common`; const loginParams = [ `${this.data.db}`, `${this.data.username}`, `${this.data.password}`, ` interactive 0 ` ]; this.methodCall(loginUrl, 'authenticate', loginParams, (err, xmlResponse) => { if (err) { console.error('Authentication failed:', err); return; } // 解析 XML 响应 const result = convert.xml2js(xmlResponse, { compact: true, spaces: 4 }); if (result.methodResponse.fault) { const faultString = result.methodResponse.fault.value.struct.member.find(member => member.name._text === 'faultString').value.string._text; console.error('Authentication failed:', faultString); return; } const userId = result.methodResponse.params.param.value.int._text; console.log('Authentication successful. User ID:', userId); // 存储用户ID this.setData({ userId: userId }); // 获取模型信息 const objectUrl = `${this.data.odooUrl}/xmlrpc/2/object`; const objectParams = [ `${this.data.db}`, `${userId}`, `${this.data.password}`, `sale.order`, `search_read`, ` id name orde_ddje date_order product_ids partner_id ` ]; this.methodCall(objectUrl, 'execute_kw', objectParams, (err, xmlResponse) => { if (err) { console.error('Failed to fetch data:', err); return; } // 解析 XML 响应 const result = convert.xml2js(xmlResponse, { compact: true, spaces: 4 }); if (result.methodResponse.fault) { const faultString = result.methodResponse.fault.value.struct.member.find(member => member.name._text === 'faultString').value.string._text; console.error('Failed to fetch data:', faultString); return; } const data = result.methodResponse.params.param.value.array.data.value; if (!data) { console.error('No data found in response'); return; } const partners = data.map(item => { const id = item.struct.member.find(member => member.name._text === 'id')?.value.int?._text || ''; const name = item.struct.member.find(member => member.name._text === 'name')?.value.string?._text || ''; const date_order = item.struct.member.find(member => member.name._text === 'date_order')?.value.string?._text || ''; const orde_ddje = item.struct.member.find(member => member.name._text === 'orde_ddje')?.value.double?._text || '0.00'; let product_ids = item.struct.member.find(member => member.name._text === 'product_ids')?.value.array?.data?.value || []; // 如果 product_ids 是对象而不是数组,则处理为数组 if (!Array.isArray(product_ids)) { product_ids = []; } else { product_ids = product_ids.map(idObj => idObj.int?._text); } // 提取 partner_id 和 partner_name const partnerInfo = item.struct.member.find(member => member.name._text === 'partner_id')?.value.array?.data?.value; const partner_id = partnerInfo?.[0]?.int?._text || ''; const partner_name = partnerInfo?.[1]?.string?._text || ''; return { id, name, orde_ddje, date_order, product_ids, partner_id, partner_name }; }); console.log('Data fetched successfully:', partners); // 获取产品详细信息 const allProductIds = partners.flatMap(partner => partner.product_ids); this.fetchProductDetails(allProductIds, (err, products) => { if (err) { console.error('Failed to fetch product details:', err); return; } // 将产品详细信息映射到每个订单 const partnersWithProducts = partners.map(partner => { const productsInfo = partner.product_ids.map(id => { return products.find(product => product.id === id); }).filter(product => product); // 过滤掉未找到的产品 return { ...partner, products: productsInfo }; }); console.log('Data with products fetched successfully:', partnersWithProducts); // 更新页面数据 this.setData({ partners: partnersWithProducts }); }); }); }); }, /** * 创建一个函数来进行 XML-RPC 请求 */ xmlrpcRequest(url, xmlData, callback) { wx.request({ url: url, method: 'POST', data: xmlData, header: { 'Content-Type': 'text/xml' }, success: function(res) { // 确保返回的数据是纯 XML 格式 if (res.data && typeof res.data === 'string') { callback(null, res.data); } else { callback(new Error('Invalid response format'), null); } }, fail: function(err) { callback(err, null); } }); }, /** * 创建一个函数来进行 XML-RPC 方法调用 */ methodCall(url, method, params, callback) { const xmlData = ` ${method} ${params.map(param => `${param}`).join('')} `; this.xmlrpcRequest(url, xmlData, callback); }, /** * 获取产品详细信息 */ fetchProductDetails(productIds, callback) { // 确保 productIds 是一个数组 if (!Array.isArray(productIds)) { productIds = [productIds]; } // 过滤掉无效的 productIds const validProductIds = productIds.filter(id => typeof id === 'number' && Number.isInteger(id)); if (validProductIds.length === 0) { callback(null, []); return; } const objectUrl = `${this.data.odooUrl}/xmlrpc/2/object`; const objectParams = [ `${this.data.db}`, `${this.data.userId}`, `${this.data.password}`, `product.product`, `search_read`, ` ${validProductIds.map(id => `${id}`).join('')} id name list_price ` ]; this.methodCall(objectUrl, 'execute_kw', objectParams, (err, xmlResponse) => { if (err) { console.error('Failed to fetch product details:', err); callback(err, []); return; } // 解析 XML 响应 const result = convert.xml2js(xmlResponse, { compact: true, spaces: 4 }); if (result.methodResponse.fault) { const faultString = result.methodResponse.fault.value.struct.member.find(member => member.name._text === 'faultString').value.string._text; console.error('Failed to fetch product details:', faultString); callback(new Error(faultString), []); return; } const products = result.methodResponse.params.param.value.array.data.value.map(item => { const id = item.struct.member.find(member => member.name._text === 'id')?.value.int?._text || ''; const name = item.struct.member.find(member => member.name._text === 'name')?.value.string?._text || ''; const list_price = item.struct.member.find(member => member.name._text === 'list_price')?.value.double?._text || '0.00'; return { id, name, list_price }; }); callback(null, products); }); }, /** * 生成分享文本 */ generateShareText(partner) { const productNames = partner.products.map(product => product.name).join(', '); return ` 销售单详情: 订单号: ${partner.id} 订单名称: ${partner.name} 订单日期: ${partner.date_order} 订单金额: ${partner.orde_ddje} 产品: ${productNames} 合作伙伴ID: ${partner.partner_id || '无'} 合作伙伴名称: ${partner.partner_name || '无'} `; }, /** * 处理卡片点击事件 */ onCardClick(event) { const partner = this.data.partners[event.currentTarget.dataset.index]; if (!partner) { return; } console.log('Card clicked:', partner); console.log('Card clicked:', event); // 在这里可以添加更多的处理逻辑,比如跳转到详情页 wx.showToast({ title: `点击了订单 ${partner.name}`, icon: 'none' }); const index = event.currentTarget.dataset.index; wx.navigateTo({ url: `/pages/sale_order/form/sale_order_form?index=${index}`, }); }, /** * 处理图片点击事件 */ onThumbClick(event) { const partner = this.data.partners[event.currentTarget.dataset.index]; if (!partner) { return; } console.log('Thumbnail clicked:', partner); // 在这里可以添加更多的处理逻辑,比如预览图片 wx.showToast({ title: `点击了订单 ${partner.name} 的图片`, icon: 'none' }); }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady() { }, /** * 生命周期函数--监听页面显示 */ onShow() { }, /** * 生命周期函数--监听页面隐藏 */ onHide() { }, /** * 生命周期函数--监听页面卸载 */ onUnload() { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh() { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom() { }, /** * 用户点击右上角分享 */ onShareAppMessage() { const partner = this.data.partners[0]; // 假设分享第一个订单 if (!partner) { return {}; } return { title: '销售单详情', path: '/pages/sale_order/sale_order?id=' + partner.id, imageUrl: 'https://fastly.jsdelivr.net/npm/@vant/assets/ipad.jpeg', desc: this.generateShareText(partner) }; } });