pay-view.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // 支付界面逻辑
  2. (function() {
  3. let overlay = null;
  4. let container = null;
  5. let closeBtn = null;
  6. let cancelBtn = null;
  7. let itemNameEl = null;
  8. let itemPriceEl = null;
  9. let currentPaymentData = null;
  10. let resolveCallback = null;
  11. function init() {
  12. overlay = document.getElementById('payViewOverlay');
  13. container = document.getElementById('payViewContainer');
  14. closeBtn = document.getElementById('payViewClose');
  15. cancelBtn = document.getElementById('payCancelBtn');
  16. itemNameEl = document.getElementById('payItemName');
  17. itemPriceEl = document.getElementById('payItemPrice');
  18. if (!overlay || !container) {
  19. console.error('[PayView] 支付界面元素未找到');
  20. return;
  21. }
  22. bindEvents();
  23. }
  24. function bindEvents() {
  25. // 关闭按钮 - 点击关闭视为支付成功
  26. if (closeBtn) {
  27. closeBtn.addEventListener('click', handlePaymentSuccess);
  28. }
  29. // 取消按钮 - 点击取消视为支付成功(演示模式)
  30. if (cancelBtn) {
  31. cancelBtn.addEventListener('click', handlePaymentSuccess);
  32. }
  33. // 点击遮罩层关闭 - 视为支付成功
  34. if (overlay) {
  35. overlay.addEventListener('click', (e) => {
  36. if (e.target === overlay) {
  37. handlePaymentSuccess();
  38. }
  39. });
  40. }
  41. // ESC 键关闭 - 视为支付成功
  42. document.addEventListener('keydown', (e) => {
  43. if (e.key === 'Escape' && overlay && overlay.classList.contains('show')) {
  44. handlePaymentSuccess();
  45. }
  46. });
  47. // 监听来自父窗口的消息
  48. window.addEventListener('message', (event) => {
  49. if (event.data && event.data.type === 'open-pay-view') {
  50. show(event.data.itemName, event.data.price, event.data.resourcePath, event.data.categoryDir);
  51. }
  52. });
  53. }
  54. function show(itemName, price, resourcePath, categoryDir) {
  55. if (!overlay) {
  56. init();
  57. }
  58. // 保存支付数据
  59. currentPaymentData = {
  60. itemName,
  61. price,
  62. resourcePath,
  63. categoryDir
  64. };
  65. // 更新显示内容
  66. if (itemNameEl) {
  67. itemNameEl.textContent = itemName;
  68. }
  69. if (itemPriceEl) {
  70. itemPriceEl.textContent = `¥${price}`;
  71. }
  72. // 显示支付界面
  73. overlay.classList.add('show');
  74. overlay.style.pointerEvents = 'auto';
  75. // 返回 Promise,等待支付结果
  76. return new Promise((resolve) => {
  77. resolveCallback = resolve;
  78. });
  79. }
  80. function hide() {
  81. if (overlay) {
  82. overlay.classList.remove('show');
  83. // 确保遮罩层不会阻止点击
  84. overlay.style.pointerEvents = 'none';
  85. }
  86. currentPaymentData = null;
  87. resolveCallback = null;
  88. }
  89. async function handlePaymentSuccess() {
  90. if (!currentPaymentData) {
  91. hide();
  92. return;
  93. }
  94. try {
  95. // 调用支付成功 API
  96. const username = getCurrentUsername();
  97. if (!username) {
  98. alert('请先登录');
  99. hide();
  100. if (resolveCallback) {
  101. resolveCallback({ success: false, message: '未登录' });
  102. }
  103. return;
  104. }
  105. const response = await fetch('/api/pay/purchase', {
  106. method: 'POST',
  107. headers: {
  108. 'Content-Type': 'application/json'
  109. },
  110. body: JSON.stringify({
  111. username: username,
  112. resourcePath: currentPaymentData.resourcePath,
  113. categoryDir: currentPaymentData.categoryDir,
  114. itemName: currentPaymentData.itemName,
  115. price: currentPaymentData.price
  116. })
  117. });
  118. const result = await response.json();
  119. if (result.success) {
  120. // 支付成功,通知父窗口
  121. if (window.parent && window.parent !== window) {
  122. window.parent.postMessage({
  123. type: 'payment-success',
  124. itemName: currentPaymentData.itemName
  125. }, '*');
  126. // 通知父窗口关闭支付界面 iframe
  127. window.parent.postMessage({
  128. type: 'close-pay-view'
  129. }, '*');
  130. }
  131. // 显示成功提示
  132. if (window.parent && window.parent.HintView) {
  133. window.parent.HintView.success('购买成功!文件已添加到网盘', 3000);
  134. }
  135. hide();
  136. if (resolveCallback) {
  137. resolveCallback({ success: true, result });
  138. }
  139. } else {
  140. // 支付失败
  141. if (window.parent && window.parent.HintView) {
  142. window.parent.HintView.error(result.message || '购买失败', 3000);
  143. }
  144. // 通知父窗口关闭支付界面 iframe
  145. if (window.parent && window.parent !== window) {
  146. window.parent.postMessage({
  147. type: 'close-pay-view'
  148. }, '*');
  149. }
  150. hide();
  151. if (resolveCallback) {
  152. resolveCallback({ success: false, message: result.message });
  153. }
  154. }
  155. } catch (error) {
  156. console.error('[PayView] 支付处理失败:', error);
  157. if (window.parent && window.parent.HintView) {
  158. window.parent.HintView.error('购买失败,请稍后重试', 3000);
  159. }
  160. // 通知父窗口关闭支付界面 iframe
  161. if (window.parent && window.parent !== window) {
  162. window.parent.postMessage({
  163. type: 'close-pay-view'
  164. }, '*');
  165. }
  166. hide();
  167. if (resolveCallback) {
  168. resolveCallback({ success: false, message: error.message });
  169. }
  170. }
  171. }
  172. // 获取当前登录用户名
  173. function getCurrentUsername() {
  174. try {
  175. const loginDataStr = localStorage.getItem('loginData');
  176. if (!loginDataStr) {
  177. return null;
  178. }
  179. const loginData = JSON.parse(loginDataStr);
  180. const now = Date.now();
  181. // 检查是否过期
  182. if (now >= loginData.expireTime) {
  183. localStorage.removeItem('loginData');
  184. return null;
  185. }
  186. return loginData.user ? loginData.user.username : null;
  187. } catch (error) {
  188. console.error('[PayView] 获取用户名失败:', error);
  189. return null;
  190. }
  191. }
  192. // 导出全局函数
  193. window.PayView = {
  194. show: show,
  195. hide: hide
  196. };
  197. // 初始化
  198. if (document.readyState === 'loading') {
  199. document.addEventListener('DOMContentLoaded', init);
  200. } else {
  201. init();
  202. }
  203. })();