Ver código fonte

分享赚钱

P 22 horas atrás
pai
commit
a5d7b80aa5

+ 1 - 0
package.json

@@ -76,6 +76,7 @@
     "node-forge": "^1.3.1",
     "pinia": "~2.0.36",
     "pinia-plugin-persistedstate": "~3.2.1",
+    "qrcode-generator": "2.0.4",
     "uniapp-router-next": "~1.2.7",
     "uview-pro": "^0.5.7",
     "vconsole": "^3.15.1",

+ 8 - 0
pnpm-lock.yaml

@@ -95,6 +95,9 @@ importers:
       pinia-plugin-persistedstate:
         specifier: ~3.2.1
         version: 3.2.3(pinia@2.0.36(typescript@7.0.2)(vue@3.5.40(typescript@7.0.2)))
+      qrcode-generator:
+        specifier: 2.0.4
+        version: 2.0.4
       uniapp-router-next:
         specifier: ~1.2.7
         version: 1.2.7(vue@3.5.40(typescript@7.0.2))
@@ -3810,6 +3813,9 @@ packages:
     resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
     engines: {node: '>=6'}
 
+  qrcode-generator@2.0.4:
+    resolution: {integrity: sha512-mZSiP6RnbHl4xL2Ap5HfkjLnmxfKcPWpWe/c+5XxCuetEenqmNFf1FH/ftXPCtFG5/TDobjsjz6sSNL0Sr8Z9g==}
+
   qrcode-reader@1.0.4:
     resolution: {integrity: sha512-rRjALGNh9zVqvweg1j5OKIQKNsw3bLC+7qwlnead5K/9cb1cEIAGkwikt/09U0K+2IDWGD9CC6SP7tHAjUeqvQ==}
 
@@ -9218,6 +9224,8 @@ snapshots:
 
   punycode@2.3.1: {}
 
+  qrcode-generator@2.0.4: {}
+
   qrcode-reader@1.0.4: {}
 
   qrcode-terminal@0.12.0: {}

+ 1 - 0
src/lang/en.js

@@ -611,4 +611,5 @@ export default {
     "澳门": "Macau",
     "新澳门": "New Macau",
     "香港": "Hong Kong",
+    "分享赚钱": "Earn by Sharing",
 }

+ 1 - 0
src/lang/vi.js

@@ -459,4 +459,5 @@ export default {
       "香港六合彩": "Xổ số Hồng Kông",
       "请先选择投注项": "Vui lòng chọn mục đặt cược trước",
       "结算时间": "Thời gian thanh toán",
+      "分享赚钱": "Chia sẻ kiếm tiền",
 }

+ 1 - 0
src/lang/zh.js

@@ -631,4 +631,5 @@ export default {
 	"已退款": "已退款",
 	"可赢金额": "可赢金额",
 	"查看订单详情": "查看订单详情",
+	"分享赚钱": "分享赚钱",
 }

+ 13 - 1
src/pages.json

@@ -337,6 +337,18 @@
     {
       "root": "pages/WorkModule/my",
       "pages": [
+        {
+          "path": "shareEarn/index",
+          "aliasPath": "/shareEarn",
+          "name": "shareEarn",
+          "style": {
+            "navigationStyle": "custom",
+            "navigationBarTitleText": "分享赚钱",
+            "app-plus": {
+              "titleNView": false
+            }
+          }
+        },
         {
           "path": "promotion/index",
           "aliasPath": "/promotion",
@@ -943,4 +955,4 @@
     "navigationBarTextStyle": "black",
     "backgroundColor": "#F8F8F8"
   }
-}
+}

+ 2 - 0
src/pages/Tabbar/My/index.vue

@@ -121,6 +121,8 @@
               @click="goPage('WalletManagement')"></u-cell-item>
             <u-cell-item :title="$t('优惠活动')" isLink icon="gift" customStyle="padding: 12px 20px"
               @click="goPage('promotion')"></u-cell-item>
+            <u-cell-item :title="$t('分享赚钱')" isLink icon="share" customStyle="padding: 12px 20px"
+              @click="goPage('shareEarn')"></u-cell-item>
             <u-cell-item :title="$t('资金记录')" isLink icon="order" customStyle="padding: 12px 20px"
               @click="goPage('fundRecord')"></u-cell-item>
             <u-cell-item :title="$t('充值记录')" isLink icon="coupon" customStyle="padding: 12px 20px"

+ 71 - 0
src/pages/WorkModule/my/shareEarn/CommissionTree.vue

@@ -0,0 +1,71 @@
+<template>
+  <view class="commission-tree" :class="agent === 'A' ? 'tree-a' : 'tree-b'">
+    <image class="tree-lines" :src="`/static/images/share-earn/tree-${agent.toLowerCase()}.svg`" mode="scaleToFill" />
+    <template v-if="agent === 'A'">
+      <view v-for="(member, index) in directMembers" :key="member.name" class="member-card direct-card"
+        :class="index === 0 ? 'direct-left' : 'direct-right'">
+        <view class="portrait"><image src="/static/images/share-earn/agent.svg" /><text class="badge">{{ member.name }}</text></view>
+        <text>有效投注 {{ member.bet }}</text>
+        <text class="commission">给A佣金{{ member.bet }}*10%=<text>{{ member.commission }}</text></text>
+      </view>
+    </template>
+    <view v-for="(member, index) in children" :key="member.name" class="member-card child-card"
+      :class="['child-' + index, { 'single-child': children.length === 1 }]">
+      <view class="portrait child-portrait"><image src="/static/images/share-earn/member.svg" /><text class="badge">{{ member.name }}</text></view>
+      <text>有效投注 {{ member.bet }}</text>
+      <text v-if="agent === 'A'" class="commission">给A佣金</text>
+      <text class="commission">{{ agent === 'A' ? member.bet + '*10%*30%' : '给' + agent + '佣金' + member.bet + '*10%' }}=<text>{{ agent === 'A' ? member.bonus : member.direct }}</text></text>
+    </view>
+    <view class="unlimited-card">
+      <view class="portrait unlimited-portrait"><image src="/static/images/share-earn/member-n.svg" /><text class="badge">N</text></view>
+      <text>(无数下级)</text>
+      <text>每一级都可给{{ agent }}贡献业绩和佣金,且不限下级层数,越多越好</text>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { computed } from 'vue'
+const props = defineProps({ agent: { type: String, default: 'A' } })
+const directMembers = [
+  { name: 'B1', bet: 500, commission: 50 }, { name: 'B2', bet: 3000, commission: 300 },
+]
+const members = [
+  { name: 'C1', bet: 1000, direct: 100, bonus: 30 },
+  { name: 'C2', bet: 2000, direct: 200, bonus: 60 },
+  { name: 'C3', bet: 20000, direct: 2000, bonus: 600 },
+]
+const children = computed(() => props.agent === 'A' ? members : props.agent === 'B1' ? members.slice(0, 2) : members.slice(2))
+</script>
+
+<style scoped lang="scss">
+.commission-tree { position: relative; margin-top: 3px; }
+.tree-a { height: 354px; }
+.tree-b { height: 226px; }
+.tree-lines { position: absolute; inset: 0; width: 100%; height: 100%; }
+.tree-a .tree-lines { width: calc(100% + 8px); }
+.member-card { position: absolute; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; box-sizing: border-box; border-radius: 9px; font-size: 10px; color: #554e3b; padding: 8px 2px 10px; line-height: 14px; }
+.direct-card { top: 44px; width: 43%; height: 67px; background: #d5c7a7; }
+.direct-left { left: 5.5%; }
+.direct-right { right: 5.5%; }
+.tree-a .direct-card { top: 43px; }
+.child-card { background: #bda657; }
+.tree-a .child-card { top: 158px; width: 31.3%; height: 81px; }
+.tree-a .child-0 { left: 0; }
+.tree-a .child-1 { left: 34.35%; }
+.tree-a .child-2 { right: 0; }
+.tree-b .child-card { top: 44px; width: 43%; height: 67px; }
+.tree-b .child-0 { left: 5.5%; }
+.tree-b .child-1 { right: 5.5%; }
+.tree-b .single-child { left: 28.5%; }
+.portrait { position: absolute; left: 50%; top: -23px; transform: translateX(-50%); width: 40px; height: 40px; border-radius: 50%; background: #f7f6ed; border: 1px solid #e5b83d; }
+.portrait image { width: 100%; height: 100%; border-radius: 50%; }
+.badge { position: absolute; right: -3px; bottom: -1px; min-width: 15px; height: 15px; border-radius: 50%; font-size: 10px; line-height: 15px; text-align: center; background: #ffb700; color: #fff; }
+.child-portrait .badge { background: #dfc67d; color: #77643d; }
+.commission { font-size: 9px; line-height: 13px; color: #5f522f; white-space: nowrap; }
+.commission text { color: #855100; font-weight: 600; }
+.unlimited-card { position: absolute; bottom: 0; left: 0; width: 100%; height: 67px; padding: 28px 5px 6px; box-sizing: border-box; border-radius: 8px; background: #b6d9b3; color: #3f6340; text-align: center; font-size: 10px; line-height: 14px; display: flex; flex-direction: column; }
+.unlimited-portrait { border-color: #00d22c; top: -22px; }
+.unlimited-portrait .badge { background: #00ce1d; }
+.tree-a .unlimited-card { height: 68px; }
+</style>

+ 233 - 0
src/pages/WorkModule/my/shareEarn/index.vue

@@ -0,0 +1,233 @@
+<template>
+  <PageContainer nav-title="分享赚钱">
+    <view class="share-earn-page">
+      <scroll-view scroll-y class="page-scroll">
+        <view class="page-content">
+        <view class="invite-card">
+          <view class="invite-heading">
+            <text>邀请好友</text>
+            <button class="invite-code" @click="copyCode">
+              <text class="muted">我的邀请码</text>
+              <text class="code-value">{{ invitationCode || '--' }}</text>
+              <u-icon name="file-text" color="#d9b34b" size="24" />
+            </button>
+          </view>
+          <view class="invite-body">
+            <button class="qr-card" @click="saveQrCode">
+              <image v-if="qrImage" :src="qrImage" class="qr-image" mode="aspectFit" />
+              <view v-else class="qr-placeholder">登录后生成<br />邀请二维码</view>
+              <text class="save-label">保存邀请码</text>
+            </button>
+            <view class="share-tools">
+              <button class="link-field" @click="copyLink">
+                <text class="link-text">{{ invitationLink || '登录后获取专属邀请链接' }}</text>
+                <view class="link-copy"><u-icon name="file-text" color="#d9b34b" size="28" /></view>
+              </button>
+              <view class="share-channels">
+                <button v-for="channel in channels" :key="channel.name" class="share-channel"
+                  @click="shareTo(channel.name)">
+                  <view v-if="channel.name === '分享'" class="share-icon">
+                    <u-icon name="share" color="#d9b34b" size="40" />
+                  </view>
+                  <image v-else :src="`/static/images/share-earn/${channel.icon}.svg`" class="channel-icon" />
+                  <text>{{ channel.name }}</text>
+                </button>
+              </view>
+            </view>
+          </view>
+        </view>
+
+        <text class="section-title">代理教程</text>
+        <view class="commission-tabs">
+          <button v-for="tab in tabs" :key="tab" class="commission-tab"
+            :class="{ active: selected === tab }" @click="selected = tab">
+            {{ tab }}的佣金
+          </button>
+        </view>
+
+        <view class="commission-summary">
+          <view class="agent-portrait summary-portrait">
+            <image :src="selected === 'A' ? '/static/images/share-earn/agent-a.svg' : '/static/images/share-earn/agent.svg'" />
+            <text class="agent-badge">{{ selected }}</text>
+          </view>
+          <view class="summary-lines">
+            <view>直属业绩={{ current.performance }}</view>
+            <view>直属佣金={{ current.total }}*10%=<text class="gold">{{ current.direct }}</text></view>
+            <view>其他佣金=<text class="gold">{{ current.otherFormula }}</text></view>
+            <view>本期佣金={{ current.direct }}+{{ current.other }}=<text class="gold">{{ current.income }}</text></view>
+          </view>
+        </view>
+
+        <CommissionTree :agent="selected" />
+
+        <view class="rules-card">
+          <view class="rules-title">举例说明如下:</view>
+          <view class="paragraph">假设当前有效投注的返佣比例为10%(即来自直属下级),跨级部分额外佣金为比例中的比例(站长额外赠送),赠送比例为30%。A是第一个发掘商机的,马上发展了B1和B2;B1又往下发展了C1和C2;B2往下发展了C3。第二天B1的有效投注为500,B2的有效投注为3000,C1的有效投注为1000,C2的有效投注为2000,C3的有效投注为20000。</view>
+          <view>那么他们之间的收益计算方式如下:</view>
+          <view class="rules-title">1、{{ selected }}的收益计算方式如下:</view>
+          <view v-if="selected === 'A'">
+            <view class="paragraph"><text class="rule-number">(1)A说明:</text>A的佣金来源除了直属下级B1和B2贡献,还有来自其他下级C1、C2和C3贡献。</view>
+            <view class="paragraph"><text class="rule-number">(2)A的直属业绩:</text>即A的直属下级B1和B2给A贡献的业绩,计算公式为:直属业绩=B1有效投注+B2有效投注=500+3000=3500;</view>
+            <view class="paragraph"><text class="rule-number">(3)A的直属佣金:</text>直属佣金=直属业绩*返佣比例=3500*10%=<text class="gold">350;</text></view>
+            <view class="paragraph"><text class="rule-number">(4)A的其他佣金:</text>即来自C1、C2和C3贡献佣金,计算公式为:其他佣金=(C1有效投注+C2有效投注+C3有效投注)*返佣比例*赠送比例=(1000+2000+20000)*10%*30%=<text class="gold">690;</text></view>
+            <view class="paragraph"><text class="rule-number">(5)A的本期佣金:</text>本期佣金=直属佣金+其他佣金=<text class="gold">350+690=1040。</text></view>
+          </view>
+          <view v-else-if="selected === 'B1'">
+            <view class="paragraph"><text class="rule-number">(1)B1说明:</text>B1的直属下级为C1和C2,他们的有效投注分别为1000和2000。</view>
+            <view class="paragraph"><text class="rule-number">(2)B1的直属业绩:</text>直属业绩=C1有效投注+C2有效投注=1000+2000=3000;</view>
+            <view class="paragraph"><text class="rule-number">(3)B1的直属佣金:</text>直属佣金=3000*10%=<text class="gold">300;</text></view>
+            <view class="paragraph"><text class="rule-number">(4)B1的其他佣金:</text>本例中C1、C2暂无下级,其他佣金=<text class="gold">0;</text></view>
+            <view class="paragraph"><text class="rule-number">(5)B1的本期佣金:</text>本期佣金=直属佣金+其他佣金=<text class="gold">300+0=300。</text></view>
+          </view>
+          <view v-else>
+            <view class="paragraph"><text class="rule-number">(1)B2说明:</text>B2的直属下级为C3,有效投注为20000。</view>
+            <view class="paragraph"><text class="rule-number">(2)B2的直属业绩:</text>直属业绩=C3有效投注=<text class="gold">20000;</text></view>
+            <view class="paragraph"><text class="rule-number">(3)B2的直属佣金:</text>直属佣金=20000*10%=<text class="gold">2000;</text></view>
+            <view class="paragraph"><text class="rule-number">(4)B2的其他佣金:</text>本例中C3暂无下级,其他佣金=<text class="gold">0;</text></view>
+            <view class="paragraph"><text class="rule-number">(5)B2的本期佣金:</text>本期佣金=直属佣金+其他佣金=<text class="gold">2000+0=2000。</text></view>
+          </view>
+          <view class="rules-title">2、全民代理补充说明:</view>
+          <view class="paragraph">因全民代理“代理模式”可以发展无限下级,即N代表无限级,即可横向发展同时也可以纵向发展。为了便于解说,本文只取2层结构作为例子阐述。</view>
+        </view>
+        </view>
+      </scroll-view>
+    </view>
+  </PageContainer>
+</template>
+
+<script setup>
+import { computed, ref } from 'vue'
+import { onShow } from '@dcloudio/uni-app'
+import qrcode from 'qrcode-generator'
+import PageContainer from '@/components/PageContainer/index.vue'
+import CommissionTree from './CommissionTree.vue'
+
+const userInfo = ref({})
+const selected = ref('A')
+const tabs = ['A', 'B1', 'B2']
+const channels = [
+  { name: '分享' }, { name: 'Wechat', icon: 'wechat' },
+  { name: '抖音', icon: 'douyin' }, { name: '快手', icon: 'kuaishou' }, { name: 'QQ', icon: 'qq' },
+]
+const examples = {
+  A: { performance: '500+3000=3500', total: 3500, direct: 350, otherFormula: '30+60+600=690', other: 690, income: 1040 },
+  B1: { performance: '1000+2000=3000', total: 3000, direct: 300, otherFormula: '0', other: 0, income: 300 },
+  B2: { performance: '20000', total: 20000, direct: 2000, otherFormula: '0', other: 0, income: 2000 },
+}
+const current = computed(() => examples[selected.value])
+const invitationCode = computed(() => String(userInfo.value.user_code || ''))
+const invitationLink = computed(() => {
+  if (!invitationCode.value) return ''
+  let base = 'https://www.f1bet888.com/'
+  // #ifdef H5
+  base = window.location.href.split('#')[0]
+  // #endif
+  return `${base}#/pages/register/index?invitationCode=${encodeURIComponent(invitationCode.value)}`
+})
+const qrImage = computed(() => {
+  if (!invitationLink.value) return ''
+  const code = qrcode(0, 'M')
+  code.addData(invitationLink.value)
+  code.make()
+  return code.createDataURL(6, 8)
+})
+
+function requireCode() {
+  if (invitationCode.value) return true
+  uni.showToast({ title: '请先登录后获取邀请码', icon: 'none' })
+  return false
+}
+function copyText(data, title = '复制成功') {
+  uni.setClipboardData({ data, showToast: false, success: () => uni.showToast({ title, icon: 'none' }) })
+}
+function copyCode() {
+  if (requireCode()) copyText(invitationCode.value)
+}
+function copyLink() {
+  if (requireCode()) copyText(invitationLink.value, '邀请链接已复制')
+}
+async function shareTo(channel) {
+  if (!requireCode()) return
+  // #ifdef H5
+  if (channel === '分享' && navigator.share) {
+    try {
+      await navigator.share({ title: '邀请好友', text: '使用我的邀请码注册', url: invitationLink.value })
+    } catch (error) {
+      if (error.name !== 'AbortError') copyLink()
+    }
+    return
+  }
+  // #endif
+  const platform = channel === 'Wechat' ? '微信' : channel
+  copyText(invitationLink.value, channel === '分享' ? '邀请链接已复制' : `链接已复制,请前往${platform}粘贴分享`)
+}
+function saveQrCode() {
+  if (!requireCode()) return
+  // #ifdef H5
+  const link = document.createElement('a')
+  link.href = qrImage.value
+  link.download = `邀请码-${invitationCode.value}.gif`
+  document.body.appendChild(link)
+  link.click()
+  link.remove()
+  return
+  // #endif
+  // #ifdef APP-PLUS
+  const bitmap = new plus.nativeObj.Bitmap('invitation-qr')
+  bitmap.loadBase64Data(qrImage.value, () => {
+    bitmap.save(`_doc/invitation-${Date.now()}.png`, { overwrite: true, format: 'png' }, (result) => {
+      uni.saveImageToPhotosAlbum({ filePath: result.target, success: () => uni.showToast({ title: '保存成功' }), complete: () => bitmap.clear() })
+    }, () => { bitmap.clear(); uni.showToast({ title: '保存失败,请重试', icon: 'none' }) })
+  }, () => { bitmap.clear(); uni.showToast({ title: '保存失败,请重试', icon: 'none' }) })
+  // #endif
+}
+onShow(() => {
+  const stored = uni.getStorageSync('user_info')
+  if (typeof stored === 'string') {
+    try { userInfo.value = JSON.parse(stored) || {} } catch { userInfo.value = {} }
+  } else userInfo.value = stored || {}
+})
+</script>
+
+<style scoped lang="scss">
+.share-earn-page { min-height: 100%; background: #fff; color: #333; font-size: 13px; }
+button { margin: 0; padding: 0; border: 0; border-radius: 0; background: transparent; color: inherit; font-size: inherit; line-height: inherit; }
+button::after { border: 0; }
+.page-scroll { height: calc(100vh - 94px - env(safe-area-inset-top)); }
+.page-content { max-width: 520px; margin: 0 auto; padding: 10px 10px calc(10px + env(safe-area-inset-bottom)); box-sizing: border-box; }
+.invite-card, .commission-summary, .rules-card { background: #f8f7f3; border: 1px solid #eeeae1; border-radius: 8px; box-shadow: none; }
+.invite-card { padding: 0 11px 16px; margin-bottom: 12px; }
+.invite-heading { display: flex; align-items: center; justify-content: space-between; height: 38px; border-bottom: 1px solid #ededed; font-weight: 600; }
+.invite-code { display: flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 400; }
+.muted { color: #858585; }
+.code-value { font-weight: 600; }
+.invite-body { display: flex; align-items: flex-start; gap: 16px; padding-top: 12px; }
+.qr-card { flex-shrink: 0; width: 66px; border-radius: 5px; background: #d2ad50; overflow: hidden; }
+.qr-image, .qr-placeholder { display: block; width: 66px; height: 66px; background: #fff; }
+.qr-placeholder { display: flex; align-items: center; justify-content: center; color: #777; font-size: 10px; line-height: 17px; }
+.save-label { display: block; line-height: 36px; font-size: 11px; color: #665124; }
+.share-tools { flex: 1; min-width: 0; }
+.link-field { display: flex; align-items: center; width: 100%; height: 38px; padding-left: 10px; border: 1px solid #e3e3e3; border-radius: 7px; color: #777; box-sizing: border-box; }
+.link-text { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 11px; text-align: left; }
+.link-copy { display: flex; justify-content: center; align-items: center; width: 36px; margin-left: 8px; border-left: 1px solid #e8e8e8; }
+.share-channels { display: flex; justify-content: space-between; margin-top: 10px; gap: 4px; }
+.share-channel { display: flex; flex-direction: column; align-items: center; gap: 3px; font-size: 12px; color: #666; }
+.share-icon, .channel-icon { display: flex; align-items: center; justify-content: center; width: 35px; height: 35px; }
+.share-icon { border: 1px solid #e5e5e5; border-radius: 50%; box-sizing: border-box; }
+.section-title { display: block; font-size: 16px; line-height: 24px; margin-bottom: 8px; color: #242424; }
+.commission-tabs { display: flex; gap: 12px; margin-bottom: 10px; }
+.commission-tab { padding: 4px 11px; border-radius: 20px; border: 1px solid #dedede; background: #f7f7f7; font-size: 12px; color: #666; }
+.commission-tab.active { color: #59451e; border-color: #d7b34c; background: #d7b34c; }
+.commission-summary { display: flex; align-items: center; min-height: 97px; padding: 10px; box-sizing: border-box; background: #eee2af; border-color: #dfcc95; color: #3f3624; }
+.agent-portrait { position: relative; width: 50px; height: 50px; border: 1px solid #e3ba44; border-radius: 50%; background: #f5f5ef; flex-shrink: 0; }
+.agent-portrait image { width: 100%; height: 100%; border-radius: 50%; }
+.agent-badge { position: absolute; bottom: -2px; right: -3px; min-width: 15px; height: 15px; line-height: 15px; padding: 0 1px; text-align: center; border-radius: 50%; background: #ffbd00; color: #fff; font-size: 11px; font-weight: 600; }
+.summary-portrait { margin-right: 48px; }
+.summary-lines { font-size: 12px; line-height: 19px; letter-spacing: -0.3px; }
+.gold { color: #a87500; font-weight: 600; }
+.rules-card { margin-top: 11px; padding: 9px 11px 12px; font-size: 13px; line-height: 21px; color: #454545; }
+.rules-title, .rule-number { color: #252525; }
+.rules-title, .rule-number { font-weight: 600; }
+.paragraph { text-indent: 2em; }
+@media (max-width: 350px) { .summary-portrait { margin-right: 28px; } .invite-body { gap: 10px; } .share-channel { font-size: 10px; } }
+</style>

+ 2 - 2
src/static/config.js

@@ -1,9 +1,9 @@
 // #ifdef H5
 window.global = {
   // baseURL: 'https://api.f1bet888.com/api',
-  baseURL: 'https://sportapi.sp2509.cc/api',
+  baseURL: "https://sportapi.paopao-api.cc/api",
   // wsURL: 'wss://api.f1bet888.com:8443',
-  wsURL: 'wss://sportapi.sp2509.cc:9501',
+  wsURL: "wss://sportapi.paopao-api:9501",
   // botURL: 'https://api.f1bet.bet/api/',
   botURL: 'https://bot28api.sp2509.cc/api/',
   openPCUrl: 'https://www.f1bet888.com',

+ 20 - 0
src/static/images/share-earn/agent-a.svg

@@ -0,0 +1,20 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 80 80">
+  <defs><clipPath id="portrait"><circle cx="40" cy="40" r="40"/></clipPath></defs>
+  <g clip-path="url(#portrait)">
+    <path fill="#f7f7f2" d="M0 0h80v80H0z"/>
+    <path fill="#263d68" d="M8 82V68q1-12 23-15h18q23 3 24 15v14"/>
+    <path fill="#fff" d="m28 55 12 13 12-13 5 25H23z"/>
+    <path fill="#b25648" d="m38 66-4 7 4 10h5l3-10-5-7"/>
+    <path fill="#dcab91" d="M32 44h16v16l-8 8-8-8z"/>
+    <path fill="#f2cbb1" d="M22 24q0-17 18-18t18 18v16q-1 8-9 13l-9 4-9-4q-8-5-9-13z"/>
+    <path fill="#9b6c3d" d="M21 31q-4-14 1-22 5-8 17-7 14-4 20 5l-3 12q-13 3-23-5l-7 7v13z"/>
+    <path d="M28 10q10-7 22-2" fill="none" stroke="#c5965e" stroke-width="3" stroke-linecap="round"/>
+    <path fill="#9b6c3d" d="m54 17 4-4v18l-3 4z"/>
+    <path d="m28 27 8-1m9 0 8 1" stroke="#805833" stroke-width="2.2" stroke-linecap="round"/>
+    <g fill="#4d7180"><ellipse cx="33" cy="32" rx="1.7" ry="2"/><ellipse cx="48" cy="32" rx="1.7" ry="2"/></g>
+    <path d="m40 33-2 8h5" fill="none" stroke="#cc9c82" stroke-linecap="round"/>
+    <path d="m26 40 5 7m23-7-5 7" fill="none" stroke="#dfb299" stroke-linecap="round"/>
+    <path d="M35 46q5 3 10 0" fill="none" stroke="#aa7465" stroke-width="1.6" stroke-linecap="round"/>
+    <path fill="#46628a" d="m23 56 6 24H16l4-14-5-3zm34 0-6 24h13l-4-14 5-3z"/>
+  </g>
+</svg>

+ 1 - 0
src/static/images/share-earn/agent.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 80 80"><defs><clipPath id="c"><circle cx="40" cy="40" r="40"/></clipPath></defs><g clip-path="url(#c)"><path fill="#f7f7f2" d="M0 0h80v80H0z"/><path fill="#344e56" d="M8 82V68q1-12 23-15h18q23 3 24 15v14"/><path fill="#fff" d="m28 55 12 13 12-13 5 25H23z"/><path fill="#d6a23d" d="m38 66-4 7 4 10h5l3-10-5-7"/><path fill="#e5a77d" d="M33 45h15v15l-8 8-8-8z"/><ellipse cx="40" cy="30" rx="18" ry="23" fill="#efbb90"/><path fill="#713d29" d="M22 30V16q3-15 19-13 20-1 18 21l-5 9-3-17q-14 6-22-1l-3 19z"/><path fill="#713d29" d="m24 34 7 6q9-5 17 0l8-7-3 15q-5 12-14 12-9-1-13-12z"/><path fill="#efbb90" d="M30 31h20v9q-10 5-20 0z"/><path d="M29 26h8m7 0h8" stroke="#713d29" stroke-width="2" stroke-linecap="round"/><g fill="#32312c"><ellipse cx="33" cy="31" rx="1.5" ry="2"/><ellipse cx="48" cy="31" rx="1.5" ry="2"/></g><path d="m39 33-1 6h4" fill="none" stroke="#c88e68"/><path d="M34 46q7 6 13 0" fill="#fff"/><path fill="#62848a" d="m23 56 6 24H16l4-14-5-3zm34 0-6 24h13l-4-14 5-3z"/></g></svg>

+ 1 - 0
src/static/images/share-earn/douyin.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="20" fill="#090909"/><path d="M24 6v19a7 7 0 1 1-7-7m7-12q1 9 10 9" fill="none" stroke="#24f4eb" stroke-width="5" transform="translate(-1 1)"/><path d="M24 6v19a7 7 0 1 1-7-7m7-12q1 9 10 9" fill="none" stroke="#fe3059" stroke-width="5" transform="translate(1 0)"/><path d="M24 6v19a7 7 0 1 1-7-7m7-12q1 9 10 9" fill="none" stroke="#fff" stroke-width="3"/></svg>

+ 1 - 0
src/static/images/share-earn/kuaishou.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="20" fill="#ff5714"/><g fill="none" stroke="#fff" stroke-width="2.6"><circle cx="14" cy="11" r="5"/><circle cx="26" cy="11" r="5"/><rect x="8" y="20" width="17" height="13" rx="4"/><path d="m26 23 6-3v13l-6-3z" stroke-linejoin="round"/></g></svg>

+ 1 - 0
src/static/images/share-earn/member-n.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 80 80"><defs><clipPath id="c"><circle cx="40" cy="40" r="40"/></clipPath></defs><g clip-path="url(#c)"><path fill="#f7f7f2" d="M0 0h80v80H0z"/><path fill="#435258" d="M8 82V69q3-14 24-16h16q23 3 24 16v13"/><path fill="#fff" d="m28 54 12 10 12-10 5 28H23z"/><path fill="#b56d7a" d="m38 65-3 8 3 9h5l3-9-4-8"/><path fill="#efb8ad" d="M32 45h16v13l-8 8-8-8z"/><ellipse cx="40" cy="30" rx="17" ry="24" fill="#f1c6bc"/><path fill="#3d3c40" d="M22 33q-3-15 1-22 6-8 17-7 22-1 20 22l-5 10-2-18q-15 6-24-3l-3 19z"/><path d="M28 27h8m9 0h8" stroke="#63514e" stroke-width="2" stroke-linecap="round"/><g fill="#39342f"><ellipse cx="33" cy="32" rx="1.5" ry="2"/><ellipse cx="48" cy="32" rx="1.5" ry="2"/></g><path d="m40 34-2 7h4" fill="none" stroke="#d7a49c"/><path d="M34 47q7 5 13-1" fill="none" stroke="#b7857c" stroke-width="1.7"/></g></svg>

+ 1 - 0
src/static/images/share-earn/member.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 80 80"><defs><clipPath id="c"><circle cx="40" cy="40" r="40"/></clipPath></defs><g clip-path="url(#c)"><path fill="#f7f7f2" d="M0 0h80v80H0z"/><path fill="#463328" d="M17 56q5-8 3-25Q16 6 39 5q25-2 24 27-3 14 2 25z"/><path fill="#6a7776" d="M9 81q-1-23 23-27h16q23 3 24 27"/><path fill="#efbe99" d="M32 45v13l8 11 8-11V45"/><path fill="#f4cbaa" d="M23 24q0-12 17-13 18 0 18 16v10q-1 18-18 20-16-3-17-20z"/><path fill="#463328" d="M22 14q18-17 35 1l3 16q-11-4-16-16-5 14-22 15z"/><path d="M28 29h7m10 0h7" stroke="#5f4431" stroke-width="1.8" stroke-linecap="round"/><g fill="#39342f"><ellipse cx="32" cy="34" rx="1.6" ry="2"/><ellipse cx="48" cy="34" rx="1.6" ry="2"/></g><path d="m39 34-1 6h3" fill="none" stroke="#cc9d7c"/><path d="M35 46q5 4 11-1" fill="none" stroke="#b26f64" stroke-width="1.7"/><path fill="#faf8ef" d="m29 54 11 15-9 5-8-16zm22 0L40 69l9 5 8-16z"/></g></svg>

+ 1 - 0
src/static/images/share-earn/qq.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="20" fill="#fff"/><path d="M12 17q-3-12 8-13 11 1 8 13l4 10q0 4-4 2-2 6-8 6-7 0-8-6-5 2-4-2z" fill="#121318"/><ellipse cx="20" cy="25" rx="8" ry="10" fill="#fff"/><path d="m11 17 18 1-1 5-17-2z" fill="#f32c23"/><path d="m12 21-2 7 4 1 1-8" fill="#f32c23"/><g fill="#fff"><ellipse cx="17" cy="11" rx="2.5" ry="4"/><ellipse cx="23" cy="11" rx="2.5" ry="4"/></g><g fill="#121318"><ellipse cx="18" cy="12" rx="1" ry="2"/><ellipse cx="22" cy="12" rx="1" ry="2"/></g><path d="m16 16 4-2 4 2-4 3zM11 33l7-1v4H9zm12-1 6 1 2 3h-8z" fill="#f5b51c"/></svg>

+ 38 - 0
src/static/images/share-earn/tree-a.svg

@@ -0,0 +1,38 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="382" height="354" viewBox="0 0 382 354" preserveAspectRatio="none">
+  <g fill="none" stroke="#6c6c68" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+    <path d="M186 4v8M101 23v-7q0-4 4-4h163q4 0 4 4v7" />
+    <path d="M121 112v9M59 135v-7q0-7 7-7h113q7 0 7 7v7M314 112v23" />
+    <path d="M59 244v2q0 6 6 6h243q6 0 6-6v-2M186 241v24" />
+  </g>
+  <g fill="#6c6c68">
+    <circle cx="186" cy="4" r="2.5" />
+    <circle cx="121" cy="112" r="2.5" />
+    <circle cx="314" cy="112" r="2.5" />
+    <circle cx="59" cy="135" r="2.5" />
+    <circle cx="186" cy="135" r="2.5" />
+    <circle cx="314" cy="135" r="2.5" />
+    <circle cx="59" cy="244" r="2.5" />
+    <circle cx="186" cy="241" r="2.5" />
+    <circle cx="314" cy="244" r="2.5" />
+    <circle cx="186" cy="265" r="2.5" />
+  </g>
+  <g fill="none" stroke="#d4b044" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+    <path d="M12 156V39q0-6 6-6h13q6 0 6-6V8" />
+    <path d="M360 156V39q0-6-6-6h-13q-6 0-6-6V8" />
+    <path d="M217 241v13q0 6 6 6h149q6 0 6-6V29q0-6-6-6h-12q-6 0-6-6V8" />
+  </g>
+  <g fill="none" stroke="#ffb600" stroke-width="2" stroke-linecap="round">
+    <path d="M56 41V8M316 41V8" />
+  </g>
+  <g fill="#ffb600">
+    <path d="m51 10 5-6 5 6zM311 10l5-6 5 6z" />
+    <circle cx="56" cy="41" r="2.5" />
+    <circle cx="316" cy="41" r="2.5" />
+  </g>
+  <g fill="#d4b044">
+    <path d="m32 10 5-6 5 6zM330 10l5-6 5 6zM349 10l5-6 5 6z" />
+    <circle cx="12" cy="156" r="2.5" />
+    <circle cx="360" cy="156" r="2.5" />
+    <circle cx="217" cy="241" r="2.5" />
+  </g>
+</svg>

+ 1 - 0
src/static/images/share-earn/tree-b1.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="374" height="226" viewBox="0 0 374 226" preserveAspectRatio="none"><defs><marker id="arrow" markerWidth="5" markerHeight="5" refX="2" refY="2.5" orient="auto"><path d="M0 0 5 2.5 0 5z" fill="#d4b044"/></marker></defs><g fill="none" stroke="#747671" stroke-width="2"><path d="M187 5v10M101 23v-4q0-4 5-4h162q6 0 6 5v3M101 111v10q0 4 5 4h162q6 0 6-5v-9M187 125v13"/></g><g fill="#747671"><circle cx="187" cy="5" r="2.5"/><circle cx="101" cy="111" r="2.5"/><circle cx="274" cy="111" r="2.5"/><circle cx="187" cy="138" r="2.5"/></g><g fill="none" stroke="#d4b044" stroke-width="2" marker-end="url(#arrow)"><path d="M57 44V8"/><path d="M317 44V8"/></g><g fill="#d4b044"><circle cx="57" cy="44" r="2.5"/><circle cx="317" cy="44" r="2.5"/></g></svg>

+ 1 - 0
src/static/images/share-earn/tree-b2.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="374" height="226" viewBox="0 0 374 226" preserveAspectRatio="none"><defs><marker id="arrow" markerWidth="5" markerHeight="5" refX="2" refY="2.5" orient="auto"><path d="M0 0 5 2.5 0 5z" fill="#e9ad00"/></marker></defs><g fill="none" stroke="#747671" stroke-width="2"><path d="M187 5v18M187 111v27"/></g><g fill="#747671"><circle cx="187" cy="5" r="2.5"/><circle cx="187" cy="111" r="2.5"/><circle cx="187" cy="138" r="2.5"/></g><path d="M244 44V8" fill="none" stroke="#e9ad00" stroke-width="2" marker-end="url(#arrow)"/><circle cx="244" cy="44" r="2.5" fill="#e9ad00"/></svg>

+ 1 - 0
src/static/images/share-earn/wechat.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="20" fill="#00df1b"/><path fill="#fff" d="M18 7C11 7 6 11 6 16c0 3 2 6 5 8l-1 4 5-3h3c7 0 12-4 12-9S25 7 18 7"/><path fill="#fff" stroke="#00df1b" stroke-width="1.2" d="M26 17c6 0 10 4 10 8 0 3-2 5-4 6l1 4-4-2h-3c-6 0-10-4-10-8s4-8 10-8"/><g fill="#00c71a"><circle cx="13" cy="14" r="1.5"/><circle cx="22" cy="14" r="1.5"/><circle cx="22" cy="23" r="1.2"/><circle cx="30" cy="23" r="1.2"/></g></svg>