IndexView.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. <script setup>
  2. import 'swiper/css'
  3. import 'swiper/css/pagination'
  4. import { useElementVisibility } from '@vueuse/core'
  5. import { nextTick, onMounted, ref, onUnmounted } from 'vue'
  6. import WOW from 'wow.js'
  7. import { v4 as uuidv4 } from 'uuid'
  8. import { clickEventApi } from '@/api'
  9. import { getUrlParams, getCommonSign } from '@/utitls'
  10. const appStoreBtnClick = () => {
  11. reportEvent('APP_STORE_CLICK', () => {
  12. fbq('track', 'FB')
  13. fbq('track', 'Metaclick')
  14. reportApiEvent()
  15. })
  16. // window.open('https://apps.apple.com/tw/app/id6504406401')
  17. }
  18. const fbBtnClick = () => {
  19. reportEvent('ONEPRE_FB_CLICK', () => {
  20. fbq('track', 'FbPage')
  21. reportApiEvent()
  22. })
  23. console.log('FbPage')
  24. window.open('https://www.facebook.com/profile.php?id=61580192046090')
  25. }
  26. const apkBtnClick = () => {
  27. reportEvent('ONEPRE_CLICK', () => {
  28. fbq('track', 'Onepre')
  29. reportApiEvent()
  30. })
  31. console.log('Onepre')
  32. window.open('http://onesto.re/0001003604')
  33. }
  34. const topBannerRef = ref(null)
  35. const topBannerIsVisible = useElementVisibility(topBannerRef)
  36. const isIOS = ref(false)
  37. const isAndroid = ref(false)
  38. // 设备去重上报相关
  39. const DEVICE_UUID_KEY = 'device_uuid'
  40. const REPORTED_EVENTS_KEY = 'reported_events'
  41. // 生成或获取设备UUID
  42. const getDeviceUUID = () => {
  43. let deviceUUID = localStorage.getItem(DEVICE_UUID_KEY)
  44. if (!deviceUUID) {
  45. deviceUUID = uuidv4()
  46. localStorage.setItem(DEVICE_UUID_KEY, deviceUUID)
  47. }
  48. return deviceUUID
  49. }
  50. // 检查事件是否已上报
  51. const isEventReported = (eventType) => {
  52. const reportedEvents = JSON.parse(localStorage.getItem(REPORTED_EVENTS_KEY) || '[]')
  53. return reportedEvents.includes(eventType)
  54. }
  55. // 标记事件为已上报
  56. const markEventAsReported = (eventType) => {
  57. const reportedEvents = JSON.parse(localStorage.getItem(REPORTED_EVENTS_KEY) || '[]')
  58. if (!reportedEvents.includes(eventType)) {
  59. reportedEvents.push(eventType)
  60. localStorage.setItem(REPORTED_EVENTS_KEY, JSON.stringify(reportedEvents))
  61. }
  62. }
  63. // 设备去重上报函数
  64. const reportEvent = (eventType, callback) => {
  65. if (!isEventReported(eventType)) {
  66. // 首次上报,执行回调
  67. callback()
  68. // 标记为已上报
  69. markEventAsReported(eventType)
  70. console.log(`事件 ${eventType} 首次上报成功`)
  71. } else {
  72. console.log(`事件 ${eventType} 已上报过,跳过`)
  73. }
  74. }
  75. const checkPlatform = () => {
  76. if (navigator.userAgent.indexOf('iPhone') > -1 || navigator.userAgent.indexOf('iPad') > -1) {
  77. isIOS.value = true
  78. } else if (navigator.userAgent.indexOf('Android') > -1) {
  79. isAndroid.value = true
  80. } else {
  81. isIOS.value = false
  82. isAndroid.value = true
  83. }
  84. }
  85. // 回传API
  86. const reportApiEvent = () => {
  87. const urlParams = getUrlParams(window.location.href)
  88. if (!urlParams) {
  89. } else {
  90. const params = {
  91. event_name: 'click',
  92. media_source: urlParams.pid,
  93. game_id: urlParams.gid,
  94. device_uuid: getDeviceUUID(),
  95. url_params: urlParams
  96. }
  97. const data = getCommonSign(params)
  98. clickEventApi(data)
  99. }
  100. }
  101. onMounted(() => {
  102. checkPlatform()
  103. // 初始化设备UUID
  104. getDeviceUUID()
  105. nextTick().then(() => {
  106. new WOW({
  107. animateClass: 'animate__animated',
  108. offset: 150
  109. }).init()
  110. })
  111. })
  112. onUnmounted(() => {
  113. })
  114. </script>
  115. <template>
  116. <div id="content-wrapper" style="width: 100%; height: auto">
  117. <section ref="topBannerRef" id="top-banner" class="flex items-center justify-end">
  118. <div
  119. class="flex items-center justify-evenly "
  120. style="width: 2.2rem"
  121. >
  122. <a
  123. class="block btn btn-download-banner-btn"
  124. href="javascript:;"
  125. @click.prevent.stop="apkBtnClick"
  126. ></a>
  127. <!-- <a class="block btn btn-fb" href="javascript:;" @click.prevent.stop="fbBtnClick"></a> -->
  128. </div>
  129. </section>
  130. <div class="container" style="width: 100%; height: auto">
  131. <img src="@/assets/imgs/bg.jpg" class="block btn" alt="">
  132. <a
  133. class="block btn download_btn"
  134. href="javascript:;"
  135. @click.prevent.stop="apkBtnClick"
  136. ></a>
  137. <div class="gift_warp">
  138. <img src="@/assets/imgs/gift_1.png" alt="">
  139. <img src="@/assets/imgs/gift_2.png" alt="">
  140. <img src="@/assets/imgs/gift_3.png" alt="">
  141. <img src="@/assets/imgs/gift_4.png" alt="">
  142. </div>
  143. </div>
  144. <transition>
  145. <section
  146. v-show="!topBannerIsVisible"
  147. id="bottom-banner"
  148. class="flex items-center justify-end"
  149. >
  150. <div
  151. class="flex items-center justify-evenly"
  152. style="width: 2.2rem"
  153. >
  154. <a
  155. class="block btn btn-download-banner-btn"
  156. href="javascript:;"
  157. @click.prevent.stop="apkBtnClick"
  158. ></a>
  159. <!-- <a class="block btn btn-fb" href="javascript:;" @click.prevent.stop="fbBtnClick"></a> -->
  160. </div>
  161. </section>
  162. </transition>
  163. </div>
  164. </template>
  165. <style scoped>
  166. .container{
  167. background-image: url('@/assets/imgs/bg.jpg');
  168. background-size: 100%;
  169. background-repeat: no-repeat;
  170. position:relative;
  171. padding-bottom: 1.1rem;
  172. }
  173. #top-banner {
  174. position: relative;
  175. z-index: 1;
  176. background-image: url('@/assets/imgs/top-banner.png');
  177. background-size: 100%;
  178. background-repeat: no-repeat;
  179. width: 100%;
  180. height: 1.11rem;
  181. }
  182. #bottom-banner {
  183. position: fixed;
  184. left: 50%;
  185. bottom: 0;
  186. z-index: 11;
  187. background-image: url('@/assets/imgs/top-banner.png');
  188. background-size: 100%;
  189. background-repeat: no-repeat;
  190. width: 7.5rem;
  191. height: 1.1rem;
  192. margin-left: -3.75rem;
  193. }
  194. .btn {
  195. position: relative;
  196. overflow: hidden;
  197. background-size: 100% 100%;
  198. background-repeat: no-repeat;
  199. &::after {
  200. content: '';
  201. position: absolute;
  202. top: 0;
  203. left: -100%;
  204. width: 100%;
  205. height: 100%;
  206. background: linear-gradient(
  207. 120deg,
  208. transparent,
  209. transparent,
  210. rgba(255, 244, 227, 0.4),
  211. transparent,
  212. transparent
  213. );
  214. transition: all 650ms;
  215. animation: btn-shiny 2s linear infinite;
  216. }
  217. }
  218. .download_btn {
  219. position: absolute;
  220. top: 47%;
  221. left: 50%;
  222. transform: translate(-50%, -94%);
  223. width: 3.58rem;
  224. height: 1.07rem;
  225. background-image: url('@/assets/imgs/top-btn.png');
  226. animation: pulse-btn 1.5s infinite ease-in-out;
  227. }
  228. @keyframes pulse-btn {
  229. 0% {
  230. transform: translate(-50%, -94%) scale(1);
  231. }
  232. 50% {
  233. transform: translate(-50%, -94%) scale(1.08);
  234. }
  235. 100% {
  236. transform: translate(-50%, -94%) scale(1);
  237. }
  238. }
  239. .character-border {
  240. position: relative;
  241. z-index: 0;
  242. width:3.58rem;
  243. height: 1.07rem;
  244. /* border-radius: 0.13rem; */
  245. overflow: hidden;
  246. margin-top: -.1rem;
  247. margin-left: -.1rem;
  248. margin-bottom: .03rem;
  249. padding-bottom: .2rem;
  250. margin-bottom:.2rem;
  251. @apply flex justify-center items-center;
  252. &::before {
  253. content: '';
  254. position: absolute;
  255. z-index: -2;
  256. left: -50%;
  257. top: -50%;
  258. width: 200%;
  259. height: 200%;
  260. background-color: #7395b8;
  261. background-repeat: no-repeat;
  262. background-position: 0 0;
  263. background-image: conic-gradient(transparent, rgba(168, 239, 255, 1), transparent 30%);
  264. animation: border-rotate 0.5s linear infinite;
  265. padding-top:.2rem;
  266. }
  267. }
  268. .gift_warp{
  269. position: absolute;
  270. top: 33%;
  271. left: 50%;
  272. transform: translate(-50%, 50%);
  273. display: flex;
  274. flex-wrap: wrap;
  275. justify-content: space-between;
  276. width: 98%;
  277. }
  278. .gift_warp img {
  279. width: 3.55rem;
  280. height: 2.78rem;
  281. animation: gift-glow 2s infinite ease-in-out;
  282. &:nth-child(1) {
  283. animation-delay: 0s;
  284. }
  285. &:nth-child(2){
  286. left: -8%;
  287. display: block;
  288. position: relative;
  289. animation-delay: 0.5s;
  290. }
  291. &:nth-child(3){
  292. left: 8%;
  293. display: block;
  294. position: relative;
  295. margin-top: .3rem;
  296. animation-delay: 1.0s;
  297. }
  298. &:nth-child(4){
  299. display: block;
  300. position: relative;
  301. margin-top: .3rem;
  302. animation-delay: 1.5s;
  303. }
  304. }
  305. @keyframes gift-glow {
  306. 0%, 100% {
  307. filter: drop-shadow(0 0 2px rgba(255, 235, 133, 0.4));
  308. }
  309. 50% {
  310. filter: drop-shadow(0 0 20px rgba(255, 215, 0, 1));
  311. }
  312. }
  313. .btn-fb {
  314. width: 1.5rem;
  315. height: 0.62rem;
  316. border-radius: 0.1rem;
  317. background-image: url('@/assets/imgs/fb.png');
  318. }
  319. .btn-download-banner-btn{
  320. width: 2.04rem;
  321. height: 0.62rem;
  322. border-radius: 0.1rem;
  323. background-image: url('@/assets/imgs/top-btn.png')
  324. }
  325. .character-wrapper {
  326. /* padding: 1.2rem 0 1.2rem 0; */
  327. padding: .04rem 0 0.45rem 0;
  328. }
  329. .character {
  330. width: 2.23rem;
  331. height: 3.29rem;
  332. margin-left: -.1rem;
  333. }
  334. .character-border {
  335. position: relative;
  336. z-index: 0;
  337. width: 2.23rem;
  338. height: 3.3rem;
  339. border-radius: 0.13rem;
  340. overflow: hidden;
  341. margin-top: -.1rem;
  342. margin-left: -.1rem;
  343. margin-bottom: .03rem;
  344. padding-bottom: .2rem;
  345. margin-bottom:.2rem;
  346. @apply flex justify-center items-center;
  347. &::before {
  348. content: '';
  349. position: absolute;
  350. z-index: -2;
  351. left: -50%;
  352. top: -50%;
  353. width: 200%;
  354. height: 200%;
  355. background-color: #7395b8;
  356. background-repeat: no-repeat;
  357. background-position: 0 0;
  358. background-image: conic-gradient(transparent, rgba(168, 239, 255, 1), transparent 30%);
  359. animation: border-rotate 0.5s linear infinite;
  360. padding-top:.2rem;
  361. }
  362. }
  363. @keyframes border-rotate {
  364. 100% {
  365. transform: rotate(1turn);
  366. }
  367. }
  368. @keyframes btn-shiny {
  369. from {
  370. left: -50%;
  371. }
  372. to {
  373. left: 90%;
  374. }
  375. }
  376. .v-enter-active {
  377. transition: opacity 0.5s ease;
  378. }
  379. .v-enter-from {
  380. opacity: 0;
  381. }
  382. </style>
  383. <style>
  384. .swiper-pagination {
  385. bottom: .3rem !important;
  386. }
  387. .banner-container .swiper-pagination {
  388. bottom: 0rem !important;
  389. }
  390. .swiper-wrapper {
  391. /* padding-bottom: 0.7rem; */
  392. }
  393. .swiper-pagination-bullet {
  394. border-radius: 0.1rem;
  395. width: 0.3rem;
  396. opacity: 1;
  397. background-color: #8e8d8e;
  398. }
  399. .swiper-pagination-bullet-active {
  400. background-color: #b6dafc;
  401. }
  402. .banner-container {
  403. width: 90%;
  404. margin: 0 auto;
  405. margin-top: .2rem;
  406. height: 5.8rem;
  407. }
  408. </style>