api.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. "use strict";
  2. const common_vendor = require("../common/vendor.js");
  3. const ENV = "local";
  4. const CONFIG = {
  5. dev: "http://localhost:8081",
  6. // 开发环境
  7. local: "http://10.167.44.71:8081",
  8. prod: "http://192.168.1.2:8081"
  9. // 生产环境
  10. };
  11. const BASE_URL = CONFIG[ENV];
  12. const getImageUrl = (url) => {
  13. if (!url)
  14. return "";
  15. if (url.startsWith("http") || url.startsWith("/static/")) {
  16. return url;
  17. }
  18. return BASE_URL + url;
  19. };
  20. const getToken = () => {
  21. return common_vendor.index.getStorageSync("user_token") || null;
  22. };
  23. const request = (options) => {
  24. return new Promise((resolve, reject) => {
  25. const token = getToken();
  26. const header = options.header || {};
  27. if (token) {
  28. header["Authorization"] = `Bearer ${token}`;
  29. }
  30. common_vendor.index.request({
  31. url: `${BASE_URL}${options.url}`,
  32. method: options.method || "GET",
  33. data: options.data || {},
  34. header,
  35. success: (res) => {
  36. const newToken = res.header["New-Token"] || res.header["new-token"];
  37. if (newToken) {
  38. console.log("检测到新token,自动续期");
  39. common_vendor.index.setStorageSync("user_token", newToken);
  40. }
  41. if (res.statusCode === 200) {
  42. resolve(res.data);
  43. } else if (res.statusCode === 401) {
  44. common_vendor.index.showToast({
  45. title: "登录已过期,请重新登录",
  46. icon: "none",
  47. duration: 2e3
  48. });
  49. common_vendor.index.removeStorageSync("user_token");
  50. common_vendor.index.removeStorageSync("user_info");
  51. setTimeout(() => {
  52. common_vendor.index.showModal({
  53. title: "登录提示",
  54. content: '登录已过期,请前往"模拟排名"或"强势池"页面重新登录',
  55. confirmText: "去登录",
  56. cancelText: "取消",
  57. success: (modalRes) => {
  58. if (modalRes.confirm) {
  59. common_vendor.index.switchTab({
  60. url: "/pages/rank/rank"
  61. });
  62. }
  63. }
  64. });
  65. }, 2e3);
  66. reject(new Error("未授权"));
  67. } else {
  68. reject(new Error(res.data.message || "服务暂不可用"));
  69. }
  70. },
  71. fail: (err) => {
  72. reject(new Error("网络异常"));
  73. }
  74. });
  75. });
  76. };
  77. const wxSilentLoginApi = (params) => {
  78. return request({
  79. url: "/v1/auth/wx/silent-login",
  80. method: "POST",
  81. header: {
  82. "content-type": "application/json"
  83. },
  84. data: params
  85. });
  86. };
  87. const wxPhoneLoginApi = (params) => {
  88. return request({
  89. url: "/v1/auth/wx/phone-verify",
  90. method: "POST",
  91. header: {
  92. "content-type": "application/json"
  93. },
  94. data: params
  95. });
  96. };
  97. const wxCompleteUserInfoApi = (params) => {
  98. return request({
  99. url: "/v1/auth/wx/register",
  100. method: "POST",
  101. header: {
  102. "content-type": "application/json"
  103. },
  104. data: params
  105. });
  106. };
  107. const getUserInfoApi = () => {
  108. return request({
  109. url: "/v1/user/info",
  110. method: "GET"
  111. });
  112. };
  113. const uploadFile = {
  114. url: `${BASE_URL}/v1/file/upload`
  115. };
  116. const updateUserProfile = (data) => {
  117. return request({
  118. url: "/v1/user/profile",
  119. method: "PUT",
  120. header: {
  121. "content-type": "application/json"
  122. },
  123. data
  124. });
  125. };
  126. const getSuggestions = (keyword) => {
  127. return request({
  128. url: "/v1/stock/suggestion",
  129. method: "GET",
  130. data: { keyword }
  131. });
  132. };
  133. const searchStocks = (keyword) => {
  134. return request({
  135. url: "/v1/stock/search",
  136. method: "POST",
  137. header: {
  138. "content-type": "application/json"
  139. },
  140. data: { keyword }
  141. });
  142. };
  143. const getStockQuotes = (codes) => {
  144. return request({
  145. url: "/api/stock/fetch",
  146. method: "GET",
  147. data: { codes }
  148. });
  149. };
  150. const getIndexQuote = (code) => {
  151. return request({
  152. url: "/api/stock/index",
  153. method: "GET",
  154. data: { code }
  155. });
  156. };
  157. const getUserStocks = () => {
  158. return request({
  159. url: "/v1/user/stock/list",
  160. method: "GET"
  161. });
  162. };
  163. const addUserStock = (data) => {
  164. return request({
  165. url: "/v1/user/stock/add",
  166. method: "POST",
  167. header: {
  168. "content-type": "application/json"
  169. },
  170. data
  171. });
  172. };
  173. const deleteUserStock = (stockCode) => {
  174. return request({
  175. url: `/v1/user/stock/delete?stockCode=${encodeURIComponent(stockCode)}`,
  176. method: "DELETE"
  177. });
  178. };
  179. const getStockPoolList = (poolType) => {
  180. return request({
  181. url: "/v1/stock/pool/list",
  182. method: "GET",
  183. data: { poolType }
  184. });
  185. };
  186. const getPaymentConfig = (poolType) => {
  187. return request({
  188. url: "/v1/order/config",
  189. method: "GET",
  190. data: { poolType }
  191. });
  192. };
  193. const createOrder = (data) => {
  194. return request({
  195. url: "/v1/order/create",
  196. method: "POST",
  197. header: {
  198. "content-type": "application/json"
  199. },
  200. data
  201. });
  202. };
  203. const queryOrder = (orderNo) => {
  204. return request({
  205. url: "/v1/order/query",
  206. method: "GET",
  207. data: { orderNo }
  208. });
  209. };
  210. const getUserOrders = () => {
  211. return request({
  212. url: "/v1/order/list",
  213. method: "GET"
  214. });
  215. };
  216. const repayOrder = (orderNo) => {
  217. return request({
  218. url: `/v1/order/repay?orderNo=${encodeURIComponent(orderNo)}`,
  219. method: "POST"
  220. });
  221. };
  222. const checkSubscription = (poolType) => {
  223. return request({
  224. url: "/v1/order/check-subscription",
  225. method: "GET",
  226. data: { poolType }
  227. });
  228. };
  229. const wxPay = (payParams) => {
  230. const totalFee = payParams.total_fee || payParams.totalFee;
  231. console.log("调起支付,参数:", JSON.stringify(payParams), "totalFee:", totalFee);
  232. if (!totalFee) {
  233. console.error("缺少 total_fee 参数,payParams:", payParams);
  234. }
  235. return new Promise((resolve, reject) => {
  236. common_vendor.index.requestPayment({
  237. provider: "wxpay",
  238. timeStamp: payParams.timeStamp,
  239. nonceStr: payParams.nonceStr,
  240. package: payParams.packageValue,
  241. signType: payParams.signType,
  242. paySign: payParams.paySign,
  243. totalFee,
  244. // 开发者工具模拟支付需要
  245. success: (res) => {
  246. resolve(res);
  247. },
  248. fail: (err) => {
  249. console.log("支付失败:", err);
  250. if (err.errMsg && err.errMsg.includes("cancel")) {
  251. reject(new Error("用户取消支付"));
  252. } else {
  253. reject(new Error("支付失败:" + (err.errMsg || JSON.stringify(err))));
  254. }
  255. }
  256. });
  257. });
  258. };
  259. const getStockHistory = (params) => {
  260. return request({
  261. url: "/v1/stock/history/list",
  262. method: "GET",
  263. data: params
  264. });
  265. };
  266. const getStockHistoryStats = (params) => {
  267. return request({
  268. url: "/v1/stock/history/stats",
  269. method: "GET",
  270. data: params
  271. });
  272. };
  273. const searchStockHistory = (keyword) => {
  274. return request({
  275. url: "/v1/stock/history/search",
  276. method: "GET",
  277. data: { keyword }
  278. });
  279. };
  280. exports.BASE_URL = BASE_URL;
  281. exports.addUserStock = addUserStock;
  282. exports.checkSubscription = checkSubscription;
  283. exports.createOrder = createOrder;
  284. exports.deleteUserStock = deleteUserStock;
  285. exports.getImageUrl = getImageUrl;
  286. exports.getIndexQuote = getIndexQuote;
  287. exports.getPaymentConfig = getPaymentConfig;
  288. exports.getStockHistory = getStockHistory;
  289. exports.getStockHistoryStats = getStockHistoryStats;
  290. exports.getStockPoolList = getStockPoolList;
  291. exports.getStockQuotes = getStockQuotes;
  292. exports.getSuggestions = getSuggestions;
  293. exports.getUserInfoApi = getUserInfoApi;
  294. exports.getUserOrders = getUserOrders;
  295. exports.getUserStocks = getUserStocks;
  296. exports.queryOrder = queryOrder;
  297. exports.repayOrder = repayOrder;
  298. exports.searchStockHistory = searchStockHistory;
  299. exports.searchStocks = searchStocks;
  300. exports.updateUserProfile = updateUserProfile;
  301. exports.uploadFile = uploadFile;
  302. exports.wxCompleteUserInfoApi = wxCompleteUserInfoApi;
  303. exports.wxPay = wxPay;
  304. exports.wxPhoneLoginApi = wxPhoneLoginApi;
  305. exports.wxSilentLoginApi = wxSilentLoginApi;