index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <template>
  2. <v-cover v-if="state.page == '封面页'"></v-cover>
  3. <v-invite v-if="state.page == '邀请页'"></v-invite>
  4. <v-result v-if="state.page == '开奖页'"></v-result>
  5. <open-box v-show="state.open_box.show"></open-box>
  6. <v-toast :show="state.toast.show" :txt="state.toast.txt" :has_icon="state.toast.has_icon"></v-toast>
  7. <div v-show="state.loading_redbag" class="redbag">
  8. <img :src="require('@/assets/img/icon-loading-redbag.png')" alt />
  9. </div>
  10. </template>
  11. <script setup>
  12. import { reactive, provide, onMounted, ref } from 'vue'
  13. import VCover from '@/view/iframe/treasure-hunt/cover.vue'
  14. import VInvite from '@/view/iframe/treasure-hunt/invite.vue'
  15. import VResult from '@/view/iframe/treasure-hunt/result.vue'
  16. import { inviteDetail, treasureDetail, treasureOpen } from '@/http/treasure.js'
  17. import { reSetBindTwtterId, reSetBindPostContent, reSetBindRepost } from '@/http/help.js'
  18. import { getQueryString } from '@/uilts/help'
  19. import { getChromeStorage, sendCurrentTabMessage } from '@/uilts/chromeExtension.js'
  20. import VToast from '@/view/iframe/treasure-hunt/components/toast.vue'
  21. import OpenBox from '@/view/iframe/treasure-hunt/components/open-box.vue'
  22. import Report from "@/log-center/log"
  23. let state = reactive({
  24. loading_redbag: true,
  25. page: '',
  26. page_status: '',
  27. detail: {},
  28. oldDetail: {},
  29. btn_loading: false,
  30. timer: null,
  31. open_box: {
  32. showed: false,
  33. show: false,
  34. clicked: false,
  35. data: {}
  36. },
  37. open_btn: {
  38. txt: '',
  39. disabled: false
  40. },
  41. dialog: {
  42. show: false,
  43. },
  44. start_task: {},
  45. toast: {},
  46. iframeId: ''
  47. })
  48. let global_refresh = ref(false)
  49. provide('global_refresh', global_refresh)
  50. provide('state', state)
  51. let params = {}
  52. onMounted(() => {
  53. params = JSON.parse(getQueryString('params') || '{}')
  54. state.iframeId = getQueryString('iframeId') || ''
  55. state.postId = params.post_Id || ''
  56. state.tweetId = params.tweet_Id || ''
  57. state.invite_code = params.invite_code || ''
  58. state.page_type = params.page_type || ''
  59. state.init();
  60. onRuntimeMsg();
  61. })
  62. state.checkIsLogin = () => {
  63. return new Promise((resolve) => {
  64. getChromeStorage('userInfo', (_userInfo) => {
  65. if (!_userInfo) {
  66. state.btn_loading = true
  67. setTimeout(() => {
  68. state.btn_loading = false
  69. }, 3000)
  70. chrome.runtime.sendMessage({ actionType: "POPUP_LOGIN", data: "" })
  71. resolve(_userInfo)
  72. } else {
  73. resolve(_userInfo)
  74. }
  75. })
  76. })
  77. }
  78. state.init = (callback) => {
  79. if (params.page_type == '邀请链接') {
  80. // 邀请链接
  81. inviteDetail({
  82. params: {
  83. inviteCode: params.invite_code
  84. }
  85. }).then((res) => {
  86. if (res.code == 0) {
  87. state.loading_redbag = false
  88. handleCommon(res, callback)
  89. // 绑定repostSrcContentId
  90. if (!res.data.repostSrcContentId) {
  91. reSetBindRepost({
  92. inviteCode: state.invite_code,
  93. tweetId: state.tweetId
  94. })
  95. }
  96. }
  97. })
  98. } else if (params.page_type == '原始链接') {
  99. // 原始链接
  100. treasureDetail({
  101. params: {
  102. postId: params.post_Id
  103. }
  104. }).then((res) => {
  105. if (res.code == 0) {
  106. state.loading_redbag = false
  107. handleCommon(res, callback)
  108. // 原始链接绑定post content
  109. if (!res.data.postSrcContent) {
  110. sendCurrentTabMessage({
  111. actionType: "GET_CONTENT_BY_TWITTER_ID",
  112. data: {
  113. tweet_Id: state.tweetId
  114. }
  115. })
  116. }
  117. }
  118. })
  119. }
  120. }
  121. const reportOpenBoxLog = () => {
  122. if (state.open_box.showed) {
  123. Report.reportLog({
  124. businessType: Report.businessType.pageView,
  125. pageSource: Report.pageSource.openTreasurePage,
  126. redPacketType: Report.redPacketType.treasure,
  127. shareLinkId: state.invite_code,
  128. myShareLinkId: state.detail.inviteCopyUrl,
  129. currentInvitedNum: state.inviteCount,
  130. postId: state.postId
  131. });
  132. state.open_box.showed = false
  133. }
  134. if (state.open_box.clicked) {
  135. Report.reportLog({
  136. businessType: Report.businessType.buttonClick,
  137. pageSource: Report.pageSource.openTreasurePage,
  138. objectType: Report.objectType.nextButton,
  139. redPacketType: Report.redPacketType.treasure,
  140. shareLinkId: state.invite_code,
  141. myShareLinkId: state.detail.inviteCopyUrl,
  142. currentInvitedNum: state.inviteCount,
  143. postId: state.postId
  144. });
  145. state.open_box.clicked = false
  146. }
  147. }
  148. const handleCommon = (res, callback) => {
  149. state.detail = res.data
  150. state.postId = state.detail.postId
  151. reportOpenBoxLog()
  152. try {
  153. state.tasks = JSON.parse(state.detail.startCondition)
  154. let follows = state.tasks.filter((item) => { return item.type == 1 })
  155. if (follows.length) {
  156. state.follows = follows[0].relatedUsers
  157. }
  158. }
  159. catch (error) {
  160. console.error('catch', error)
  161. }
  162. if (!res.data.srcContentId) {
  163. reSetBindTwtterId({
  164. postId: state.postId || '',
  165. tweetId: state.tweetId || ''
  166. }, () => {
  167. sendCurrentTabMessage({
  168. actionType: "IFRAME_API_GET_TWEET_USER_INFO_REQ",
  169. data: {
  170. screen_name: state.detail.postUserInfo.nickName,
  171. tweetId: state.tweetId,
  172. objectType: Report.objectType.tweetPostBinded,
  173. iframeId: state.iframeId
  174. }
  175. })
  176. state.init()
  177. })
  178. }
  179. handleStatus(callback)
  180. }
  181. let silver_open_box_big = require('@/assets/img/icon-silver-open-box-big.png')
  182. let gold_open_box_big = require('@/assets/img/icon-gold-open-box-big.png')
  183. state.refreshInit = () => {
  184. state.init(() => {
  185. global_refresh.value = true
  186. setTimeout(() => {
  187. global_refresh.value = false
  188. }, 1000)
  189. })
  190. }
  191. state.treasureOpen = () => {
  192. treasureOpen({
  193. params: {
  194. postId: state.postId,
  195. treasureId: state.treasureId,
  196. }
  197. }).then((res) => {
  198. state.btn_loading = false
  199. if (res.code == 0) {
  200. // icon
  201. for (let i in state.boxs) {
  202. if (state.boxs[i].id == state.treasureId) {
  203. if (i > 0) {
  204. state.open_box.icon = gold_open_box_big
  205. } else {
  206. state.open_box.icon = silver_open_box_big
  207. }
  208. break
  209. }
  210. }
  211. state.open_box.show = true
  212. state.open_box.showed = true
  213. state.open_box.data = res.data
  214. state.refreshInit()
  215. } else {
  216. switch (String(res.code)) {
  217. case '2037':
  218. state.dialog.show = true
  219. break;
  220. case '2203':
  221. state.toast.txt = 'You have already opened the treasure chest'
  222. state.toast.show = true
  223. break
  224. case '2208':
  225. state.toast.txt = 'No treasure chests to open'
  226. state.toast.show = true
  227. break
  228. default:
  229. state.toast.txt = 'System Error'
  230. state.toast.show = true
  231. break
  232. }
  233. state.toast.has_icon = false
  234. setTimeout(() => {
  235. state.toast.show = false
  236. }, 2000)
  237. state.refreshInit()
  238. }
  239. }).catch(() => {
  240. state.btn_loading = false
  241. })
  242. }
  243. const handleStatus = (callback) => {
  244. // 如果 夺宝状态 = 未开始
  245. // 显示未开始页面
  246. // 如果 夺宝状态 = 进行中
  247. // 如果 夺宝参与状态 = 未参与夺宝
  248. // 显示封面页
  249. // 如果 夺宝参与状态 = 已参与夺宝
  250. // 显示邀请页
  251. // 如果 夺宝状态 = 已结束
  252. // 显示结束页面
  253. let { status, joinStatus } = state.detail || {}
  254. // 如果 夺宝状态 = 未开始
  255. if (status == 0) {
  256. // 未做处理
  257. }
  258. // 如果 夺宝状态 = 进行中
  259. else if (status == 1) {
  260. // 如果 夺宝参与状态 = 未参与夺宝
  261. if (joinStatus == 0) {
  262. // 显示封面页
  263. state.page = '封面页'
  264. state.cover_status = '有邀请人'
  265. state.open_btn.txt = 'Start'
  266. // state.cover_status = '无邀请人'
  267. // state.cover_status = '奖励已被领光'
  268. }
  269. // 如果 夺宝参与状态 = 已参与夺宝
  270. else if (joinStatus == 1) {
  271. if (state.page_show != '总邀请者页') {
  272. state.page = '邀请页'
  273. }
  274. }
  275. }
  276. // 如果 夺宝状态 = 已结束
  277. else {
  278. state.open_btn.txt = 'Look for more treasures'
  279. state.page = '封面页'
  280. state.cover_status = '奖励已被领光'
  281. state.btn_loading = false
  282. return
  283. }
  284. callback && callback()
  285. }
  286. function onRuntimeMsg() {
  287. chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
  288. switch (req.actionType) {
  289. case 'CONTENT_GET_TWEET_TXT':
  290. if (req.data.tweet_Id == state.tweetId && !state.detail.postSrcContent) {
  291. state.detail.postSrcContent = req.data.txt
  292. reSetBindPostContent({
  293. postId: state.postId || '',
  294. postSrcContent: req.data.txt,
  295. })
  296. }
  297. break
  298. case 'CONTENT_API_GET_TWEET_USER_INFO_RES':
  299. if(state.iframeId != req.iframeId) {
  300. return;
  301. }
  302. let twitterFans = 0;
  303. let { user } = req.data || {};
  304. if (user && user.result && user.result.legacy) {
  305. let legacy = user.result.legacy;
  306. twitterFans = legacy ? legacy.followers_count : 0;
  307. }
  308. if (state.tweetId == req.tweetId && req.objectType == Report.objectType.tweetPostBinded) {
  309. Report.reportLog({
  310. objectType: Report.objectType.tweetPostBinded,
  311. twitterFans: twitterFans,
  312. redPacketType: Report.redPacketType.treasure,
  313. postId: state.postId
  314. });
  315. }
  316. break;
  317. }
  318. sendResponse && sendResponse();
  319. })
  320. }
  321. </script>
  322. <style lang="scss" >
  323. html,
  324. body {
  325. margin: 0;
  326. padding: 0;
  327. width: 100%;
  328. height: 100%;
  329. overflow: hidden;
  330. .redbag {
  331. z-index: 222;
  332. text-align: center;
  333. width: 375px;
  334. height: 580px;
  335. position: fixed;
  336. top: 0;
  337. left: 0;
  338. user-select: none;
  339. img {
  340. position: absolute;
  341. top: 50%;
  342. left: 50%;
  343. margin-top: -65px;
  344. margin-left: -65px;
  345. width: 130px;
  346. height: 130px;
  347. }
  348. }
  349. }
  350. </style>