650 lines
18 KiB
JavaScript
650 lines
18 KiB
JavaScript
/**
|
||
* 孔夫子旧书网API服务
|
||
*/
|
||
|
||
/**
|
||
* 登录孔夫子旧书网
|
||
* @param {string} username - 用户名
|
||
* @param {string} password - 密码
|
||
* @returns {Promise<{success: boolean, token: string, message: string}>} - 登录结果
|
||
*/
|
||
export function login(username, password) {
|
||
return new Promise((resolve, reject) => {
|
||
if (!username || !password) {
|
||
resolve({
|
||
success: false,
|
||
message: '请输入用户名和密码'
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 构建请求参数
|
||
const url = 'https://login.kongfz.com/Pc/Login/account';
|
||
const data = {
|
||
loginName: username,
|
||
loginPass: password,
|
||
autoLogin: '0',
|
||
returnUrl: 'http://user.kongfz.com/'
|
||
};
|
||
|
||
// 发送请求
|
||
uni.request({
|
||
url: url,
|
||
method: 'POST',
|
||
data: data,
|
||
header: {
|
||
'Content-Type': 'application/x-www-form-urlencoded'
|
||
// 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
||
},
|
||
success: (res) => {
|
||
console.log("登录...", res)
|
||
// 检查登录是否成功
|
||
if (res.data && res.data.indexOf(
|
||
"window.location.href='https://login.kongfz.cn/Pc/Session/rsync") !== -1) {
|
||
// 提取PHPSESSID
|
||
const cookies = res.cookies;
|
||
let phpsessid = '';
|
||
|
||
if (cookies && cookies.length > 0) {
|
||
for (const cookie of cookies) {
|
||
if (cookie.indexOf('PHPSESSID=') !== -1) {
|
||
phpsessid = cookie.split('PHPSESSID=')[1].split(';')[0];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (phpsessid) {
|
||
resolve({
|
||
success: true,
|
||
token: phpsessid,
|
||
message: '登录成功'
|
||
});
|
||
} else {
|
||
resolve({
|
||
success: false,
|
||
message: '登录失败: 未找到PHPSESSID'
|
||
});
|
||
}
|
||
} else {
|
||
// 尝试解析错误信息
|
||
try {
|
||
const data = JSON.parse(res.data);
|
||
if (data.errCode === 1001) {
|
||
resolve({
|
||
success: false,
|
||
message: '登录失败: 账号或密码错误'
|
||
});
|
||
} else if (data.errInfo) {
|
||
resolve({
|
||
success: false,
|
||
message: `登录失败: ${data.errInfo}`
|
||
});
|
||
} else {
|
||
resolve({
|
||
success: false,
|
||
message: '登录失败: 未知错误'
|
||
});
|
||
}
|
||
} catch (e) {
|
||
resolve({
|
||
success: false,
|
||
message: '登录失败: 响应不包含成功跳转信息'
|
||
});
|
||
}
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
reject(new Error(`登录请求失败: ${err.errMsg}`));
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 获取商品列表
|
||
* @param {string} token - 登录令牌
|
||
* @param {Object} params - 查询参数
|
||
* @param {function} onProgress - 进度回调
|
||
* @returns {Promise<Array>} - 商品列表
|
||
*/
|
||
export function fetchItems(token, params = {}, onProgress = null) {
|
||
return new Promise((resolve, reject) => {
|
||
if (!token) {
|
||
reject(new Error('请先登录获取Token'));
|
||
return;
|
||
}
|
||
// const token = 'ebb26189289d0dc068f9aac748881bccf890e694';
|
||
const url = 'https://seller.kongfz.com/pc-gw/book-manage-service/client/pc/goods/unSold/list';
|
||
const headers = {
|
||
'Cookie': `PHPSESSID=${token}`,
|
||
// 'Cookie': 'PHPSESSID=ebb26189289d0dc068f9aac748881bccf890e694'
|
||
// 'User-Agent' 头在浏览器环境中无法设置,会被拒绝
|
||
// 'Content-Type': 'application/json'
|
||
};
|
||
|
||
let page = 1;
|
||
const size = 50;
|
||
const allItemIds = [];
|
||
|
||
const fetchPage = () => {
|
||
// 准备请求体
|
||
const requestBody = {
|
||
"requestType": "onSale", // 标识 出售中
|
||
"isItemSnEqual": "0",
|
||
"page": page,
|
||
"size": size
|
||
};
|
||
|
||
// 添加可选参数
|
||
if (params.itemSn) requestBody.itemSn = params.itemSn;
|
||
if (params.priceMin) requestBody.priceMin = params.priceMin;
|
||
if (params.priceMax) requestBody.priceMax = params.priceMax;
|
||
if (params.startCreateTime) requestBody.startCreateTime = params.startCreateTime;
|
||
if (params.endCreateTime) requestBody.endCreateTime = params.endCreateTime;
|
||
|
||
// 调用进度回调
|
||
if (onProgress) {
|
||
onProgress(`正在获取第 ${page} 页数据...`);
|
||
// 添加请求参数日志
|
||
if (page === 1) {
|
||
onProgress(`请求参数: ${JSON.stringify(requestBody)}`);
|
||
}
|
||
}
|
||
console.log("请求参数", requestBody)
|
||
|
||
// 发送请求
|
||
uni.request({
|
||
url: url,
|
||
method: 'POST',
|
||
data: requestBody,
|
||
header: headers,
|
||
success: (res) => {
|
||
if (res.statusCode !== 200) {
|
||
console.error('API 失败响应:', res);
|
||
reject(new Error(`API返回错误: HTTP ${res.statusCode}`));
|
||
return;
|
||
}
|
||
|
||
const data = res.data;
|
||
if (!data.status) {
|
||
console.error('API 失败响应:', data);
|
||
reject(new Error(`API返回错误: ${data.errMessage || '未知错误'}`));
|
||
return;
|
||
}
|
||
|
||
// 获取商品列表
|
||
const result = data.result || {};
|
||
const productInfo = result.productInfoPageResult || {};
|
||
const items = productInfo.list || [];
|
||
const pager = productInfo.pager || {};
|
||
|
||
// 提取商品ID
|
||
for (const item of items) {
|
||
const itemId = item.itemId;
|
||
if (itemId) {
|
||
allItemIds.push({
|
||
id: itemId,
|
||
status: 'wait'
|
||
});
|
||
}
|
||
}
|
||
|
||
// 更新状态
|
||
const totalPages = pager.pages || 0;
|
||
const totalCount = pager.count || 0;
|
||
if (onProgress) {
|
||
onProgress(`获取到 ${items.length} 个商品 (第 ${page}/${totalPages} 页)`);
|
||
// 添加更详细的商品信息
|
||
if (items.length > 0) {
|
||
const firstItem = items[0];
|
||
onProgress(
|
||
`商品示例: ID=${firstItem.itemId}, 标题=${firstItem.title || '无标题'}, 价格=${firstItem.price || '未知'}`
|
||
);
|
||
}
|
||
// 添加总数信息
|
||
onProgress(`当前已获取: ${allItemIds.length}/${totalCount} 个商品`);
|
||
}
|
||
|
||
// 检查是否还有下一页
|
||
if (page >= totalPages) {
|
||
if (onProgress) {
|
||
onProgress(`拉取完成,共获取 ${allItemIds.length} 个商品`);
|
||
if (allItemIds.length === 0) {
|
||
onProgress('未找到符合条件的商品,请检查筛选条件');
|
||
} else {
|
||
onProgress(
|
||
`商品ID示例: ${allItemIds.slice(0, 3).map(item => item.id).join(', ')}${allItemIds.length > 3 ? '...' : ''}`
|
||
);
|
||
}
|
||
}
|
||
resolve(allItemIds);
|
||
} else {
|
||
page++;
|
||
// 延迟1秒后获取下一页
|
||
if (onProgress) {
|
||
onProgress(`等待1秒后获取下一页...`);
|
||
}
|
||
setTimeout(fetchPage, 1000);
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
const errorMsg = `拉取商品失败: ${err.errMsg}`;
|
||
if (onProgress) {
|
||
onProgress(errorMsg);
|
||
onProgress('请检查网络连接是否正常');
|
||
onProgress('请确认登录状态是否有效');
|
||
}
|
||
reject(new Error(errorMsg));
|
||
}
|
||
});
|
||
};
|
||
|
||
// 开始获取第一页
|
||
fetchPage();
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 获取商品模板字段
|
||
* @param {string} token - 登录令牌
|
||
* @param {string} itemId - 商品ID
|
||
* @returns {Promise<Object>} - 商品模板字段
|
||
*/
|
||
export function getItemTplFields(token, itemId) {
|
||
return new Promise((resolve, reject) => {
|
||
if (!token) {
|
||
reject(new Error('请先登录获取Token'));
|
||
return;
|
||
}
|
||
|
||
const url =
|
||
`https://seller.kongfz.com/pc/itemInfo/getTplFields?itemId=${itemId}&isClone=1&v=${Math.floor(Date.now() / 1000)}`;
|
||
|
||
uni.request({
|
||
url: url,
|
||
method: 'GET',
|
||
header: {
|
||
'Cookie': `PHPSESSID=${token}`,
|
||
// 'User-Agent' 头在浏览器环境中无法设置,会被拒绝
|
||
'Referer': 'https://seller.kongfz.com/',
|
||
'Origin': 'https://seller.kongfz.com'
|
||
},
|
||
success: (res) => {
|
||
if (res.statusCode !== 200) {
|
||
reject(new Error(`HTTP错误: ${res.statusCode}`));
|
||
return;
|
||
}
|
||
|
||
const data = res.data;
|
||
if (data.status === 1) {
|
||
resolve(data);
|
||
} else {
|
||
reject(new Error(`API返回错误: ${data.message || '未知错误'}`));
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
reject(new Error(`请求失败: ${err.errMsg}`));
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 提交商品表单
|
||
* @param {string} token - 登录令牌
|
||
* @param {Object} itemData - 商品数据
|
||
* @param {Object} priceConfig - 价格配置
|
||
* @returns {Promise<boolean>} - 是否成功
|
||
*/
|
||
export function submitItemForm(token, itemData, priceConfig) {
|
||
return new Promise((resolve, reject) => {
|
||
if (!token) {
|
||
reject(new Error('请先登录获取Token'));
|
||
return;
|
||
}
|
||
|
||
// 准备表单数据
|
||
const formData = {
|
||
"pageType": "clone"
|
||
};
|
||
|
||
// 添加图书基本信息(bookSection)
|
||
const bookSection = (itemData.data && itemData.data.bookSection) || [];
|
||
for (const field of bookSection) {
|
||
const key = field.key;
|
||
const value = field.value;
|
||
|
||
// 处理嵌套字段(如出版时间)
|
||
if (field.group) {
|
||
for (const subField of field.group) {
|
||
const subKey = subField.key;
|
||
const subValue = subField.value;
|
||
|
||
if (subKey && subValue !== null && subValue !== undefined) {
|
||
formData[subKey] = String(subValue);
|
||
}
|
||
|
||
// 处理options中的嵌套
|
||
if (subField.options) {
|
||
const selectedValue = subField.value; // 获取当前选中的值
|
||
for (const option of subField.options) {
|
||
const optionValue = option.value;
|
||
// 如果选项是当前选中的,或者选项中有group字段,则处理其中的字段
|
||
if (String(optionValue) === String(selectedValue) || option.group) {
|
||
if (option.group) {
|
||
for (const optionField of option.group) {
|
||
const optionKey = optionField.key;
|
||
const optionValue = optionField.value;
|
||
|
||
if (optionKey && optionValue !== null && optionValue !== undefined) {
|
||
formData[optionKey] = String(optionValue);
|
||
}
|
||
|
||
// 处理更深层的嵌套
|
||
if (optionField.group) {
|
||
for (const deepField of optionField.group) {
|
||
const deepKey = deepField.key;
|
||
const deepValue = deepField.value;
|
||
|
||
if (deepKey && deepValue !== null && deepValue !== undefined) {
|
||
formData[deepKey] = String(deepValue);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 处理更深层的嵌套(如年月)
|
||
if (subField.group) {
|
||
for (const deepField of subField.group) {
|
||
const deepKey = deepField.key;
|
||
const deepValue = deepField.value;
|
||
|
||
if (deepKey && deepValue !== null && deepValue !== undefined) {
|
||
formData[deepKey] = String(deepValue);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 添加顶层字段
|
||
if (key && value !== null && value !== undefined) {
|
||
formData[key] = String(value);
|
||
}
|
||
|
||
// 特殊处理 yearsGroup 字段,确保处理其 options 中的字段
|
||
if (key === 'yearsGroup' && field.options) {
|
||
const selectedValue = value; // 获取当前选中的值
|
||
for (const option of field.options) {
|
||
const optionValue = option.value;
|
||
// 如果选项是当前选中的,处理其中的字段
|
||
if (String(optionValue) === String(selectedValue) && option.group) {
|
||
for (const optionField of option.group) {
|
||
const optionKey = optionField.key;
|
||
const optionValue = optionField.value;
|
||
|
||
if (optionKey && optionValue !== null && optionValue !== undefined) {
|
||
formData[optionKey] = String(optionValue);
|
||
}
|
||
|
||
// 处理出版时间的年月字段
|
||
if (optionKey === 'pubDate' && optionField.group) {
|
||
for (const dateField of optionField.group) {
|
||
const dateKey = dateField.key;
|
||
const dateValue = dateField.value;
|
||
|
||
if (dateKey && dateValue !== null && dateValue !== undefined) {
|
||
formData[dateKey] = String(dateValue);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 添加商品基本信息
|
||
const goodsSection = (itemData.data && itemData.data.goodsSection) || [];
|
||
for (const field of goodsSection) {
|
||
const key = field.key;
|
||
const value = field.value;
|
||
|
||
// 跳过 images 字段,因为我们会单独处理图片
|
||
if (key === 'images') {
|
||
const images = field.images || [];
|
||
for (let i = 0; i < images.length; i++) {
|
||
formData[`images[${i}][imgId]`] = String(images[i].imgId || '');
|
||
formData[`images[${i}][imgType]`] = String(images[i].imgType || '');
|
||
formData[`images[${i}][imgDesc]`] = '';
|
||
formData[`images[${i}][isMain]`] = String(images[i].isMain || '');
|
||
formData[`images[${i}][imgUrl]`] = images[i].imgUrl || '';
|
||
}
|
||
continue;
|
||
}
|
||
|
||
if (key && value !== null && value !== undefined) {
|
||
// 特殊处理价格字段
|
||
if (key === 'price') {
|
||
try {
|
||
let price = parseFloat(value);
|
||
// 应用价格调整
|
||
if (priceConfig.configType === 1) { // 折扣
|
||
price *= (priceConfig.value / 100);
|
||
} else if (priceConfig.configType === 2) { // 加减值
|
||
price += priceConfig.value; // priceConfig.value已经包含了正负号
|
||
} else if (priceConfig.configType === 3) { // 直接赋值
|
||
price = priceConfig.value;
|
||
}
|
||
formData[key] = price.toFixed(2);
|
||
} catch (e) {
|
||
formData[key] = String(value);
|
||
}
|
||
} else {
|
||
// 添加到表单数据
|
||
formData[key] = String(value);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 添加物流信息
|
||
const shippingSection = (itemData.data && itemData.data.shippingSection) || [];
|
||
for (const field of shippingSection) {
|
||
const key = field.key;
|
||
const value = field.value;
|
||
|
||
if (key && value !== null && value !== undefined) {
|
||
formData[key] = String(value);
|
||
}
|
||
}
|
||
|
||
// 添加交付信息
|
||
const deliverSection = (itemData.data && itemData.data.deliverSection) || [];
|
||
for (const field of deliverSection) {
|
||
const key = field.key;
|
||
const value = field.value;
|
||
|
||
if (key && value !== null && value !== undefined) {
|
||
formData[key] = String(value);
|
||
}
|
||
}
|
||
|
||
// 添加分类ID
|
||
const categorySection = (itemData.data && itemData.data.categorySection) || {};
|
||
if (categorySection.value !== null && categorySection.value !== undefined) {
|
||
formData.catId = String(categorySection.value);
|
||
}
|
||
|
||
const url = 'https://seller.kongfz.com/pc/itemInfo/add';
|
||
console.log("formData1111111111", formData)
|
||
// 发送请求
|
||
uni.request({
|
||
url: url,
|
||
method: 'POST',
|
||
data: formData,
|
||
header: {
|
||
'Cookie': `PHPSESSID=${token}`,
|
||
// 'User-Agent' 头在浏览器环境中无法设置,会被拒绝
|
||
'Content-Type': 'application/x-www-form-urlencoded',
|
||
'Referer': 'https://seller.kongfz.com/',
|
||
'Origin': 'https://seller.kongfz.com'
|
||
},
|
||
success: (res) => {
|
||
console.log("处理后的res", res)
|
||
if (res.statusCode !== 200) {
|
||
reject(new Error(`HTTP错误: ${res.statusCode}`));
|
||
return;
|
||
}
|
||
|
||
const data = res.data;
|
||
if (res.statusCode === 200 && data.status === 1) {
|
||
// 保存新商品ID到本地存储,同时保存对应的旧商品ID
|
||
if (data.data) {
|
||
try {
|
||
const newId = String(data.data); // 确保newId为字符串
|
||
const oldId = String(formData.itemId); // 确保oldId为字符串
|
||
|
||
// 严格校验oldId和newId都不为空
|
||
const existingNewIds = uni.getStorageSync('kongfz_new_ids') || [];
|
||
const newIds = Array.isArray(existingNewIds) ? existingNewIds : [];
|
||
if (oldId && newId && oldId.trim() !== '' && newId.trim() !== '') {
|
||
newIds.push({
|
||
oldId: oldId,
|
||
newId: newId,
|
||
createTime: new Date().toISOString()
|
||
});
|
||
uni.setStorageSync('kongfz_new_ids', newIds);
|
||
console.log('新商品ID已保存:', newId, '对应旧ID:', oldId);
|
||
console.log('存储的ids', newIds);
|
||
} else {
|
||
console.warn('跳过保存无效的商品ID:', {
|
||
oldId,
|
||
newId
|
||
});
|
||
}
|
||
} catch (e) {
|
||
console.error('保存新商品ID失败:', e);
|
||
}
|
||
}
|
||
resolve(true);
|
||
} else {
|
||
resolve(false);
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
reject(new Error(`提交表单失败: ${err.errMsg}`));
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 批量更新孔网平台商品ID
|
||
* @param {Array} items - 商品ID对应关系数组,格式:[{oldPlatformId: "旧ID", newPlatformId: "新ID"}]
|
||
* @returns {Promise<{success: boolean, message: string}>} - 处理结果
|
||
*/
|
||
export function batchUpdatePddPlatformId(items) {
|
||
return new Promise((resolve, reject) => {
|
||
if (!items || !Array.isArray(items) || items.length === 0) {
|
||
resolve({
|
||
success: false,
|
||
message: '请提供有效的商品ID对应关系'
|
||
});
|
||
return;
|
||
}
|
||
|
||
const url = 'https://api.buzhiyushu.cn/zhishu/shopGoodsPublished/batchUpdateKfzPlatformId';
|
||
|
||
uni.request({
|
||
url: url,
|
||
method: 'POST',
|
||
data: items,
|
||
header: {
|
||
'Content-Type': 'application/json'
|
||
},
|
||
success: (res) => {
|
||
if (res.statusCode === 200) {
|
||
const data = res.data;
|
||
if (data.code === 200) {
|
||
resolve({
|
||
success: true,
|
||
message: data.msg || '操作成功'
|
||
});
|
||
} else {
|
||
resolve({
|
||
success: false,
|
||
message: data.msg || '操作失败'
|
||
});
|
||
}
|
||
} else {
|
||
resolve({
|
||
success: false,
|
||
message: `HTTP错误: ${res.statusCode}`
|
||
});
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
reject(new Error(`请求失败: ${err.errMsg}`));
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 删除商品
|
||
* @param {string} token - 登录令牌
|
||
* @param {string} itemId - 商品ID
|
||
* @returns {Promise<boolean>} - 是否成功
|
||
*/
|
||
export function deleteItem(token, itemId) {
|
||
return new Promise((resolve, reject) => {
|
||
if (!token) {
|
||
reject(new Error('请先登录获取Token'));
|
||
return;
|
||
}
|
||
|
||
const url = 'https://seller.kongfz.com/pc-gw/book-manage-service/client/pc/goods/quickUpdate';
|
||
|
||
// 准备JSON数据
|
||
const payload = {
|
||
"itemId": String(itemId),
|
||
"updateType": "delete",
|
||
"value": "1"
|
||
};
|
||
|
||
uni.request({
|
||
url: url,
|
||
method: 'POST',
|
||
data: payload,
|
||
header: {
|
||
'Cookie': `PHPSESSID=${token}`,
|
||
// 'User-Agent' 头在浏览器环境中无法设置,会被拒绝
|
||
'Content-Type': 'application/json; charset=UTF-8',
|
||
'Referer': 'https://seller.kongfz.com/',
|
||
'Origin': 'https://seller.kongfz.com'
|
||
},
|
||
success: (res) => {
|
||
console.log("delect", res)
|
||
if (res.statusCode !== 200) {
|
||
reject(new Error(`HTTP错误: ${res.statusCode}`));
|
||
return;
|
||
}
|
||
|
||
const result = res.data;
|
||
if (result.status === true || result.status === 1) {
|
||
resolve(true);
|
||
} else {
|
||
resolve(false);
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
reject(new Error(`删除商品时出错: ${err.errMsg}`));
|
||
}
|
||
});
|
||
});
|
||
} |