ソースを参照

merge dev_1.1.7

nieyuge 2 年 前
コミット
f9976a6b49
90 ファイル変更3456 行追加751 行削除
  1. 2 1
      .env.development
  2. 2 1
      .env.pre
  3. 2 1
      .env.production
  4. 2 0
      .env.test
  5. 2 1
      package.json
  6. BIN
      src/assets/img/icon-card-cover-treasure-big.png
  7. BIN
      src/assets/img/icon-flash-active.png
  8. BIN
      src/assets/img/icon-gold-close-box.png
  9. BIN
      src/assets/img/icon-gold-open-box.png
  10. BIN
      src/assets/img/icon-silver-close-box.png
  11. BIN
      src/assets/img/icon-silver-open-box.png
  12. BIN
      src/assets/img/icon-treasure-box.png
  13. BIN
      src/assets/img/img-preview-treasure-link-bg.png
  14. 2 0
      src/assets/svg/icon-big-treasure.svg
  15. 2 0
      src/assets/svg/icon-btn-box.svg
  16. 2 0
      src/assets/svg/icon-card-cover-treasure-small.svg
  17. 1 0
      src/assets/svg/icon-card-cover-treasure-tasks.svg
  18. 3 0
      src/assets/svg/icon-custom-cover-btn.svg
  19. 3 0
      src/assets/svg/icon-form-amount.svg
  20. 4 0
      src/assets/svg/icon-form-cost.svg
  21. 3 0
      src/assets/svg/icon-form-custom-cover.svg
  22. 1 0
      src/assets/svg/icon-form-follow.svg
  23. 3 0
      src/assets/svg/icon-form-task.svg
  24. 8 0
      src/assets/svg/icon-form-time.svg
  25. 1 0
      src/assets/svg/icon-form-winners.svg
  26. 4 0
      src/assets/svg/icon-green-yes.svg
  27. 5 0
      src/assets/svg/icon-silver-open-box.svg
  28. 1 0
      src/assets/svg/icon-small-treasure.svg
  29. 1 0
      src/assets/svg/icon-three-line.svg
  30. 3 0
      src/assets/svg/icon-tip-arrow.svg
  31. 4 0
      src/assets/svg/icon-treasure-return.svg
  32. 3 0
      src/assets/svg/icon-while-user.svg
  33. 3 0
      src/assets/svg/icon-while-yes.svg
  34. 0 19
      src/assets/svg/img-A0.svg
  35. 0 19
      src/assets/svg/img-A1.svg
  36. 0 44
      src/assets/svg/img-B0.svg
  37. 0 44
      src/assets/svg/img-B1.svg
  38. 3 0
      src/assets/svg/img-LT0.svg
  39. 3 0
      src/assets/svg/img-LT1.svg
  40. 3 0
      src/assets/svg/img-P1.svg
  41. 3 0
      src/assets/svg/img-P2.svg
  42. 3 0
      src/assets/svg/img-P3.svg
  43. 2 0
      src/assets/svg/img-T0.svg
  44. 2 0
      src/assets/svg/img-T1.svg
  45. 11 0
      src/assets/svg/img-preview-treasure-01-bg.svg
  46. 195 192
      src/entry/background.js
  47. 14 5
      src/entry/content.js
  48. 3 1
      src/http/configAPI.js
  49. 68 0
      src/http/treasure.js
  50. 9 0
      src/http/treasureApi.js
  51. 1 2
      src/iframe/tool-box.js
  52. 5 0
      src/iframe/treasure-hunt.js
  53. 21 1
      src/log-center/logger.js
  54. 9 0
      src/logic/background/twitter.js
  55. 30 0
      src/logic/content/ParseCard.js
  56. 198 82
      src/logic/content/twitter.js
  57. 2 1
      src/manifest.json
  58. 6 2
      src/types/global.js
  59. 50 0
      src/uilts/messageCenter/index.js
  60. 19 7
      src/view/components/component-zoom.vue
  61. 0 1
      src/view/components/currency-list.vue
  62. 152 14
      src/view/components/custom-card-cover.vue
  63. 112 28
      src/view/components/custom-card-horizontal-cover.vue
  64. 32 9
      src/view/components/popup-transactions.vue
  65. 11 3
      src/view/iframe/publish/components/follow-input.vue
  66. 61 0
      src/view/iframe/publish/components/form-input.vue
  67. 6 0
      src/view/iframe/publish/components/preview-card.vue
  68. 8 2
      src/view/iframe/publish/components/preview-sheet.vue
  69. 523 205
      src/view/iframe/publish/give-dialog.vue
  70. 3 1
      src/view/iframe/publish/publish.vue
  71. 1 2
      src/view/iframe/publish/tool-box/child/preview.vue
  72. 6 3
      src/view/iframe/red-packet/luck-draw.vue
  73. 6 3
      src/view/iframe/red-packet/red-packet.vue
  74. 3 26
      src/view/iframe/test/index.vue
  75. 3 3
      src/view/iframe/tool-box/card.vue
  76. 96 0
      src/view/iframe/treasure-hunt/components/btn.vue
  77. 74 0
      src/view/iframe/treasure-hunt/components/dialog.vue
  78. 72 0
      src/view/iframe/treasure-hunt/components/head.vue
  79. 57 0
      src/view/iframe/treasure-hunt/components/hover-tip.vue
  80. 160 0
      src/view/iframe/treasure-hunt/components/invite-friends.vue
  81. 159 0
      src/view/iframe/treasure-hunt/components/invite-list.vue
  82. 114 0
      src/view/iframe/treasure-hunt/components/open-box.vue
  83. 80 0
      src/view/iframe/treasure-hunt/components/toast.vue
  84. 285 0
      src/view/iframe/treasure-hunt/cover.vue
  85. 126 0
      src/view/iframe/treasure-hunt/index.vue
  86. 369 0
      src/view/iframe/treasure-hunt/invite.vue
  87. 118 0
      src/view/iframe/treasure-hunt/result.vue
  88. 72 18
      src/view/popup/tabbar-page/message/index.vue
  89. 7 4
      src/view/popup/withdraw/info.vue
  90. 13 6
      vue.config.js

+ 2 - 1
.env.development

@@ -1 +1,2 @@
-NODE_ENV='development'
+NODE_ENV='development'
+VUE_APP_IFRAME_HOST='https://localhost:3000'

+ 2 - 1
.env.pre

@@ -1 +1,2 @@
-NODE_ENV='pre'
+NODE_ENV='pre'
+VUE_APP_IFRAME_HOST='https://iframe-pre.denet.me'

+ 2 - 1
.env.production

@@ -1 +1,2 @@
-NODE_ENV='production'
+NODE_ENV='production'
+VUE_APP_IFRAME_HOST='https://iframe.denet.me'

+ 2 - 0
.env.test

@@ -0,0 +1,2 @@
+NODE_ENV='development'
+VUE_APP_IFRAME_HOST='https://iframe-test.denet.me'

+ 2 - 1
package.json

@@ -4,7 +4,7 @@
   "private": true,
   "scripts": {
     "serve": "vue-cli-service serve",
-    "build-test": "vue-cli-service build --mode development",
+    "build-test": "vue-cli-service build --mode test",
     "build-local": "sh buildTestApp.sh",
     "build-pre": "vue-cli-service build --mode pre",
     "build-prod": "vue-cli-service build --mode production",
@@ -23,6 +23,7 @@
     "eslint-plugin-vue": "^8.7.0",
     "mathjs": "^10.5.0",
     "moment": "^2.29.1",
+    "node-polyfill-webpack-plugin": "^2.0.1",
     "node-sass": "^7.0.1",
     "postcss-import": "^14.0.2",
     "postcss-url": "^10.1.3",

BIN
src/assets/img/icon-card-cover-treasure-big.png


BIN
src/assets/img/icon-flash-active.png


BIN
src/assets/img/icon-gold-close-box.png


BIN
src/assets/img/icon-gold-open-box.png


BIN
src/assets/img/icon-silver-close-box.png


BIN
src/assets/img/icon-silver-open-box.png


BIN
src/assets/img/icon-treasure-box.png


BIN
src/assets/img/img-preview-treasure-link-bg.png


ファイルの差分が大きいため隠しています
+ 2 - 0
src/assets/svg/icon-big-treasure.svg


ファイルの差分が大きいため隠しています
+ 2 - 0
src/assets/svg/icon-btn-box.svg


ファイルの差分が大きいため隠しています
+ 2 - 0
src/assets/svg/icon-card-cover-treasure-small.svg


ファイルの差分が大きいため隠しています
+ 1 - 0
src/assets/svg/icon-card-cover-treasure-tasks.svg


+ 3 - 0
src/assets/svg/icon-custom-cover-btn.svg

@@ -0,0 +1,3 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M17.8749 11.7838L17.1198 12.5169L15.6097 11.0508L16.3648 10.3177C16.4403 10.2444 16.5158 10.1711 16.6668 10.1711C16.7423 10.1711 16.8933 10.2444 16.9688 10.3177L17.9504 11.2707C18.0259 11.4173 18.0259 11.6372 17.8749 11.7838ZM10.5507 15.8891V17.4286H12.1364L16.7423 12.9568L15.2321 11.4906L10.5507 15.8891ZM16.5913 4.96617C16.5913 4.15977 15.9117 3.5 15.0811 3.5H4.51014C3.67956 3.5 3 4.15977 3 4.96617V15.2293C3 16.0357 3.67956 16.6955 4.51014 16.6955H9.04057V15.3026L9.87115 14.4962H4.51014L7.15289 11.1974L9.04057 13.3966L11.6833 10.0977L12.8914 11.6372L16.5913 7.9718V4.96617Z" fill="#2F2F2F"/>
+</svg>

+ 3 - 0
src/assets/svg/icon-form-amount.svg

@@ -0,0 +1,3 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4 12.0058V13.5734C4 14.8694 6.6875 15.9231 10 15.9231C13.3125 15.9231 16 14.8694 16 13.5734V12.0058C14.7094 13.0741 12.35 13.5734 10 13.5734C7.65 13.5734 5.29062 13.0741 4 12.0058ZM4 8.15454V10.049C4 11.3449 6.6875 12.3986 10 12.3986C13.3125 12.3986 16 11.3449 16 10.049V8.15454C14.7094 9.4028 12.3469 10.049 10 10.049C7.65313 10.049 5.29062 9.4028 4 8.15454ZM10 3C6.6875 3 4 4.31434 4 5.93706C4 7.55979 6.6875 8.87413 10 8.87413C13.3125 8.87413 16 7.55979 16 5.93706C16 4.31434 13.3125 3 10 3Z" fill="#2F2F2F"/>
+</svg>

+ 4 - 0
src/assets/svg/icon-form-cost.svg

@@ -0,0 +1,4 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M11 13.575V14.5455C11 15.3477 12.5677 16 14.5 16C16.4323 16 18 15.3477 18 14.5455V13.575C17.2471 14.2364 15.8708 14.5455 14.5 14.5455C13.1292 14.5455 11.7529 14.2364 11 13.575ZM11 11.1909V12.3636C11 13.1659 12.5677 13.8182 14.5 13.8182C16.4323 13.8182 18 13.1659 18 12.3636V11.1909C17.2471 11.9636 15.869 12.3636 14.5 12.3636C13.131 12.3636 11.7529 11.9636 11 11.1909ZM14.5 8C12.5677 8 11 8.81364 11 9.81818C11 10.8227 12.5677 11.6364 14.5 11.6364C16.4323 11.6364 18 10.8227 18 9.81818C18 8.81364 16.4323 8 14.5 8Z" fill="#2F2F2F"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M5.42061 15.1282H5.4046C5.36893 15.2284 5.31128 15.3204 5.23468 15.397C5.09904 15.5326 4.91508 15.6088 4.72326 15.6088C4.53144 15.6088 4.34747 15.5326 4.21184 15.397C4.0762 15.2614 4 15.0774 4 14.8856C4 14.8202 4.01049 14.7614 4.02325 14.7114C4.33797 12.5974 5.72065 10.833 7.60544 9.98625C6.73631 9.26192 6.18262 8.1708 6.18262 6.95024C6.18262 4.76854 7.95117 3 10.1329 3C11.9921 3 13.5513 4.28442 13.9716 6.01437C13.5574 6.03701 13.1526 6.08619 12.7643 6.16045C12.6313 5.7191 12.3901 5.32421 12.0716 5.00682C12.3898 5.32432 12.6308 5.71925 12.7636 6.16059C12.6833 6.17595 12.6037 6.19239 12.5248 6.20988C12.2083 5.18971 11.2556 4.44651 10.1329 4.44651C8.75252 4.44651 7.62914 5.5699 7.62914 6.95024C7.62914 7.92308 8.18723 8.76842 9 9.18266V11.0304C7.15844 11.4847 5.73735 13.02 5.45165 14.9216L5.42061 15.1282ZM4.24375 14.8867C4.24375 15.0139 4.29418 15.1359 4.38397 15.226L4.38341 15.2254C4.29328 15.1353 4.24264 15.013 4.24264 14.8856C4.24264 14.842 4.25033 14.8004 4.26132 14.7602C4.56633 12.6796 5.9484 10.9491 7.82382 10.1557C7.91323 10.1179 8.00376 10.0822 8.09535 10.0487L8.09682 10.0497C6.08391 10.7858 4.582 12.5814 4.26243 14.7613C4.25144 14.8016 4.24375 14.8432 4.24375 14.8867Z" fill="#2F2F2F"/>
+</svg>

+ 3 - 0
src/assets/svg/icon-form-custom-cover.svg

@@ -0,0 +1,3 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M17.8749 11.7838L17.1198 12.5169L15.6097 11.0508L16.3648 10.3177C16.4403 10.2444 16.5158 10.1711 16.6668 10.1711C16.7423 10.1711 16.8933 10.2444 16.9688 10.3177L17.9504 11.2707C18.0259 11.4173 18.0259 11.6372 17.8749 11.7838ZM10.5507 15.8891V17.4286H12.1364L16.7423 12.9568L15.2321 11.4906L10.5507 15.8891ZM16.5913 4.96617C16.5913 4.15977 15.9117 3.5 15.0811 3.5H4.51014C3.67956 3.5 3 4.15977 3 4.96617V15.2293C3 16.0357 3.67956 16.6955 4.51014 16.6955H9.04057V15.3026L9.87115 14.4962H4.51014L7.15289 11.1974L9.04057 13.3966L11.6833 10.0977L12.8914 11.6372L16.5913 7.9718V4.96617Z" fill="#2F2F2F"/>
+</svg>

ファイルの差分が大きいため隠しています
+ 1 - 0
src/assets/svg/icon-form-follow.svg


+ 3 - 0
src/assets/svg/icon-form-task.svg

@@ -0,0 +1,3 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4.267 4.82609L4.27273 15.7875L15.7324 15.7826L15.7273 4.82122L13.8182 4.82609V5.4287C13.819 5.75195 13.6858 6.06233 13.4476 6.29171C13.2095 6.52109 12.886 6.65072 12.548 6.65217H7.452C6.75136 6.65217 6.18182 6.10313 6.18182 5.4287V4.82609H4.267ZM12.548 5.43478L12.5455 4.22348L7.452 4.21739L7.45455 4.22348V5.4287L12.548 5.43478ZM13.64 3.6087H15.7241C16.0613 3.60789 16.3851 3.73512 16.6243 3.96246C16.8635 4.1898 16.9987 4.49866 17 4.82122V15.7875C16.9995 16.1089 16.8658 16.417 16.6282 16.6443C16.3905 16.8716 16.0684 16.9995 15.7324 17H4.26764C3.56891 17 3 16.4558 3 15.7875V4.82122C3.00017 4.49979 3.13369 4.19157 3.37124 3.96423C3.6088 3.73689 3.93096 3.60902 4.267 3.6087H6.36C6.58082 3.24591 6.98491 3 7.452 3H12.548C13.0151 3 13.4198 3.24652 13.64 3.6087ZM9.17585 11.4432L11.9743 8.20321C12.0799 8.08088 12.2271 8.00801 12.3835 8.00062C12.5399 7.99324 12.6926 8.05195 12.8081 8.16383C12.9236 8.27572 12.9924 8.43162 12.9994 8.59723C13.0064 8.76285 12.951 8.92461 12.8453 9.04694L9.60606 12.7969C9.49393 12.9263 9.33577 13 9.17054 13H9.167C9.08447 12.9995 9.00296 12.9806 8.92774 12.9447C8.85252 12.9087 8.78526 12.8565 8.7303 12.7913L7.14992 10.9163C7.04568 10.7926 6.99209 10.6302 7.00095 10.4647C7.0098 10.2992 7.08037 10.1442 7.19713 10.0338C7.31389 9.92341 7.46727 9.86665 7.62354 9.87603C7.77981 9.88541 7.92616 9.96014 8.0304 10.0838L9.17585 11.4432Z" fill="#2F2F2F"/>
+</svg>

+ 8 - 0
src/assets/svg/icon-form-time.svg

@@ -0,0 +1,8 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<mask id="path-1-outside-1_24371_182246" maskUnits="userSpaceOnUse" x="2" y="2" width="16" height="16" fill="black">
+<rect fill="white" x="2" y="2" width="16" height="16"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M3 10C3 6.14 6.14 3 10 3C13.86 3 17 6.14 17 10C17 13.86 13.86 17 10 17C6.14 17 3 13.86 3 10ZM4.0045 10C4.0045 13.3055 6.694 15.9955 10 15.9955C13.3055 15.9955 15.9955 13.3055 15.9955 10C15.9955 6.694 13.3055 4.0045 10 4.0045C6.694 4.0045 4.0045 6.694 4.0045 10ZM10.001 9.99788H12.5005C12.778 9.99788 13.0025 10.2204 13.0025 10.4979C13.0025 10.7754 12.778 10.9979 12.5005 10.9979H9.50104C9.22404 10.9979 9.00104 10.7754 9.00104 10.4979V6.49887C9.00104 6.22187 9.22354 5.99688 9.50104 5.99688C9.77854 5.99688 10.001 6.22137 10.001 6.49887V9.99788Z"/>
+</mask>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M3 10C3 6.14 6.14 3 10 3C13.86 3 17 6.14 17 10C17 13.86 13.86 17 10 17C6.14 17 3 13.86 3 10ZM4.0045 10C4.0045 13.3055 6.694 15.9955 10 15.9955C13.3055 15.9955 15.9955 13.3055 15.9955 10C15.9955 6.694 13.3055 4.0045 10 4.0045C6.694 4.0045 4.0045 6.694 4.0045 10ZM10.001 9.99788H12.5005C12.778 9.99788 13.0025 10.2204 13.0025 10.4979C13.0025 10.7754 12.778 10.9979 12.5005 10.9979H9.50104C9.22404 10.9979 9.00104 10.7754 9.00104 10.4979V6.49887C9.00104 6.22187 9.22354 5.99688 9.50104 5.99688C9.77854 5.99688 10.001 6.22137 10.001 6.49887V9.99788Z" fill="#2F2F2F"/>
+<path d="M10.001 9.99788H9.80104V10.1979H10.001V9.99788ZM10 2.8C6.02954 2.8 2.8 6.02954 2.8 10H3.2C3.2 6.25046 6.25046 3.2 10 3.2V2.8ZM17.2 10C17.2 6.02954 13.9705 2.8 10 2.8V3.2C13.7495 3.2 16.8 6.25046 16.8 10H17.2ZM10 17.2C13.9705 17.2 17.2 13.9705 17.2 10H16.8C16.8 13.7495 13.7495 16.8 10 16.8V17.2ZM2.8 10C2.8 13.9705 6.02954 17.2 10 17.2V16.8C6.25046 16.8 3.2 13.7495 3.2 10H2.8ZM10 15.7955C6.80447 15.7955 4.2045 13.1951 4.2045 10H3.8045C3.8045 13.4159 6.58353 16.1955 10 16.1955V15.7955ZM15.7955 10C15.7955 13.195 13.195 15.7955 10 15.7955V16.1955C13.416 16.1955 16.1955 13.416 16.1955 10H15.7955ZM10 4.2045C13.1951 4.2045 15.7955 6.80447 15.7955 10H16.1955C16.1955 6.58353 13.4159 3.8045 10 3.8045V4.2045ZM4.2045 10C4.2045 6.80446 6.80446 4.2045 10 4.2045V3.8045C6.58354 3.8045 3.8045 6.58354 3.8045 10H4.2045ZM12.5005 9.79788H10.001V10.1979H12.5005V9.79788ZM13.2025 10.4979C13.2025 10.1089 12.8875 9.79788 12.5005 9.79788V10.1979C12.6686 10.1979 12.8025 10.3319 12.8025 10.4979H13.2025ZM12.5005 11.1979C12.8875 11.1979 13.2025 10.8869 13.2025 10.4979H12.8025C12.8025 10.6639 12.6686 10.7979 12.5005 10.7979V11.1979ZM9.50104 11.1979H12.5005V10.7979H9.50104V11.1979ZM8.80104 10.4979C8.80104 10.886 9.11372 11.1979 9.50104 11.1979V10.7979C9.33437 10.7979 9.20104 10.6648 9.20104 10.4979H8.80104ZM8.80104 6.49887V10.4979H9.20104V6.49887H8.80104ZM9.50104 5.79688C9.11192 5.79688 8.80104 6.11259 8.80104 6.49887H9.20104C9.20104 6.33116 9.33517 6.19688 9.50104 6.19688V5.79688ZM10.201 6.49887C10.201 6.11196 9.89004 5.79688 9.50104 5.79688V6.19688C9.66705 6.19688 9.80104 6.33079 9.80104 6.49887H10.201ZM10.201 9.99788V6.49887H9.80104V9.99788H10.201Z" fill="#2F2F2F" mask="url(#path-1-outside-1_24371_182246)"/>
+</svg>

ファイルの差分が大きいため隠しています
+ 1 - 0
src/assets/svg/icon-form-winners.svg


+ 4 - 0
src/assets/svg/icon-green-yes.svg

@@ -0,0 +1,4 @@
+<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="6" cy="6" r="6" fill="#08B706"/>
+<path d="M3.6875 6L5.4783 7.79096L8.71773 3.34812" stroke="white" stroke-width="1.2"/>
+</svg>

ファイルの差分が大きいため隠しています
+ 5 - 0
src/assets/svg/icon-silver-open-box.svg


ファイルの差分が大きいため隠しています
+ 1 - 0
src/assets/svg/icon-small-treasure.svg


ファイルの差分が大きいため隠しています
+ 1 - 0
src/assets/svg/icon-three-line.svg


+ 3 - 0
src/assets/svg/icon-tip-arrow.svg

@@ -0,0 +1,3 @@
+<svg width="10" height="5" viewBox="0 0 10 5" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0.5 0H9.5L4.5 5L0.5 0Z" fill="black" fill-opacity="0.6"/>
+</svg>

+ 4 - 0
src/assets/svg/icon-treasure-return.svg

@@ -0,0 +1,4 @@
+<svg width="34" height="34" viewBox="0 0 34 34" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 17C0 7.61116 7.61116 0 17 0C26.3888 0 34 7.61116 34 17C34 26.3888 26.3888 34 17 34C7.61116 34 0 26.3888 0 17Z" fill="#FFB443"/>
+<path d="M14.7368 11.8V7L7 15.4L14.7368 23.8V18.88C20.2632 18.88 24.1316 20.8 26.8947 25C25.7895 19 22.4737 13 14.7368 11.8Z" fill="white"/>
+</svg>

+ 3 - 0
src/assets/svg/icon-while-user.svg

@@ -0,0 +1,3 @@
+<svg width="9" height="8" viewBox="0 0 9 8" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.5 4C5.60514 4 6.5 3.10514 6.5 2C6.5 0.894857 5.60514 8.16868e-08 4.5 8.16868e-08C4.23734 -7.49976e-05 3.97723 0.0516053 3.73454 0.152088C3.49186 0.252571 3.27135 0.399887 3.08562 0.585619C2.89989 0.771351 2.75257 0.991859 2.65209 1.23454C2.55161 1.47723 2.49992 1.73734 2.5 2C2.5 3.10514 3.39486 4 4.5 4ZM4.5 4.57143C3.16514 4.57143 0.5 5.33714 0.5 6.85714V8H8.5V6.85714C8.5 5.33714 5.83486 4.57143 4.5 4.57143Z" fill="white"/>
+</svg>

+ 3 - 0
src/assets/svg/icon-while-yes.svg

@@ -0,0 +1,3 @@
+<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 15C11.6421 15 15 11.6421 15 7.5C15 3.35786 11.6421 0 7.5 0C3.35786 0 0 3.35786 0 7.5C0 11.6421 3.35786 15 7.5 15ZM3.96965 8.83499L6.50193 11.3675L7.1218 11.9874L7.6383 11.2791L12.219 4.99666L11.007 4.11293L6.94276 9.68696L5.03035 7.77438L3.96965 8.83499Z" fill="white"/>
+</svg>

ファイルの差分が大きいため隠しています
+ 0 - 19
src/assets/svg/img-A0.svg


ファイルの差分が大きいため隠しています
+ 0 - 19
src/assets/svg/img-A1.svg


ファイルの差分が大きいため隠しています
+ 0 - 44
src/assets/svg/img-B0.svg


ファイルの差分が大きいため隠しています
+ 0 - 44
src/assets/svg/img-B1.svg


ファイルの差分が大きいため隠しています
+ 3 - 0
src/assets/svg/img-LT0.svg


ファイルの差分が大きいため隠しています
+ 3 - 0
src/assets/svg/img-LT1.svg


ファイルの差分が大きいため隠しています
+ 3 - 0
src/assets/svg/img-P1.svg


ファイルの差分が大きいため隠しています
+ 3 - 0
src/assets/svg/img-P2.svg


ファイルの差分が大きいため隠しています
+ 3 - 0
src/assets/svg/img-P3.svg


ファイルの差分が大きいため隠しています
+ 2 - 0
src/assets/svg/img-T0.svg


ファイルの差分が大きいため隠しています
+ 2 - 0
src/assets/svg/img-T1.svg


+ 11 - 0
src/assets/svg/img-preview-treasure-01-bg.svg

@@ -0,0 +1,11 @@
+<svg width="375" height="500" viewBox="0 0 375 500" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="375" height="500" fill="url(#paint0_linear_24395_274606)"/>
+<defs>
+<linearGradient id="paint0_linear_24395_274606" x1="187" y1="-7.83211e-09" x2="187.5" y2="500" gradientUnits="userSpaceOnUse">
+<stop offset="0.388068" stop-color="#25180D"/>
+<stop offset="0.554041" stop-color="#5E4025"/>
+<stop offset="0.616047" stop-color="#876635"/>
+<stop offset="0.716041" stop-color="#24180C"/>
+</linearGradient>
+</defs>
+</svg>

+ 195 - 192
src/entry/background.js

@@ -35,207 +35,210 @@ import {
 import {
     closeAchPayNoticeHandler
 } from "@/logic/background/denet";
-try {
-    //加载bg.js 执行
-    setMessageCount();
-
-    // 消息通讯
-    chrome.runtime.onConnect.addListener(function (port) {
-        port.onDisconnect.addListener(function () {
-            onDisconnectHandler(port);
-        });
-    });
 
-    // 当有可用更新时触发
-    chrome.runtime.onUpdateAvailable.addListener(() => {
-        try {
-            setChromeStorage({ onUpdateAvailable: JSON.stringify({ onUpdateAvailable: '1' }) }, () => {
-                chrome.runtime.reload()
-            })
-        } catch (error) {
-            Report.reportLog({
-                objectType: Report.objectType.background_function_catch,
-                funcName: 'onUpdateAvailable',
-                errMsg: error.message
-            });
-        }
-    })
-
-    chrome.runtime.onInstalled.addListener(onInstalledMethod);
-
-    chrome.runtime.onMessage.addListener(onMessageMethod);
-
-    // 定时器
-    chrome.alarms.onAlarm.addListener(function (alarm) {
-        // console.log("onAlarm-", alarm);
-        switch (alarm.name) {
-            case 'denetChromeAlarm':
-                getMessageInfo();
-                break
-            case 'PingPong':
-                PingPong()
-                break;
-            case 'LuckMessage':
-                getSysMessage()
-                break
-        }
-    });
+//加载bg.js 执行
+setMessageCount();
 
-    chrome.action.onClicked.addListener(function (tab) {
-        injectExtensionPopup(tab);
+// 消息通讯
+chrome.runtime.onConnect.addListener(function (port) {
+    port.onDisconnect.addListener(function () {
+        onDisconnectHandler(port);
     });
+});
 
-    chrome.tabs.onActivated.addListener(function (activeInfo) {
-        setPopupConfig(activeInfo);
-    })
-
-    function thenInstalledMethod() {
-        try {
-
-            onInstalledCreateTab()
-            onInstalledMid()
-            onInstalledUserSet()
-            // pingpang
-            chrome.alarms.create('PingPong', {
-                //1分鐘之後開始(該值不能小於1) 
-                delayInMinutes: 2,
-                //開始後每一分鐘執行一次(該值不能小于1) 
-                periodInMinutes: 4
-            });
-            chrome.alarms.create('LuckMessage', {
-                //1分鐘之後開始(該值不能小於1) 
-                delayInMinutes: 1,
-                //開始後每一分鐘執行一次(該值不能小于1) 
-                periodInMinutes: 1
-            });
-        } catch (error) {
-            Report.reportLog({
-                objectType: Report.objectType.background_function_catch,
-                funcName: 'thenInstalledMethod',
-                errMsg: error.message
-            });
-        }
+// 当有可用更新时触发
+chrome.runtime.onUpdateAvailable.addListener(() => {
+    try {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_try,
+            funcName: 'onUpdateAvailable'
+        });
+        chrome.runtime.reload()
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'onUpdateAvailable',
+            errMsg: error.message
+        });
     }
-    function onInstalledMethod() {
-        try {
-            // 3.onInstalledMethod 执行了那个
-            // 版本更新判断
-            getChromeStorage('baseInfo', (info) => {
-                if (!info || !info.appVersionCode) {
-                    setChromeStorage({ onInstalledMethod: JSON.stringify({ onInstalledMethod: '1' }) })
-                    setChromeStorage({ baseInfo: JSON.stringify({ appVersionCode }) })
-                    thenInstalledMethod()
-                } else if (appVersionCode != info.appVersionCode) {
-                    setChromeStorage({ onInstalledMethod: JSON.stringify({ onInstalledMethod: '2' }) }, () => {
-                        setChromeStorage({ baseInfo: JSON.stringify({ appVersionCode }) }, () => {
-                            chrome.runtime.reload()
-                        })
-                    })
-                } else {
-                    setChromeStorage({ onInstalledMethod: JSON.stringify({ onInstalledMethod: '3' }) })
-                    thenInstalledMethod()
-                }
-            })
-
-            // 1.onUpdateAvailable 存储到本地,再上报
-            getChromeStorage('onUpdateAvailable', (res) => {
-                if (res && res.onUpdateAvailable) {
-                    Report.reportLog({
-                        objectType: Report.objectType.background_function_try,
-                        funcName: 'onUpdateAvailable',
+})
+
+chrome.runtime.onInstalled.addListener(onInstalledMethod);
+
+chrome.runtime.onMessage.addListener(onMessageMethod);
+
+// 定时器
+chrome.alarms.onAlarm.addListener(function (alarm) {
+    // console.log("onAlarm-", alarm);
+    switch (alarm.name) {
+        case 'denetChromeAlarm':
+            getMessageInfo();
+            break
+        case 'PingPong':
+            PingPong()
+            break;
+        case 'LuckMessage':
+            getSysMessage()
+            break
+    }
+});
+
+chrome.action.onClicked.addListener(function (tab) {
+    injectExtensionPopup(tab);
+});
+
+chrome.tabs.onActivated.addListener(function (activeInfo) {
+    setPopupConfig(activeInfo);
+})
+
+function thenInstalledMethod() {
+    try {
+
+        onInstalledCreateTab()
+        onInstalledMid()
+        onInstalledUserSet()
+        // pingpang
+        chrome.alarms.create('PingPong', {
+            //1分鐘之後開始(該值不能小於1) 
+            delayInMinutes: 2,
+            //開始後每一分鐘執行一次(該值不能小于1) 
+            periodInMinutes: 4
+        });
+        chrome.alarms.create('LuckMessage', {
+            //1分鐘之後開始(該值不能小於1) 
+            delayInMinutes: 1,
+            //開始後每一分鐘執行一次(該值不能小于1) 
+            periodInMinutes: 1
+        });
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'thenInstalledMethod',
+            errMsg: error.message
+        });
+    }
+}
+
+// 2.reportLog 异常 存储到本地,再上报
+// 3.onInstalledMethod 执行了那个
+
+function onInstalledMethod() {
+    try {
+        // 3.onInstalledMethod 执行了那个
+        // 版本更新判断
+        getChromeStorage('baseInfo', (info) => {
+            if (!info || !info.appVersionCode) {
+                setChromeStorage({ onInstalledMethod: JSON.stringify({ onInstalledMethod: '1' }) })
+                setChromeStorage({ baseInfo: JSON.stringify({ appVersionCode }) })
+                thenInstalledMethod()
+            } else if (appVersionCode != info.appVersionCode) {
+                setChromeStorage({ onInstalledMethod: JSON.stringify({ onInstalledMethod: '2' }) }, () => {
+                    setChromeStorage({ baseInfo: JSON.stringify({ appVersionCode }) }, () => {
+                        chrome.runtime.reload()
                     })
-                }
-            })
-        } catch (error) {
-            Report.reportLog({
-                objectType: Report.objectType.background_function_catch,
-                funcName: 'onInstalledMethod',
-                errMsg: error.message
-            })
-        }
+                })
+            } else {
+                setChromeStorage({ onInstalledMethod: JSON.stringify({ onInstalledMethod: '3' }) })
+                thenInstalledMethod()
+            }
+        })
+
+        // 1.onUpdateAvailable 存储到本地,再上报
+        getChromeStorage('onUpdateAvailable', (res) => {
+            if (res && res.onUpdateAvailable) {
+                Report.reportLog({
+                    objectType: Report.objectType.background_function_try,
+                    funcName: 'onUpdateAvailable',
+                })
+            }
+        })
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'onInstalledMethod',
+            errMsg: error.message
+        })
     }
+}
 
-    function onMessageMethod(req, sender, sendResponse) {
-        try {
-            if (req) {
-                switch (req.actionType) {
-                    case "POPUP_LOGIN":
-                        twitterPinLoginToken();
-                        break;
-                    case "POPUP_PUBLISH_TWITTER_RED_PACK":
-                        popupRePublish(req);
-                        break;
-                    case "POPUP_SHOW_DENET_PUBLISH_DIALOG":
-                        checkShowPublishDialog();
-                        break;
-                    case 'CONTENT_GET_PINED':
-                        checkPined();
-                        break;
-                    case 'CONTENT_SET_BADGE':
-                        setBadgeInfo(req);
-                        break;
-                    case 'CONTENT_HIDE_BADGE':
-                        hideBadge();
-                        break
-                    case 'CONTENT_SEND_CODE':
-                        twitterPinLoginCode(sender, req.code);
-                        break;
-                    case 'CONTENT_TWITTER_LOGIN':
-                        if (req.data) {
-                            twitterPinLoginToken()
+function onMessageMethod(req, sender, sendResponse) {
+    try {
+        if (req) {
+            switch (req.actionType) {
+                case "POPUP_LOGIN":
+                    twitterPinLoginToken();
+                    break;
+                case "POPUP_PUBLISH_TWITTER_RED_PACK":
+                    popupRePublish(req);
+                    break;
+                case "POPUP_SHOW_DENET_PUBLISH_DIALOG":
+                    checkShowPublishDialog();
+                    break;
+                case 'CONTENT_GET_PINED':
+                    checkPined();
+                    break;
+                case 'CONTENT_SET_BADGE':
+                    setBadgeInfo(req);
+                    break;
+                case 'CONTENT_HIDE_BADGE':
+                    hideBadge();
+                    break
+                case 'CONTENT_SEND_CODE':
+                    twitterPinLoginCode(sender, req.code);
+                    break;
+                case 'CONTENT_TWITTER_LOGIN':
+                    if (req.data) {
+                        twitterPinLoginToken()
+                    }
+                    break
+                case "CONTENT_SEND_DISCORD_AUTH_CODE":
+                    discordLoginCode(req, sender);
+                    break
+                case 'RED_PACKET_SAVE_DISCORD_AUTH_WINDOW_ID':
+                    saveDiscordAuthWindowId(req);
+                    break;
+                case 'CONTENT_FACEBOOK_SHARE_SUCCESS':
+                    facebookShareSuccess(req, sender);
+                    break;
+                case 'CONTENT_PONG':
+                    console.log('CONTENT_PONG')
+                    break
+                case 'CONTENT_WINDOW_LOADED_SET_POPUP_PAGE':
+                    // windwoLoadSetPopupPage(req, sender);
+                    break;
+                case 'CONTENT_SET_POPUP_CONFIG':
+                    setActionPopup(req, sender);
+                    break;
+                case 'CONTENT_GET_TWITTER_NFT_POST_PRE':
+                    getTwitterNftPostPre(req.data, sender)
+                    break
+                case 'CONTENT_NFT_TXT_PUBLISH':
+                    nftTxtPublish(req.data, sender)
+                    break
+                case 'CONTENT_HTTP_NET_WORK':
+                    httpNetWork(req.funcName, req.data, sender)
+                    break
+                case 'HTTP_CONTENT_TO_BACK':
+                    httpContentToBack(req, sender)
+                    break
+                case 'CONTENT_TWITTER_SHORT_LINK':
+                    sendResponse('ok')
+                    req.arr_url.forEach(item => {
+                        if (item) {
+                            twitterShortUrl(sender, item)
                         }
-                        break
-                    case "CONTENT_SEND_DISCORD_AUTH_CODE":
-                        discordLoginCode(req, sender);
-                        break
-                    case 'RED_PACKET_SAVE_DISCORD_AUTH_WINDOW_ID':
-                        saveDiscordAuthWindowId(req);
-                        break;
-                    case 'CONTENT_FACEBOOK_SHARE_SUCCESS':
-                        facebookShareSuccess(req, sender);
-                        break;
-                    case 'CONTENT_PONG':
-                        console.log('CONTENT_PONG')
-                        break
-                    case 'CONTENT_WINDOW_LOADED_SET_POPUP_PAGE':
-                        // windwoLoadSetPopupPage(req, sender);
-                        break;
-                    case 'CONTENT_SET_POPUP_CONFIG':
-                        setActionPopup(req, sender);
-                        break;
-                    case 'CONTENT_GET_TWITTER_NFT_POST_PRE':
-                        getTwitterNftPostPre(req.data, sender)
-                        break
-                    case 'CONTENT_NFT_TXT_PUBLISH':
-                        nftTxtPublish(req.data, sender)
-                        break
-                    case 'CONTENT_HTTP_NET_WORK':
-                        httpNetWork(req.funcName, req.data, sender)
-                        break
-                    case 'HTTP_CONTENT_TO_BACK':
-                        httpContentToBack(req, sender)
-                        break
-                    case 'CONTENT_TWITTER_SHORT_LINK':
-                        sendResponse('ok')
-                        req.arr_url.forEach(item => {
-                            if (item) {
-                                twitterShortUrl(sender, item)
-                            }
-                        });
-                        break
-                    case 'CONTENT_CLOSE_ACH_PAY_NOTICE':
-                        closeAchPayNoticeHandler();
-                        break;
-                }
+                    });
+                    break
+                case 'CONTENT_CLOSE_ACH_PAY_NOTICE':
+                    closeAchPayNoticeHandler();
+                    break;
             }
-        } catch (error) {
-            Report.reportLog({
-                objectType: Report.objectType.background_function_catch,
-                funcName: 'onMessageMethod',
-                errMsg: error.message
-            });
         }
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'onMessageMethod',
+            errMsg: error.message
+        });
     }
-} catch (error) {
-    console.log('error', error)
-}
+}

+ 14 - 5
src/entry/content.js

@@ -105,6 +105,15 @@ window.onmessage = (res) => {
             // case "IFRAME_DO_TASK":
             //     findTweetByIdDoTask(res.data.task_data, res.data.task_type)
             //     break
+            case 'IFREME_TAB_GROUP_SET_IFRAME_HEIGHT':
+                setTabGroupIframeStyle(res.data.data);
+                break
+            case 'IFREME_TAB_GROUP_CONTENT_GET_NAV_TOP':
+                getTweetProfileNavTop(res.data.data);
+                break;
+            case 'IFRAME_PAGE_JUMP':
+                pageJumpHandler(res.data.data);
+                break;
         }
     }
 };
@@ -149,11 +158,11 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
         case 'BG_SET_POPUP_CONFIG':
             setPopupConfByPopupPage();
             break
-        case 'IFREME_TAB_GROUP_SET_IFRAME_HEIGHT':
-            setTabGroupIframeStyle(req.data);
-            break
-        case 'IFREME_TAB_GROUP_CONTENT_GET_NAV_TOP':
-            getTweetProfileNavTop(req.data);
+        // case 'IFREME_TAB_GROUP_SET_IFRAME_HEIGHT':
+        //     setTabGroupIframeStyle(req.data);
+        //     break
+        // case 'IFREME_TAB_GROUP_CONTENT_GET_NAV_TOP':
+        //     getTweetProfileNavTop(req.data);
         case 'IFRAME_PAGE_JUMP':
 
             pageJumpHandler(req.data);

+ 3 - 1
src/http/configAPI.js

@@ -38,4 +38,6 @@ export const discordAuthRedirectUri = `${pageUrl}/auth/discordCallback`;
 
 export const faceShareRedirectUrl = `${pageUrl}/facebook/shareCallback`;
 
-export const payAchNoticeUrl = `${pageUrl}/ach_pay/pay_notice`;
+export const payAchNoticeUrl = `${pageUrl}/ach_pay/pay_notice`;
+
+export const iframeHost = process.env.VUE_APP_IFRAME_HOST;

+ 68 - 0
src/http/treasure.js

@@ -0,0 +1,68 @@
+import { service } from "./request";
+
+export function treasureDetail(params) {
+    return service({
+        url: `/post/treasure/detail`,
+        method: "post",
+        data: params,
+    });
+}
+
+
+export function inviteChannel(params) {
+    return service({
+        url: `/post/treasure/invite/channel`,
+        method: "post",
+        data: params,
+    });
+}
+
+export function inviteDetail(params) {
+    return service({
+        url: `/post/treasure/invite/detail`,
+        method: "post",
+        data: params,
+    });
+}
+
+export function inviteList(params) {
+    return service({
+        url: `/post/treasure/invite/list`,
+        method: "post",
+        data: params,
+    });
+}
+
+export function treasureOpen(params) {
+    return service({
+        url: `/post/treasure/open`,
+        method: "post",
+        data: params,
+    });
+}
+
+export function prepareStart(params) {
+    return service({
+        url: `/post/treasure/prepareStart`,
+        method: "post",
+        data: params,
+    });
+}
+
+
+export function receiveList(params) {
+    return service({
+        url: `/post/treasure/receive/list`,
+        method: "post",
+        data: params,
+    });
+}
+
+
+export function treasureStart(params) {
+    return service({
+        url: `/post/treasure/start`,
+        method: "post",
+        data: params,
+    });
+}

+ 9 - 0
src/http/treasureApi.js

@@ -0,0 +1,9 @@
+import { service } from "./request";
+
+export function upGainCalculate(params) {
+    return service({
+        url: `/post/treasure/upGainCalculate`,
+        method: 'post',
+        data: params
+    })
+}

+ 1 - 2
src/iframe/tool-box.js

@@ -1,5 +1,4 @@
 import { createApp } from 'vue'
 import App from '@/view/iframe/tool-box/index.vue'
-
 const app = createApp(App);
-app.mount('#app');
+app.mount('#app');

+ 5 - 0
src/iframe/treasure-hunt.js

@@ -0,0 +1,5 @@
+import { createApp } from 'vue'
+import App from '@/view/iframe/test/index.vue'
+
+const app = createApp(App);
+app.mount('#app');

+ 21 - 1
src/log-center/logger.js

@@ -97,4 +97,24 @@ function wrapObject(extParams) {
  */
 function typeDecide(o, type) {
     return Object.prototype.toString.call(o) === `[object ${type}]`;
-}
+}
+
+export async function getReportCommonParams () {
+  let commonParams = {};
+  if (!userInfo) {
+      userInfo = await getChromeStorage('userInfo') || null;
+  }
+  let isMobile = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
+  let platform = isMobile ? `mobile` : `pc`;
+
+  if (chrome && chrome.tabs) {
+      let tab = await chrome.tabs.getCurrent();
+      commonParams = {
+          url: tab && tab.url ? tab.url : '',
+          platform,
+          browser: getBrowser(),
+          twitterId: userInfo && userInfo.nickName || '',
+      }
+  }
+  return commonParams;
+}

+ 9 - 0
src/logic/background/twitter.js

@@ -405,6 +405,15 @@ export function onInstalledCreateTab() {
                         });
                     }
                     break
+                case 'treasure_info':
+                  if (res && res.postNickName && res.srcContentId) {
+                      created_detail = true
+                      url = `https://twitter.com/${res.postNickName}/status/${res.srcContentId}`
+                      chrome.tabs.create({
+                          url
+                      });
+                  }
+                  break;
             }
 
             if (created_detail == false) {

+ 30 - 0
src/logic/content/ParseCard.js

@@ -285,6 +285,13 @@ class ParseCard {
         _iframe.style.cssText = 'border:medium none; width:505px; min-height:180px;'
         return _iframe
     }
+    createTreasureIframe(params = { page_type, tweet_Id, post_Id, invite_code }) {
+        let _iframe = document.createElement('iframe')
+        _iframe.id = params.post_Id
+        _iframe.src = chrome.runtime.getURL('/iframe/treasure-hunt.html') + `?params=${JSON.stringify(params)}`;
+        _iframe.style.cssText = 'border:medium none; width:375px; min-height:500px;'
+        return _iframe
+    }
     isHasIframeByArticle(dom_card) {
         if (!dom_card || !dom_card.parentElement) {
             return
@@ -473,6 +480,29 @@ class ParseCard {
             dom.appendChild(this.createIframe({ post_Id, tweet_Id, page_type }))
         }
     }
+    replaceDOMRreasureCard({ invite_code, dom_card, tweet_Id, post_Id, time, short_url, page_type = '' }) {
+        if (!dom_card || !dom_card.parentElement) {
+            return
+        }
+        let type
+        let dom = dom_card.querySelector('div[aria-labelledby]')
+        if (dom) {
+            type = 'card'
+            for (let i = 0; i < dom.childNodes.length; i++) {
+                if (dom.childNodes[i].dataset && dom.childNodes[i].dataset.testid && dom.childNodes[i].dataset.testid == 'card.wrapper') {
+                    dom.children[i].style.display = 'none'
+                }
+            }
+        } else {
+            type = 'txt'
+            dom = dom_card.querySelector('div[lang][dir=auto]').parentElement
+        }
+
+        dom.style = 'min-height:500px'
+        if (dom) {
+            dom.appendChild(this.createTreasureIframe({ post_Id, tweet_Id, page_type, invite_code }))
+        }
+    }
     replaceNftDomRedPacket({ dom_card, tweet_Id, post_Id, time, short_url }) {
         if (!dom_card || !dom_card.parentElement) {
             return

+ 198 - 82
src/logic/content/twitter.js

@@ -1,6 +1,6 @@
 import { getChromeStorage, setChromeStorage } from '@/uilts/chromeExtension.js'
 import { throttle, getQueryString, getCookie, nextTick, getQueryStringByUrl } from '@/uilts/help'
-import { discordAuthRedirectUri } from '@/http/configAPI'
+import { discordAuthRedirectUri, iframeHost } from '@/http/configAPI'
 import { reportSrcPublishEvent } from '@/http/publishApi'
 import Report from "@/log-center/log"
 import { fetchAddFinishEvent } from '@/logic/background/fetch/facebook';
@@ -9,6 +9,7 @@ import { jumpTwitterDetailByAlert, showEditTweet } from '@/logic/content/help/tw
 import { clearPostContent, setGroupIconStatus } from '@/logic/content/nft.js'
 import { toolBox } from '@/logic/content/ToolBox'
 import axios from 'axios';
+import messageCenter from '@/uilts/messageCenter';
 
 let dom = {};
 
@@ -275,66 +276,64 @@ function checkIsShowReSend(dom, params) {
  * @param isClick
  * @private
  */
-function _addDeNetEditBtn(params = {}) {
-    setTimeout(() => {
-        let toolElem = document.querySelector('div[data-testid="toolBar"]');
-        if (toolElem) {
-            let innerDeIcon = document.getElementById('de-btn1');
-            if (!innerDeIcon) {
-                toolElem.firstChild.appendChild(createTweetToolbarDenet());
-                popupShowGiveawayDialog();
-                Report.reportLog({
-                    pageSource: Report.pageSource.mainPage,
-                    businessType: Report.businessType.buttonView,
-                    objectType: Report.objectType.buttonSecond
-                }, {
-                    type: 0
-                });
-            }
+ function _addDeNetEditBtn(params = {}) {
+    let toolElem = document.querySelector('div[data-testid="toolBar"]');
+    if (toolElem) {
+        let innerDeIcon = toolElem.querySelector('#de-btn1');
+        if (!innerDeIcon) {
+            toolElem.firstChild.appendChild(createTweetToolbarDenet());
+            popupShowGiveawayDialog();
+            Report.reportLog({
+                pageSource: Report.pageSource.mainPage,
+                businessType: Report.businessType.buttonView,
+                objectType: Report.objectType.buttonSecond
+            }, {
+                type: 0
+            });
+        }
 
-            let innerToolBoxIcon = document.getElementById('de-tool-box-btn-01');
-            if (!innerToolBoxIcon) {
-                toolElem.firstChild.appendChild(createTweetToolbarToolBox())
-                Report.reportLog({
-                    pageSource: Report.pageSource.mainPage,
-                    businessType: Report.businessType.buttonView,
-                    objectType: Report.objectType.buttonSecond
-                }, {
-                    type: 1
-                });
-            }
-        } else {
-            setTimeout(() => {
-                let toolElem = document.querySelector('div[data-testid="toolBar"]');
-                if (toolElem) {
-                    let innerDeIcon = document.getElementById('de-btn1');
-                    if (!innerDeIcon) {
-                        toolElem.firstChild.appendChild(createTweetToolbarDenet());
-                        popupShowGiveawayDialog();
-                        Report.reportLog({
-                            pageSource: Report.pageSource.mainPage,
-                            businessType: Report.businessType.buttonView,
-                            objectType: Report.objectType.buttonSecond
-                        }, {
-                            type: 0
-                        });
-                    }
+        let innerToolBoxIcon = toolElem.querySelector('#de-tool-box-btn-01');
+        if (!innerToolBoxIcon) {
+            toolElem.firstChild.appendChild(createTweetToolbarToolBox())
+            Report.reportLog({
+                pageSource: Report.pageSource.mainPage,
+                businessType: Report.businessType.buttonView,
+                objectType: Report.objectType.buttonSecond
+            }, {
+                type: 1
+            });
+        }
+    } else {
+        setTimeout(() => {
+            let toolElem = document.querySelector('div[data-testid="toolBar"]');
+            if (toolElem) {
+                let innerDeIcon = toolElem.querySelector('#de-btn1');
+                if (!innerDeIcon) {
+                    toolElem.firstChild.appendChild(createTweetToolbarDenet());
+                    popupShowGiveawayDialog();
+                    Report.reportLog({
+                        pageSource: Report.pageSource.mainPage,
+                        businessType: Report.businessType.buttonView,
+                        objectType: Report.objectType.buttonSecond
+                    }, {
+                        type: 0
+                    });
+                }
 
-                    let innerToolBoxIcon = document.getElementById('de-tool-box-btn-01');
-                    if (!innerToolBoxIcon) {
-                        toolElem.firstChild.appendChild(createTweetToolbarToolBox())
-                        Report.reportLog({
-                            pageSource: Report.pageSource.mainPage,
-                            businessType: Report.businessType.buttonView,
-                            objectType: Report.objectType.buttonSecond
-                        }, {
-                            type: 1
-                        });
-                    }
+                let innerToolBoxIcon = toolElem.querySelector('#de-tool-box-btn-01');
+                if (!innerToolBoxIcon) {
+                    toolElem.firstChild.appendChild(createTweetToolbarToolBox())
+                    Report.reportLog({
+                        pageSource: Report.pageSource.mainPage,
+                        businessType: Report.businessType.buttonView,
+                        objectType: Report.objectType.buttonSecond
+                    }, {
+                        type: 1
+                    });
                 }
-            }, 1000)
-        }
-    })
+            }
+        }, 1000)
+    }
 }
 
 const popupShowGiveawayDialog = async () => {
@@ -717,8 +716,9 @@ function onWindowResize() {
 function checkHasDeBtn() {
     try {
         let toolBar = document.querySelector('div[data-testid="toolBar"]');
-        let innerDeIcon = document.getElementById('de-btn1');
-        if (toolBar && !innerDeIcon) {
+        let append = toolBar && !toolBar.querySelector('#de-btn1');
+
+        if (append) {
             _addDeNetEditBtn();
         }
     } catch (e) {
@@ -741,9 +741,9 @@ export function bindTwitterArtMethod() {
             }
         }).then((res) => {
             if (res.code == 0) {
-                Report.reportLog({
-                    objectType: Report.objectType.tweetPostBinded
-                });
+                // Report.reportLog({
+                //     objectType: Report.objectType.tweetPostBinded
+                // });
                 bindTwitterArt.needBind = false;
                 bindTwitterArt.postId = '';
                 bindTwitterArt.isBindIng = false;
@@ -830,6 +830,26 @@ function setIframeRedPacket(type = 'twitter') {
                     } else if (item && item.post_Id && !item.post_Id.includes('/')) {
                         item.page_type = '红包'
                         parseCard.replaceDOMRedPacket(item)
+                        // 夺宝链接
+                    } else if (item && item.post_Id && item.post_Id.includes('treasure/')) {
+                        // https://testh5.denetme.net/treasure/{postid}
+                        // https://testh5.denetme.net/treasure/invite/{inviteCode}
+                        // 邀请链接 
+                        if (item.post_Id.includes('invite/')) {
+                            item.invite_code = item.post_Id.split('invite/')[1] || ''
+                            item.page_type = '邀请链接'
+                            if (item.invite_code) {
+                                item.post_Id = ''
+                                parseCard.replaceDOMRreasureCard(item)
+                            }
+                        } else {
+                            // 原始链接
+                            item.page_type = '原始链接'
+                            item.post_Id = item.post_Id.split('treasure/')[1] || ''
+                            if (item.post_Id) {
+                                parseCard.replaceDOMRreasureCard(item)
+                            }
+                        }
                     }
                 }
                 if (res.need_net_short_url.length > 0) {
@@ -902,6 +922,7 @@ function initParseCard() {
             clearInterval(timer)
             setInterval(() => {
                 onChangePageMain(inTwitterNode)
+                checkHasDeBtn()
                 twitterPinLogin()
                 showNFTGroupIcon()
                 if (queue_num <= 0) {
@@ -909,7 +930,6 @@ function initParseCard() {
                 }
                 initGroupTip()
                 setIframeRedPacket()
-                checkHasDeBtn()
                 checkHasSliderDeBtn();
                 changeQueueNum(-1)
                 showNFTCard()
@@ -1314,7 +1334,7 @@ export function getTweetAuthorByDom(params) {
         }
     }
 }
-export function doTaskTwitterAPI({ task_data, task_type }) {
+export function doTaskTwitterAPI({ task_data, task_type, tasks }) {
     switch (task_type) {
         case 'like':
             TwitterLikeAPI(task_data.tweet_Id)
@@ -1329,6 +1349,32 @@ export function doTaskTwitterAPI({ task_data, task_type }) {
                 }
             })
             break
+        case 'tasks':
+            tasks.forEach((item) => {
+                // 
+                switch (String(item.type)) {
+                    // 关注指定用户
+                    case '1':
+                        item.relatedUsers.forEach((item) => {
+                            if (item.name && item.twitterUserId) {
+                                TwitterFollowAPI(item, task_data.tweet_Id)
+                            }
+                        })
+                        break
+                    // 点赞
+                    case '2':
+                        TwitterLikeAPI(task_data.tweet_Id)
+                        break
+
+                    // 推文发推
+                    case '10':
+                        // 发推
+                        TwitterApiCreateTweet({ text: task_data.tweet_text, tweet_Id: task_data.tweet_Id })
+                        break
+                }
+
+            })
+            break
     }
 }
 
@@ -1431,6 +1477,60 @@ const TwitterLikeAPI = (tweet_Id) => {
     })
 }
 
+
+const TwitterApiCreateTweet = ({ text, tweet_Id }) => {
+    let data = {
+        queryId: "hC1nuE-2d1NX5LYBuuAvtQ",
+        features: {
+            "dont_mention_me_view_api_enabled": true,
+            "interactive_text_enabled": true,
+            "responsive_web_uc_gql_enabled": false,
+            "vibe_api_enabled": true,
+            "responsive_web_edit_tweet_api_enabled": false,
+            "standardized_nudges_misinfo": true,
+            "responsive_web_enhance_cards_enabled": false
+        },
+        variables: {
+            "tweet_text": text,
+            "media": {
+                "media_entities": [],
+                "possibly_sensitive": false
+            },
+            "withDownvotePerspective": true,
+            "withReactionsMetadata": false,
+            "withReactionsPerspective": false,
+            "withSuperFollowsTweetFields": true,
+            "withSuperFollowsUserFields": true,
+            "semantic_annotation_ids": [],
+            "dark_request": false
+        }
+    };
+    axios.post(`https://twitter.com/i/api/graphql/hC1nuE-2d1NX5LYBuuAvtQ/CreateTweet`,
+        data, {
+        headers: {
+            "accept": "*/*",
+            "accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
+            "authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
+            "content-type": "application/json",
+            "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"101\", \"Google Chrome\";v=\"101\"",
+            "sec-ch-ua-mobile": "?0",
+            "sec-ch-ua-platform": "\"Windows\"",
+            "sec-fetch-dest": "empty",
+            "sec-fetch-mode": "cors",
+            "sec-fetch-site": "same-origin",
+            "x-csrf-token": getCookie('ct0'),
+            "x-twitter-active-user": "yes",
+            "x-twitter-auth-type": "OAuth2Session",
+            "x-twitter-client-language": "en"
+        },
+    }).then(function (response) {
+        chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'createTweet', task_data: '', task_done: true })
+    }).catch(function (err) {
+        chrome.runtime.sendMessage({ actionType: "DO_TASK", do_type: 'api', tweet_Id, task_type: 'createTweet', task_data: '', task_done: false })
+    });
+}
+
+
 export const TwitterApiUserByScreenName = (params) => {
     let { screen_name } = params;
     axios.get(`https://twitter.com/i/api/graphql/mCbpQvZAw6zu_4PvuAUVVQ/UserByScreenName?variables=%7B%22screen_name%22%3A%22${screen_name}%22%2C%22withSafetyModeUserFields%22%3Atrue%2C%22withSuperFollowsUserFields%22%3Atrue%7D`, {
@@ -2004,7 +2104,7 @@ const hiddenMaskWeb3Tab = (count) => {
  * 跳转到个人主页 检查是否需要选中 Group tab
  */
 const checkNeedSelectGroupTab = () => {
-    if (window.location.pathname != '/home') {
+    if (window.location.pathname != '/home' && !document.hidden) {
         setTimeout(() => {
             getChromeStorage('groupTabData', (res) => {
                 console.log('groupTabData', res);
@@ -2107,10 +2207,12 @@ const addPageScrollEvent = () => {
         contentHeight: contentDom.offsetHeight
     }
 
-    chrome.runtime.sendMessage({
-        actionType: "CONTENT_GROUP_LIST_SCROLL",
-        data: data
-    }, () => { });
+    messageCenter.send('de-tab-group-content', 'CONTENT_GROUP_LIST_SCROLL', data)
+
+    // chrome.runtime.sendMessage({
+    //     actionType: "CONTENT_GROUP_LIST_SCROLL",
+    //     data: data
+    // }, () => { });
 };
 
 const removeTweetTabEvent = (params) => {
@@ -2191,10 +2293,11 @@ const setGroupTabSelfStyle = (params = {}) => {
  * 切换到 Group tab时 刷新列表
  */
 export const refreshTabGroup = () => {
-    chrome.runtime.sendMessage({
-        actionType: "CONTENT_REFRESH_TAB_GROUP_LIST",
-        data: {}
-    }, () => { });
+    messageCenter.send('de-tab-group-content', 'CONTENT_REFRESH_TAB_GROUP_LIST', {})
+    //     chrome.runtime.sendMessage({
+    //         actionType: "CONTENT_REFRESH_TAB_GROUP_LIST",
+    //         data: {}
+    //     }, () => { });
 }
 
 /**
@@ -2271,7 +2374,7 @@ const addTabGroupContent = (cb) => {
     }
     let iframe = document.createElement('iframe');
     iframe.id = 'de-tab-group-content';
-    iframe.src = chrome.runtime.getURL('/iframe/tab-group.html') + `?params=${JSON.stringify(params)}`;
+    iframe.src = `${iframeHost}/tab-group` + `?params=${JSON.stringify(params)}`;
     iframe.style.cssText = `border: medium none; height: 500px;display: none`
 
     let iframeContent = getGroupTabContentNode();
@@ -2372,12 +2475,19 @@ export const pageJumpHandler = (params) => {
 export const getTweetProfileNavTop = (params) => {
     let top = document.querySelector('div[role="tablist"]').closest('nav').getBoundingClientRect().top;
 
-    chrome.runtime.sendMessage({
-        actionType: "CONTENT_SEND_GROUP_NAV_TOP", data: {
+    messageCenter.send({
+        actionType: "CONTENT_SEND_GROUP_NAV_TOP",
+        data: {
             top,
             scrollTop: params.scrollTop
         }
-    }, () => { })
+    })
+    // chrome.runtime.sendMessage({
+    //     actionType: "CONTENT_SEND_GROUP_NAV_TOP", data: {
+    //         top,
+    //         scrollTop: params.scrollTop
+    //     }
+    // }, () => { })
 }
 
 
@@ -2432,13 +2542,19 @@ const getSysTheme = () => {
 const sysThemeChange = () => {
     setTimeout(() => {
         let bgColor = document.querySelector('body').style.backgroundColor;
-
-        chrome.runtime.sendMessage({
-            actionType: "CONTENT_SYS_THEME_CHANGE", data: {
+        messageCenter.send({
+            actionType: "CONTENT_SYS_THEME_CHANGE",
+            data: {
                 theme: systemInfo.theme,
                 twitterTheme: bgColor == 'rgb(0, 0, 0)' ? 'dark' : 'light'
             }
-        }, () => { })
+        })
+        // chrome.runtime.sendMessage({
+        //     actionType: "CONTENT_SYS_THEME_CHANGE", data: {
+        //         theme: systemInfo.theme,
+        //         twitterTheme: bgColor == 'rgb(0, 0, 0)' ? 'dark' : 'light'
+        //     }
+        // }, () => { })
     }, 800)
 }
 

+ 2 - 1
src/manifest.json

@@ -98,7 +98,8 @@
                 "/iframe/tool-box-buy-nft.html",
                 "/iframe/test.html",
                 "/iframe/ach-cashier.html",
-                "/img/icon-denet-logo.svg"
+                "/img/icon-denet-logo.svg",
+                "/iframe/treasure-hunt.html"
             ],
             "matches": [
                 "<all_urls>"

+ 6 - 2
src/types/global.js

@@ -6,10 +6,12 @@
  * 玩法类型
  * 普通任务:common=1;
  * 抽奖:lottery=2
+ * 夺宝:treasure=3
  */
 export const PlayType = {
   common: 1,
   lottery: 2,
+  treasure: 3
 };
 
 /**
@@ -32,6 +34,7 @@ export const TaskType = {
   joinDiscord: 7,
   repostToFacebook: 8,
   twitterCommentAndTag: 9,
+  twitterRePost: 10
 };
 
 /**
@@ -40,6 +43,7 @@ export const TaskType = {
 
 export const PostType = {
   giveaway: 1,
-  nftGroup: 2,
-  postEditor: 3
+  lottery: 2,
+  postEditor: 3,
+  treasure: 4
 }

+ 50 - 0
src/uilts/messageCenter/index.js

@@ -0,0 +1,50 @@
+class MessageCenter { 
+    constructor() { 
+        this.iframeMap = new Map();
+        this.messageCallbackMap = new Map();
+        // this.listen()
+    }
+
+    findIframeById(id) { 
+        let target = this.iframeMap.get(id);
+        if (!target) { 
+            target = document.getElementById(id)
+            this.iframeMap.set('id', target)
+        }
+        return target
+    }
+
+    send(id, actionType, data) {
+        const target = this.findIframeById(id);
+        target && target.contentWindow.postMessage({
+            actionType,
+            data
+        }, '*')
+    }
+
+    // don't use
+    add(actionType, callback) {
+        let activeQuene = this.messageCallbackMap.get(actionType);
+        if (activeQuene?.length > 0) {
+            activeQuene.push(callback)
+        } else { 
+            this.messageCallbackMap.set(actionType, [callback])
+        }
+    }
+    // don't use
+    listen() { 
+        window.addEventListener('message', (e) => { 
+            const { actionType, data } = e.data;
+            console.log('get message in content ...', actionType, data)
+            const quene = this.messageCallbackMap.get(actionType) ||  [];
+            while (quene.length > 0) { 
+                let callback = quene.pop();
+                callback(data)
+            }
+        })
+    }
+}
+
+const messageCenter = new MessageCenter();
+
+export default messageCenter;

+ 19 - 7
src/view/components/component-zoom.vue

@@ -5,26 +5,38 @@
     </span>
 </template>
 <script setup>
-import { ref, defineProps, onMounted, getCurrentInstance } from 'vue'
+import { ref, defineProps, onMounted, watch } from 'vue'
 
 let props = defineProps({
     width: {
-        type: String,
+        type: [String, Number],
         default: '375'
     },
     fontSize: {
         type: String,
         default: '22'
+    },
+    txt: {
+        type: String,
+        default: ''
     }
 })
 
+watch(() => props.txt, (newVal) => {
+    setFontZoom(300)
+},
+{
+    deep: true
+})
+
 let zoom = ref(1);
-let currentInstance;
+let zoomDom = ref({});
 
-const setFontZoom = () => {
-    const currentInstance = getCurrentInstance()
-    let offsetWidth = currentInstance.ctx.$refs.zoomDom.offsetWidth;
-    zoom.value = offsetWidth > props.width ? +props.width / offsetWidth : 1
+const setFontZoom = (time = 600) => {
+    setTimeout(() => {
+        let offsetWidth = zoomDom.value && zoomDom.value.offsetWidth || props.width;
+        zoom.value = offsetWidth > props.width ? +props.width / offsetWidth : 1
+    }, time)
 }
 
 onMounted(() => {

+ 0 - 1
src/view/components/currency-list.vue

@@ -356,7 +356,6 @@ defineExpose({
     .list-wrapper {
         height: calc(100% - 60px);
         overflow-y: auto;
-        padding-bottom: 50px;
 
         .list-item {
             .item-title {

+ 152 - 14
src/view/components/custom-card-cover.vue

@@ -21,51 +21,83 @@
         </div>
     </div>
     <div class="not-open" v-else-if="isMoneyRewardCpd">
-        <img class="cover" v-if="data.type == 2" :src="require('@/assets/svg/img-preview-draw-bg.svg')"  />
-        <img class="cover" v-else :src="require('@/assets/subject/001-card.png')"  />
+        <img class="cover" v-if="data.type == PlayType.lottery" :src="require('@/assets/svg/img-preview-draw-bg.svg')"  />
+        <img class="cover" v-else-if="data.type == PlayType.common" src="@/assets/subject/001-card.png"  />
+        <img class="cover" v-else-if="data.type == PlayType.treasure" :src="require('@/assets/svg/img-preview-treasure-01-bg.svg')"  />
 
         <img class="open-gif"
-            v-if="data.type == 2"
+            v-if="data.type == PlayType.lottery"
             src="@/assets/img/img-preview-draw-box.png" />
         <img class="open-gif"
-            v-else
+            v-else-if="data.type == PlayType.common"
             :src="require('@/assets/gif/001.gif')" />
 
-        <img v-if="data.type == 2"
+        <img v-if="data.type == PlayType.lottery"
             :src="require('@/assets/svg/img-preview-draw-open.svg')"
             class="open"
             @click="open" />
-        <img v-else
+        <img v-else-if="data.type == PlayType.common"
             :src="require('@/assets/svg/icon-open.svg')"
             class="open"
             @click="open"/>
 
         <div class="title" v-if="data.userInfo">
             <img :src="data.userInfo.avatarUrl" />
-            <span>{{
-                data.userInfo.nickName || ""
-            }}</span>
+            <span v-if="data.type != PlayType.treasure">
+                {{data.userInfo.nickName || ""}}
+            </span>
+            <span class="treasure-info" v-else>
+                from @{{data.userInfo.nickName || ""}}
+            </span>
         </div>
-        <div class="money-area">
+
+        <div class="money-area" v-if="data.type != PlayType.treasure">
             <div class="txt">
                 <span>{{data.currencyCode == 'USD' ? 'US Dollar' : data.tokenSymbol}} </span>
                 &nbsp;GIVEAWAY
             </div>
             <div class="coin">
-                <img :src="data.currencyIconUrl || imgHeaderCover" />
+                <img v-if="data.currencyIconUrl" :src="data.currencyIconUrl || imgHeaderCover" />
                 <span id="preview-after-amount"
                     :style="{
                         fontSize: amount_font_size + 'px'
-                    }">{{ data.amountValue }}</span>
+                    }">{{ data.amountValue || 0 }}</span>
             </div>
-            <div class="time-area" v-if="data.type == 2">
+            <div class="time-area" v-if="data.type == PlayType.lottery">
                 <img class="icon-clock" :src="require('@/assets/svg/icon-time.svg')" />
                 {{data.countDown || formatSecondsAsDaysOrTime(data.validityDuration * 3600)}} 
             </div>
-            <div class="people" v-else>
+            <div class="people" v-else-if="data.type == PlayType.common">
                 {{ data.totalCount }} WINNERS TO SHARE
             </div>
         </div>
+        <div class="treasure-card-info" v-else>
+            <div class="treasure-row-1">
+                <div class="left">Treasure</div>
+                <component-zoom :width="160" :txt="data.amountValue || 0">
+                    <div class="right">${{ data.usdEstimateOrderAmount || 0 }}</div>
+                </component-zoom>
+            </div>
+
+            <div class="treasure-row-2">
+                Your Gain Up to $ <div class="amount">{{data.upGainAmountUsdValue}}</div>
+            </div>
+
+            <div class="treasure-row-3" :style="{'visibility': data.currencyCode? 'visible' : 'hidden'}">
+                <img class="img" :src="data.currencyIconUrl" /> <span class="txt"> {{data.tokenSymbol}} equivalent (Crypto)</span>
+            </div>
+
+            <img class="img-treasure-big" :src="require('@/assets/img/icon-card-cover-treasure-big.png')">
+
+            <div class="treasure-row-4">
+               <img class="img" :src="require('@/assets/svg/icon-card-cover-treasure-tasks.svg')"> to Hunt Treasure
+            </div>
+
+            <div class="open-btn" @click="open">
+                <img :src="require('@/assets/svg/icon-card-cover-treasure-small.svg')" alt="">
+                START
+            </div>
+        </div>
     </div>
 
     <!-- 改版之后的卡片 -->
@@ -130,6 +162,7 @@ const props = defineProps({
                 },
                 rewardType: RewardType.money,
                 customizedReward: "",
+                upGainAmountUsdValue: ""
             };
         },
     },
@@ -250,6 +283,105 @@ onMounted(() => {
         }
     }
 
+    .treasure-card-info {
+        color: #fff; 
+        position: absolute; 
+        top: 86px;
+        width: 100%;
+        text-align: center;
+
+        .treasure-row-1 {
+            display: flex; 
+            align-items: center;
+            justify-content: center;
+            font-weight: 900;
+            font-size: 25px;
+
+            .left {
+                margin-right: 7px;
+                color: #FFC83A;
+            }
+
+            .right {
+                font-weight: 900;
+                font-size: 25px;
+            }
+        }
+
+        .treasure-row-2 {
+            margin: 6px 0; 
+            background: rgba(255, 255, 255, .1); 
+            width: 100%; 
+            height: 27px;
+            display: flex; 
+            align-items: center;
+            justify-content: center;
+            font-weight: 500;
+            font-size: 12px;
+
+            .amount {
+                font-weight: 800;
+                font-size: 17px;
+                margin-top: -2px;
+            }
+        }
+
+        .treasure-row-3 {
+            display: flex; 
+            align-items: center;
+            justify-content: center;
+
+            .img {
+                width: 13px; 
+                margin-right: 3px;
+            }
+
+            .txt {
+                zoom: .8;
+                opacity: 0.7;
+            }
+        }
+
+        .treasure-row-4 {
+            display: flex;
+            align-items:center;
+            justify-content: center;
+            color: #65C1FF;
+            margin-top: 18px;
+            font-size: 16px;
+
+            .img {
+                width: 76px;
+            }
+        }
+
+        .img-treasure-big {
+            width: 200px;
+        }
+
+        .open-btn {
+            width: 88%;
+            height: 40px;
+            background: #1D9BF0;
+            border-radius: 75px;
+            display: flex;
+            align-items:center;
+            justify-content: center;
+            cursor: pointer;
+            font-weight: 800;
+            font-size: 15px;
+            margin-top: 12px;
+            position: relative; 
+            left: 50%; 
+            transform: translateX(-50%);
+
+            img {
+                width: 18px;
+                margin-right: 5px;
+            }
+        }
+    }
+
     .title {
         position: absolute;
         top: 15px;
@@ -273,6 +405,12 @@ onMounted(() => {
             letter-spacing: 0.3px;
             color: #fff;
         }
+
+        .treasure-info {
+            color: #fff; 
+            opacity: 0.7;
+            font-weight: 300;
+        }
     }
 
     // .txt {

+ 112 - 28
src/view/components/custom-card-horizontal-cover.vue

@@ -6,47 +6,83 @@
         </template>
         <template v-else-if="isMoneyRewardCpd">
             <img :src="require('@/assets/img/img-preview-draw-after-bg.png')"
-                v-if="data.type == 2"
+                v-if="data.type == PlayType.lottery"
                 class="card-cover">
             <img :src="require('@/assets/subject/img-card-cover-blue.png')"
-                v-else
+                v-else-if="data.type == PlayType.common"
                 class="card-cover"/>
+            <img :src="require('@/assets/img/img-preview-treasure-link-bg.png')"
+                v-else-if="data.type == PlayType.treasure"
+                class="card-cover"/>
+
             <div class="bottom-bar">
                 <div class="title">
                     DeNet.me
                 </div>
                 <div class="desc">
-                    🎁 <template v-if="data.tokenSymbol=='USD'">$</template>{{data.amountValue}} GIVEAWAY
+                    DeNet: An Easy Web3 Tool For GIVEAWAY / AIRDROP
+                    <!-- 🎁 <template v-if="data.tokenSymbol=='USD'">$</template>{{data.amountValue}} GIVEAWAY -->
                 </div>
             </div>
+
             <div class="user-info">
                 <img :src="data.userInfo.avatarUrl" 
-                class="avatar"/> {{data.userInfo.name}}
+                class="avatar"/> 
+                <template v-if="data.type != PlayType.treasure">
+                    {{data.userInfo.nickName}}
+                </template>
+                <span class="treasure-info" style="color: #fff; opacity: 0.7;font-weight: 300;" v-else>
+                    from @{{data.userInfo.nickName || ""}}
+                </span>
             </div>
+
             <div class="content-text">
-                <div class="title">
-                    <span>{{data.currencyCode == 'USD' ? 'US Dollar' : data.tokenSymbol}} </span>
-                    &nbsp;GIVEAWAY
-                </div>
-                <div class="center"
-                    :style="{
-                        fontSize: amountFontSize + 'px'
-                    }">
-                    <img :src="data.currencyIconUrl" class="icon">
-                    <span id="preview-before-amount">
-                        {{data.amountValue}}
-                    </span>
-                </div>
-                <div class="desc">
-                    <template  v-if="data.type == 2">
-                        <img class="icon-clock" 
-                        :src="require('@/assets/svg/icon-preview-clock.svg')" />  {{data.validityDuration}} H
-                        <img class="icon-trophy" 
-                        :src="require('@/assets/svg/icon-preview-trophy.svg')" /> <span class="trophy-count">{{data.totalCount}} WINNERS</span>
-                    </template>
-                    <template v-else>
-                        {{data.totalCount}} WINNERS TO SHARE
-                    </template>
+                <template v-if="data.type != PlayType.treasure">
+                    <div class="title">
+                        <span>{{data.currencyCode == 'USD' ? 'US Dollar' : data.tokenSymbol}} </span>
+                        &nbsp;GIVEAWAY
+                    </div>
+
+                    <div class="center"
+                        :style="{
+                            fontSize: amountFontSize + 'px'
+                        }">
+                        <img :src="data.currencyIconUrl" class="icon">
+                        <span id="preview-before-amount">
+                            {{data.amountValue}}
+                        </span>
+                    </div>
+
+                    <div class="desc">
+                        <template  v-if="data.type == PlayType.lottery">
+                            <img class="icon-clock" 
+                            :src="require('@/assets/svg/icon-preview-clock.svg')" />  {{data.validityDuration}} H
+                            <img class="icon-trophy" 
+                            :src="require('@/assets/svg/icon-preview-trophy.svg')" /> <span class="trophy-count">{{data.totalCount}} WINNERS</span>
+                        </template>
+                        <template v-else-if="data.type == PlayType.common">
+                            {{data.totalCount}} WINNERS TO SHARE
+                        </template>
+                    </div>
+                </template>
+                <div class="treasure-layout" v-else>
+                    <div class="treasure-row-1">
+                        <span class="left">Treasure</span>
+                        <component-zoom width="160">
+                            <span class="right">${{data.amountValue}}</span>
+                        </component-zoom>
+                    </div>
+                    <div class="treasure-desc-data">
+                        <div class="item">
+                            <img class="icon" 
+                                :src="require('@/assets/svg/icon-preview-trophy.svg')" />
+                            {{data.totalCount}} Winners
+                        </div>
+                        <div class="item">
+                            <img class="icon" :src="data.currencyIconUrl">
+                            {{data.currencyCode == 'USD' ? 'US Dollar' : data.tokenSymbol}} equivalent
+                        </div>
+                    </div>
                 </div>
             </div>
         </template>
@@ -62,7 +98,7 @@
                 </div>
             </div>
             <div class="custom-card-prize">
-                <component-zoom :width="showBottom ? 210 : 300">
+                <component-zoom width="showBottom ? 210 : 300">
                     <span class="custom-card-prize-name" id="custom-name" >
                         <img class="custom-card-prize-gift-inline" :src="require('@/assets/subject/icon-gift-inline.svg')" />
                         {{data.customizedReward}}
@@ -169,6 +205,12 @@ watch(() => props.data, () => {
             border-radius: 50%;
             margin-right: 10px;
         }
+
+        .treasure-info {
+            color: #fff; 
+            opacity: 0.7;
+            font-weight: 300;
+        }
     }
     .content-text {
         position: absolute;
@@ -219,6 +261,48 @@ watch(() => props.data, () => {
                 color: #FFCC4D;
             }
         }
+
+        .treasure-layout {
+            margin-top: -8px;
+
+            .treasure-row-1 {
+                display: flex; 
+                align-items: center;
+                justify-content: center;
+                font-weight: 900;
+                font-size: 35px;
+                color: #fff;
+
+                .left {
+                    margin-right: 7px;
+                    color: #FFC83A;
+                }
+
+                .right {
+                    font-weight: 900;
+                    font-size: 35px;
+                    color: #fff;
+                }
+            }
+
+            .treasure-desc-data {
+                margin-top: 18px;
+
+                .item {
+                    font-weight: 500;
+                    font-size: 14px;
+                    color: #E1D4C5;
+                    margin-bottom: 10px;
+                    display: flex; 
+                    align-items: center;
+
+                    .icon {
+                        width: 20px;
+                        margin-right: 8px;
+                    }
+                }
+            }
+        }
     }
     .card-cover {
         width: 100%;

+ 32 - 9
src/view/components/popup-transactions.vue

@@ -18,12 +18,15 @@
                     <red-dot class="red-dots" v-if="item.unReadMsgCount > 0 && isReadMsg"></red-dot>
                     <div class="img-wrapper">
                         <!-- 收入- 任务红包领取 -->
-                        <template v-if="item.bizType == 1 || item.bizType == 5">
-                            <img class="icon-avatar" :src="item.bizData.avatarUrl" />
-                            <img class="icon-give" :src="
+                        <template v-if="item.bizType == 1 || item.bizType == 5 || item.bizType == 10 || item.bizType == 11 || item.bizType == 12">
+                            <img class="icon-avatar" v-if="item.bizType != 12" :src="item.bizData.avatarUrl" />
+                            <img class="icon-avatar" v-else :src="require('@/assets/svg/icon-treasure-return.svg')" />
+                            <img class="icon-give" v-if="item.bizType == 10 || item.bizType == 11" :src="require('@/assets/svg/icon-small-treasure.svg')" />
+                            <img class="icon-give" v-else :src="
                                 require('@/assets/svg/icon-get-giveaways-s.svg')
                             " />
                         </template>
+
                         <!-- 收入- 任务红包结余退款, -->
                         <template v-else-if="item.bizType == 2 || item.bizType == 6">
                             <img style="margin-left:-4px" :src="
@@ -66,8 +69,11 @@
                         </template>
                         <!-- 支出-任务红包余额支付 -->
                         <template v-else-if="item.bizType == -2">
-                            <img style="margin-left:-4px" :src="
-                                require('@/assets/svg/icon-big-give.svg')
+                            <img class="icon-avatar" style="margin-left:-4px" :src="
+                                        require('@/assets/svg/icon-big-give.svg')
+                            " />
+                            <img class="icon-give" :src="
+                                require('@/assets/svg/icon-list-withdraw-s.svg')
                             " />
                         </template>
                         <!-- 支出-买盲盒 -->
@@ -92,6 +98,15 @@
                                 :src="require('@/assets/img/icon-box2.png')" v-else />
                             <img class="icon-give" :src="require('@/assets/svg/icon-transaction-s.svg')" />
                         </template>
+                        <!-- 支出-夺宝 -->
+                        <template v-else-if="item.bizType == -6">
+                            <img class="icon-avatar" style="margin-left:-4px" :src="
+                                        require('@/assets/svg/icon-big-give.svg')
+                            " />
+                            <img class="icon-give" :src="
+                                require('@/assets/svg/icon-list-withdraw-s.svg')
+                            " />
+                        </template>
                     </div>
                     <div class="info-wrapper">
                         <div class="left">
@@ -120,6 +135,12 @@
                                 <template v-else-if="item.bizType == 8">
                                     NFT Refund
                                 </template>
+                                <template v-else-if="item.bizType == 10 || item.bizType == 11">
+                                    Get Treasure Chest
+                                </template>
+                                <template v-else-if="item.bizType == 12">
+                                    Treasure Chest Refund
+                                </template>
                                 <template v-else-if="item.bizType == -1">
                                     Withdrawal
                                 </template>
@@ -135,6 +156,9 @@
                                 <template v-else-if="item.bizType == -5">
                                     Transaction Royalties
                                 </template>
+                                <template v-else-if="item.bizType == -6">
+                                    Send Treasure Chest
+                                </template>
                             </div>
                             <div class="time">{{ moment(item.createTimestamp).format('MM-DD HH:mm:ss') }}</div>
                         </div>
@@ -180,9 +204,9 @@
                                     <template v-else-if="item.bizData.withdrawStatus == 3">
                                         <div>
                                             <div class="balance"
-                                                :class="{ 'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12 }">
+                                                :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">
                                                 <span class="amount">
-                                                    <a-tooltip :title="'-' + item.trxAmountValue">
+                                                    <a-tooltip :title="'-'+item.trxAmountValue">
                                                         -{{ getBit(item.trxAmountValue) || 0 }}
                                                     </a-tooltip>
                                                 </span>
@@ -218,8 +242,7 @@
                                         :class="{ 'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12 }">
 
                                         <!--支出—— -2:零钱余额支付 、-3: NFT盲盒余额支付 -->
-                                        <span class="amount"
-                                            v-if="item.bizType == -2 || item.bizType == -3 || item.bizType == -4 || item.bizType == -5">
+                                        <span class="amount" v-if="item.bizType == -2 || item.bizType == -3 || item.bizType == -4 || item.bizType == -5 || item.bizType == -6">
                                             <a-tooltip :title="'-' + item.trxAmountValue">
                                                 -{{ getBit(item.trxAmountValue) || 0 }}
                                             </a-tooltip>

+ 11 - 3
src/view/iframe/publish/components/follow-input.vue

@@ -1,14 +1,16 @@
 <template>
 <!-- 发布器-@关注人 输入组件 -->
     <div class="follow-input-wrapper">
-        <div class="at-user-item" v-for="(item, index) in pageAtUserList" :key="index">
+        <div class="at-user-item" :style="{'padding': padding}" v-for="(item, index) in pageAtUserList" :key="index">
             <img :src="require('@/assets/svg/icon-del-follows-user.svg')" 
                 class="icon-del"
+                v-if="!isRequire || isRequire && index > 0"
                 @click="delUser(item, index)">
             <pre :id='"pre" + index' class="at-user-input-placeholder">{{item.name}}</pre>
             @<input class="at-user-input" 
                     :id='"input" + index' 
                     v-model="item.name" 
+                    :readonly="index == 0 && isRequire"
                     @change="onIptChange(item, index)"
                     @input="onInput(item, index)"
                     @keydown="onKeydown(item, index)"
@@ -72,6 +74,13 @@ const props = defineProps({
     isAddSelf: {
         type: Boolean,
         default: true
+    },
+    isRequire: {
+        type: Boolean,
+        default: false
+    },
+    padding: {
+        type: String,
     }
 })
 
@@ -273,7 +282,6 @@ const onUserMouseLeave = (params, index) => {
             color: #1D9BF0;
             font-weight: 500;
             font-size: 15px;
-            padding: 4px 12px;
             position: relative;
             margin-right: 10px;
             background-color: #fff;
@@ -308,7 +316,7 @@ const onUserMouseLeave = (params, index) => {
                 overflow-y: auto;
                 background-color: #fff; 
                 top: 30px;
-                left: -150px;
+                left: 0px;
                 z-index: 1000;
                 border-radius: 10px;
 

+ 61 - 0
src/view/iframe/publish/components/form-input.vue

@@ -0,0 +1,61 @@
+<template>
+    <div class="form-input-wrapper">
+        <div class="prefix" v-if="prefix">
+            {{prefix}}
+        </div>
+        <slot name="content"></slot>
+        <component-zoom width="50" fontSize="14" :txt="suffix" v-if="suffix">
+            <div class="suffix">
+                {{suffix}}
+            </div>
+        </component-zoom>
+    </div>
+</template>
+
+<script setup>
+import { onMounted, ref, defineProps, defineEmits } from "vue";
+import ComponentZoom from '@/view/components/component-zoom.vue'
+
+const props = defineProps({
+    prefix: {
+        type: String,
+        default: '',
+    },
+    suffix: {
+        type: String,
+        default: '',
+    },
+});
+const emits = defineEmits(["close", "confirm", "postPublishFinish"]);
+
+onMounted(() => {
+}) 
+</script>
+
+<style scoped lang="scss">
+.form-input-wrapper {
+    width: max-content;
+    height: 38px;
+    border: 1px solid #D9D9D9;
+    border-radius: 5px;
+    padding: 0 10px;
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    color: #999999;
+    font-weight: 500;
+    font-size: 12px;
+
+    .prefix {
+        margin-right: 4px;
+    }
+
+    .suffix {
+        margin-left: 4px;
+        white-space: nowrap;
+        color: #999999;
+        font-weight: 500;
+        font-size: 12px;
+    }
+}
+</style>

+ 6 - 0
src/view/iframe/publish/components/preview-card.vue

@@ -33,6 +33,7 @@
                             },
                             rewardType: baseFormData.rewardType,
                             customizedReward: baseFormData.customizedReward,
+                            upGainAmountUsdValue: upGainAmountUsdValue
                         }"></custom-card-cover>
                     </div>
                 </div>
@@ -68,6 +69,7 @@
                             type: baseFormData.type,
                             validityDuration: baseFormData.validityDuration,
                             customPosterUrl: customPosterInfo && customPosterInfo.before && customPosterInfo.before.imagePath || '',
+                            addFans: baseFormData.addFans,
                             userInfo: {
                                 nickName: userInfo.name,
                                 avatarUrl: userInfo.avatarUrl
@@ -134,6 +136,10 @@ defineProps({
             }
         }
     },
+    upGainAmountUsdValue: {
+        type: String,
+        default: ''
+    }
 })
 
 const getUserInfo = (cb) => {

+ 8 - 2
src/view/iframe/publish/components/preview-sheet.vue

@@ -23,7 +23,8 @@
                     :postData="publishRes"
                     :baseFormData="baseFormData" 
                     :amountFontSize="previewFontSize" 
-                    :customPosterInfo="customPosterData">
+                    :customPosterInfo="customPosterData"
+                    :upGainAmountUsdValue="upGainAmountUsdValue">
                 </preview-card>
             </div>
         </div>
@@ -118,7 +119,8 @@ const props = defineProps({
                 validityDuration: "",
                 type: selectModeInfo.type,
                 rewardType: RewardType.money,
-                customizedReward: ""
+                customizedReward: "",
+                addFans: ''
             }
         },
     },
@@ -160,6 +162,10 @@ const props = defineProps({
                 requestAmountValue: 0,
             }
         }
+    },
+    upGainAmountUsdValue: {
+        type: String, 
+        default: ''
     }
 });
 

ファイルの差分が大きいため隠しています
+ 523 - 205
src/view/iframe/publish/give-dialog.vue


+ 3 - 1
src/view/iframe/publish/publish.vue

@@ -26,7 +26,9 @@ let selectVisible = ref(false);
 
 const close = () => {
     dialogData.visible = false;
-    hideIframe();
+    setTimeout(() => {
+        hideIframe();
+    }, 500)
 };
 
 const finish = (params) => {

+ 1 - 2
src/view/iframe/publish/tool-box/child/preview.vue

@@ -205,8 +205,7 @@ const publishHandler = () => {
     if (loadingHide) {
         return;
     }
-    if ((!appId || appId && !props.previewData.linkImagePath) &&
-        (!props.screenshotWebsiteData.url && !props.screenshotWebsiteData.status)) {
+    if ((!appId || appId && !props.previewData.linkImagePath) && (!props.screenshotWebsiteData.url && !props.screenshotWebsiteData.status)) {
         loadingHide = message.loading('loading...', 0);
         return;
     }

+ 6 - 3
src/view/iframe/red-packet/luck-draw.vue

@@ -1085,7 +1085,8 @@ const reportBindTweetSuccess = (params) => {
                         objectType: Report.objectType.tweetPostBinded,
                         twitterFans: reportParams.twitterFans,
                         discordFans: reportParams.discordFans,
-                        redPacketType: 1
+                        redPacketType: 1,
+                        postId: state.postId
                     });
                 }
             }
@@ -2016,7 +2017,8 @@ function onRuntimeMsg() {
                         Report.reportLog({
                             objectType: Report.objectType.tweetPostBinded,
                             twitterFans: reportParams.twitterFans,
-                            redPacketType: 1
+                            redPacketType: 1,
+                            postId: state.postId
                         });
                     } else {
                         if (reportParams.discordFans !== '') {
@@ -2026,7 +2028,8 @@ function onRuntimeMsg() {
                                 objectType: Report.objectType.tweetPostBinded,
                                 twitterFans: reportParams.twitterFans,
                                 discordFans: reportParams.discordFans,
-                                redPacketType: 1
+                                redPacketType: 1,
+                                postId: state.postId
                             });
                         }
                     }

+ 6 - 3
src/view/iframe/red-packet/red-packet.vue

@@ -968,7 +968,8 @@ const reportBindTweetSuccess = (params) => {
             objectType: Report.objectType.tweetPostBinded,
             twitterFans: reportParams.twitterFans,
             discordFans: reportParams.discordFans,
-            redPacketType: 0
+            redPacketType: 0,
+            postId: state.postId
           });
         }
       }
@@ -1811,7 +1812,8 @@ function onRuntimeMsg() {
             Report.reportLog({
               objectType: Report.objectType.tweetPostBinded,
               twitterFans: reportParams.twitterFans,
-              redPacketType: 0
+              redPacketType: 0,
+              postId: state.postId
             });
           } else {
             if (reportParams.discordFans !== '') {
@@ -1821,7 +1823,8 @@ function onRuntimeMsg() {
                 objectType: Report.objectType.tweetPostBinded,
                 twitterFans: reportParams.twitterFans,
                 discordFans: reportParams.discordFans,
-                redPacketType: 0
+                redPacketType: 0,
+                postId: state.postId
               });
             }
           }

+ 3 - 26
src/view/iframe/test/index.vue

@@ -1,31 +1,8 @@
 <template>
-    <!-- <div class="denet-toolbox" @click.stop="clickHead">
-        
-    </div> -->
-    <input type="button" value="点击" @click="state.show = !state.show">
-    <p v-if="state.show" :data-view="1" :data-click="'按钮'" @click.stop="clickTest">1</p>
-    <p v-else :data-view="2">2</p>
-
+    <treasure-hunt></treasure-hunt>
 </template>
 <script setup>
-import { onMounted, reactive } from "vue";
-
-let state = reactive({
-    show: false
-})
-onMounted(() => {
-    var io = new IntersectionObserver((e) => {
-        console.log(e[0].target)
-    });
-    io.observe(document.querySelector('p[data-view]'))
-
-})
-
-function clickTest() {
-    console.log('clickTest')
-}
-
+import TreasureHunt from '@/view/iframe/treasure-hunt/index.vue'
 </script>
-
-<style lang="scss">
+<style lang="scss" scoped>
 </style>

+ 3 - 3
src/view/iframe/tool-box/card.vue

@@ -204,9 +204,9 @@ const getDetail = () => {
             }
             console.log('postBizData', state.detail)
             // 加载iframe
-            // if (state.detail.viewBgImagePath) {
-            //     state.cover_url = state.detail.viewBgImagePath
-            // }
+            if (state.detail.viewBgImagePath) {
+                state.cover_url = state.detail.viewBgImagePath
+            }
             state.iframe_url = state.detail.convertUrl
             state.show_btn = true
             state.status = 'iframe'

+ 96 - 0
src/view/iframe/treasure-hunt/components/btn.vue

@@ -0,0 +1,96 @@
+<template>
+    <div class="btn-submit" @click="clickBtn" :class="{ 'no': loading, 'disabled': disabled }">
+        <img :src="require('@/assets/svg/icon-iframe-loading.svg')" alt="" class="loading" v-if="loading && icon" />
+        <img :src="require('@/assets/svg/icon-btn-box.svg')" alt="" v-if="!loading && icon" />
+        <span :style="{ 'font-size': fontSize, 'color': txtCorlor }">{{ txt }}</span>
+    </div>
+</template>
+<script setup>
+import { defineProps, defineEmits } from 'vue'
+defineProps({
+    txt: {
+        type: String,
+        default: ''
+    },
+    loading: {
+        type: Boolean,
+        default: false
+    },
+    fontSize: {
+        type: String,
+        default: '20px'
+    },
+    icon: {
+        type: Boolean,
+        default: true
+    },
+    disabled: {
+        type: Boolean,
+        default: false
+    },
+    txtCorlor: {
+        type: String
+    }
+})
+const emit = defineEmits(['on-click'])
+const clickBtn = () => {
+    emit('on-click')
+}
+</script>
+<style scoped lang="scss">
+.btn-submit {
+    background: #1D9BF0;
+    border-radius: 100px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 53px;
+    width: 343px;
+    margin: 0 auto;
+    cursor: pointer;
+    user-select: none;
+
+    span {
+        font-weight: 800;
+        color: #FFFFFF;
+        font-size: 20px;
+        line-height: 24px;
+        margin-left: 6px;
+
+    }
+
+    img {
+        width: 20px;
+        height: 20px;
+    }
+
+
+
+    .loading {
+        animation: loading 1s infinite linear;
+    }
+}
+
+.no {
+    cursor: no-drop;
+}
+
+.disabled {
+    cursor: no-drop;
+    background: #F1F1F1;
+
+    span {
+        color: #AFAFAF;
+    }
+}
+
+@keyframes loading {
+    from {
+        transform: rotate(0deg);
+    }
+
+    to {
+        transform: rotate(360deg);
+    }
+}
+</style>

+ 74 - 0
src/view/iframe/treasure-hunt/components/dialog.vue

@@ -0,0 +1,74 @@
+<template>
+    <div class="content" v-show="">
+        <div class="background"></div>
+        <!-- 开奖页 -->
+        <div class="dialog">
+            <div class="txt">{{ txt }}</div>
+            <div class="btn" @click="clickBtn">OK</div>
+        </div>
+    </div>
+</template>
+<script setup>
+import { inject, defineProps, defineEmits } from 'vue'
+
+let state = inject('state')
+defineProps({
+    txt: {
+        type: String,
+        default: 'All treasures are hunted, good luck next time!'
+    }
+})
+const clickBtn = () => {
+
+}
+</script>
+<style lang="scss" scoped>
+.content {
+    width: 375px;
+    height: 500px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    position: fixed;
+    top: 0;
+    left: 0;
+    z-index: 999;
+
+    .background {
+        background: #000000;
+        opacity: .9;
+        position: fixed;
+        width: 375px;
+        height: 500px;
+    }
+
+    .dialog {
+        z-index: 1;
+        width: 335px;
+        background: #FFFFFF;
+        border-radius: 15px;
+
+        .txt {
+            color: #000000;
+            font-weight: 500;
+            font-size: 16px;
+            padding: 27px 30px 16px 30px;
+            text-align: center;
+
+        }
+
+        .btn {
+            cursor: pointer;
+            border-top: 1px solid #EEEEEE;
+            width: 100%;
+            height: 52px;
+            color: #1D9BF0;
+            font-weight: 500;
+            font-size: 17px;
+            line-height: 52px;
+            text-align: center;
+
+        }
+    }
+}
+</style>

+ 72 - 0
src/view/iframe/treasure-hunt/components/head.vue

@@ -0,0 +1,72 @@
+<template>
+    <div class="head">
+        <div class="left" v-if="leftData">
+            <img :src="leftData.avatarUrl" alt="" />
+            <span>from</span>
+            <span>{{ leftData.nickName || '' }}</span>
+        </div>
+        <div class="right" v-if="rightData">
+            <span>
+                Remaining
+            </span>
+            <span>{{ rightData }}</span>
+        </div>
+
+    </div>
+</template>
+<script setup>
+import { defineProps } from 'vue'
+defineProps({
+    leftData: {
+        type: Object,
+        default: null
+    },
+    rightData: {
+        type: String,
+        default: ''
+    }
+})
+</script>
+<style lang="scss" scoped>
+.head {
+    padding: 10px;
+    display: flex;
+    justify-content: space-between;
+
+    .left {
+        display: flex;
+        align-items: center;
+
+        img {
+            width: 16px;
+            height: 16px;
+            border-radius: 100px;
+        }
+
+        span {
+            color: #B69882;
+            font-weight: 400;
+            margin-left: 5px;
+            font-size: 11px;
+            flex-grow: 0;
+        }
+    }
+
+    .right {
+        span {
+            font-weight: 400;
+            font-size: 11px;
+            line-height: 15px;
+        }
+
+        span:first-child {
+            color: #FFFFFF;
+            opacity: 0.7;
+        }
+
+        span:last-child {
+            color: #FFD23B;
+        }
+    }
+}
+</style>

+ 57 - 0
src/view/iframe/treasure-hunt/components/hover-tip.vue

@@ -0,0 +1,57 @@
+<template>
+    <div class="hover-tip">
+        <img :src="icon" alt="" />
+        <span>{{ txt }}</span>
+        <img :src="require('@/assets/svg/icon-tip-arrow.svg')" alt="" class="arrow" />
+    </div>
+</template>
+<script setup>
+import { defineProps } from 'vue'
+defineProps({
+    txt: {
+        type: String,
+        default: ''
+    },
+    icon: {
+        type: String,
+        default: require('@/assets/svg/icon-green-yes.svg')
+    }
+})
+</script>
+<style lang="scss">
+.hover-tip {
+    width: fit-content;
+    height: 20px;
+    line-height: 20px;
+    padding: 0 7px;
+    background: rgba(0, 0, 0, 0.6);
+    border-radius: 3px;
+    display: flex;
+    align-items: center;
+    position: relative;
+    margin-bottom: 5px;
+    position: absolute;
+    top: -20px;
+
+    img {
+        width: 12px;
+        height: 12px;
+    }
+
+    span {
+        margin-left: 4px;
+        font-weight: 500;
+        font-size: 12px;
+        color: #FFFFFF;
+    }
+
+    .arrow {
+        position: absolute;
+        width: 9px;
+        height: 5px;
+        bottom: -5px;
+        left: 50%;
+        margin-left: -4.5px;
+    }
+}
+</style>

+ 160 - 0
src/view/iframe/treasure-hunt/components/invite-friends.vue

@@ -0,0 +1,160 @@
+<template>
+    <div class="invite-friends">
+        <div class="txt">To open the treasure chest you need to share the URL to your friends. Make sure they finish
+            the
+            tasks.</div>
+        <div class="area-url">
+            <div class="url">{{ state.detail.inviteUrl }}</div>
+            <div class="btn copy-btn" @click="clickCopy" :data-clipboard-text="state.detail.inviteCopyUrl">
+                Copy
+            </div>
+        </div>
+        <div class="share-list">
+            <img :src="item.iconPath" alt="" v-for="item in state.share_list" @click="clickShare(item)" />
+        </div>
+        <v-btn :txt="state.open_btn.txt" :font-size="'17px'" class="btn" :icon="false"
+            :disabled="state.open_btn.disabled" @onClick="clickBtn"></v-btn>
+        <v-toast :show="state.toast.show" :txt="state.toast.txt"></v-toast>
+        <open-box v-if="state.open_box.show"></open-box>
+    </div>
+</template>
+<script setup>
+import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
+import VToast from '@/view/iframe/treasure-hunt/components/toast.vue'
+import OpenBox from '@/view/iframe/treasure-hunt/components/dialog.vue'
+import { inviteChannel } from '@/http/treasure'
+import { treasureOpen } from '@/http/treasure'
+import { inject, onMounted } from 'vue'
+let ClipboardJS = require('clipboard');
+let state = inject('state')
+state.toast = {}
+
+onMounted(() => {
+    inviteChannel({
+        params: {
+            postId: state.postId
+        }
+    }).then((res) => {
+        if (res.code == 0) {
+            state.share_list = res.data
+        }
+    })
+})
+
+const clickBtn = () => {
+    treasureOpen({
+        params: {
+            postId: state.postId,
+            treasureId: state.treasureId,
+        }
+    }).then((res) => {
+        if (res.code == 0) {
+            state.open_box.show = true
+            state.open_box = res.data
+        }
+    })
+}
+
+const clickShare = (item) => {
+    window.open(item.redirectPath)
+}
+var clipboard = new ClipboardJS('.copy-btn');
+
+const clickCopy = () => {
+    clipboard.on('success', function (e) {
+        state.toast.txt = 'Copy Successfully'
+        state.toast.show = true
+        setTimeout(() => {
+            state.toast.show = false
+        }, 2000)
+        e.clearSelection();
+    });
+
+    clipboard.on('error', function (e) {
+        state.toast.txt = 'Copy Error'
+        state.toast.show = true
+        setTimeout(() => {
+            state.toast.show = false
+        }, 2000)
+    });
+
+}
+</script>
+<style lang="scss" scoped>
+.invite-friends {
+    padding: 18px 16px 25px 16px;
+    background: #fff;
+
+    .txt {
+        font-style: normal;
+        font-weight: 500;
+        font-size: 14px;
+        line-height: 18px;
+        /* or 129% */
+
+        letter-spacing: 0.3px;
+
+        color: #000000;
+    }
+
+    .area-url {
+        height: 70px;
+        background: rgba(29, 155, 240, 0.01);
+        border: 1px solid #1D9BF0;
+        border-radius: 5px;
+        display: flex;
+        align-items: center;
+        padding-left: 15px;
+        padding-right: 11px;
+        justify-content: space-between;
+
+        .url {
+            display: -webkit-box;
+            -webkit-box-orient: vertical;
+            -webkit-line-clamp: 3;
+            overflow: hidden;
+            width: 194px;
+
+            color: #737373;
+            font-weight: 400;
+            font-size: 13px;
+            white-space: normal;
+
+            word-wrap: break-word;
+
+            word-break: break-all;
+        }
+
+        .btn {
+            user-select: none;
+            background: #1D9BF0;
+            border-radius: 35px;
+            width: 100px;
+            text-align: center;
+            line-height: 37px;
+            height: 37px;
+            font-weight: 700;
+            font-size: 15px;
+            color: #fff;
+            cursor: pointer;
+        }
+    }
+
+    .share-list {
+        margin-top: 20px;
+        text-align: center;
+        margin-bottom: 14px;
+
+        img {
+            user-select: none;
+            cursor: pointer;
+            width: 33px;
+            height: 33px;
+            margin-right: 14px;
+            border-radius: 100px;
+        }
+    }
+
+
+}
+</style>

+ 159 - 0
src/view/iframe/treasure-hunt/components/invite-list.vue

@@ -0,0 +1,159 @@
+<template>
+    <div class="content">
+        <div class="error" v-if="state.invited_list.length == 0">
+            Invite people to hunt treasure with you!
+        </div>
+        <div class="list" v-else>
+            <div class="item" v-for="item in state.invited_list">
+                <div class="left">
+                    <img :src="require('@/assets/svg/icon-btn-box.svg')" alt="" />
+                </div>
+                <div class="right">
+                    <div>{{ item.userInfo.nickName }}</div>
+                    <div>{{ getTime(item.timestamp) }}</div>
+                </div>
+            </div>
+        </div>
+        <div class="footer">
+            <v-btn :txt="state.open_btn.txt" :font-size="'17px'" class="btn" :icon="false"
+                :disabled="state.open_btn.disabled" @onClick="clickBtn"></v-btn>
+        </div>
+    </div>
+</template>
+<script setup>
+import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
+import { inviteList } from '@/http/treasure'
+import { inject, onMounted } from 'vue'
+import { treasureOpen } from '@/http/treasure'
+
+var moment = require('moment')
+let state = inject('state')
+state.invited_list = [
+]
+
+onMounted(() => {
+    inviteList({
+        params: {
+            postId: state.postId,
+            pageNum: 1,
+            pageSize: 10,
+        }
+
+    }).then((res) => {
+        if (res.code == 0) {
+            state.invited_list = res.data
+        }
+    })
+
+    // btnStatus()
+})
+
+
+const getTime = (timestamp) => {
+    let _d1 = moment(new Date().getTime())
+    let _d2 = moment(timestamp)
+    const plural = (n, s) => {
+        let _str = `${n} ${s} ago`
+        if (n > 1) {
+            _str = `${n} ${s}s ago`
+        }
+        return _str
+    }
+    let _d = moment.duration(_d1.diff(_d2)).days()
+    if (_d) {
+        return plural(_d, 'day')
+    }
+    let _h = moment.duration(_d1.diff(_d2)).hours()
+    if (_h) {
+        return plural(_h, 'hour')
+    }
+    let _m = moment.duration(_d1.diff(_d2)).minutes()
+    if (_m) {
+        return plural(_m, 'min')
+    }
+    let _s = moment.duration(_d1.diff(_d2)).seconds()
+    return plural(_s, 'sec')
+}
+
+const clickBtn = () => {
+    treasureOpen({
+        params: {
+            postId: state.postId,
+            treasureId: state.treasureId,
+        }
+    }).then((res) => {
+        if (res.code == 0) {
+            state.open_box.show = true
+            state.open_box = res.data
+        }
+    })
+}
+
+</script>
+<style lang="scss" scoped>
+.content {
+    position: relative;
+    height: 292px;
+
+    .footer {
+        background: #fff;
+        padding: 10px 16px 25px 16px;
+    }
+
+    .error {
+        height: 204px;
+        color: #BABABA;
+        background-color: #fff;
+        font-weight: 500;
+        font-size: 15px;
+        line-height: 204px;
+        text-align: center;
+
+    }
+
+    .list {
+        height: 204px;
+        overflow-y: auto;
+
+        .item {
+            height: 60px;
+            display: flex;
+            align-items: center;
+
+            .left {
+                width: 58px;
+                text-align: center;
+
+                img {
+                    width: 30px;
+                    height: 30px;
+                }
+            }
+
+            .right {
+                flex: 1;
+                border-bottom: 1px solid #D9D9D9;
+                display: flex;
+                align-items: center;
+                height: 100%;
+                justify-content: space-between;
+
+                div:nth-child(1) {
+                    color: #000000;
+                    font-weight: 500;
+                    font-size: 15px;
+
+                }
+
+                div:nth-child(2) {
+                    color: #A6A6A6;
+                    font-weight: 400;
+                    font-size: 12px;
+                    margin-right: 17px;
+
+                }
+            }
+        }
+    }
+}
+</style>

+ 114 - 0
src/view/iframe/treasure-hunt/components/open-box.vue

@@ -0,0 +1,114 @@
+<template>
+    <div>
+        <div class="background"></div>
+        <!-- 开奖页 -->
+        <div class="content">
+
+            <img :src="require('@/assets/img/icon-silver-open-box.png')" alt="" />
+            <div class="mark">
+                <p>You Win</p>
+                <div class="money">{{ state.open_box.usdAmountValue }}</div>
+                <div class="mark2">
+                    <img :src="state.open_box.currencyIcon" alt="" />
+                    <div>{{ state.open_box.amountValue }} {{ state.open_box.currencySymbol }} stored in your DeNet
+                        account
+                    </div>
+                </div>
+
+            </div>
+            <v-btn :txt="'OK'" :font-size="'16px'" class="btn" :icon="false" @onClick="clickBtn"></v-btn>
+        </div>
+    </div>
+</template>
+<script setup>
+import { inject } from 'vue'
+import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
+let state = inject('state')
+
+const clickBtn = () => {
+    state.open_box.show = false
+}
+</script>
+<style lang="scss" scoped>
+.background {
+    background: #000000;
+    opacity: .9;
+    position: fixed;
+    width: 100%;
+    height: 100%;
+    z-index: 1;
+}
+
+.content {
+    z-index: 2;
+    width: 375px;
+    height: 500px;
+    text-align: center;
+    position: relative;
+
+
+
+    img {
+        margin-top: 15px;
+    }
+
+    .mark {
+        position: absolute;
+        top: 246px;
+        width: 375px;
+
+        p {
+            margin: 0;
+            padding: 0;
+            text-align: center;
+
+        }
+
+
+        p:nth-child(1) {
+            margin-bottom: 10px;
+            color: #FFFFFF;
+            font-weight: 800;
+            font-size: 18px;
+        }
+
+        .txt {
+            color: #FFC83A;
+            font-weight: 800;
+            font-size: 24px;
+
+        }
+
+        .money {
+            color: #FFC83A;
+            font-weight: 800;
+            font-size: 34px;
+        }
+
+        .mark2 {
+            margin-top: 10px;
+            display: flex;
+            justify-content: center;
+
+            img {
+                width: 17px;
+                height: 17px;
+                margin: 0;
+            }
+
+            div {
+                color: #A9A49F;
+                font-weight: 400;
+                font-size: 12px;
+
+            }
+        }
+    }
+
+    .btn {
+        position: absolute;
+        bottom: 25px;
+        left: 15px;
+    }
+}
+</style>

+ 80 - 0
src/view/iframe/treasure-hunt/components/toast.vue

@@ -0,0 +1,80 @@
+<template>
+    <div class="content" v-show="show">
+        <div class="mark">
+            <div class="background"></div>
+            <img :src="icon" alt="">
+            <span>{{ txt }}</span>
+        </div>
+    </div>
+</template>
+<script setup>
+import { defineProps, watch, reactive } from "vue";
+
+let props = defineProps({
+    txt: {
+        type: String,
+        default: ''
+    },
+
+    icon: {
+        type: String,
+        default: require('@/assets/svg/icon-while-yes.svg')
+    },
+    show: {
+        type: Boolean,
+        default: false
+    },
+})
+
+
+</script>
+<style lang="scss" scoped>
+.content {
+    position: fixed;
+    width: 375px;
+    height: 500px;
+    text-align: center;
+    display: flex;
+    justify-content: center;
+    top: 0;
+
+    .mark {
+        height: 39px;
+        top: 50%;
+        width: fit-content;
+        color: #FFFFFF;
+        border-radius: 44px;
+        overflow: hidden;
+        position: relative;
+
+        display: flex;
+        align-items: center;
+        padding: 0 13px;
+
+        img {
+            z-index: 2;
+            width: 15px;
+            height: 15px;
+            margin-right: 6px;
+        }
+
+        span {
+            z-index: 2;
+            font-weight: 600;
+            font-size: 14px;
+            color: #fff;
+        }
+
+        .background {
+            z-index: 1;
+            width: 100%;
+            left: 0;
+            top: 0;
+            height: 100%;
+            position: absolute;
+            background: rgba(0, 0, 0, 0.8);
+        }
+    }
+
+}
+</style>

+ 285 - 0
src/view/iframe/treasure-hunt/cover.vue

@@ -0,0 +1,285 @@
+<template>
+    <!-- 封面页 -->
+    <div class="cover">
+        <v-head :left-data="state.detail.postUserInfo || null"></v-head>
+        <div class="waring" v-if="state.cover_status == '奖励已被领光'">
+            <div>All treasures</div>
+            <div>are hunted</div>
+        </div>
+        <!-- 邀请人 -->
+        <template v-else>
+            <div class="invite" v-if="state.detail.inviteUserInfo">
+                <img :src="state.detail.inviteUserInfo.avatarUrl" alt="" />
+                <span>{{ state.detail.inviteUserInfo.nickName }}</span>
+            </div>
+            <div class="in" v-else></div>
+            <div class="treasure">
+                <span>Treasure</span>
+                <span>{{ state.detail.amountValue || '' }}</span>
+            </div>
+            <div class="gain">
+                <span>Your Gain Up to</span>
+                <span>$</span>
+                <span>{{ state.detail.remainAmountValue }}</span>
+            </div>
+            <div class="coin">
+                <img :src="require('@/assets/svg/icon-warning.svg')" alt="" />
+                <span>{{ state.detail.amountCurrencyCode }}</span>
+            </div>
+        </template>
+
+        <div class="box">
+            <img :src="require('@/assets/img/icon-gold-close-box.png')" alt="" v-if="state.cover_status == '奖励已被领光'" />
+            <img :src="require('@/assets/img/icon-treasure-box.png')" alt="" v-else />
+        </div>
+        <div class="mark">
+            <img :src="require('@/assets/svg/icon-three-line.svg')" alt="" />
+            <span>to Hunt Treasure</span>
+        </div>
+        <v-btn :txt="state.open_btn.txt" :font-size="'17px'" class="btn" :icon="true"
+            :disabled="state.open_btn.disabled" @onClick="clickBtn" :loading="state.btn_loading"></v-btn>
+    </div>
+
+</template>
+<script setup>
+import { inject } from 'vue'
+import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
+import VHead from '@/view/iframe/treasure-hunt/components/head.vue'
+
+import { prepareStart, treasureStart } from '@/http/treasure.js'
+
+chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
+    switch (req.actionType) {
+        case 'DO_TASK':
+            if (!req.task_type || state.tweetId != req.tweet_Id || !req.task_done) {
+                return
+            }
+            if (req.task_type == 'createTweet') {
+                treasureStart({
+                    params: {
+                        postId: state.postId || '',
+                        inviteCode: state.invite_code || ''
+                    }
+                }).then((res) => {
+                    if (res.code == 0) {
+                        state.page = '开奖页'
+                        state.start_task = res.data
+                        state.btn_loading = false
+                    }
+                })
+            }
+            break
+    }
+})
+
+let state = inject('state')
+state.btn_loading = false
+
+const clickBtn = () => {
+    if (state.cover_status == '奖励已被领光') {
+        window.open('https://twitter.com/search?q=%23denet')
+        return
+    }
+
+    state.btn_loading = true
+    setTimeout(() => {
+        if (state.btn_loading == true) {
+            state.btn_loading = false
+        }
+    }, 10000)
+
+    // four_task
+    // 获取文章
+    prepareStart({
+        params: {
+            postId: state.postId || '',
+            inviteCode: state.invite_code || ''
+        }
+    }).then((res) => {
+        if (res.code == 0) {
+            let text = res.data.rePostTweetContent
+            // 发送推文
+            chrome.tabs.getCurrent((tab) => {
+                chrome.tabs.sendMessage(tab.id, {
+                    actionType: "IFRAME_TWITTER_API_DO_TASK",
+                    task_data: {
+                        tweet_Id: state.tweetId,
+                        tweet_text: text
+                    },
+                    task_type: 'tasks',
+                    tasks: JSON.parse(state.detail.startCondition),
+                }, (res) => { console.log(res) });
+            })
+        } else {
+            console.log(res)
+        }
+    })
+}
+</script>
+<style lang="scss" scoped>
+.cover {
+    width: 375px;
+    height: 500px;
+    background: linear-gradient(179.96deg, #25180D 38.82%, #5E4025 55.4%, #876635 61.6%, #24180C 71.59%);
+    border-radius: 20px;
+
+    .head {
+        padding: 10px;
+        display: flex;
+        align-items: center;
+
+        img {
+            width: 16px;
+            height: 16px;
+            border-radius: 100px;
+        }
+
+        span {
+            color: #B69882;
+            font-weight: 400;
+            margin-left: 5px;
+            font-size: 11px;
+            flex-grow: 0;
+        }
+    }
+
+    .waring {
+        margin-top: 54px;
+        font-weight: 900;
+        font-size: 34px;
+        color: #FFFFFF;
+        text-align: center;
+        opacity: 0.7;
+        margin-bottom: 35px;
+    }
+
+    .in {
+        height: 58px;
+    }
+
+    .invite {
+        background: rgba(255, 255, 255, 0.1);
+        height: 28px;
+        display: flex;
+        align-items: center;
+        margin: 0 auto;
+        margin-top: 20px;
+        margin-bottom: 10px;
+        border-radius: 100px;
+        width: fit-content;
+        padding-right: 11px;
+
+
+        img {
+            width: 18px;
+            height: 18px;
+            border-radius: 100px;
+            margin-left: 11px;
+            margin-right: 6px;
+        }
+
+        span {
+            color: #BE9F89;
+        }
+    }
+
+    .treasure {
+        text-align: center;
+
+        span {
+            font-size: 34px;
+            font-weight: 900;
+            line-height: 40px;
+        }
+
+        span:first-child {
+            color: #FFC83A;
+            margin-right: 10px;
+        }
+
+        span:last-child {
+            color: #FFFFFF;
+        }
+    }
+
+    .gain {
+        width: 100%;
+        background: #332319;
+        height: 37px;
+        margin-top: 10px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+
+        span {
+            color: #fff;
+            font-weight: 500;
+            font-size: 16px;
+            line-height: 16px;
+
+        }
+
+        span:first-child {
+            font-size: 15px;
+            line-height: 15px;
+            margin-right: 10px;
+        }
+
+        span:last-child {
+            margin-left: 2px;
+            font-weight: 800;
+            font-size: 24px;
+            line-height: 24px;
+        }
+    }
+
+    .coin {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin-top: 10px;
+
+        img {
+            width: 17px;
+            height: 17px;
+        }
+
+        span {
+            margin-left: 4px;
+            font-weight: 400;
+            font-size: 11px;
+            line-height: 15px;
+            color: #FFFFFF;
+
+            opacity: 0.7;
+        }
+    }
+
+    .box {
+        text-align: center;
+
+        img {
+            width: 160px;
+            height: 160px;
+        }
+
+    }
+
+    .mark {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin-top: 24px;
+        margin-bottom: 15px;
+
+        span {
+            font-weight: 500;
+            font-size: 12px;
+            line-height: 17px;
+            color: #65C1FF;
+
+        }
+    }
+
+}
+</style>

+ 126 - 0
src/view/iframe/treasure-hunt/index.vue

@@ -0,0 +1,126 @@
+<template>
+    <v-cover v-if="state.page == '封面页'"></v-cover>
+    <v-invite v-if="state.page == '邀请页'"></v-invite>
+    <v-result v-if="state.page == '开奖页'"></v-result>
+</template>
+<script setup>
+import { reactive, provide, onMounted } from 'vue'
+import VCover from '@/view/iframe/treasure-hunt/cover.vue'
+import VInvite from '@/view/iframe/treasure-hunt/invite.vue'
+import VResult from '@/view/iframe/treasure-hunt/result.vue'
+import { inviteDetail, treasureDetail } from '@/http/treasure.js'
+import { reSetBindTwtterId } from '@/http/help.js'
+import { getQueryString } from '@/uilts/help'
+
+let state = reactive({
+    page: '',
+    detail: {},
+    open_box: {
+        show: false
+    },
+    open_btn: {
+        txt: '',
+        disabled: false
+    },
+    start_task: {}
+})
+provide('state', state)
+
+onMounted(() => {
+    let params = JSON.parse(getQueryString('params') || '{}')
+    state.postId = params.post_Id || ''
+    state.tweetId = params.tweet_Id || ''
+    state.invite_code = params.invite_code || ''
+
+    if (params.page_type == '邀请链接') {
+        // 邀请链接
+        inviteDetail({
+            params: {
+                inviteCode: params.invite_code
+            }
+
+        }).then((res) => {
+            if (res.code == 0) {
+                state.detail = res.data
+                handleStatus()
+                if (!res.data.srcContentId) {
+                    reSetBindTwtterId({
+                        postId: state.postId || '',
+                        tweetId: state.tweetId || ''
+                    })
+                }
+            }
+        })
+
+    } else if (params.page_type == '原始链接') {
+        // 原始链接
+        treasureDetail({
+            params: {
+                postId: params.post_Id
+            }
+        }).then((res) => {
+            if (res.code == 0) {
+                state.detail = res.data
+                handleStatus()
+
+                if (!res.data.srcContentId) {
+                    reSetBindTwtterId({
+                        postId: state.postId || '',
+                        tweetId: state.tweetId || ''
+                    })
+                }
+            }
+        })
+    }
+
+})
+
+const handleStatus = () => {
+    // 如果 夺宝状态 = 未开始
+    //   显示未开始页面
+    // 如果 夺宝状态 = 进行中
+    //   如果 夺宝参与状态 = 未参与夺宝
+    //      显示封面页
+    //   如果 夺宝参与状态 = 已参与夺宝
+    //      显示邀请页
+    // 如果 夺宝状态 = 已结束
+    //  显示结束页面
+
+    let { status, joinStatus } = state.detail || {}
+    state.open_btn.txt = 'Start'
+    // 如果 夺宝状态 = 未开始
+    if (status == 0) {
+        state.page = '封面页'
+
+    }
+    // 如果 夺宝状态 = 进行中
+    else if (status == 1) {
+        // 如果 夺宝参与状态 = 未参与夺宝
+        if (joinStatus == 0) {
+            // 显示封面页
+            state.page = '封面页'
+            state.cover_status = '有邀请人'
+            state.open_btn.txt = 'Start'
+            // state.cover_status = '无邀请人'
+            // state.cover_status = '奖励已被领光'
+        }
+        // 如果 夺宝参与状态 = 已参与夺宝
+        else if (joinStatus == 1) {
+            state.page = '邀请页'
+        }
+    }
+    // 如果 夺宝状态 = 已结束
+    else {
+        state.page = '封面页'
+        state.cover_status = '奖励已被领光'
+        state.open_btn.txt = 'Look for more treasures'
+    }
+}
+</script>
+<style lang="scss" >
+html,
+body {
+    margin: 0;
+    padding: 0;
+}
+</style>

+ 369 - 0
src/view/iframe/treasure-hunt/invite.vue

@@ -0,0 +1,369 @@
+<template>
+    <!-- 邀请页 -->
+    <div class="area-process">
+        <v-head :left-data="state.detail.postUserInfo || null" :rightData="state.detail.remainAmountValue"></v-head>
+        <div class="box-process">
+            <div class="item" v-for="item, i in state.boxs">
+                <hover-tip :txt="item.txt" v-show="item.show || item.openStatus" :icon="item.hover_icon"></hover-tip>
+                <img :src="item.icon" alt="" @mouseenter="mouseItem(i)" @mouseleave="mouseLeaveItem(i)" />
+                <img :src="require('@/assets/img/icon-flash-active.png')" alt="" class="flash"
+                    v-if="item.openStatus == 0 && item.taskFinishStatus == 1" />
+            </div>
+            <div class="line">
+                <div class="full" ref="line_full"></div>
+            </div>
+        </div>
+        <div class="area-success-message" @mouseover="mouseOver" @mouseleave="mouseLeave">
+            <div class="content-success-message" ref="content_success_message">
+                <div class="success-message" v-for="item, index in state.success_message_list" :key="index">
+                    <img :src="item.userInfo.avatarUrl" alt="" />
+                    <span>{{ item.userInfo.nickName }} </span> &nbsp;
+                    <span>Opened Treasure Chest</span>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="area-nav">
+        <div class="item" :class="{ active: state.tab_index == i }" @click="state.tab_index = i"
+            v-for="item, i in state.tabs">
+            {{ item.txt }}
+        </div>
+    </div>
+    <div class="area-info">
+        <invite-friends v-show="state.tab_index == 0"></invite-friends>
+        <invite-list v-show="state.tab_index == 1"></invite-list>
+    </div>
+
+</template>
+<script setup>
+import { reactive, ref, onMounted, watch, inject } from 'vue'
+import { receiveList } from '@/http/treasure.js'
+import VHead from '@/view/iframe/treasure-hunt/components/head.vue'
+import InviteList from '@/view/iframe/treasure-hunt/components/invite-list.vue'
+import HoverTip from '@/view/iframe/treasure-hunt/components/hover-tip.vue'
+import InviteFriends from '@/view/iframe/treasure-hunt/components/invite-friends.vue'
+let content_success_message = ref(null)
+let state = inject('state')
+
+// ---- 走马灯
+state.success_message_list = []
+
+
+// ---- box 区域
+let silver_close_box = require('@/assets/img/icon-silver-close-box.png')
+let silver_open_box = require('@/assets/img/icon-silver-open-box.png')
+let gold_open_box = require('@/assets/img/icon-gold-open-box.png')
+let gold_close_box = require('@/assets/img/icon-gold-close-box.png')
+
+
+// ---- tab区域 ----
+state.tab_index = 0
+state.tabs = [{
+    txt: 'invite friends'
+}, {
+    txt: 'invited'
+}]
+
+
+watch(state, () => {
+    if (content_success_message && content_success_message.value) {
+        let dom = content_success_message.value
+        let width = dom.clientWidth
+        let s = parseInt(width / 80)
+        dom.style.animationDuration = s + 's'
+    }
+})
+
+state.boxs = []
+
+let line_full = ref(null)
+onMounted(() => {
+    if (state.detail.inviteCount > 0) {
+        state.tabs[1].txt = `invited(${state.detail.inviteCount})`
+    }
+
+    state.detail.treasureRecords.forEach((item, index) => {
+        if (item.openStatus == 0) {
+            item.hover_icon = require('@/assets/svg/icon-user.svg')
+            // 最后一条
+            if ((index + 1) == state.detail.treasureRecords.length) {
+                item.icon = gold_close_box
+            } else {
+                item.icon = silver_close_box
+            }
+            item.txt = item.inviteProgress
+        } else {
+            item.icon = silver_open_box
+            item.hover_icon = require('@/assets/svg/icon-green-yes.svg')
+            // 最后一条
+            if ((index + 1) == state.detail.treasureRecords.length) {
+                item.icon = gold_open_box
+            } else {
+                item.icon = silver_open_box
+            }
+            item.txt = '$' + item.amountValue
+        }
+
+        state.boxs.push(item)
+    })
+
+    receiveList({
+        params: {
+            postId: state.postId,
+            pageNum: 1,
+            pageSize: 10,
+        }
+    }).then((res) => {
+        if (res.code == 0) {
+            state.success_message_list = res.data
+            state.success_message_list = state.success_message_list.concat(state.success_message_list)
+            state.success_message_list = state.success_message_list.concat(state.success_message_list)
+        }
+    })
+    btnStatus()
+})
+
+const setLineFull = (box_num = 0, needInviteCount = 0, successInviteCount = 0) => {
+    if (box_num == 0) {
+        line_full.value.style.width = (successInviteCount / needInviteCount) * 80 + 'px'
+    } else if (box_num = 1) {
+        line_full.value.style.width = ((successInviteCount / needInviteCount) * 100 + 80) + 'px'
+    } else if (box_num = 2) {
+        line_full.value.style.width = ((successInviteCount / needInviteCount) * 100 + 180) + 'px'
+    }
+}
+
+const btnStatus = () => {
+
+
+    for (let i in state.boxs) {
+        if (state.boxs[i].taskFinishStatus == 0) {
+            let num = state.boxs[i].needInviteCount - state.boxs[i].successInviteCount
+            if (num == 1) {
+                state.open_btn.txt = 'Invite a friend to open the chest'
+            } else {
+                state.open_btn.txt = `Invite ${num} friends to open the chest`
+            }
+            state.open_btn.disabled = true
+            break
+        }
+    }
+
+    state.treasureId = ''
+    let open_num = 0
+    // 有打开的箱子 Open the chest 
+    state.boxs.forEach((item, index) => {
+        if (item.taskFinishStatus == 1 && item.openStatus == 0) {
+            state.open_btn.txt = 'Open the Chest'
+            state.open_btn.disabled = false
+            if (!state.treasureId) {
+                state.treasureId = item.id
+            }
+        }
+        if (item.taskFinishStatus == 1) {
+            setLineFull(index, item.needInviteCount, item.successInviteCount)
+        }
+        // 三个箱子全部打开了 
+        if (item.openStatus == 1) {
+            open_num++
+        }
+        if (open_num == state.boxs.length) {
+            state.open_btn.txt = 'All Chests are Open'
+            state.open_btn.disabled = true
+        }
+    })
+}
+
+const mouseItem = (i) => {
+    state.boxs[i].show = true
+}
+const mouseLeaveItem = (i) => {
+    state.boxs[i].show = false
+}
+
+const mouseOver = () => {
+    if (content_success_message && content_success_message.value && content_success_message.value.style) {
+        content_success_message.value.style.animationPlayState = 'paused'
+    }
+}
+const mouseLeave = () => {
+    if (content_success_message && content_success_message.value && content_success_message.value.style) {
+        content_success_message.value.style.animationPlayState = 'running'
+    }
+}
+
+</script>
+<style lang="scss"  scoped>
+.area-process {
+    width: 375px;
+    height: 170px;
+    background: linear-gradient(179.96deg, #735931 0.04%, #0E0803 53.64%);
+    position: relative;
+
+    .box-process {
+        width: 350px;
+        height: 90px;
+        margin: 0 auto;
+        display: flex;
+        align-items: center;
+        position: absolute;
+        top: 32px;
+        left: 13px;
+
+        img {
+            width: 60px;
+            height: 60px;
+            z-index: 2;
+        }
+
+        .item {
+            z-index: 2;
+            display: flex;
+            justify-content: center;
+            position: relative;
+
+            .flash {
+                position: absolute;
+                top: 0;
+                left: 0;
+                z-index: 0;
+                width: 100%;
+                height: 100%;
+            }
+        }
+
+        .item:nth-child(1) {
+
+            margin-left: 56px;
+        }
+
+        .item:nth-child(2) {
+            width: 60px;
+            height: 60px;
+            margin-left: 40px;
+        }
+
+        .item:nth-child(3) {
+            img {
+                width: 90px;
+                height: 90px;
+            }
+
+            margin-left: 40px;
+        }
+
+        .line {
+            width: 300px;
+            height: 4px;
+            background: rgba(255, 210, 59, 0.2);
+            position: absolute;
+            border-radius: 100px;
+            overflow: hidden;
+            left: 13px;
+            top: 45px;
+
+            .full {
+                position: absolute;
+                left: 0;
+                top: 0;
+                height: 4px;
+                width: 0px;
+                background: #FFD23B;
+            }
+        }
+
+    }
+
+    .area-success-message {
+        height: 30px;
+        width: 100%;
+        position: absolute;
+        bottom: 13px;
+        overflow: hidden;
+
+        .content-success-message {
+
+            width: fit-content;
+            display: flex;
+            animation: rolling 18s linear infinite;
+
+            .success-message {
+                cursor: default;
+                width: fit-content;
+                height: 30px;
+                padding: 0 9px;
+                border-radius: 100px;
+                background: rgba(255, 255, 255, 0.1);
+                display: flex;
+                align-items: center;
+                overflow: hidden;
+                margin-right: 15px;
+
+                img {
+                    width: 20px;
+                    height: 20px;
+                    border-radius: 100px;
+                    margin-right: 8px;
+
+                }
+
+                span {
+                    font-style: normal;
+                    font-weight: 500;
+                    font-size: 12px;
+                    line-height: 14px;
+                    white-space: nowrap;
+                }
+
+                span:nth-child(2) {
+                    color: #1D9BF0;
+                }
+
+                span:nth-child(3) {
+                    color: #A8A8A8;
+                }
+            }
+        }
+    }
+}
+
+@keyframes rolling {
+    from {
+        transform: translateX(0);
+    }
+
+    to {
+        transform: translateX(-50%);
+    }
+}
+
+.area-nav {
+    width: 375px;
+    height: 38px;
+    display: flex;
+
+    .item {
+        user-select: none;
+        color: #757575;
+        background: #F0F0F0;
+        text-align: center;
+        width: 50%;
+        font-weight: 500;
+        font-size: 14px;
+        line-height: 38px;
+        cursor: pointer;
+    }
+
+    .active {
+        background: #FFFFFF;
+        color: #000000;
+    }
+}
+
+.area-info {
+    width: 375px;
+
+
+}
+</style>

+ 118 - 0
src/view/iframe/treasure-hunt/result.vue

@@ -0,0 +1,118 @@
+<template>
+    <!-- 开奖页 -->
+    <div class="content">
+        <img :src="require('@/assets/img/icon-silver-open-box.png')" alt="" />
+        <div class="mark">
+            <p>You already followed Younan111 </p>
+            <!-- 新粉 -->
+            <template v-if="state.start_task.amountValue > 0">
+                <p>You Win</p>
+                <div class="money">${{ state.start_task.usdAmountValue }}</div>
+                <div class="mark2">
+                    <img :src="state.start_task.currencyIcon" alt="" />
+                    <div>{{ state.start_task.amountValue }} {{ state.start_task.currencySymbol }} stored in your DeNet
+                        account</div>
+                </div>
+            </template>
+            <!-- 老粉不给钱 -->
+            <template v-else>
+                <p>Only new followers open silver chest</p>
+                <p class="txt">Invite people to</p>
+                <p class="txt">open golden chest!</p>
+            </template>
+        </div>
+        <v-btn :txt="'Invite friends for more treasures'" :font-size="'16px'" class="btn"
+            v-if="state.start_task.amountValue > 0" @onClick="clickBtn"></v-btn>
+        <v-btn :txt="'Invite'" :font-size="'16px'" class="btn" v-else @onClick="clickBtn"></v-btn>
+    </div>
+</template>
+<script setup>
+import { inject } from 'vue'
+import VBtn from '@/view/iframe/treasure-hunt/components/btn.vue'
+let state = inject('state')
+
+const clickBtn = () => {
+    state.page = '邀请页'
+}
+
+</script>
+<style lang="scss" scoped>
+.content {
+    width: 375px;
+    height: 500px;
+    background: linear-gradient(179.96deg, #876635 20.15%, #31251A 44.61%, #24180C 78.18%);
+    text-align: center;
+    position: relative;
+
+    img :first-child {
+        margin-top: 15px;
+        width: 250px;
+        height: 250px;
+    }
+
+    .mark {
+        position: absolute;
+        top: 246px;
+        width: 375px;
+
+        p {
+            margin: 0;
+            padding: 0;
+            text-align: center;
+
+        }
+
+        p:nth-child(1) {
+            color: #A9A49F;
+            font-weight: 400;
+            font-size: 12px;
+            margin-bottom: 10px;
+        }
+
+        p:nth-child(2) {
+            margin-bottom: 10px;
+            color: #FFFFFF;
+            font-weight: 800;
+            font-size: 18px;
+        }
+
+        .txt {
+            color: #FFC83A;
+            font-weight: 800;
+            font-size: 24px;
+
+        }
+
+        .money {
+            color: #FFC83A;
+            font-weight: 800;
+            font-size: 34px;
+        }
+
+        .mark2 {
+            margin-top: 10px;
+            display: flex;
+            justify-content: center;
+
+            img {
+                width: 17px;
+                height: 17px;
+                margin: 0;
+            }
+
+            div {
+                color: #A9A49F;
+                font-weight: 400;
+                font-size: 12px;
+
+            }
+        }
+    }
+
+    .btn {
+        position: absolute;
+        bottom: 25px;
+        left: 15px;
+    }
+}
+</style>

+ 72 - 18
src/view/popup/tabbar-page/message/index.vue

@@ -4,20 +4,27 @@
       <div class="list-wrapper" ref="pageGiveListDom">
         <div class="give-list" v-if="currentTabIndex == 0">
           <template v-if="giveList.length">
-            <div class="cell" :class="{ 'cell-center': item.type == 1 || item.type == 3 }"
+            <div class="cell" :class="{ 'cell-center': item.type == 1 || item.type == 3 || item.type == 5 }"
               v-for="(item, index) in giveList" :key="index" @click="clickListItem(item, index)">
               <red-dot class="red-dots" v-if="item.unReadMsgCount > 0 && isReadMsg"></red-dot>
 
               <div class="img-wrapper">
                 <!-- 收到红包 -->
-                <template v-if="item.type == 1 || item.type == 3">
+                <template v-if="item.type == 1 || item.type == 3 || item.type == 5">
                   <img class="icon-avatar" :src="item.userInfo.avatarUrl" />
-                  <img class="icon-give" :src="require('@/assets/svg/icon-get-giveaways-s.svg')" />
+                  <img class="icon-give" v-if="item.type == 5" :src="require('@/assets/svg/icon-small-treasure.svg')" />
+                  <img class="icon-give" v-else :src="require('@/assets/svg/icon-get-giveaways-s.svg')" />
                 </template>
                 <!-- 发出去红包 -->
                 <template v-else-if="item.type == 2">
-                  <img class="icon-big-give" :src="require('@/assets/svg/icon-send-giveaways-s.svg')" />
-                  <img class="icon-mark-give" :src="require('@/assets/svg/icon-send-giveaways-mark.svg')" />
+                  <template v-if="item.postTaskLuckdrop.luckdropType === PlayType.treasure">
+                    <img class="icon-big-give" :src="require('@/assets/svg/icon-big-treasure.svg')" />
+                    <img class="icon-mark-give" :src="require('@/assets/svg/icon-send-giveaways-mark.svg')" />
+                  </template>
+                  <template v-else>
+                    <img class="icon-big-give" :src="require('@/assets/svg/icon-send-giveaways-s.svg')" />
+                    <img class="icon-mark-give" :src="require('@/assets/svg/icon-send-giveaways-mark.svg')" />
+                  </template>
                 </template>
                 <!-- 转出NFT记录 -->
                 <template v-else-if="item.type == 4">
@@ -28,14 +35,22 @@
                   </div>
                 </template>
               </div>
-              <div class="info-wrapper" :class="{ 'info-center': item.type == 1 }">
+              <div class="info-wrapper" :class="{ 'info-center': item.type == 1 || item.type == 5 }">
                 <div class="left">
                   <div class="nickname">
                     <template v-if="item.type == 1">
                       Get Giveaway
                     </template>
                     <template v-else-if="item.type == 2">
-                      {{ item.postTaskLuckdrop.luckdropType === 1 ? 'Send Giveaway' : 'Lottery Giveaway' }}
+                        <template v-if="item.postTaskLuckdrop.luckdropType === PlayType.common">
+                          Send Giveaway
+                        </template>
+                        <template v-else-if="item.postTaskLuckdrop.luckdropType === PlayType.lottery">
+                          Lottery Giveaway
+                        </template>
+                        <template v-else-if="item.postTaskLuckdrop.luckdropType === PlayType.treasure">
+                          Treasure Hunt
+                        </template>
                     </template>
                     <template v-else-if="item.type == 3">
                       Lottery
@@ -43,6 +58,9 @@
                     <template v-else-if="item.type == 4">
                       Transfer NFT
                     </template>
+                    <template v-else-if="item.type == 5">
+                      Treasure Hunt
+                    </template>
                   </div>
                   <div class="time">
                     {{ moment(item.timestamp).format("MM-DD HH:mm:ss") }}
@@ -53,11 +71,11 @@
                     <div class="bold" :class="{
                       'align-content':
                         (item.type == 2 ||
-                          (item.type == 1 && item.status == 1)) &&
+                          (item.type == 1 && item.status == 1 || item.type == 5 && item.status == 1)) &&
                         item?.amount?.length + item?.currencySymbol?.length > 12,
                       'custom-bold': item.rewardType === RewardType.custom
                     }">
-                      <!-- 收到的 -->
+                      <!-- 领取的普通红包 -->
                       <template v-if="item.type == 1">
                         <!-- 进行中-->
                         <template v-if="item.status == 0">
@@ -114,6 +132,7 @@
 
                         </template>
                       </template>
+                      <!-- 抽奖 -->
                       <template v-else-if="item.type == 3">
                         <template v-if="item.status == 1">In Progress</template>
                         <template v-else-if="item.status == 2">
@@ -150,12 +169,38 @@
                           Giveaway Expired
                         </template>
                       </template>
+                      <!-- NFT 转出记录 -->
                       <template v-else-if="item.type == 4">
                         <template v-if="item.status == 0 || item.status == 1">Transferring</template>
                         <template v-else-if="item.status == 2">Successful</template>
                         <template v-else-if="item.status == 3">Transfe Failed</template>
                       </template>
+                      <!-- 领取的夺宝红包 -->
+                      <template v-else-if="item.type == 5">
+                        <!-- 进行中-->
+                        <template v-if="item.status == 0">
+                          In Progress
+                        </template>
+                        <!-- 已完成 -->
+                        <template v-else-if="item.status == 2">
+                            <span class="blance">
+                              <a-tooltip :title="item.amount">
+                                {{ getBit(item.amount) }}</a-tooltip>
+                            </span>
+                            <div class="coin-type-wrapper">
+                              <span class="coin-type">{{
+                                  item.currencySymbol || ""
+                              }}</span>
+                              <img :src="item.currencyIconPath" alt="" />
+                            </div>
+                        </template>
+                        <!-- 已过期 -->
+                        <template v-else-if="item.status == 3">
+                          Giveaway Expired
+                        </template>
+                      </template>
                     </div>
+
                     <!-- 发出的红包显示 -->
                     <div class="desc" v-if="item.type == 2">
                       <!-- 未发送-->
@@ -164,7 +209,7 @@
                       </template>
                       <!-- 进行中 -->
                       <template v-else-if="item.status == 1">
-                        <template v-if="item.postTaskLuckdrop && item.postTaskLuckdrop.luckdropType == 2">
+                        <template v-if="item.postTaskLuckdrop && item.postTaskLuckdrop.luckdropType == PlayType.lottery">
                           {{ item.downTime || '' }}
                         </template>
                         <template v-else>
@@ -173,12 +218,13 @@
                           }}
                         </template>
                       </template>
+
                       <!-- 2:已结束; 3:提前终止-->
                       <template v-else-if="item.status == 2 || item.status == 3">
                         <!-- 普通红包 -->
-                        <template v-if="item.postTaskLuckdrop && item.postTaskLuckdrop.luckdropType == 1">
+                        <template v-if="item.postTaskLuckdrop.luckdropType == PlayType.common || item.postTaskLuckdrop.luckdropType == PlayType.treasure">
                           <template v-if="item.status == 2">
-                            (Time expired)
+                            {{item.postTaskLuckdrop.luckdropType == PlayType.common ? '(Time expired)': 'Complete'}}
                           </template>
                           <template v-if="item.status == 3">
                             {{ item.srcContentId ? '(Termination)' : 'Termination' }}
@@ -202,8 +248,7 @@
                         }}
                       </template>
 
-                      <!-- 进行中或者未发送成功时显示 
-                                                v-if="item.status == 1 || item.postTaskLuckdrop.reSendAvailable"-->
+                      <!-- 进行中或者未发送成功时显示 -->
                       <div class="desc-bottom-bar">
                         <!-- 没有终止红包时显示 -->
                         <div v-if="item.postTaskLuckdrop.terminatedAvailable" class="btn"
@@ -254,7 +299,7 @@ import { terminatedLuckdrop } from "@/http/redPacket";
 import { readAllMsgByType, getAllMessageInfo } from "@/http/messageApi"
 import { setBadgeInfo, hideBadge } from "@/logic/background/twitter";
 import { getChromeStorage } from "@/uilts/chromeExtension";
-import { RewardType } from "@/types";
+import { PlayType, RewardType } from '@/types';
 
 var moment = require("moment");
 
@@ -407,13 +452,22 @@ const terminaHandler = (params, index) => {
   terminaTask.index = index;
 
   // set font
-  if (params && params.postTaskLuckdrop && params.postTaskLuckdrop.luckdropType == 2) {
-    modalTitle.value = `Early Termination of Lottery?`
-    modalContent.value = `This operation will terminate the lottery process and refund the lottery prizes.`
+  if(params && params.postTaskLuckdrop) {
+    if (params.postTaskLuckdrop.luckdropType == PlayType.lottery) {
+      modalTitle.value = `Early Termination of Lottery?`
+      modalContent.value = `This operation will terminate the lottery process and refund the lottery prizes.`
+    } else if(params.postTaskLuckdrop.luckdropType == PlayType.treasure) {
+      modalTitle.value = `Early Termination of treasure Hunt?`
+      modalContent.value = `This operation will stop the treasure hunt and refund the remaining amount within 2 days`
+    } else{
+      modalTitle.value = `Early termination of Giveaway?`
+      modalContent.value = `The remaining amount will be returned to your wallet within 1 day.`
+    }
   } else {
     modalTitle.value = `Early termination of Giveaway?`
     modalContent.value = `The remaining amount will be returned to your wallet within 1 day.`
   }
+  
   modalVisible.value = true;
 };
 

+ 7 - 4
src/view/popup/withdraw/info.vue

@@ -93,6 +93,9 @@ let state = reactive({
 })
 
 const inputWithdrawCalcFee = () => {
+  if(!state.input_amount) {
+    return;
+  }
   withdrawCalcFee({
     params: {
       "amountValue": state.input_amount,
@@ -104,7 +107,7 @@ const inputWithdrawCalcFee = () => {
       if (res.data) {
         state.currency_code = res.data.currencyCode || ''
         state.fee_amount = res.data.feeAmountValue || 0
-        state.amount = res.data.finalAmountValue || 111
+        state.amount = res.data.finalAmountValue > 0 ? res.data.finalAmountValue : 0
         state.is_enter_state = true
         inputText('yes')
       }
@@ -114,6 +117,9 @@ const inputWithdrawCalcFee = () => {
 }
 
 const inputText = (is_check_input) => {
+  if (is_check_input != 'yes') {
+    inputWithdrawCalcFee()
+  }
   if (!state.withdraw_switch) {
     return
   }
@@ -144,9 +150,6 @@ const inputText = (is_check_input) => {
     return
   } else {
     state.error_msg = ''
-    if (is_check_input != 'yes') {
-      inputWithdrawCalcFee()
-    }
   }
 }
 

+ 13 - 6
vue.config.js

@@ -1,6 +1,6 @@
 const path = require('path')
 const fs = require('fs')
-
+const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
 // webpack.config.js
 const AutoImport = require('unplugin-auto-import/webpack')
 const Components = require('unplugin-vue-components/webpack')
@@ -8,6 +8,7 @@ const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
 const CopyWebpackPlugin = require('copy-webpack-plugin');
 
 
+
 // Generate pages object
 const pages = {}
 
@@ -76,14 +77,20 @@ module.exports = {
     resolve: {
       alias: {
         '@': path.resolve('src')
+      },
+      fallback: {
+        fs: false
       }
     },
+
+
     output: {
       filename: `js/[name].js`,
       chunkFilename: `[name].js`
     },
     devtool: isDevMode ? 'inline-source-map' : false,
     plugins: [
+      new NodePolyfillPlugin(),
       AutoImport({
         resolvers: [ElementPlusResolver()],
       }),
@@ -109,9 +116,9 @@ module.exports = {
     ],
   },
   // 配置 content.css
-	css: {
-		extract: {
-			filename: "css/[name].css"
-		}
-	}
+  css: {
+    extract: {
+      filename: "css/[name].css"
+    }
+  }
 }

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません