浏览代码

[fix] 提现:接口计算金额、校验、bug修复、获取配置; 发布:预览显示真实数据、发布器 输入框动态宽度、Tips、输入校验、优化、动态计算支付金额、deNet loading

wenliming 3 年之前
父节点
当前提交
2e572f3ebd

二进制
src/assets/img/icon-btn-loading.png


二进制
src/assets/img/icon-red-pack-card.png


+ 6 - 0
src/assets/svg/icon-btn-loading.svg

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto; animation-play-state: running; animation-delay: 0s;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
+<circle cx="50" cy="50" fill="none" stroke="#f9f9f9" stroke-width="10" r="35" stroke-dasharray="164.93361431346415 56.97787143782138" style="animation-play-state: running; animation-delay: 0s;">
+  <animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s" values="0 50 50;360 50 50" keyTimes="0;1" style="animation-play-state: running; animation-delay: 0s;"></animateTransform>
+</circle>
+<!-- [ldio] generated by https://loading.io/ --></svg>

+ 4 - 0
src/assets/svg/icon-following-user.svg

@@ -0,0 +1,4 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="9.00977" cy="5.5" r="3.5" fill="#566370"/>
+<path d="M3.51018 15C3.51018 15 3.01062 10 9.01018 10C15.0097 10 14.5102 15 14.5102 15H3.51018Z" fill="#566370"/>
+</svg>

二进制
src/assets/svg/icon-red-pack-card.png


+ 18 - 0
src/http/pay.js

@@ -0,0 +1,18 @@
+import { service } from "./request";
+
+export function withdrawCalcFee(params) {
+    return service({
+        url: `/wallet/withdraw/calcFee`,
+        method: "post",
+        data: params,
+    });
+}
+
+export function payCalcFee(params) {
+    return service({
+        url: `/wallet/pay/calcFee`,
+        method: "post",
+        data: params,
+    });
+}
+

+ 1 - 1
src/http/request.js

@@ -1,5 +1,5 @@
 import axios from 'axios'
-import {getStorage} from "../uilts/chromeExtension"
+import {getStorage} from "../uilts/help"
 
 let baseUrl = 'https://denettestapi.piaoquantv.com/denet';
 let userInfo = '';

+ 16 - 6
src/logic/twitter.js

@@ -285,7 +285,6 @@ function _getTwitterArtId(contentStr, cb) {
 function _deNetBtnClick(port) {
     getUserInfo((res) => {
         if (res) {
-
             if (window.location.pathname != '/home') {
                 if (!dom.homeBtn) {
                     dom.homeBtn = document.querySelector('a[data-testid="AppTabBar_Home_Link"]');
@@ -294,6 +293,10 @@ function _deNetBtnClick(port) {
             }
             showGiveDialogHandler(res);
         } else {
+            dom.deBtn.insertBefore(dom.loadingImg, dom.deBtn.querySelector('span'));
+            setTimeout(() => {
+                dom.deBtn.innerHTML = '<span>DeNet<span>';
+            }, 3000)
             port.postMessage({ state: 'CONTENT_TWITTER_LOGIN' })
         }
     })
@@ -317,13 +320,19 @@ function _setPublishContent(content) {
  * @private
  */
 function _createBtnDom(port) {
+    let loadingImg = document.createElement('img');
+    loadingImg.src = require("../assets/img/icon-btn-loading.png");
+    loadingImg.style.cssText = 'width:20px;height: 20px;margin-right:3px;-webkit-animation:load 1.1s infinite linear;';
+
+    let style = document.createElement('style'); 
+    style.innerHTML=" @-webkit-keyframes load{from{ transform: rotate(0deg);} to{transform: rotate(360deg);}}"; 
+    document.getElementsByTagName('head').item(0).appendChild(style); 
+
     let deBtn = document.createElement('span');
-    const shadowRoot = deBtn.attachShadow({ mode: 'closed' })
     const shadowDiv = document.createElement('div');
-    shadowDiv.innerText = 'DeNet';
-    shadowDiv.id = 'de-btn';
-    shadowDiv.style.cssText = 'width:220px;height: 52px;text-align:center;line-height:52px;margin-bottom: 4px;margin-top: 4px;background: linear-gradient(274.8deg, #FF9900 -3.69%, #BD00FF 69.71%, #00F0FF 122.65%);color:#fff;font-size:15px;font-weight:700;border-radius:100px;cursor: pointer;';
-    shadowRoot.appendChild(shadowDiv);
+    deBtn.innerHTML  = '<span>DeNet</span>';
+    deBtn.id = 'de-btn';
+    deBtn.style.cssText = 'width:220px;height: 52px;text-align:center;line-height:52px;margin-bottom: 4px;margin-top: 4px;background: linear-gradient(274.8deg, #FF9900 -3.69%, #BD00FF 69.71%, #00F0FF 122.65%);color:#fff;font-size:15px;font-weight:700;border-radius:100px;cursor: pointer;display: flex;align-items: center;justify-content: center;';
 
     const deBtn1 = document.createElement('img');
     let src = require("../assets/img/icon-gift-pack.png");
@@ -349,6 +358,7 @@ function _createBtnDom(port) {
     dom.deBtn = deBtn;
     dom.deBtn1 = deBtn1;
     dom.deBtn2 = deBtn2;
+    dom.loadingImg = loadingImg;
 }
 
 /* setInterval(() => {

+ 0 - 13
src/uilts/chromeExtension.js

@@ -13,16 +13,3 @@ export function getChromeStorage(key = '',callback) {
         }
     });
 }
-
-export function setStorage(key, value) {
-    return localStorage.setItem(key, JSON.stringify(value));
-}
-
-export function getStorage(key) {
-    const item = localStorage.getItem(key);
-    try {
-        return item ? JSON.parse(item) : '';
-    } catch (e) {
-        return item;
-    }
-}

+ 13 - 1
src/uilts/help.js

@@ -20,4 +20,16 @@ export function getQueryString(name) {
       },delay)
     }
   }
-  
+  
+export function setStorage(key, value) {
+    return localStorage.setItem(key, JSON.stringify(value));
+}
+
+export function getStorage(key) {
+    const item = localStorage.getItem(key);
+    try {
+        return item ? JSON.parse(item) : '';
+    } catch (e) {
+        return item;
+    }
+}

+ 90 - 30
src/view/components/followInput.vue

@@ -1,10 +1,10 @@
 <template>
     <div class="follow-input-wrapper">
-        <div class="at-user-item" v-for="(item, index) in atUserList" :key="index">
+        <div class="at-user-item" v-for="(item, index) in pageAtUserList" :key="index">
             <img :src="require('../../assets/svg/icon-del-follows-user.svg')" 
                 class="icon-del"
                 @click="delUser(item, index)">
-            <pre :id='"pre" + index'   style="position:absolute; top:-1000px;font-size:12px">{{item.name}}</pre>
+            <pre :id='"pre" + index' class="at-user-input-placeholder">{{item.name}}</pre>
             @<input class="at-user-input" 
                     :id='"input" + index' 
                     v-model="item.name" 
@@ -22,7 +22,9 @@
                     @mouseenter="onUserMouseEnter(item, index)"
                     @mouseleave="onUserMouseLeave(item, index)"
                     @click="selectedUser(item, index)">
-                    <div class="following" v-if="item.following"> following </div>
+                    <div class="following" v-if="item.following">
+                        <img :src="require('../../assets/svg/icon-following-user.svg')">following 
+                    </div>
                     <div class="content">
                         <img class="avatar" :src="item.avatarlUrl">
                         <div>
@@ -34,8 +36,8 @@
             </div>
         </div>
 
-        <div class="icon-add-wrapper"  v-if="atUserList.length < 5"
-            @click="addUser('')"
+        <div class="icon-add-wrapper"  v-if="pageAtUserList.length < 5"
+            @click="addInput"
             @mouseenter="handleMouseEn"
             @mouseleave="handleMouseLe">
             <img :src="require('../../assets/svg/icon-add-user-default.svg')" 
@@ -51,42 +53,60 @@
 
 <script setup>
 /* eslint-disable */
-import { reactive, ref, onMounted, defineEmits, watch } from "vue";
+import { reactive, ref, onMounted, defineEmits, defineProps, watch } from "vue";
 import {searchTwitterUser} from "../../http/publishApi";
-import {debounce} from "../../uilts/help";
-import {getStorage} from "../../uilts/chromeExtension"
+import {debounce, getStorage} from "../../uilts/help";
 
+const props = defineProps({
+    atUserList: {
+        type: Array,
+        default: () => {
+            return []
+        }
+    }
+})
 
 let currentIptIndex = ref(-1);
 let isActiveAddBtn = ref(false);
 let currentUserIndex = ref(-1);
 
 let userList = ref([]);
-let atUserList = ref([]);
-
 let userInfo = reactive({});
+let pageAtUserList = ref(props.atUserList);
 
 
-const emits = defineEmits(["updateAtUser"]);
+const emits = defineEmits(["addUser", "setUser", "delUser"]);
 
 onMounted(() => {
-    getUserInfo((info) => {
-        if(info.nickName) {
-            addUser(info.nickName);
+    if(!pageAtUserList.value.length) {
+        getUserInfo((info) => {
+            if(info.nickName) {
+                addUser(info.nickName);
+                setTimeout(() => {
+                    setIptWidth(0);
+                })
+            }
+        });
+    } else {
+        for(let i = 0; i < pageAtUserList.value.length; i++ ) {
+            setTimeout(() => {
+                setIptWidth(i);
+            })
         }
-    });
+    }
 }) 
 
 watch(
-    () => atUserList,
+    () => props.atUserList,
     (newVal) => {
-        emits('updateAtUser', newVal)
+        console.log(newVal, '222')
     },
     {
         deep: true
     }
 );
 
+
 const getUserInfo = (cb) => {
     let localUserInfo = getStorage('de-userInfo');
     console.log('localUserInfo',localUserInfo)
@@ -97,13 +117,20 @@ const getUserInfo = (cb) => {
 }
 
 const addUser = (name = '') => {
-    atUserList.value.push({
+    emits('addUser', {
         name
     })
 }
 
+const addInput = () => {
+    addUser('');
+    setTimeout(() => {
+        setIptWidth(props.atUserList.length - 1);
+    })
+}
+
 const delUser = (params, index) => {
-    atUserList.value.splice(index, 1);
+    emits("delUser", {index})
 }
 
 const onfocus = (params, index) => {
@@ -115,12 +142,16 @@ const onblur = (params, index) => {
 
 const onInput = debounce(function(params, index) {
     currentIptIndex.value = index;
+    emits("setUser", {index: index, name: params.name})
     getTwitterUsers(params.name)
 }, 800) 
 
 const onKeyup = (params, index) => {
-    console.log('sskks', document.getElementById('input'+index).offsetWidth)
-// document.getElementById('input'+index).style.width = document.getElementById('pre'+index).offsetWidth - 5 + 'px'
+    setIptWidth(index);
+}
+
+const setIptWidth = (index) => {
+    document.getElementById('input'+index).style.width = document.getElementById('pre'+index).offsetWidth + 'px'
 }
 
 const onIptChange = (params, index) => {
@@ -150,18 +181,19 @@ const getTwitterUsers = (query, cb) => {
 }
 
 const selectedUser = (params, index) => {
-    atUserList.value[currentIptIndex.value]['name'] = params.screenName;
-    currentIptIndex.value = -1;
+    emits("setUser", {index: currentIptIndex.value, name: params.screenName});
+    setTimeout(() => {
+        setIptWidth(currentIptIndex.value);
+        currentIptIndex.value = -1;
+    })
 }
 
 const onUserMouseEnter = (params, index) => {
     currentUserIndex.value = index;
-    console.log(params, index)
 }
 
 const onUserMouseLeave = (params, index) => {
     currentUserIndex.value = -1;
-    console.log(params, index)
 }
 </script>
 
@@ -170,7 +202,7 @@ const onUserMouseLeave = (params, index) => {
         width: 100%;
         display: flex;
         flex-wrap: wrap;
-        padding: 14px 0 14px 18px;
+        padding: 0px 0 14px 18px;
         box-sizing: border-box;
         border-left: 1px solid #ECECEC;
 
@@ -194,7 +226,7 @@ const onUserMouseLeave = (params, index) => {
             position: relative;
             margin-right: 10px;
             background-color: #fff;
-            margin-bottom: 14px;
+            margin-top: 14px;
 
             .icon-del {
                 width: 18px;
@@ -205,11 +237,17 @@ const onUserMouseLeave = (params, index) => {
                 cursor: pointer;
             }
 
+            .at-user-input-placeholder {
+                position: absolute; 
+                top: -1000px;
+                font-size: 13px;
+                min-width: 12px;
+                max-width: 128px;
+            }
             .at-user-input {
                 color: #389AFF;
                 border: none;
                 outline: none;
-                width: 80px;
             }
 
             .user-list-wrapper {
@@ -220,19 +258,34 @@ const onUserMouseLeave = (params, index) => {
                 overflow-y: scroll;
                 background-color: #fff; 
                 top: 30px;
+                left: -90px;
                 z-index: 1000;
                 border-radius: 10px;
 
                 .item {
                     width: 100%;
-                    height: 72px;
+                    height: auto;
                     box-sizing: border-box;
-                    padding: 0 16px;
+                    padding: 8px 16px;
                     cursor: pointer;
 
+                    .following {
+                        font-weight: 500;
+                        font-size: 14px;
+                        color: #566370;
+                        display: flex;
+                        align-items: center;
+                        margin-left: 20px;
+                        img {
+                            margin-right: 6px;
+                        }
+                    }
+
                     .content {
                         display: flex;
                         align-items: center;
+                        box-sizing: border-box;
+                        margin: 5px 0;
                         height: 100%;
 
                         .avatar {
@@ -267,5 +320,12 @@ const onUserMouseLeave = (params, index) => {
             }
         }
 
+        .icon-add-wrapper {
+            display: flex;
+            align-items: center;
+            margin-top: 14px;
+        }
+
+
     }
 </style>

+ 99 - 18
src/view/components/give-dialog.vue

@@ -67,7 +67,10 @@
                                         {{ item.label }}
                                     </div>
                                     <div class="control"  v-if="item.nodeType == 'textarea'">
-                                        <follow-input @updateAtUser="updateAtUser"></follow-input>
+                                        <follow-input 
+                                        :atUserList="atUserList"
+                                        @addUser="addFollowUser" @setUser="setFollowUser"
+                                        @delUser="delFollowUser"></follow-input>
                                     </div>
                                     <el-switch v-if="item.type == 2" v-model="item.checked" />
                                 </div>
@@ -81,34 +84,37 @@
                                 </div>
                                 <el-switch v-model="openAntiBot" />
                             </div>
-                            <!-- <div class="tips-wrapper">
+                            <div class="tips-wrapper">
                                 <div class="title">
                                     TIPS
                                 </div>
                                 <div class="row">
-                                    用户完成你的任务后,即可自动领取你的Giveaways
+                                    1. 用户完成你的任务后,即可自动领取你的Giveaways
                                 </div>
                                 <div class="row">
-                                    Paypal charges 4.4% + $0.3 fee
+                                    2. Paypal charges 4.4% + $0.3 fee
                                 </div>
                                 <div class="row">
-                                    Giveaways 有效期是7天,过期后余额将自动返回到你的钱包账户
+                                    3. Giveaways 有效期是7天,过期后余额将自动返回到你的钱包账户
                                 </div>
                                 <div class="more">
                                     More
                                 </div>
-                            </div> -->
+                            </div>
 
                             <div class="submit-btn-wrapper">
-                                <div class="submit-btn" @click="confirm">NEXT</div>
+                                <div class="submit-btn" @click="confirm">
+                                    <img class="icon-loading" v-if="submitIng" :src="require('../../assets/svg/icon-btn-loading.svg')"  />
+                                    NEXT
+                                </div>
                             </div>
                         </div>
                     </template>
                     <template v-if="showPreview">
-                        <preview-card :postData="publishRes"></preview-card>
+                        <preview-card :postData="publishRes" :baseFormData="baseFormData"></preview-card>
                     </template>
                     <div v-show="showPreview">
-                        <paypal-button :amount="baseFormData.amountValue" @payPalFinsh="payPalFinsh"></paypal-button>
+                        <paypal-button :finalAmountData="finalAmountData" @payPalFinsh="payPalFinsh"></paypal-button>
                     </div>
                 </div>
             </div>
@@ -119,6 +125,8 @@
 <script setup>
 import { ref, watch, reactive, defineProps, defineEmits, onMounted } from "vue";
 import {postPublish, verifyPaypalResult} from "../../http/publishApi"
+import {payCalcFee} from "../../http/pay"
+
 import previewCard from "./preview-card";
 import paypalButton from "./paypal-button";
 import followInput from "./followInput";
@@ -131,7 +139,15 @@ let visible = ref(false);
 let showPreview = ref(false);
 let openAntiBot = ref(false);
 let dialogHeight = ref(620);
-let previewDialogHeight = ref(880)
+let previewDialogHeight = ref(880);
+let submitIng = ref(false);
+let atUserList = ref([]);
+let finalAmountData = ref({
+    currencyCode: "USD",
+    feeAmountValue: 0,
+    finalAmountValue: 0,
+    requestAmountValue: 0
+})
 
 let baseFormData = reactive({
     amountCurrencyCode: "USD",
@@ -199,13 +215,34 @@ const setPreviewDialogHeight = () => {
     }
 };
 
+const getPayAmount = (amountValue) => {
+    payCalcFee({
+        params : {
+            amountValue,
+            currencyCode: "USD",
+            payChannel: 1
+        }
+    }).then(res => {
+        if(res.code == 0) {
+            let {finalAmountValue} = res.data;
+            if(finalAmountValue >= 100) {
+                res.data.finalAmountValue = finalAmountValue / 100;
+                finalAmountData.value = res.data
+            }
+        }
+    })
+}
+
 const confirm = () => {
+    if(submitIng.value) {
+        return;
+    }
     let {amountValue = 0, totalCount = 0, amountCurrencyCode} = baseFormData;
-    if(!amountValue || !totalCount) {
+    if(!totalCount) {
         return;
     }
     amountValue = amountValue * 100; // 元转分
-
+    formList[0]['text'] = atUserList.value
     let finishConditions = [];
     for(let i = 0; i < formList.length; i++) {
         let item = {};
@@ -227,6 +264,11 @@ const confirm = () => {
         finishConditions,
         receiveConditions
     }
+
+    //每人平均要分到大于 0.01美元(1美分),需要提示语
+    if(amountValue / totalCount < 1) {
+        return;
+    }
     let data = {
         params: {
             postBizData: JSON.stringify(formData),
@@ -234,19 +276,27 @@ const confirm = () => {
             postType: 1, //1 红包
         }
     }
+    submitIng.value = true;
+    getPayAmount(amountValue);
     postPublish(data).then((res) => {
+        submitIng.value = false;
         if(res.code == 0) {
             publishRes = res.data;
-            setPreviewDialogHeight();
+            // setPreviewDialogHeight();
             showPreview.value = true;
+        } else {
+            console.log(res);
         }
+    }).catch(err => {
+        console.log(err);
     })
 };
 
 const initParams = () => {
     baseFormData.amountValue = '';
     baseFormData.totalCount = '';
-    formList[0].text = '';
+    formList[0].text = [];
+    atUserList.value = [];
 }
 
 const payPalFinsh = (params) => {
@@ -270,8 +320,16 @@ const payPalFinsh = (params) => {
     })
 }
 
-const updateAtUser = (val) => {
-    formList[0]['text'] = val;
+const addFollowUser = (params) => {
+    atUserList.value.push(params)
+}
+
+const setFollowUser = (params) => {
+    atUserList.value[params.index]['name'] = params.name;
+}
+
+const delFollowUser = (params) => {
+    atUserList.value.splice(params.index, 1);
 }
 
 const onUsdInput = (val) => {
@@ -285,6 +343,9 @@ const onCountInput = (val) => {
         val = ''
     }
     val = val.replace(/[^\d]/g,'');
+    if(val > 9999) {
+        val = 9999;
+    }
     baseFormData.totalCount = val;
     return val;
 }
@@ -314,7 +375,7 @@ onMounted(() => {
         width: 650px;
         height: 620px;
         background: #ffffff;
-        border-radius: 16px;
+        border-radius: 20px;
         position: absolute;
         left: 50%;
         top: 50%;
@@ -496,12 +557,23 @@ onMounted(() => {
                 }
 
                 .tips-wrapper {
+                    margin-top: 23px;
                     .title, .row {
                         font-weight: 400;
                         font-size: 13px;
                         color: rgba(0, 0, 0, 0.3);
                     }
-                    
+                    .row {
+                        box-sizing: border-box;
+                        padding-left: 4px;
+                    }
+
+                    .more {
+                        color: #389AFF;
+                        font-size: 13px;
+                        padding-left: 4px;
+                        cursor: pointer;
+                    }
                 }
 
                 .submit-btn-wrapper {
@@ -521,7 +593,16 @@ onMounted(() => {
                         border-radius: 100px;
                         color: #fff;
                         margin-left: 18px;
+                        display: flex;
+                        align-items: center;
+                        justify-content: center;
                         cursor: pointer;
+                        
+                        .icon-loading {
+                            width: 20px;
+                            height: 20px;
+                            margin-right: 3px;
+                        }
                     }
                 }
             }

+ 2 - 2
src/view/components/option-login.vue

@@ -18,10 +18,10 @@
 <script setup>
 import {defineEmits} from 'vue';
 
-let emits = defineEmits(['loginSuccess']);
+let emits = defineEmits(['loginAction']);
 
 const login = () => {
-    emits('loginSuccess', {})
+    emits('loginAction', {})
 }
 </script>
 

+ 124 - 48
src/view/components/option-withdraw.vue

@@ -44,6 +44,7 @@
                             <el-input
                                 type="text"
                                 @input="onAmountInput"
+                                @blur="onAmountBlur"
                                 v-model="requestWithdrawParams.amountValue"
                                 placeholder="$0"
                                 :input-style="{
@@ -68,25 +69,23 @@
                 </div>
 
                 <div class="bottom-msg">
-                    <div>
+                    <div v-show="finalWithdrawalAmount">
                         final amount
                         <span
                             >${{
-                                (requestWithdrawParams.amountValue * 100 -
-                                    walletWithdrawConfig.withdrawUSDPaypalFee) /
-                                    100 >
-                                0
-                                    ? (requestWithdrawParams.amountValue * 100 -
-                                          walletWithdrawConfig.withdrawUSDPaypalFee) /
-                                      100
+                                finalWithdrawalAmount > 0
+                                    ? finalWithdrawalAmount
                                     : 0
                             }}</span
                         >
                     </div>
-                    <div>(Paypal charges fee: 4.4% + $0.3)</div>
+                    <div>{{walletWithdrawConfig.withdrawUSDPaypalFeeDesc}}</div>
                 </div>
             </div>
-            <div @click="withdraw" class="confirm-btn">Confirm</div>
+            <div @click="withdraw" class="confirm-btn">
+                <img class="icon-loading" v-if="withdrawIng" :src="require('../../assets/svg/icon-btn-loading.svg')"  />
+                Confirm
+            </div>
         </template>
         <template v-else>
             <div class="withdraw-status">
@@ -102,29 +101,40 @@
                     </div>
                 </div>
             </div>
-            <div class="confirm-btn">Done</div>
+            <div class="confirm-btn" @click="doneWithdraw">
+                Done
+            </div>
         </template>
     </div>
 </template>
 
 <script setup>
 /* eslint-disable */
-import { defineProps, defineEmits, ref, onMounted, watch } from "vue";
-
-import { getWithdrawConfig, withdrawRequest } from "../../http/account";
+import { defineProps, defineEmits, ref, onMounted, watch, computed } from "vue";
+import { ElMessage } from 'element-plus';
+import 'element-plus/es/components/message/style/css'
+import { withdrawRequest } from "../../http/account";
+import { withdrawCalcFee } from "../../http/pay";
+import {debounce} from "../../uilts/help"
 
 const props = defineProps({
     amountValue: {
-        type: [Number, String],
-        default: false,
+        type: Number,
+        default: 0,
     },
+    walletWithdrawConfig: {
+        type: Object,
+        default: () => {
+            return {
+                withdrawUSDPaypalFee: 0,
+                withdrawUSDPreMinAmount: 100,
+                withdrawUSDSwitch: "",
+                withdrawUSDPaypalFeeDesc: ''
+            }
+        }
+    }
 });
 
-let walletWithdrawConfig = ref({
-    withdrawUSDPaypalFee: 25,
-    withdrawUSDPreMinAmount: 100,
-    withdrawUSDSwitch: "",
-});
 
 let requestWithdrawParams = ref({
     amountValue: "",
@@ -133,49 +143,94 @@ let requestWithdrawParams = ref({
     withdrawReceiveAccount: "",
 });
 
-let canWithdrawBalance = ref(0);
+let canWithdrawBalance = ref(props.amountValue);
 
 let showWithdrawError = ref(false);
 let isSubmit = ref(false);
+let withdrawIng = ref(false);
+
+let finalWithdrawalAmount = ref('');
 
 onMounted(() => {
-    queryWithdrawConfig();
 });
 
-watch(
-    () => props.amountValue,
-    (newVal) => {
-        canWithdrawBalance.value = newVal;
+const emits = defineEmits("back");
+const back = () => {
+    if (isSubmit.value) {
+        isSubmit.value = false;
+    } else {
+        emits("back", {});
     }
-);
+};
 
-const queryWithdrawConfig = () => {
-    getWithdrawConfig({
-        params: {},
-    }).then((res) => {
-        console.log(res);
-        if (res.code == 0) {
-            walletWithdrawConfig.value = res.data;
-        }
-    });
+const doneWithdraw = () => {
+    isSubmit.value = false;
+    emits("back", {});
 };
 
+
 const withdrawalAll = () => {
-    if (canWithdrawBalance.value && canWithdrawBalance.value > 100) {
+    console.log(canWithdrawBalance.value)
+    if (
+        canWithdrawBalance.value &&
+        canWithdrawBalance.value >
+            props.walletWithdrawConfig.withdrawUSDPaypalFee
+    ) {
         requestWithdrawParams.value.amountValue =
             canWithdrawBalance.value / 100;
     }
 };
 
+const withdrawCalcAmount = () => {
+    withdrawCalcFee({
+        params: {
+            amountValue: requestWithdrawParams.value.amountValue * 100,
+            currencyCode: requestWithdrawParams.value.currencyCode,
+            withdrawChannel: requestWithdrawParams.value.withdrawChannel
+        }
+    }).then(res => {
+        if(res.code == 0) {
+            finalWithdrawalAmount.value = res.data.finalAmountValue / 100;
+        }
+    })
+}
+
+const withdrawCalcAmountDebounce = debounce(function() {
+    withdrawCalcAmount();
+}, 3000) 
+
+/**
+ * 提现
+ */
 const withdraw = () => {
     console.log("requestWithdrawParams.value", requestWithdrawParams.value);
+    if (withdrawIng.value) {
+        return;
+    }
+    
     let params = {
         ...requestWithdrawParams.value,
     };
+    if(!params.amountValue || !params.withdrawReceiveAccount) {
+        return;
+    }
+    params.withdrawReceiveAccount = params.withdrawReceiveAccount.replace(/\s*/g,"");
     params.amountValue = params.amountValue * 100;
+    if(params.amountValue > canWithdrawBalance.value) {
+        ElMessage({
+            message: '大于可提现金额',
+            type: 'warning',
+        })
+        return;
+    }
+    if(params.amountValue <= props.walletWithdrawConfig.withdrawUSDPaypalFee) {
+        return;
+    }
+    withdrawIng.value = true;
     withdrawRequest({
         params,
     }).then((res) => {
+        withdrawIng.value = false;
         if (res.code == 0) {
             canWithdrawBalance.value =
                 canWithdrawBalance.value - params.amountValue;
@@ -186,20 +241,21 @@ const withdraw = () => {
                 withdrawReceiveAccount: "",
             };
             isSubmit.value = true;
+        } else {
+            console.log(res);
         }
+    })
+    .catch((err) => {
+        console.log(err);
     });
 };
 
-const emits = defineEmits("back");
-const back = () => {
-    if (isSubmit.value) {
-        isSubmit.value = false;
-    } else {
-        emits("back", {});
-    }
-};
+const onAmountBlur = () => {
+    withdrawCalcAmount();
+}
 
 const onAmountInput = (value) => {
+    //限制输入数字 小数点俩位
     value = value
         .replace(/[^\d.]/g, "")
         .replace(/\.{2,}/g, ".")
@@ -209,15 +265,26 @@ const onAmountInput = (value) => {
         .replace(/^(-)*(\d+)\.(\d\d).*$/, "$1$2.$3")
         .replace(/^\./g, "");
     requestWithdrawParams.value.amountValue = value;
+
     let amount = value * 100;
+    //显示tips
     if (
         amount > 0 &&
-        amount < walletWithdrawConfig.value.withdrawUSDPaypalFee
+        amount < props.walletWithdrawConfig.withdrawUSDPaypalFee
     ) {
         showWithdrawError.value = true;
     } else {
         showWithdrawError.value = false;
     }
+    // 输入金额大于可提现金额
+    // if(amount > canWithdrawBalance.value) {
+    //     // let newVal = canWithdrawBalance.value / 100;
+    //     value = '';
+    //     requestWithdrawParams.value.amountValue = '';
+    // }
+
+    withdrawCalcAmountDebounce();
+
     return value;
 };
 </script>
@@ -327,11 +394,20 @@ const onAmountInput = (value) => {
         font-weight: 600;
         font-size: 18px;
         color: #fff;
-        cursor: pointer;
         position: absolute;
         left: 50%;
         bottom: 35px;
         transform: translateX(-50%);
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        cursor: pointer;
+
+        .icon-loading {
+            width: 20px;
+            height: 20px;
+            margin-right: 3px;
+        }
     }
 }
 </style>

+ 3 - 3
src/view/components/options-transactions.vue

@@ -94,7 +94,7 @@
                                 </template>
                                 <template v-else>
                                     <template v-if="item.bizType == -1">-</template>
-                                    {{item.balance/100}}
+                                    ${{item.balance/100}}
                                 </template>
                                 
                             </div>
@@ -154,10 +154,10 @@ onMounted(() => {
     getTransactionsList();
 });
 
-const emits = defineEmits(["showHome"]);
+const emits = defineEmits(["back"]);
 
 const back = () => {
-    emits("showHome", {});
+    emits("back", {});
 };
 
 const listScroll = (e) => {

+ 20 - 7
src/view/components/paypal-button.vue

@@ -1,14 +1,14 @@
 <template>
     <div class="pay-wrapper">
         <div class="pay-msg">
-            <div class="row">Pay ${{amount || 0}}</div>
-            <div class="msg">Generate Giveaways</div>
+            <div class="row">Pay ${{finalAmountData.finalAmountValue || 0}}<span>(Available ${{finalAmountData.requestAmountValue / 100}})</span></div>
+            <div class="msg">Paypal charges fee: 4.4% + $0.3</div>
         </div>
         <div class="pay-btn">
             <iframe
                 class="iframe-pay"
                 ref="iframe"
-                :src="`https://art-weapp.oss-cn-hangzhou.aliyuncs.com/chromeExtension/paypal.html?amount=${amount}`"></iframe>
+                :src="`https://art-weapp.oss-cn-hangzhou.aliyuncs.com/chromeExtension/paypal.html?amount=${finalAmountData.finalAmountValue}`"></iframe>
         </div>
     </div>
 </template>
@@ -19,9 +19,16 @@ import { onMounted, ref, defineProps, defineEmits } from "vue";
 let iframe = ref(null);
 
 const props = defineProps({
-    amount: {
-        type: Number,
-        default: 0,
+    finalAmountData: {
+        type: Object,
+        default: () => {
+            return {
+                currencyCode: "USD",
+                feeAmountValue: 0,
+                finalAmountValue: 0,
+                requestAmountValue: 0
+            }
+        },
     },
 });
 
@@ -41,7 +48,7 @@ onMounted(() => {
                     break;
                 case "iframeLoaded":
                     iframe.value.contentWindow.postMessage(
-                        { actionType: "setAmount", amount: props.amount },
+                        { actionType: "setAmount", amount: props.finalAmountData.finalAmountValue },
                         "*"
                     );
                     break;
@@ -74,6 +81,12 @@ onMounted(() => {
         .row {
             font-weight: 600;
             font-size: 17px;
+            color: #389AFF;
+            span {
+                display: inline-block;
+                color: #000000;
+                margin-left: 6px;
+            }
         }
         .msg {
             font-size: 13px;

+ 34 - 23
src/view/components/preview-card.vue

@@ -38,11 +38,15 @@
             </div>
             <div class="content-before" v-else>
                 <div class="card-wrapper">
-                    <img :src="require('../../assets/svg/icon-red-pack-card.svg')"
+                    <img :src="require('../../assets/img/icon-red-pack-card.png')"
                         class="card-cover"/>
-                    <div class="bottom">
-                        <div class="url">DeNet.me</div>
-                        <div class="desc">🎁 Open the Giveaways</div>
+                    <div class="text-wrapper">
+                        <div class="amount">
+                            ${{baseFormData.amountValue}}
+                        </div>
+                        <div class="desc">
+                            to {{baseFormData.totalCount}} People , Good Luck !
+                        </div>
                     </div>
                 </div>
             </div>
@@ -52,7 +56,7 @@
 
 <script setup>
 import { reactive, ref, defineProps, onMounted } from "vue";
-import {getStorage} from "../../uilts/chromeExtension"
+import {getStorage} from "../../uilts/help"
 
 let previewType = ref(1);
 let userInfo = ref({});
@@ -70,6 +74,14 @@ defineProps({
 
             }
         }
+    },
+    baseFormData: {
+        type: Object,
+        default: () => {
+            return {
+
+            }
+        }
     }
 })
 
@@ -189,33 +201,32 @@ onMounted(() => {
             margin-left: 60px;
             .card-wrapper {
                 background: #ffffff;
-                border: 1px solid #d1d9dd;
                 box-sizing: border-box;
                 border-radius: 16px;
                 width: 100%;
-                height: 260px;
                 overflow: hidden;
+                position: relative;
+                .text-wrapper {
+                    position: absolute;
+                    top: 30px;
+                    left: 108px;
 
-                .card-cover {
-                    width: 100%;
-                    object-fit: contain;
-                }
-
-                .bottom {
-                    margin-top: 6px;
-                    margin-left: 13px;
-
-                    .url {
-                        font-size: 14px;
-                        color: #566370;
-                        margin-bottom: 3px;
+                    .amount {
+                        font-weight: bolder;
+                        font-size: 40px;
+                        color: #F5CD77;
                     }
-
                     .desc {
-                        font-weight: 500;
-                        font-size: 15px;
+                        font-weight: 700;
+                        font-size: 12px;
+                        color: #F5CD77;
                     }
                 }
+
+                .card-cover {
+                    width: 100%;
+                    object-fit: contain;
+                }
             }
         }
     }

+ 143 - 92
src/view/popup.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="page-wrapper" ref="pageWrapper" @scroll="pageScroll">
+    <div class="page-wrapper" ref="pageWrapperDom" @scroll="pageScroll">
         <template v-if="isLogin && homeVisibility">
             <div class="nav-bar">
                 <div class="item left">
@@ -18,7 +18,7 @@
                 />
                 <div class="amount">${{ canWithdrawBalance / 100 }}</div>
                 <div class="withdraw-btn" @click="clickWithdraw">Withdraw</div>
-                <div class="msg">(Paypal charges fee: 4.4% + $0.3)</div>
+                <div class="msg">({{walletWithdrawConfig.withdrawUSDPaypalFeeDesc}})</div>
             </div>
             <div class="tab-bar">
                 <div
@@ -32,7 +32,7 @@
                     {{ item.label }}
                 </div>
             </div>
-            <div class="list-wrapper" ref="pageGiveList">
+            <div class="list-wrapper" ref="pageGiveListDom">
                 <div class="give-list" v-if="currentTabIndex == 0">
                     <template v-if="giveList.length">
                         <div
@@ -145,7 +145,7 @@
                                             </template>
                                             <!-- 红包未发出显示 -->
                                             <div
-                                                v-if="item.status == 0"
+                                                v-if="!item.postTaskLuckdrop.srcPublishStatus"
                                                 class="send-btn"
                                                 @click.stop="sendTwitter(item)"
                                             >
@@ -158,7 +158,7 @@
                                         v-if="
                                             !(
                                                 item.type == 2 &&
-                                                item.status == 0
+                                                !item.postTaskLuckdrop.srcPublishStatus
                                             )
                                         "
                                         class="icon"
@@ -202,18 +202,21 @@
             </div>
         </template>
         <!-- login -->
-        <option-login v-if="!isLogin" @loginSuccess="loginSuccess" />
-        <!-- 交易列表 -->
-        <option-transactions
-            v-if="isLogin && !homeVisibility && transactionsVisibility"
-            @showHome="onShowHome"
-        />
-        <!-- 提现页 -->
-        <option-withdraw
-            :amountValue="canWithdrawBalance"
-            v-if="isLogin && !homeVisibility && withdrawVisibility"
-            @back="withdrawBack"
-        />
+        <option-login v-if="!isLogin" @loginAction="loginAction" />
+        <template v-if="isLogin && !homeVisibility">
+            <!-- 交易列表 -->
+            <option-transactions
+                v-if="transactionsVisibility"
+                @back="transactionsBack"
+            />
+            <!-- 提现页 -->
+            <option-withdraw
+                :amountValue="canWithdrawBalance"
+                :walletWithdrawConfig="walletWithdrawConfig"
+                v-if="withdrawVisibility"
+                @back="withdrawBack"
+            />
+        </template>
     </div>
 </template>
 
@@ -225,14 +228,16 @@ import optionLogin from "./components/option-login.vue";
 import optionWithdraw from "./components/option-withdraw.vue";
 import {
     getChromeStorage,
+} from "../uilts/chromeExtension";
+import {
     setStorage,
     getStorage,
-} from "../uilts/chromeExtension";
-import { getBalance, getMineLuckdropRecords } from "../http/account";
+} from "../uilts/help";
+import { getBalance, getMineLuckdropRecords, getWithdrawConfig } from "../http/account";
 var moment = require("moment");
 
-let pageWrapper = ref(null);
-let pageGiveList = ref(null);
+let pageWrapperDom = ref(null);
+let pageGiveListDom = ref(null);
 
 let isLogin = ref(false);
 let homeVisibility = ref(false);
@@ -253,6 +258,14 @@ let giveReqParams = {
     loadMore: false,
 };
 
+
+let walletWithdrawConfig = ref({
+        withdrawUSDPaypalFee: 0,
+        withdrawUSDPreMinAmount: 100,
+        withdrawUSDSwitch: "",
+        withdrawUSDPaypalFeeDesc: ''
+    });
+
 let moreTabList = ref([
     {
         icon: require("../assets/svg/icon-twitter.svg"),
@@ -275,21 +288,33 @@ let tabList = ref([
     },
 ]);
 
-const login = () => {
-    callEventPageMethod("POPUP_LOGIN", "", function (response) {
-        console.log("res", response);
+onMounted(() => {
+    checkLoginState(() => {
+        if (isLogin.value) {
+            getAccountBalance();
+            getLuckdropRecordsList();
+            queryWithdrawConfig();
+        }
     });
-};
+});
 
-const callEventPageMethod = (method, data, callback) => {
-    chrome.runtime.sendMessage(
-        { method: method, data: data },
-        function (response) {
-            if (typeof callback === "function") callback(response);
+/**
+ * 获取提现配置
+ */
+const queryWithdrawConfig = () => {
+    getWithdrawConfig({
+        params: {},
+    }).then((res) => {
+        console.log(res);
+        if (res.code == 0) {
+            walletWithdrawConfig.value = res.data;
         }
-    );
+    });
 };
 
+/**
+ * 获取账户余额
+ */
 const getAccountBalance = () => {
     getBalance({
         params: {
@@ -304,6 +329,50 @@ const getAccountBalance = () => {
     });
 };
 
+const getUserInfo = (cb) => {
+    getChromeStorage("userInfo", (res) => {
+        cb && cb(res);
+    });
+};
+
+/**
+ * 检查登录状态
+ */
+const checkLoginState = (cb) => {
+    getUserInfo((res) => {
+        if (res && res.accessToken) {
+            userInfo.value = res;
+            setStorage("de-userInfo", res);
+            isLogin.value = true;
+            homeVisibility.value = true;
+        } else {
+            userInfo.value = {};
+            isLogin.value = false;
+        }
+        cb && cb();
+    });
+};
+
+const pageScroll = (e) => {
+    let wrapperHeight = pageWrapperDom.value.offsetHeight;
+    let pageGiveListHeight = pageGiveListDom.value.offsetHeight;
+    let scrollTop = e.target.scrollTop || 0;
+    if (currentTabIndex.value != 0) {
+        return;
+    }
+    if (
+        giveReqParams.loadMore === false &&
+        wrapperHeight + scrollTop >= pageGiveListHeight
+    ) {
+        giveReqParams.loadMore = true;
+        giveReqParams.params.pageNum++;
+        getLuckdropRecordsList();
+    }
+};
+
+/**
+ * 获取红包列表
+ */
 const getLuckdropRecordsList = () => {
     getMineLuckdropRecords({
         params: giveReqParams.params,
@@ -321,7 +390,18 @@ const getLuckdropRecordsList = () => {
     });
 };
 
+const clickTab = (params, index) => {
+    currentTabIndex.value = index;
+    console.log(params, index);
+};
+
+/**
+ * 点击列表跳转到推文
+ */
 const clickListItem = (params, index) => {
+    if(!params.srcContentId) {
+        return;
+    }
     let url = "";
     let twitterUrl = "https://twitter.com/";
     let nickName = "";
@@ -335,63 +415,12 @@ const clickListItem = (params, index) => {
     chrome.tabs.create({
         url,
     });
-    console.log(url);
 };
 
-const pageScroll = (e) => {
-    let wrapperHeight = pageWrapper.value.offsetHeight;
-    let pageGiveListHeight = pageGiveList.value.offsetHeight;
-    let scrollTop = e.target.scrollTop || 0;
-    if (currentTabIndex.value != 0) {
-        return;
-    }
-    if (
-        giveReqParams.loadMore === false &&
-        wrapperHeight + scrollTop >= pageGiveListHeight
-    ) {
-        giveReqParams.loadMore = true;
-        giveReqParams.params.pageNum++;
-        getLuckdropRecordsList();
-    }
-};
-
-const getUserInfo = (cb) => {
-    getChromeStorage("userInfo", (res) => {
-        cb && cb(res);
-    });
-};
-
-const checkLoginState = (cb) => {
-    let res = getStorage("de-userInfo");
-    getUserInfo((res) => {
-        if (res && res.accessToken) {
-            userInfo.value = res;
-            setStorage("de-userInfo", res);
-            isLogin.value = true;
-            homeVisibility.value = true;
-        } else {
-            userInfo.value = {};
-            isLogin.value = false;
-        }
-        cb && cb();
-    });
-};
-
-onMounted(() => {
-    checkLoginState(() => {
-        if (isLogin.value) {
-            getAccountBalance();
-            getLuckdropRecordsList();
-        }
-    });
-});
-
-const clickTab = (params, index) => {
-    currentTabIndex.value = index;
-    console.log(params, index);
-};
-
-const onShowHome = () => {
+/**
+ * 交易列表返回
+ */
+const transactionsBack = () => {
     if (!homeVisibility.value) {
         if (transactionsVisibility.value) {
             transactionsVisibility.value = false;
@@ -400,6 +429,9 @@ const onShowHome = () => {
     }
 };
 
+/**
+ * 提现返回
+ */
 const withdrawBack = () => {
     if (!homeVisibility.value) {
         if (withdrawVisibility.value) {
@@ -411,12 +443,6 @@ const withdrawBack = () => {
     }
 };
 
-const loginSuccess = () => {
-    login()
-    // isLogin.value = true;
-    // onShowHome();
-};
-
 const showTransactions = () => {
     homeVisibility.value = false;
     transactionsVisibility.value = true;
@@ -427,6 +453,31 @@ const clickWithdraw = () => {
     withdrawVisibility.value = true;
 };
 
+const loginAction = () => {
+    login();
+};
+
+const login = () => {
+    callEventPageMethod("POPUP_LOGIN", "", function (response) {
+        console.log("res", response);
+    });
+};
+
+/**
+ * sendMessage
+ */
+const callEventPageMethod = (method, data, callback) => {
+    chrome.runtime.sendMessage(
+        { method: method, data: data },
+        function (response) {
+            if (typeof callback === "function") callback(response);
+        }
+    );
+};
+
+/**
+ * 点击发送,去发推
+ */
 const sendTwitter = (params) => {
     callEventPageMethod(
         "POPUP_PUBLISH_TWITTER_RED_PACK",

+ 1 - 1
src/view/publish.vue

@@ -11,7 +11,7 @@
 
 <script setup>
 import { ref } from "vue";
-import {setStorage} from "../uilts/chromeExtension";
+import {setStorage} from "../uilts/help";
 import giveDialog from "./components/give-dialog.vue";
 
 let dialogVisible = ref(false);