strong.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. "use strict";
  2. const common_vendor = require("../../common/vendor.js");
  3. const utils_auth = require("../../utils/auth.js");
  4. const utils_api = require("../../utils/api.js");
  5. if (!Math) {
  6. (HistorySearchCard + PurchaseModal)();
  7. }
  8. const PurchaseModal = () => "../../components/PurchaseModal.js";
  9. const HistorySearchCard = () => "../../components/HistorySearchCard.js";
  10. const _sfc_main = {
  11. __name: "strong",
  12. setup(__props) {
  13. const isPurchased = common_vendor.ref(false);
  14. const showModal = common_vendor.ref(false);
  15. const isPageVisible = common_vendor.ref(false);
  16. const strongPrice = common_vendor.ref(98);
  17. const stockList = common_vendor.ref([]);
  18. let refreshTimer = null;
  19. const getChangeClass = (changePercent) => {
  20. if (!changePercent || changePercent === "-")
  21. return "";
  22. return changePercent.startsWith("+") ? "text-red" : "text-green";
  23. };
  24. const getRandomInterval = () => 2e3 + Math.random() * 1e3;
  25. const startAutoRefresh = () => {
  26. if (!isPageVisible.value)
  27. return;
  28. stopAutoRefresh();
  29. const scheduleNextRefresh = () => {
  30. if (!isPageVisible.value) {
  31. stopAutoRefresh();
  32. return;
  33. }
  34. refreshTimer = setTimeout(async () => {
  35. if (!isPageVisible.value) {
  36. stopAutoRefresh();
  37. return;
  38. }
  39. await loadStockPool();
  40. scheduleNextRefresh();
  41. }, getRandomInterval());
  42. };
  43. scheduleNextRefresh();
  44. };
  45. const stopAutoRefresh = () => {
  46. if (refreshTimer) {
  47. clearTimeout(refreshTimer);
  48. refreshTimer = null;
  49. }
  50. };
  51. const checkPurchaseStatus = async () => {
  52. if (!utils_auth.isLoggedIn()) {
  53. isPurchased.value = false;
  54. stopAutoRefresh();
  55. return;
  56. }
  57. try {
  58. const res = await utils_api.checkSubscription(2);
  59. if (res.code === 200 && res.data.hasSubscription) {
  60. isPurchased.value = true;
  61. loadAndStartRefresh();
  62. } else {
  63. isPurchased.value = false;
  64. stopAutoRefresh();
  65. }
  66. } catch (e) {
  67. console.error("检查订阅状态失败:", e);
  68. isPurchased.value = false;
  69. stopAutoRefresh();
  70. }
  71. };
  72. const loadStockPool = async () => {
  73. try {
  74. const res = await utils_api.getStockPoolList(2);
  75. if (res.code === 200 && res.data) {
  76. stockList.value = res.data;
  77. }
  78. } catch (e) {
  79. console.error("加载标的池失败:", e);
  80. }
  81. };
  82. const loadAndStartRefresh = async () => {
  83. await loadStockPool();
  84. startAutoRefresh();
  85. };
  86. const showPurchaseModal = async () => {
  87. if (!utils_auth.isLoggedIn()) {
  88. common_vendor.index.showModal({
  89. title: "登录提示",
  90. content: "此功能需要登录后使用,是否前往登录?",
  91. confirmText: "去登录",
  92. cancelText: "取消",
  93. success: (res) => {
  94. if (res.confirm) {
  95. common_vendor.index.navigateTo({ url: "/pages/login/login" });
  96. }
  97. }
  98. });
  99. return;
  100. }
  101. try {
  102. const res = await utils_api.getPaymentConfig(2);
  103. if (res.code === 200 && res.data) {
  104. strongPrice.value = res.data.price || 98;
  105. }
  106. } catch (e) {
  107. console.error("获取价格配置失败:", e);
  108. }
  109. showModal.value = true;
  110. };
  111. const closePurchaseModal = () => {
  112. showModal.value = false;
  113. };
  114. const pollOrderStatus = async (orderNo, maxRetries = 5, interval = 1e3) => {
  115. for (let i = 0; i < maxRetries; i++) {
  116. try {
  117. const res = await utils_api.queryOrder(orderNo);
  118. if (res.code === 200 && res.data && res.data.orderStatus === 1) {
  119. return true;
  120. }
  121. } catch (e) {
  122. console.log("查询订单状态失败:", e);
  123. }
  124. if (i < maxRetries - 1) {
  125. await new Promise((r) => setTimeout(r, interval));
  126. }
  127. }
  128. return false;
  129. };
  130. const handlePurchase = async () => {
  131. try {
  132. common_vendor.index.showLoading({ title: "正在支付..." });
  133. const res = await utils_api.createOrder({ poolType: 2 });
  134. if (res.code !== 200) {
  135. throw new Error(res.message || "创建订单失败");
  136. }
  137. const orderNo = res.data.orderNo;
  138. common_vendor.index.hideLoading();
  139. await utils_api.wxPay(res.data);
  140. common_vendor.index.showLoading({ title: "确认支付结果..." });
  141. const confirmed = await pollOrderStatus(orderNo);
  142. common_vendor.index.hideLoading();
  143. if (confirmed) {
  144. isPurchased.value = true;
  145. closePurchaseModal();
  146. common_vendor.index.showToast({ title: "支付成功", icon: "success" });
  147. loadAndStartRefresh();
  148. } else {
  149. closePurchaseModal();
  150. common_vendor.index.showToast({ title: "支付处理中,请稍后刷新", icon: "none" });
  151. }
  152. } catch (e) {
  153. common_vendor.index.hideLoading();
  154. common_vendor.index.showToast({ title: e.message || "支付失败", icon: "none" });
  155. }
  156. };
  157. const addToMyStocks = async (stock) => {
  158. const tokenDirect = common_vendor.index.getStorageSync("user_token");
  159. console.log("[强势池] 点击自选 - 直接读取token:", tokenDirect ? "有值" : "空");
  160. console.log("[强势池] 点击自选 - checkLoginStatus():", utils_auth.isLoggedIn());
  161. if (!utils_auth.isLoggedIn()) {
  162. common_vendor.index.showModal({
  163. title: "登录提示",
  164. content: "添加自选需要登录,是否前往登录?",
  165. confirmText: "去登录",
  166. cancelText: "取消",
  167. success: (res) => {
  168. if (res.confirm) {
  169. common_vendor.index.navigateTo({ url: "/pages/login/login" });
  170. }
  171. }
  172. });
  173. return;
  174. }
  175. try {
  176. common_vendor.index.showLoading({ title: "添加中..." });
  177. let currentPrice = null;
  178. try {
  179. const quoteRes = await utils_api.getStockQuotes(stock.code);
  180. if (quoteRes.code === 200 && quoteRes.data && quoteRes.data.length > 0) {
  181. currentPrice = quoteRes.data[0].currentPrice;
  182. }
  183. } catch (e) {
  184. console.error("获取行情数据失败:", e);
  185. }
  186. const addRes = await utils_api.addUserStock({
  187. stockCode: stock.code,
  188. stockName: stock.name,
  189. currentPrice,
  190. poolType: 2
  191. // 强势池
  192. });
  193. common_vendor.index.hideLoading();
  194. if (addRes.code === 200 && addRes.data === true) {
  195. common_vendor.index.showToast({ title: "添加成功", icon: "success" });
  196. } else if (addRes.code === 200 && addRes.data === false) {
  197. common_vendor.index.showToast({ title: "标的已存在", icon: "none" });
  198. } else {
  199. common_vendor.index.showToast({ title: addRes.message || "添加失败", icon: "none" });
  200. }
  201. } catch (e) {
  202. common_vendor.index.hideLoading();
  203. console.error("添加标的失败:", e);
  204. common_vendor.index.showToast({ title: "添加失败", icon: "none" });
  205. }
  206. };
  207. common_vendor.onLoad(() => {
  208. console.log("[强势池] onLoad");
  209. isPageVisible.value = true;
  210. checkPurchaseStatus();
  211. });
  212. common_vendor.onShow(() => {
  213. console.log("[强势池] onShow");
  214. isPageVisible.value = true;
  215. checkPurchaseStatus();
  216. common_vendor.index.setNavigationBarTitle({ title: "量化交易大师" });
  217. });
  218. common_vendor.onHide(() => {
  219. console.log("[强势池] onHide");
  220. isPageVisible.value = false;
  221. stopAutoRefresh();
  222. });
  223. common_vendor.onUnmounted(() => {
  224. isPageVisible.value = false;
  225. stopAutoRefresh();
  226. });
  227. return (_ctx, _cache) => {
  228. return common_vendor.e({
  229. a: !isPurchased.value
  230. }, !isPurchased.value ? {
  231. b: common_vendor.o(showPurchaseModal)
  232. } : {
  233. c: common_vendor.f(stockList.value, (stock, index, i0) => {
  234. return {
  235. a: common_vendor.t(stock.name),
  236. b: common_vendor.t(stock.code),
  237. c: common_vendor.t(stock.currentPrice || "-"),
  238. d: common_vendor.t(stock.changePercent || "-"),
  239. e: common_vendor.n(getChangeClass(stock.changePercent)),
  240. f: common_vendor.o(($event) => addToMyStocks(stock), index),
  241. g: index
  242. };
  243. })
  244. }, {
  245. d: common_vendor.p({
  246. poolType: 2,
  247. canSearch: isPurchased.value
  248. }),
  249. e: common_vendor.o(closePurchaseModal),
  250. f: common_vendor.o(handlePurchase),
  251. g: common_vendor.p({
  252. visible: showModal.value,
  253. icon: "📅",
  254. title: "年订阅解锁",
  255. description: "订阅全年,解锁强势趋势池内容",
  256. amountLabel: "订阅金额:",
  257. amount: strongPrice.value
  258. })
  259. });
  260. };
  261. }
  262. };
  263. const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__file", "D:/program/gupiao/gupiao-wx/src/pages/strong/strong.vue"]]);
  264. wx.createPage(MiniProgramPage);