// pages/deal/saleOrder/kanban/saleOrderKanban.js // pages/sale_order/sale_order.js const convert = require('xml-js'); const app = getApp(); Page({ /** * 页面的初始数据 */ data: { httpsUrl: '', db: '', username: '', password: '', kanban_datas: [], userId: null, // 用于存储用户ID currentPage: 1, // 当前页码 pageSize: 20, // 每页记录数 totalRecords: 0, // 总记录数 isLoading: false // 是否正在加载数据 }, /** * 生命周期函数--监听页面加载 */ onLoad(options) { // Odoo 服务器配置 const { httpsUrl, db, username, password } = app.globalData; this.setData({ httpsUrl: httpsUrl, db: db, username: username, password: password }); // 登录到 Odoo const loginUrl = `${this.data.httpsUrl}/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 }); // 加载第一页数据 this.fetchData(); }); }, /** * 加载数据 */ fetchData() { if (this.data.isLoading) return; // 避免重复加载 this.setData({ isLoading: true }); const objectUrl = `${this.data.httpsUrl}/xmlrpc/2/object`; const objectParams = [ `${this.data.db}`, `${this.data.userId}`, `${this.data.password}`, `sale.order`, `search_read`, ` id name orde_ddje date_order partner_id order_line ${(this.data.currentPage - 1) * this.data.pageSize} ${this.data.pageSize} ` ]; this.methodCall(objectUrl, 'execute_kw', objectParams, (err, xmlResponse) => { if (err) { console.error('Failed to fetch data:', err); this.setData({ isLoading: false }); 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); this.setData({ isLoading: false }); return; } const data = result.methodResponse.params.param.value.array.data.value; if (!data) { console.error('No data found in response'); this.setData({ isLoading: false }); return; } const kanban_datas = 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'; // 提取 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 || ''; // 提取 order_line const order_lineInfo = item.struct.member.find(member => member.name._text === 'order_line')?.value.array?.data?.value || []; const order_lineInfoArray = Array.isArray(order_lineInfo) ? order_lineInfo : [order_lineInfo]; const orderLineIds = order_lineInfoArray.map(orderLine => orderLine.int?._text); return { id, name, orde_ddje, order_lineInfo, date_order, partner_id, partner_name, orderLineIds, partnerInfo, orderLines: [] // 初始化 orderLines 为空数组 }; }); // 获取每个订单的 order_line 详细信息 const fetchOrderLinePromises = kanban_datas.map(partner => { const order_lineInfoArray = Array.isArray(partner.order_lineInfo) ? partner.order_lineInfo : [partner.order_lineInfo]; const orderLineIds = order_lineInfoArray.map(orderLine => orderLine.int?._text); return new Promise((resolve, reject) => { this.fetchOrderLineDetails(orderLineIds, (err, orderLines) => { if (err) { reject(err); } else { resolve({ ...partner, orderLines }); } }); }); }); Promise.all(fetchOrderLinePromises) .then(updatedPartners => { console.log('Data fetched successfully:', updatedPartners); this.setData({ kanban_datas: updatedPartners, isLoading: false }); }) .catch(err => { console.error('Failed to fetch order line details:', err); this.setData({ isLoading: false }); }); // 获取总记录数 this.getTotalRecords(); }); }, /** * 获取总记录数 */ getTotalRecords() { const objectUrl = `${this.data.httpsUrl}/xmlrpc/2/object`; const objectParams = [ `${this.data.db}`, `${this.data.userId}`, `${this.data.password}`, `sale.order`, `search_count`, ` ` ]; this.methodCall(objectUrl, 'execute_kw', objectParams, (err, xmlResponse) => { if (err) { console.error('Failed to fetch total records:', 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 total records:', faultString); return; } const totalRecords = result.methodResponse.params.param.value.int._text; console.log('Total records:', totalRecords); this.setData({ totalRecords }); }); }, /** * 加载更多数据 */ loadMore() { if (this.data.isLoading || (this.data.currentPage * this.data.pageSize) >= this.data.totalRecords) return; this.setData({ currentPage: this.data.currentPage + 1 }); this.fetchData(); }, loadPrevious() { if (this.data.isLoading || this.data.currentPage <= 1) return; this.setData({ currentPage: this.data.currentPage - 1 }); this.fetchData(); }, /** * 创建一个函数来进行 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); }, /** * 获取 order_line 的详细信息 */ fetchOrderLineDetails(orderLineIds, callback) { const objectUrl = `${this.data.httpsUrl}/xmlrpc/2/object`; const objectParams2 = [ `${this.data.db}`, `${this.data.userId}`, `${this.data.password}`, `sale.order.line`, `read`, ` ${orderLineIds.map(id => `${id}`).join('')} product_id name price_unit product_uom_qty fineCode_Text ` ]; this.methodCall(objectUrl, 'execute_kw', objectParams2, (err, xmlResponse) => { if (err) { console.error('Failed to fetch order line 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 order line details:', faultString); callback(new Error(faultString), []); return; } const data = result.methodResponse.params.param.value.array.data.value; if (!data) { console.error('No data found in response'); callback(null, []); return; } // 确保 data 是一个数组 const dataArray = Array.isArray(data) ? data : [data]; const orderLines = dataArray.map(item => { const saleorderid = 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 priceUnit = item.struct.member.find(member => member.name._text === 'price_unit')?.value.double?._text || '0.00'; const productUomQty = item.struct.member.find(member => member.name._text === 'product_uom_qty')?.value.double?._text || '0.00'; // const fineCode_3 = item.struct.member.find(member => member.name._text === 'fineCode_3')?.value.array?.data?.value || []; const fineCode_Text = item.struct.member.find(member => member.name._text === 'fineCode_Text')?.value.string?._text || ''; return { fineCode_Text, // fineCode_3, saleorderid, name, priceUnit, productUomQty }; }); callback(null, orderLines); }); }, /** * 获取产品详细信息 */ 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; } // 实现获取产品详细信息的逻辑 }, /** * 生成分享文本 */ generateShareText(partner) { return ` 销售单详情: 订单号: ${partner.id} 订单名称: ${partner.name} 订单日期: ${partner.date_order} 订单金额: ${partner.orde_ddje} 产品: ${partner.orderLines.map(line => `${line.name} (Fine Codes: ${line.fineCode_Text.join(', ')})`).join(', ')} 合作伙伴ID: ${partner.partner_id || '无'} 合作伙伴名称: ${partner.partner_name || '无'} `; }, /** * 处理卡片点击事件 */ onCardClick(event) { const partner = this.data.kanban_datas[event.currentTarget.dataset.index]; if (!partner) { return; } console.log('Card clicked:', partner); console.log('Card clicked:', event); // 将选中的 partner 数据存储到全局应用实例中 const app = getApp(); app.globalData.selectedPartner = partner; // 在这里可以添加更多的处理逻辑,比如跳转到详情页 wx.showToast({ title: `点击了订单 ${partner.name}`, icon: 'none' }); const index = event.currentTarget.dataset.index; wx.navigateTo({ url: `/pages/deal/saleOrder/kanban/from/saleOrderFrom?index=${index}`, }); }, /** * 处理图片点击事件 */ onThumbClick(event) { const partner = this.data.kanban_datas[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() { this.loadMore(); }, /** * 用户点击右上角分享 */ onShareAppMessage() { const partner = this.data.kanban_datas[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) }; } });