// pages/sale_order/sale_order.js
const convert = require('xml-js');
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
odooUrl: '',
db: '',
username: '',
password: '',
partners: [],
userId: null, // 用于存储用户ID
currentPage: 1, // 当前页码
pageSize: 20, // 每页记录数
totalRecords: 0, // 总记录数
isLoading: false // 是否正在加载数据
},
/**
* 生命周期函数--监听页面加载
*/
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
});
// 加载第一页数据
this.fetchData();
});
},
/**
* 加载数据
*/
fetchData() {
if (this.data.isLoading) return; // 避免重复加载
this.setData({ isLoading: true });
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}
`
];
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 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';
// 提取 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 = 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 请求
*/
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.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);
});
},
/**
* 获取产品详细信息
*/
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.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() {
this.loadMore();
},
/**
* 用户点击右上角分享
*/
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)
};
}
});