diff --git a/pages/sale_order/sale_order.js b/pages/sale_order/sale_order.js index 01e234b..9fcd2cc 100644 --- a/pages/sale_order/sale_order.js +++ b/pages/sale_order/sale_order.js @@ -12,7 +12,11 @@ Page({ username: '', password: '', partners: [], - userId: null // 用于存储用户ID + userId: null, // 用于存储用户ID + currentPage: 1, // 当前页码 + pageSize: 20, // 每页记录数 + totalRecords: 0, // 总记录数 + isLoading: false // 是否正在加载数据 }, /** @@ -20,7 +24,12 @@ Page({ */ onLoad(options) { // Odoo 服务器配置 - const { odooUrl, db, username, password } = app.globalData; + const { + odooUrl, + db, + username, + password + } = app.globalData; this.setData({ odooUrl: odooUrl, db: db, @@ -49,7 +58,10 @@ Page({ } // 解析 XML 响应 - const result = convert.xml2js(xmlResponse, { compact: true, spaces: 4 }); + 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; @@ -65,106 +77,199 @@ Page({ 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.fetchData(); + }); + }, - this.methodCall(objectUrl, 'execute_kw', objectParams, (err, xmlResponse) => { - if (err) { - console.error('Failed to fetch data:', err); - return; - } + /** + * 加载数据 + */ + fetchData() { + if (this.data.isLoading) return; // 避免重复加载 - // 解析 XML 响应 - const result = convert.xml2js(xmlResponse, { compact: true, spaces: 4 }); + this.setData({ isLoading: true }); - 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 objectUrl = `${this.data.odooUrl}/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} + + ` + ]; - const data = result.methodResponse.params.param.value.array.data.value; - if (!data) { - console.error('No data found in response'); - return; - } + this.methodCall(objectUrl, 'execute_kw', objectParams, (err, xmlResponse) => { + if (err) { + console.error('Failed to fetch data:', err); + this.setData({ isLoading: false }); + 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 || []; + // 解析 XML 响应 + const result = convert.xml2js(xmlResponse, { + compact: true, + spaces: 4 + }); - // 如果 product_ids 是对象而不是数组,则处理为数组 - if (!Array.isArray(product_ids)) { - product_ids = []; - } else { - product_ids = product_ids.map(idObj => idObj.int?._text); - } + 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; + } - // 提取 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 || ''; + const data = result.methodResponse.params.param.value.array.data.value; + if (!data) { + console.error('No data found in response'); + this.setData({ isLoading: false }); + return; + } - return { id, name, orde_ddje, date_order, product_ids, partner_id, partner_name }; - }); + 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'; - console.log('Data fetched successfully:', partners); + // 提取 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 || ''; - // 获取产品详细信息 - const allProductIds = partners.flatMap(partner => partner.product_ids); - this.fetchProductDetails(allProductIds, (err, products) => { - if (err) { - console.error('Failed to fetch product details:', err); - return; - } + // 提取 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 为空数组 + }; + }); - // 将产品详细信息映射到每个订单 - 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 + // 获取每个订单的 order_line 详细信息 + const fetchOrderLinePromises = partners.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({ + partners: 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.odooUrl}/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 请求 */ @@ -176,7 +281,7 @@ Page({ header: { 'Content-Type': 'text/xml' }, - success: function(res) { + success: function (res) { // 确保返回的数据是纯 XML 格式 if (res.data && typeof res.data === 'string') { callback(null, res.data); @@ -184,7 +289,7 @@ Page({ callback(new Error('Invalid response format'), null); } }, - fail: function(err) { + fail: function (err) { callback(err, null); } }); @@ -206,6 +311,87 @@ Page({ this.xmlrpcRequest(url, xmlData, callback); }, + /** + * 获取 order_line 的详细信息 + */ + fetchOrderLineDetails(orderLineIds, callback) { + const objectUrl = `${this.data.odooUrl}/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); + }); + }, + /** * 获取产品详细信息 */ @@ -223,72 +409,20 @@ Page({ 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} + 产品: ${partner.orderLines.map(line => `${line.name} (Fine Codes: ${line.fineCode_Text.join(', ')})`).join(', ')} 合作伙伴ID: ${partner.partner_id || '无'} 合作伙伴名称: ${partner.partner_name || '无'} `; @@ -373,7 +507,7 @@ Page({ * 页面上拉触底事件的处理函数 */ onReachBottom() { - + this.loadMore(); }, /** @@ -390,6 +524,7 @@ Page({ path: '/pages/sale_order/sale_order?id=' + partner.id, imageUrl: 'https://fastly.jsdelivr.net/npm/@vant/assets/ipad.jpeg', desc: this.generateShareText(partner) - }; - } -}); \ No newline at end of file + + }; + } + }); \ No newline at end of file diff --git a/pages/sale_order/sale_order.wxml b/pages/sale_order/sale_order.wxml index f7c8416..a84d560 100644 --- a/pages/sale_order/sale_order.wxml +++ b/pages/sale_order/sale_order.wxml @@ -18,8 +18,11 @@ - {{item.product_ids || ''}} + {{item.name}} + {{item.fineCode_Text}}