429 lines
13 KiB
JavaScript
429 lines
13 KiB
JavaScript
/**
|
||
* 孔夫子网 API - 登录与商品操作
|
||
*/
|
||
|
||
/**
|
||
* 登录孔夫子(从响应Cookie中提取PHPSESSID)
|
||
* @param {string} username 用户名(手机号)
|
||
* @param {string} password 明文密码
|
||
* @returns {Promise<{success: boolean, token: string, message: string}>}
|
||
*/
|
||
export function login(username, password) {
|
||
return new Promise((resolve, reject) => {
|
||
uni.request({
|
||
url: 'https://login.kongfz.com/Pc/Login/account',
|
||
method: 'POST',
|
||
header: {
|
||
'Content-Type': 'application/x-www-form-urlencoded',
|
||
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148'
|
||
},
|
||
data: {
|
||
loginName: username,
|
||
loginPass: password,
|
||
autoLogin: '0',
|
||
returnUrl: 'http://user.kongfz.com/'
|
||
},
|
||
success: (res) => {
|
||
console.log('孔夫子登录响应 status:', res.statusCode)
|
||
console.log('孔夫子登录响应 header:', JSON.stringify(res.header))
|
||
console.log('孔夫子登录响应 data:', typeof res.data === 'string' ? res.data.substring(0, 500) : JSON.stringify(res.data))
|
||
|
||
// 提取PHPSESSID
|
||
let phpsessid = ''
|
||
const setCookie = res.header['Set-Cookie'] || res.header['set-cookie']
|
||
if (setCookie) {
|
||
const match = setCookie.match(/PHPSESSID=([^;]+)/)
|
||
if (match) {
|
||
phpsessid = match[1]
|
||
}
|
||
}
|
||
|
||
const responseText = typeof res.data === 'string' ? res.data : JSON.stringify(res.data)
|
||
const isSuccess = responseText.includes('login.kongfz.cn/Pc/Session/rsync') ||
|
||
responseText.includes('window.location.href') ||
|
||
res.statusCode === 302 ||
|
||
(res.statusCode === 200 && phpsessid)
|
||
|
||
if (isSuccess && phpsessid) {
|
||
resolve({
|
||
success: true,
|
||
token: phpsessid,
|
||
message: '登录成功'
|
||
})
|
||
} else if (res.statusCode === 200 && responseText.includes('errCode')) {
|
||
try {
|
||
const json = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
|
||
if (json.errCode === 1001) {
|
||
resolve({ success: false, token: '', message: json.errInfo || '账号或密码错误' })
|
||
} else if (json.errCode === 1005) {
|
||
resolve({ success: false, token: '', message: json.errInfo || '密码错误' })
|
||
} else if (json.errCode === 1009) {
|
||
resolve({ success: false, token: '', message: json.errInfo || '调用次数已达上限,请稍后再试' })
|
||
} else {
|
||
resolve({ success: false, token: '', message: json.errInfo || '登录失败' })
|
||
}
|
||
} catch (e) {
|
||
resolve({ success: false, token: '', message: '登录失败,请检查账号密码' })
|
||
}
|
||
} else {
|
||
resolve({ success: false, token: '', message: '登录失败,请检查网络和账号密码' })
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('孔夫子登录请求失败:', err)
|
||
resolve({ success: false, token: '', message: '网络请求失败,请检查网络连接' })
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 搜索孔夫子商品品相统计(全新/古旧等)
|
||
* @param {string} keyword ISBN或书名
|
||
* @param {object} options {phpsessid, userArea, dataType} dataType=0在售 / 1已售
|
||
* @returns {Promise<{newCount: number, oldCount: number, totalFound: number}>}
|
||
*/
|
||
export function searchFacet(keyword, options = {}) {
|
||
const { phpsessid = '', userArea = '1006000000', dataType = 0 } = options
|
||
return new Promise((resolve, reject) => {
|
||
uni.request({
|
||
url: 'https://search.kongfz.com/pc-gw/search-web/client/pc/product/keyword/normal/facet',
|
||
method: 'GET',
|
||
data: {
|
||
dataType: dataType,
|
||
keyword: keyword,
|
||
page: 1,
|
||
userArea: userArea
|
||
},
|
||
header: {
|
||
'Cookie': phpsessid ? `PHPSESSID=${phpsessid}` : ''
|
||
},
|
||
success: (res) => {
|
||
console.log('孔夫子统计响应:', res.statusCode, res.data)
|
||
if (res.statusCode === 200 && res.data && res.data.status === 1 && res.data.data) {
|
||
const qualities = res.data.data.qualities || []
|
||
let newCount = 0
|
||
let oldCount = 0
|
||
qualities.forEach(q => {
|
||
if (q.showName === '全新') {
|
||
newCount = parseInt(q.showValue || 0, 10)
|
||
}
|
||
if (q.showName === '古 | 旧 | 二手') {
|
||
oldCount = parseInt(q.showValue || 0, 10)
|
||
}
|
||
})
|
||
const totalFound = parseInt(res.data.data.totalFoundText || res.data.data.matchInfo?.totalFound || 0, 10)
|
||
resolve({ newCount, oldCount, totalFound })
|
||
} else if (res.statusCode === 200 && res.data && res.data.status === 0 && res.data.errType === '102') {
|
||
console.warn('孔夫子统计-会话过期,需要重新登录')
|
||
reject(new Error('KONGZ_SESSION_EXPIRED'))
|
||
} else {
|
||
resolve({ newCount: 0, oldCount: 0, totalFound: 0 })
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('孔夫子统计失败:', err)
|
||
resolve({ newCount: 0, oldCount: 0, totalFound: 0 })
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 获取商品列表(分页)
|
||
*/
|
||
export function fetchItems(token, params = {}, onProgress) {
|
||
const items = []
|
||
const pageSize = 50
|
||
let currentPage = 1
|
||
|
||
return new Promise((resolve, reject) => {
|
||
const fetchPage = (page) => {
|
||
const requestBody = {
|
||
requestType: 'onSale',
|
||
page: page,
|
||
size: pageSize
|
||
}
|
||
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
|
||
|
||
uni.request({
|
||
url: 'https://seller.kongfz.com/pc-gw/book-manage-service/client/pc/goods/unSold/list',
|
||
method: 'POST',
|
||
header: {
|
||
'Content-Type': 'application/json',
|
||
'Cookie': `PHPSESSID=${token}`,
|
||
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148'
|
||
},
|
||
data: requestBody,
|
||
success: (res) => {
|
||
if (res.data && res.data.data && res.data.data.list) {
|
||
const list = res.data.data.list
|
||
items.push(...list.map(item => ({ id: item.itemId || item.id, status: 'wait' })))
|
||
if (onProgress) onProgress(items.length, res.data.data.total || 0)
|
||
|
||
if (list.length >= pageSize) {
|
||
currentPage++
|
||
setTimeout(() => fetchPage(currentPage), 1000)
|
||
} else {
|
||
resolve(items)
|
||
}
|
||
} else {
|
||
resolve(items)
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取商品列表失败:', err)
|
||
reject(err)
|
||
}
|
||
})
|
||
}
|
||
fetchPage(currentPage)
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 搜索孔夫子在售商品(需要登录Cookie)
|
||
* @param {string} keyword ISBN或书名
|
||
* @param {object} options {phpsessid, page}
|
||
* @returns {Promise<{total: number, list: Array}>}
|
||
* list中每项: {id, title, author, press, priceText, imgBigUrl, shopName, qualityText, pubDateText, postage}
|
||
*/
|
||
export function searchProducts(keyword, options = {}) {
|
||
const { phpsessid = '', page = 1, sortType = '', quality = '', publisher = '', author = '' } = options
|
||
return new Promise((resolve, reject) => {
|
||
const reqData = {
|
||
dataType: 0,
|
||
keyword: keyword,
|
||
page: page,
|
||
userArea: '1006000000'
|
||
}
|
||
const actionPaths = []
|
||
if (sortType) {
|
||
reqData.sortType = sortType
|
||
actionPaths.push('sortType')
|
||
}
|
||
if (quality) {
|
||
reqData.quality = quality
|
||
reqData.quaSelect = '2'
|
||
actionPaths.push('quality')
|
||
}
|
||
if (publisher) {
|
||
reqData.press = publisher
|
||
}
|
||
if (author) {
|
||
reqData.author = author
|
||
}
|
||
if (actionPaths.length > 0) {
|
||
reqData.actionPath = actionPaths.join(',')
|
||
}
|
||
uni.request({
|
||
url: 'https://search.kongfz.com/pc-gw/search-web/client/pc/product/keyword/list',
|
||
method: 'GET',
|
||
data: reqData,
|
||
header: {
|
||
'Cookie': phpsessid ? `PHPSESSID=${phpsessid}` : ''
|
||
},
|
||
success: (res) => {
|
||
console.log('孔夫子在售搜索响应:', res.statusCode, res.data)
|
||
if (res.statusCode === 200 && res.data && res.data.status === 1) {
|
||
const itemResp = res.data.data && res.data.data.itemResponse
|
||
if (itemResp) {
|
||
resolve({
|
||
total: itemResp.total || 0,
|
||
list: itemResp.list || []
|
||
})
|
||
} else {
|
||
resolve({ total: 0, list: [] })
|
||
}
|
||
} else if (res.statusCode === 200 && res.data && res.data.status === 0 && res.data.errType === '102') {
|
||
console.warn('孔夫子搜索-会话过期,需要重新登录')
|
||
reject(new Error('KONGZ_SESSION_EXPIRED'))
|
||
} else {
|
||
resolve({ total: 0, list: [] })
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('孔夫子搜索失败:', err)
|
||
resolve({ total: 0, list: [] })
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 获取孔网图书分类(根据书名搜索孔网 facet 接口)
|
||
* @param {string} keyword 书名
|
||
* @param {object} options { phpsessid, userArea }
|
||
* @returns {Promise<Array<{value:string, showName:string}>>} 图书分类列表(normal组)
|
||
*/
|
||
export function searchCategories(keyword, options = {}) {
|
||
const { phpsessid = '', userArea = '1006000000' } = options
|
||
return new Promise((resolve) => {
|
||
if (!keyword || !keyword.trim()) {
|
||
resolve([])
|
||
return
|
||
}
|
||
uni.request({
|
||
url: 'https://search.kongfz.com/pc-gw/search-web/client/pc/product/keyword/normal/facet',
|
||
method: 'GET',
|
||
data: {
|
||
dataType: 0,
|
||
keyword: keyword.trim(),
|
||
page: 1,
|
||
userArea: userArea
|
||
},
|
||
header: {
|
||
'Cookie': phpsessid ? `PHPSESSID=${phpsessid}` : ''
|
||
},
|
||
success: (res) => {
|
||
if (res.statusCode === 200 && res.data && res.data.status === 1 && res.data.data) {
|
||
var categories = res.data.data.categories || []
|
||
// 找到 normal 组(图书分类)
|
||
var normalGroup = null
|
||
for (var i = 0; i < categories.length; i++) {
|
||
if (categories[i].type === 'GROUP' && categories[i].name === 'normal') {
|
||
normalGroup = categories[i]
|
||
break
|
||
}
|
||
}
|
||
if (normalGroup && normalGroup.subLabels) {
|
||
resolve(normalGroup.subLabels.map(function(item) {
|
||
return { value: item.value, showName: item.showName, showValue: item.showValue }
|
||
}))
|
||
} else {
|
||
resolve([])
|
||
}
|
||
} else {
|
||
resolve([])
|
||
}
|
||
},
|
||
fail: () => {
|
||
resolve([])
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 获取孔网出版社列表(根据书名)
|
||
* @param {string} keyword 书名
|
||
* @param {object} options { phpsessid, userArea }
|
||
* @returns {Promise<Array<{showName:string}>>} 出版社列表
|
||
*/
|
||
export function searchPresses(keyword, options = {}) {
|
||
const { phpsessid = '', userArea = '1006000000' } = options
|
||
return new Promise((resolve) => {
|
||
if (!keyword || !keyword.trim()) {
|
||
resolve([])
|
||
return
|
||
}
|
||
var reqData = {
|
||
requestId: Math.random().toString(36).substring(2, 10),
|
||
platform: 'web',
|
||
searchType: 'keyword',
|
||
dataType: 0,
|
||
keyword: keyword.trim(),
|
||
hasStock: 'true',
|
||
isNewBook: 'false',
|
||
searchMode: 0,
|
||
userArea: userArea,
|
||
page: 1,
|
||
size: 50,
|
||
tplParams: '{}',
|
||
sortType: 0,
|
||
abGroup: 'B',
|
||
filterType: 'press',
|
||
notSelectSearchMode: 'true'
|
||
}
|
||
uni.request({
|
||
url: 'https://search.kongfz.com/pc-gw/search-web/client/pc/product/keyword/more/press/facet',
|
||
method: 'GET',
|
||
data: reqData,
|
||
header: {
|
||
'Cookie': phpsessid ? `PHPSESSID=${phpsessid}` : ''
|
||
},
|
||
success: (res) => {
|
||
if (res.statusCode === 200 && res.data && res.data.status === 1 && res.data.data) {
|
||
var labels = res.data.data.labels || []
|
||
resolve(labels.map(function(item) {
|
||
return { showName: item.showName }
|
||
}))
|
||
} else {
|
||
resolve([])
|
||
}
|
||
},
|
||
fail: () => {
|
||
resolve([])
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 获取孔网作者列表(根据书名)
|
||
* @param {string} keyword 书名
|
||
* @param {object} options { phpsessid, userArea }
|
||
* @returns {Promise<Array<{showName:string}>>} 作者列表
|
||
*/
|
||
export function searchAuthors(keyword, options = {}) {
|
||
const { phpsessid = '', userArea = '1006000000' } = options
|
||
return new Promise((resolve) => {
|
||
if (!keyword || !keyword.trim()) {
|
||
resolve([])
|
||
return
|
||
}
|
||
uni.request({
|
||
url: 'https://search.kongfz.com/pc-gw/search-web/client/pc/product/keyword/more/author/facet',
|
||
method: 'GET',
|
||
data: {
|
||
requestId: Math.random().toString(36).substring(2, 10),
|
||
platform: 'web',
|
||
searchType: 'keyword',
|
||
dataType: 0,
|
||
keyword: keyword.trim(),
|
||
hasStock: 'true',
|
||
isNewBook: 'false',
|
||
searchMode: 0,
|
||
userArea: userArea,
|
||
page: 1,
|
||
size: 50,
|
||
tplParams: '{}',
|
||
sortType: 0,
|
||
abGroup: 'B',
|
||
notSelectSearchMode: 'true',
|
||
filterType: 'author'
|
||
},
|
||
header: {
|
||
'Cookie': phpsessid ? `PHPSESSID=${phpsessid}` : ''
|
||
},
|
||
success: (res) => {
|
||
if (res.statusCode === 200 && res.data && res.data.status === 1 && res.data.data) {
|
||
var labels = res.data.data.labels || []
|
||
resolve(labels.map(function(item) {
|
||
return { showName: item.showName }
|
||
}))
|
||
} else {
|
||
resolve([])
|
||
}
|
||
},
|
||
fail: () => {
|
||
resolve([])
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
export default {
|
||
login,
|
||
searchFacet,
|
||
fetchItems,
|
||
searchProducts,
|
||
searchCategories,
|
||
searchPresses,
|
||
searchAuthors
|
||
}
|