国内市场双十一活动仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

248 lines
6.7 KiB

3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <link rel="icon" href="/favicon.ico" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  7. <title></title>
  8. <style>
  9. * {
  10. margin: 0;
  11. padding: 0;
  12. box-sizing: border-box;
  13. }
  14. body {
  15. font-family: "Microsoft Yahei", sans-serif;
  16. }
  17. /* 落地页 */
  18. .landing-page {
  19. width: 375px;
  20. height: auto;
  21. margin: 0 auto;
  22. overflow-y: auto;
  23. overflow-x: hidden;
  24. }
  25. .landing-page img {
  26. width: 100%;
  27. height: auto;
  28. display: block;
  29. }
  30. /* 弹窗 */
  31. .popup {
  32. display: none;
  33. position: fixed;
  34. top: 0;
  35. left: 0;
  36. width: 100%;
  37. height: 100%;
  38. background: rgba(0, 0, 0, 0.7);
  39. justify-content: center;
  40. align-items: center;
  41. z-index: 999;
  42. }
  43. .popup.show {
  44. display: flex;
  45. }
  46. .popup-content {
  47. width: 320px;
  48. text-align: center;
  49. }
  50. .popup-content img {
  51. width: 100%;
  52. height: auto;
  53. margin-bottom: 15px;
  54. }
  55. .popup-content img#closeBtn {
  56. width: 60%;
  57. margin-bottom: 5px;
  58. }
  59. </style>
  60. </head>
  61. <body>
  62. <!-- 落地页 -->
  63. <div class="landing-page">
  64. <img id="landingImage" />
  65. </div>
  66. <!-- 弹窗样式 -->
  67. <div class="popup" id="popup">
  68. <div class="popup-content">
  69. <img id="popupImage" />
  70. <img src="./assent/开心收下.png" id="closeBtn"/>
  71. </div>
  72. </div>
  73. <script type="module">
  74. // 导入API函数
  75. import { getImageApi, acceptCardApi, getStateApi } from './src/api/member.js';
  76. const userAgent = navigator.userAgent;
  77. // 获取弹窗元素
  78. const landingImage = document.getElementById('landingImage');
  79. const popupImage = document.getElementById('popupImage');
  80. const popup = document.getElementById("popup");
  81. const closeBtn = document.getElementById("closeBtn");
  82. // 防抖多次点击
  83. let isClickable = true;
  84. // 记录页面打开时间
  85. const pageOpenTime = getBeijingTime();
  86. // 获取北京时间(东八区)的函数
  87. function getBeijingTime() {
  88. const date = new Date();
  89. const beijingTime = new Date(date.getTime() + 8 * 60 * 60 * 1000);
  90. return beijingTime.toISOString();
  91. }
  92. // 缓存键名
  93. const CACHE_KEY = 'landing_image';
  94. // 从缓存获取落地图
  95. function getLandingImageFromCache() {
  96. const cached = localStorage.getItem(CACHE_KEY);
  97. return cached ? JSON.parse(cached) : null;
  98. }
  99. // 将落地图存入缓存
  100. function saveLandingImageToCache(imageUrl) {
  101. localStorage.setItem(CACHE_KEY, JSON.stringify({
  102. url: imageUrl,
  103. }));
  104. }
  105. // 获取图片方法
  106. async function getImage() {
  107. try {
  108. const res = await getImageApi({
  109. id:3
  110. });
  111. console.log(res.data)
  112. if (res.code == 200 && res.data) {
  113. return {
  114. landingImageUrl: res.data.list[0].landing_page,
  115. popupImageUrl: res.data.list[0].landing_page_popup,
  116. title: res.data.list[0].name
  117. };
  118. } else {
  119. return {
  120. msg:res.msg
  121. };
  122. }
  123. } catch (error) {
  124. console.error('网络错误,请稍后重试');
  125. return null
  126. }
  127. }
  128. // 加载
  129. window.onload = async function () {
  130. try {
  131. await acceptCardApi({
  132. user_info:userAgent,
  133. state: 0,
  134. });
  135. // 缓存
  136. const cachedImage = getLandingImageFromCache();
  137. // 接口
  138. const imagePaths = await getImage();
  139. // 确定最终落地图和是否展示弹窗
  140. let finalLandingUrl;
  141. let shouldShowPopup = false;
  142. document.title = imagePaths.title?imagePaths.title:imagePaths.msg
  143. if(imagePaths?.msg){
  144. document.body.innerHTML = `
  145. <div style="
  146. display:flex;
  147. align-items:center;
  148. justify-content:center;
  149. height:100vh;
  150. font-size:40px;
  151. color:#333;
  152. font-family:'PingFang SC', 'Microsoft Yahei', Arial, sans-serif;
  153. text-align:center;
  154. padding:20px;
  155. box-sizing:border-box;
  156. ">
  157. ${imagePaths.msg}
  158. </div>
  159. `;
  160. return
  161. }
  162. if (imagePaths?.landingImageUrl) {
  163. finalLandingUrl = imagePaths.landingImageUrl;
  164. // if (!cachedImage || cachedImage.url !== finalLandingUrl) {
  165. // shouldShowPopup = true;
  166. // saveLandingImageToCache(finalLandingUrl);
  167. // popupImage.src = imagePaths.popupImageUrl;
  168. // }
  169. } else {
  170. // 接口失败时使用缓存(如果有)
  171. finalLandingUrl = cachedImage?.url;
  172. }
  173. // 4. 设置落地图
  174. landingImage.src = finalLandingUrl;
  175. const stateRes = await getStateApi({
  176. user_info:userAgent
  177. });
  178. if(stateRes.code == 200 ){
  179. if(stateRes.data > 0){
  180. shouldShowPopup = false
  181. } else {
  182. shouldShowPopup = true
  183. popupImage.src = imagePaths.popupImageUrl;
  184. }
  185. }
  186. // 5. 新增:根据对比结果决定是否展示弹窗
  187. if (shouldShowPopup) {
  188. setTimeout(() => {
  189. popup.classList.add("show");
  190. }, 500);
  191. }
  192. } catch (err) {
  193. console.error('页面初始化失败');
  194. }
  195. };
  196. // 点击"开心收下",关闭弹窗
  197. closeBtn.addEventListener('click', closePopupAndSendData);
  198. // 点击弹窗空白处,关闭弹窗
  199. popup.addEventListener('click', function(e) {
  200. if (e.target === popup) {
  201. closePopupAndSendData();
  202. }
  203. });
  204. // 关闭弹窗并发送数据
  205. async function closePopupAndSendData() {
  206. if (!isClickable) {
  207. return;
  208. }
  209. // 关闭弹窗
  210. popup.classList.remove("show");
  211. // 发送页面打开时间到后端
  212. try {
  213. await acceptCardApi({
  214. user_info:userAgent,
  215. state: 1,
  216. });
  217. } catch (error) {
  218. console.error('发送失败', pageOpenTime);
  219. }
  220. // 设置点击冷却
  221. isClickable = false;
  222. setTimeout(() => {
  223. isClickable = true;
  224. }, 10000);
  225. }
  226. </script>
  227. </body>
  228. </html>