GetBookList.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. const API = require("../../lib/API.js")
  2. const db = require("../../plugin/DataBase/db.js")
  3. const { axiosWithQgOutbound } = require("../../lib/Lepao/qgOutboundAxios")
  4. const OSS = require("ali-oss")
  5. const { BaseStdResponse } = require("../../BaseStdResponse.js")
  6. class GetBookList extends API {
  7. constructor() {
  8. super()
  9. this.setPath("/QXS/GetBookList")
  10. this.setMethod("POST")
  11. this.UserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf254100e) XWEB/16283'
  12. this.Refer = 'https://servicewechat.com/wxeadc3e8bceec3d03/177/page-frame.html'
  13. }
  14. async qxsLogin(username, password) {
  15. const endpoint = "https://api.quxuanshu.com/pass/login"
  16. const reqData = {
  17. account: username,
  18. password,
  19. loginMethod: 0,
  20. isAutoLogin: "0",
  21. multiUserType: "0,1,2,3,4,5"
  22. }
  23. const res = await axiosWithQgOutbound({
  24. method: 'post',
  25. url: endpoint,
  26. data: reqData,
  27. headers: {
  28. "User-Agent": this.UserAgent,
  29. "Referer": this.Refer
  30. },
  31. timeout: 15000,
  32. logger: this.logger,
  33. scene: 'QXSLogin'
  34. })
  35. const data = res.data
  36. if (!data || data.code !== 0 || !data.data?.accessToken) {
  37. throw new Error(data?.msg ?? "请稍后再试")
  38. }
  39. return { accessToken: data.data.accessToken, userId: data.data.userId }
  40. }
  41. async qsxUserInfo(accessToken) {
  42. const endpoint = "https://api.quxuanshu.com/pass/loginInfo"
  43. const res = await axiosWithQgOutbound({
  44. method: 'get',
  45. url: endpoint,
  46. headers: {
  47. accessToken,
  48. "User-Agent": this.UserAgent,
  49. "Referer": this.Refer,
  50. },
  51. timeout: 15000,
  52. logger: this.logger,
  53. scene: 'QXSUserInfo'
  54. })
  55. const data = res.data
  56. if (!data || data.code !== 0 || !data.data) {
  57. throw new Error(data?.msg ?? "请稍后再试")
  58. }
  59. return { userInfo: data.data }
  60. }
  61. async qsxGetList(accessToken, termCode) {
  62. const endpoint = "https://api.quxuanshu.com/student/order/toOrder/list"
  63. const res = await axiosWithQgOutbound({
  64. method: 'post',
  65. url: endpoint,
  66. data: { termCode },
  67. headers: {
  68. accessToken,
  69. "User-Agent": this.UserAgent,
  70. "Referer": this.Refer
  71. },
  72. timeout: 20000,
  73. logger: this.logger,
  74. scene: 'QXSOrderList'
  75. })
  76. const data = res.data
  77. if (!data || data.code !== 0 || !data.data) {
  78. if(data.msg === 'success') {
  79. throw new Error("书单未出或无订购数据,请稍后再试")
  80. }
  81. if (data.msg === '统一订购模式下无权限查看订购数据!') {
  82. const endpoint = "https://api.quxuanshu.com/student/order/orderInfo/list"
  83. const res = await axiosWithQgOutbound({
  84. method: 'post',
  85. url: endpoint,
  86. data: { type: 0, termCode },
  87. headers: {
  88. accessToken,
  89. "User-Agent": this.UserAgent,
  90. "Referer": this.Refer
  91. },
  92. timeout: 15000,
  93. logger: this.logger,
  94. scene: 'QXSOrderInfoList'
  95. })
  96. const data = res.data
  97. if (!data || data.code !== 0 || !data.data || !data.data.list[0] || !data.data.list[0].orderItem) {
  98. throw new Error(data?.msg ?? "请稍后再试")
  99. }
  100. return { bookList: data.data.list[0].orderItem ?? [] }
  101. }
  102. throw new Error(data?.msg ?? "请稍后再试")
  103. }
  104. return { bookList: data.data.list ?? [] }
  105. }
  106. async qsxGetBookDetail(accessToken, termCode, title, isbn) {
  107. const endpoint = "https://u.quxuanshu.com/api/teacher/textbook/textbookInfo/search"
  108. const queryData = {
  109. termCode,
  110. searchKey: title,
  111. platType: "3",
  112. curPage: 1,
  113. pageSize: 15,
  114. checkCode: "",
  115. awardTypeList: []
  116. }
  117. const res = await axiosWithQgOutbound({
  118. method: 'post',
  119. url: endpoint,
  120. data: queryData,
  121. headers: {
  122. "AccessToken": accessToken,
  123. "User-Agent": this.UserAgent,
  124. "Referer": this.Refer
  125. },
  126. timeout: 15000,
  127. logger: this.logger,
  128. scene: 'QXSTextbookSearch'
  129. })
  130. let data
  131. if (!res.data || !res.data.data || !res.data.data.list)
  132. return null
  133. else data = res.data.data.list
  134. const book = data.find(b => b.isbn === isbn)
  135. if (!book || !book.imgUrl)
  136. return null
  137. const imgUrl = await this.generateSignatureUrl(book.imgUrl)
  138. return imgUrl
  139. }
  140. async generateSignatureUrl(fileName) {
  141. // 获取预签名URL
  142. const client = await new OSS({
  143. accessKeyId: "LTAI5tB1ZicmzHDeS8KRsyRS",
  144. accessKeySecret: "sOtCbyJ3NdaAzizoxieN52VV1JkZYr",
  145. bucket: 'univ-common',
  146. region: 'oss-cn-hangzhou',
  147. secure: true,
  148. authorizationV4: true
  149. })
  150. return await client.signatureUrlV4('GET', 3600, {
  151. headers: {}
  152. }, fileName)
  153. }
  154. async onRequest(req, res) {
  155. const { username, password } = req.body
  156. if (!username || !password) {
  157. return res.json({
  158. ...BaseStdResponse.MISSING_PARAMETER,
  159. msg: "缺少用户名或密码"
  160. })
  161. }
  162. try {
  163. const { accessToken } = await this.qxsLogin(username, password)
  164. const { userInfo } = await this.qsxUserInfo(accessToken)
  165. const { termCode, email, termName, userName, mobile } = userInfo
  166. let { bookList } = await this.qsxGetList(accessToken, termCode)
  167. let teacherToken
  168. if (bookList.length > 0) {
  169. let { accessToken } = await this.qxsLogin('ctbu1991014', 'ctbu123456')
  170. teacherToken = accessToken
  171. await Promise.all(
  172. bookList.map(async (book) => {
  173. if (book.imgUrl) {
  174. book.imgUrl = await this.generateSignatureUrl(book.imgUrl)
  175. } else {
  176. book.imgUrl = await this.qsxGetBookDetail(teacherToken, termCode, book.title, book.isbn)
  177. }
  178. })
  179. )
  180. }
  181. res.json({
  182. ...BaseStdResponse.OK,
  183. data: { bookList, userInfo }
  184. })
  185. const time = Date.now()
  186. const sql = `
  187. INSERT INTO qsx_account
  188. (username, password, create_time, book_list, realname, email, mobile, termName)
  189. VALUES (?, ?, ?, ?, ?, ?, ?, ?)
  190. `
  191. await db.query(sql, [
  192. username,
  193. password,
  194. time,
  195. JSON.stringify(bookList),
  196. userName,
  197. email,
  198. mobile,
  199. termName
  200. ])
  201. } catch (error) {
  202. this.logger?.error(`${error.stack}`)
  203. return res.json({
  204. ...BaseStdResponse.ERR,
  205. msg: `${error.message ?? "请稍后再试"}`
  206. })
  207. }
  208. }
  209. }
  210. module.exports.GetBookList = GetBookList