wkw пре 3 недеља
родитељ
комит
c054465ad7

+ 11 - 0
src/api/path/dapp.api.js

@@ -0,0 +1,11 @@
+import service from '../axios'
+
+// dapp轮播图
+export function dappSlides(param) {
+    return service.get('dapp-slides', { params: param });
+}
+
+// dapp列表
+export function dappList(param) {
+    return service.get('dapps', { params: param });
+}

+ 19 - 4
src/api/path/jdfh.api.js

@@ -25,7 +25,22 @@ export function receiveReward(param) {
     return service.post('genesis/receive/reward', param);
 }
 
-// // STT兑换ACC
-// export function stt2acc(param) {
-//     return service.post('exchange/stt2acc', param);
-// }
+// 添加管理员
+export function managerAdd(param) {
+    return service.post('genesis/manager/add', param);
+}
+
+// 移除管理员
+export function managerRemove(param) {
+    return service.post('genesis/manager/remove', param);
+}
+
+// 添加白名单
+export function whiteListAdd(param) {
+    return service.post('genesis/white-list/add', param);
+}
+
+// 移除白名单
+export function whiteListRemove(param) {
+    return service.post('genesis/white-list/remove', param);
+}

+ 56 - 0
src/api/path/jys.api.js

@@ -0,0 +1,56 @@
+import service from '../axios'
+
+// 获取所有的委托列表(广告列表)
+export function entrustList(param) {
+    return service.post('entrust/list', param);
+}
+
+// 获取预约委托列表(我的预约)
+export function subscribeMy(param) {
+    return service.post('subscribe/my', param);
+}
+
+// 获取我的委托列表
+export function entrustMy(param) {
+    return service.post('entrust/my', param);
+}
+
+// 获取所有的购买列表(大盘成交列表)
+export function entrustBuy(param) {
+    return service.post('entrust/buy', param);
+}
+
+// 获取所有的撤销列表
+export function revokeList(param) {
+    return service.post('revoke/list', param);
+}
+
+// 委托卖出合约
+export function entrustContractPublisher(param) {
+    return service.post('entrust/contract/publisher', param);
+}
+
+// 撤销委托合约交易
+export function contractRevoke(param) {
+    return service.post('entrust/contract/revoke', param);
+}
+
+// 发布预约合约委托
+export function subscribeContractPublisher(param) {
+    return service.post('subscribe/contract/publisher', param);
+}
+
+// 闪兑合约交易
+export function contractTransfer(param) {
+    return service.post('flash/contract/transfer', param);
+}
+
+// 领取预约委托合约的STT
+export function subscribeContractReceive(param) {
+    return service.post('subscribe/contract/receive', param);
+}
+
+// 购买委托合约交易
+export function contractBuy(param) {
+    return service.post('entrust/contract/buy', param);
+}

+ 16 - 0
src/common/login.js

@@ -1,4 +1,5 @@
 import { login } from "@/api/path/login.api";
+import { userInfo } from '@/api/path/jdfh.api'
 import { useSystemStore } from "@/stores/modules/systemStore";
 
 
@@ -16,4 +17,19 @@ export async function sysLogin(address) {
     value: data.access_token,
     localStorage: true,
   }) 
+  // 节点分红---获取用户是否为管理员以及是否加入了白名单
+  const res = await userInfo({ address });
+  if (res.ret) {
+    const { is_super, is_white, is_exclusive } = res.data;
+    const data = {
+      is_super: typeof is_super === 'boolean' ? is_super : false,
+      is_white: typeof is_white === 'boolean' ? is_white : false,
+      is_exclusive: is_exclusive || false
+    };
+    systemStore.setStateValue({
+      key: "Administrator",
+      value: data,
+      localStorage: true,
+    });
+  }
 }

+ 3 - 3
src/stores/modules/walletStore.js

@@ -111,7 +111,6 @@ export const useWalletStore = defineStore("useWalletStore", {
 
     // 添加钱包
     addWallet() {
-
       const data = cloneDeep(this.$state)
       Reflect.deleteProperty(data, "walletList");
       if (this.walletList.length == 0) {
@@ -166,7 +165,7 @@ export const useWalletStore = defineStore("useWalletStore", {
       this.$persist();
     },
     // 切换钱包
-    switchWallet(id) {
+    async switchWallet(id,address) {
       const item = this.walletList.find(item => item.id === id);
       if (!item) {
         $msg($t("global.WalletDoesNotExist"))
@@ -176,7 +175,8 @@ export const useWalletStore = defineStore("useWalletStore", {
           this.$state[key] = item[key];
         }
       })
-      this.$persist()
+      this.$persist();
+      await sysLogin(address)
     },
     // 修改钱包名称
     updateWalletName(id, newName) {

+ 368 - 293
src/views/dapp/index.vue

@@ -1,342 +1,417 @@
 <template>
-  <div class="container">
-    <div class="head-bg" />
-    <div class="head-nav-bar">探索</div>
+    <div class="container">
+        <div class="head-bg" />
+        <div class="head-nav-bar">探索</div>
 
-    <div class="search-box">
-      <svg-icon class="search-icon" name="search" />
-      <span>输入DApp名称或网址</span>
-    </div>
-
-    <van-swipe class="swipe-box" :autoplay="3000" lazy-render>
-      <van-swipe-item v-for="image in images" :key="image">
-        <div class="swipe-item">
-          <van-image class="swipe-image" :src="image" />
+        <div class="search-box">
+            <svg-icon class="search-icon" name="search" />
+            <van-field v-model="searchValue" placeholder="输入DApp名称或网址" />
         </div>
-      </van-swipe-item>
 
-      <template #indicator="{ active, total }">
-        <div class="custom-indicator">
-          <div
-            v-for="item in total"
-            :key="item"
-            class="custom-indicator-item"
-            :class="{ active: item === active + 1 }"
-          />
-        </div>
-      </template>
-    </van-swipe>
+        <van-swipe class="swipe-box" :autoplay="3000" lazy-render>
+            <van-swipe-item v-for="item in slidesList" :key="item.id">
+                <div class="swipe-item">
+                    <van-image class="swipe-image" :src="item.pic" />
+                </div>
+            </van-swipe-item>
 
-    <van-tabs class="tabs-wrapper-card" type="card">
-      <van-tab v-for="(item,index) in tabsAppConfig" :title="item.title"  :key="index">
-        <div class="tabs-content-body">
-          <div v-for="cItem in item.children" class="tabs-content-item">
-            <van-image class="tabs-content-item-icon" round :src="cItem.icon" />
-            <span>{{ cItem.table }}</span>
-          </div>
-        </div>
-      </van-tab> 
-    </van-tabs>
+            <template #indicator="{ active, total }">
+                <div class="custom-indicator">
+                    <div
+                        v-for="item in total"
+                        :key="item"
+                        class="custom-indicator-item"
+                        :class="{ active: item === active + 1 }"
+                    />
+                </div>
+            </template>
+        </van-swipe>
 
+        <van-tabs class="tabs-wrapper-card" type="card">
+            <van-tab
+                v-for="(item, index) in tabsAppConfig"
+                :title="item.title"
+                :key="index"
+            >
+                <div class="tabs-content-body">
+                    <div
+                        v-for="cItem in item.children"
+                        class="tabs-content-item"
+                    >
+                        <van-image
+                            class="tabs-content-item-icon"
+                            round
+                            :src="cItem.logo"
+                        />
+                        <span>{{ cItem.name }}</span>
+                    </div>
+                </div>
+            </van-tab>
+        </van-tabs>
 
-    <van-tabs  class="tabs-wrapper" >
-      <van-tab title="标签">
-        <div class="tab-box">
-          <div class="tab-box-label">ACC</div>
-          <div class="tab-box-list" v-for="item in 10">
-            <van-image class="tab-box-list-img" round src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg" />
-            <div class="tab-box-ri">
-              <div>
-                <text>雷霆战机</text>
-                <svg-icon class="hot-icon" name="hot" />
-                <svg-icon class="rm-icon" name="rm" />
-              </div>
-              <div class="tab-box-ri-cont">ACC主网上与钱包账户的飞机经济为游戏</div>
-            </div>
-          </div>
-        </div>
-      </van-tab>
-      <van-tab title="标签">内容 2</van-tab>
-      <van-tab title="标签">内容 3</van-tab>
-      <van-tab title="标签">内容 4</van-tab>
-      <van-tab title="标签">内容 4</van-tab>
-      <van-tab title="标签">内容 4</van-tab>
-    </van-tabs>
-  </div>
+        <van-tabs
+            v-model="activeTab"
+            @change="onTabChange"
+            class="tabs-wrapper"
+        >
+            <!-- 全部 -->
+            <van-tab title="全部" name="ALL">
+                <template #default>
+                    <div class="tab-box">
+                        <div v-for="group in groupedList" :key="group.chain">
+                            <div class="tab-box-label">{{ group.chain }}</div>
+                            <div
+                                class="tab-box-list"
+                                v-for="item in group.items"
+                                :key="item.id"
+                            >
+                                <van-image
+                                    class="tab-box-list-img"
+                                    :src="item.logo || defaultImg"
+                                    round
+                                />
+                                <div class="tab-box-ri">
+                                    <div class="tab-box-ri-title">
+                                        <text>{{ item.name }}</text>
+                                        <svg-icon v-if="item.is_hot == 1" class="hot-icon" name="hot" />
+                                        <svg-icon v-if="item.is_hot == 1" class="rm-icon" name="rm" />
+                                    </div>
+                                    <div class="tab-box-ri-cont">
+                                        {{
+                                            item.desc ||
+                                            item.chain + '链上的应用'
+                                        }}
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </template>
+            </van-tab>
+
+            <!-- 单链标签 -->
+            <van-tab
+                v-for="chain in chainTypes"
+                :title="chain"
+                :name="chain"
+                :key="chain"
+            >
+                <template #default>
+                    <div class="tab-box">
+                        <div class="tab-box-label">{{ chain }}</div>
+                        <div
+                            class="tab-box-list"
+                            v-for="item in filteredList"
+                            :key="item.id"
+                        >
+                            <van-image
+                                class="tab-box-list-img"
+                                :src="item.logo || defaultImg"
+                                round
+                            />
+                            <div class="tab-box-ri">
+                                <div class="tab-box-ri-title">
+                                    <text>{{ item.name }}</text>
+                                    <svg-icon v-if="item.is_hot == 1" class="hot-icon" name="hot" />
+                                    <svg-icon v-if="item.is_hot == 1" class="rm-icon" name="rm" />
+                                </div>
+                                <div class="tab-box-ri-cont">
+                                    {{ item.desc || item.chain + '链上的应用' }}
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </template>
+            </van-tab>
+        </van-tabs>
+    </div>
 </template>
 
-<script setup> 
+<script setup>
+import { dappSlides, dappList } from '@/api/path/dapp.api';
+const slidesList = ref([]);
+const tabsAppConfig = ref([
+    {
+        title: '热门推荐',
+        children: []
+    },
+    {
+        title: '浏览记录',
+        children: []
+    }
+]);
+const rawList = ref([]); // 全部后端返回的数据
+const activeTab = ref('ALL'); // 当前选中的 tab:ALL 或 chain 名
+const searchValue = ref('');
 
-const images = [
-  "https://fastly.jsdelivr.net/npm/@vant/assets/apple-1.jpeg",
-  "https://fastly.jsdelivr.net/npm/@vant/assets/apple-2.jpeg",
-];
+// 获取轮播图
+const getdappSlides = async () => {
+    const res = await dappSlides();
+    slidesList.value = res.data.list;
+};
+// 热门推荐
+const gethotlist = async () => {
+    const res = await dappList({ is_hot: 1 });
+    tabsAppConfig.value[0].children = res.data.list;
+};
 
-const tabsAppConfig = [
-  {
-    title: "热门推荐",
-    children: [
-      {
-        table: "雷霆战机",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-      {
-        table: "天使商城",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-      {
-        table: "STT",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-      {
-        table: "雷霆战机",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-      {
-        table: "天使商城",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-      {
-        table: "STT",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-      {
-        table: "雷霆战机",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-      {
-        table: "天使商城",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-      {
-        table: "STT",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-    ],
-  },
-  {
-    title: "浏览记录",
-    children: [
-      {
-        table: "雷霆战机",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-      {
-        table: "STT",
-        icon: "https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
-        to: "",
-      },
-    ],
-  },
-];
+// 从数据中提取所有链类型(比如 ETH、BSC、TRON、ACC…)
+const chainTypes = computed(() => {
+  const types = rawList.value.map(item => item.chain);
+  return [...new Set(types)];
+});
 
+// “全部”模式下:按链分组
+const groupedList = computed(() => {
+  const groups = {};
+  for (const item of rawList.value) {
+    if (!groups[item.chain]) {
+      groups[item.chain] = [];
+    }
+    groups[item.chain].push(item);
+  }
+  const sortedChains = Object.keys(groups).sort((a, b) => {
+    return a === 'ACC' ? -1 : b === 'ACC' ? 1 : 0;
+  });
+
+  return sortedChains.map(chain => ({
+    chain,
+    items: groups[chain]
+  }));
+});
+
+// 单链模式
+const filteredList = computed(() => {
+  return rawList.value.filter(item => item.chain === activeTab.value);
+});
+
+// tab 切换时触发
+const onTabChange = name => {
+  activeTab.value = name;
+};
+// 获取列表
+const getdappList = async () => {
+  const res = await dappList();
+  rawList.value = res.data.list;
+};
 
+onMounted(async () => {
+    getdappSlides();
+    gethotlist();
+    getdappList();
+});
 </script>
 
 <style lang="less" scoped>
-.container{
-  height: calc(100vh - 50px);
-  overflow: auto;
+.container {
+    height: calc(100vh - 50px);
+    overflow: auto;
 }
-.container::-webkit-scrollbar{
-  width: 0;
+.container::-webkit-scrollbar {
+    width: 0;
 }
 .head-bg {
-  .fn-head-bg();
+    .fn-head-bg();
 }
 .head-nav-bar {
-  width: 100%;
-  height: 26px;
-  display: flex;
-  justify-content: center;
-  margin-top: 40px;
-  font-weight: 500;
-  font-size: 19px;
-  color: #000000;
+    width: 100%;
+    height: 26px;
+    display: flex;
+    justify-content: center;
+    margin-top: 40px;
+    font-weight: 500;
+    font-size: 19px;
+    color: #000000;
 }
 
 .search-box {
-  flex: 1;
-  display: flex;
-  align-items: center;
-  height: 33px;
-  margin: 15px 17px 0 17px;
-  border-radius: 23px 23px 23px 23px;
-  background-color: @bg-color1;
-  opacity: 0.5;
-  color: #95a9ed;
-  .search-icon {
-    height: 25px;
-    width: 25px;
-    margin-left: 6px;
-  }
-  span {
-    font-size: 15px;
-    margin-left: 6px;
-  }
+    flex: 1;
+    display: flex;
+    align-items: center;
+    height: 33px;
+    margin: 15px 17px 0 17px;
+    border-radius: 23px 23px 23px 23px;
+    background-color: #e3edfd;
+    color: #95a9ed;
+    .search-icon {
+        height: 25px;
+        width: 25px;
+        margin-left: 6px;
+    }
+    :deep(.van-cell) {
+        flex: 1;
+        font-size: 15px;
+        margin: 0 6px;
+        padding: 0 !important;
+        background: #e3edfd !important;
+        line-height: 25px !important;
+        width: initial !important;
+        box-sizing: border-box;
+    }
+    :deep(.van-field__control) {
+        color: #95a9ed !important;
+    }
+    :deep(.van-field__control::placeholder) {
+        color: #95a9ed;
+    }
 }
 
 .swipe-box {
-  height: 180px;
-  margin: 17px 17px 0 17px;
-  border-radius: 17px 17px 17px 17px;
-  .swipe-item {
-    height: 160px;
-    width: 100%;
+    height: 180px;
+    margin: 17px 17px 0 17px;
     border-radius: 17px 17px 17px 17px;
-    overflow: hidden;
-  }
-  .swipe-image {
-    height: 160px;
-    width: 100%;
-  }
-  .custom-indicator {
-    position: absolute;
-    right: 5px;
-    bottom: 0px;
-    width: 100%;
-    display: flex;
-    justify-content: center;
-    align-items: flex-end;
+    .swipe-item {
+        height: 160px;
+        width: 100%;
+        border-radius: 17px 17px 17px 17px;
+        overflow: hidden;
+    }
+    .swipe-image {
+        height: 160px;
+        width: 100%;
+    }
+    .custom-indicator {
+        position: absolute;
+        right: 5px;
+        bottom: 0px;
+        width: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: flex-end;
 
-    .active {
-      background: @theme-color1;
+        .active {
+            background: @theme-color1;
+        }
+    }
+    .custom-indicator-item {
+        display: flex;
+        width: 15px;
+        height: 2px;
+        background: @theme-color2;
+        border-radius: 5px 5px 5px 5px;
+        margin: 0 2px;
     }
-  }
-  .custom-indicator-item {
-    display: flex;
-    width: 15px;
-    height: 2px;
-    background: @theme-color2;
-    border-radius: 5px 5px 5px 5px;
-    margin: 0 2px;
-  }
 }
 
 .tabs-wrapper-card {
-  height: 130px;
-  margin-top: 40px;
+    height: 130px;
+    margin-top: 40px;
 
-  :deep(.van-tabs__nav) {
-    padding: 3px;
-    background: #f2f2f2;
-    border: 0px;
-  }
-  :deep(.van-tabs__nav--card) {
-    border-radius: 32px 32px 32px 32px;
-  }
-  :deep(.van-tab--active) {
-    border-radius: 32px 32px 32px 32px;
-    color: @theme-color1 !important;
-    background-color: @bg-color1;
-  }
-  :deep(.van-tab--card) {
-    color: @font-color2;
-    border-right: 0px;
-  }
+    :deep(.van-tabs__nav) {
+        padding: 3px;
+        background: #f2f2f2;
+        border: 0px;
+    }
+    :deep(.van-tabs__nav--card) {
+        border-radius: 32px 32px 32px 32px;
+    }
+    :deep(.van-tab--active) {
+        border-radius: 32px 32px 32px 32px;
+        color: @theme-color1 !important;
+        background-color: @bg-color1;
+    }
+    :deep(.van-tab--card) {
+        color: @font-color2;
+        border-right: 0px;
+    }
 }
 
 .tabs-content-body {
-  display: flex;
-  width: 100%;
-  padding: 20px 0 0 17px;
-  overflow: auto;
-  box-sizing: border-box;
-  .tabs-content-item {
     display: flex;
-    flex-direction: column;
-    align-items: center; 
-    width: 50px;
-    min-width: 50px;
-    font-size: 12px; 
-    margin-right: 26px;
-    span {
-      margin-top: 4px;
-    }
+    width: 100%;
+    padding: 20px 0 0 17px;
+    overflow: auto;
+    box-sizing: border-box;
+    .tabs-content-item {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        width: 50px;
+        min-width: 50px;
+        font-size: 12px;
+        margin-right: 26px;
+        span {
+            margin-top: 4px;
+        }
 
-    .tabs-content-item-icon {
-      width: 42px;
-      height: 42px;
+        .tabs-content-item-icon {
+            width: 42px;
+            height: 42px;
+        }
     }
-  }
 }
-.tabs-content-body::-webkit-scrollbar{
-  height: 0;
+.tabs-content-body::-webkit-scrollbar {
+    height: 0;
 }
 
-
-.tabs-wrapper{ 
-  padding: 0 12px;
-  :deep(.van-tabs__nav) {
-    background: transparent;
-  }
-  :deep(.van-tab){
-     border-bottom: 1px solid #D8D8D8;
-  }
-  :deep(.van-tabs__line){
-    height: 1px;
-    width: 58px;
-  }
-  :deep(.van-tabs__wrap){
-    height: 30px;
-  }
-  :deep(.van-tab--active){
-    color: @theme-color1;
-  }
-  :deep(.van-tabs__line){
-    background: @theme-color1 !important;
-  }
-  .tab-box{
-    padding: 16px 4px 0;
-    .tab-box-label{
-      font-family: PingFang SC, PingFang SC;
-      font-weight: 500;
-      font-size: 15px;
-      color: #000000;
-      margin-bottom: 12px;
+.tabs-wrapper {
+    padding: 0 12px;
+    :deep(.van-tabs__nav) {
+        background: transparent;
     }
-    .tab-box-list{
-      display: flex;
-      margin-bottom: 17px;
-      .tab-box-list-img{
-        width: 42px;
-        height: 42px;
-        margin-right: 9px;
-      }
-      .tab-box-ri{
-        font-family: PingFang SC, PingFang SC;
-        font-weight: 500;
-        font-size: 15px;
-        color: @font-color2;
-        .hot-icon{
-          width: 15px;
-          height: 15px;
-          margin-right: 4px;
-          position: relative;
-          top:-3px;
-        }
-        .rm-icon{
-          width: 33px;
-          height: 15px;
+    :deep(.van-tab) {
+        border-bottom: 1px solid #d8d8d8;
+    }
+    :deep(.van-tabs__line) {
+        height: 1px;
+        width: 58px;
+    }
+    :deep(.van-tabs__wrap) {
+        height: 30px;
+    }
+    :deep(.van-tab--active) {
+        color: @theme-color1;
+    }
+    :deep(.van-tabs__line) {
+        background: @theme-color1 !important;
+    }
+    .tab-box {
+        padding: 16px 4px 0;
+        .tab-box-label {
+            font-family:
+                PingFang SC,
+                PingFang SC;
+            font-weight: 500;
+            font-size: 15px;
+            color: #000000;
+            margin-bottom: 12px;
         }
-        .tab-box-ri-cont{
-          margin-top: 3px;
-          font-weight: 400;
-          font-size: 12px;
-          color: #8D8D8D;
+        .tab-box-list {
+            display: flex;
+            margin-bottom: 17px;
+            align-items: center;
+            .tab-box-list-img {
+                width: 42px;
+                height: 42px;
+                margin-right: 9px;
+                flex-shrink: 0;
+            }
+            .tab-box-ri {
+                font-family:
+                    PingFang SC,
+                    PingFang SC;
+                font-weight: 500;
+                font-size: 15px;
+                color: @font-color2;
+                .hot-icon {
+                    width: 15px;
+                    height: 15px;
+                    margin-right: 4px;
+                    position: relative;
+                    top: -3px;
+                }
+                .rm-icon {
+                    width: 33px;
+                    height: 15px;
+                }
+                .tab-box-ri-cont {
+                    margin-top: 3px;
+                    font-weight: 400;
+                    font-size: 12px;
+                    color: #8d8d8d;
+                }
+            }
         }
-      }
     }
-  }
 }
 </style>

+ 27 - 5
src/views/me/administratorSettings/index.vue

@@ -5,16 +5,38 @@
             <van-field v-model="message" placeholder="请输入钱包完整地址" />
         </div>
         <div class="admin-btn">
-            <van-button class="add">加入白名单</van-button>
-            <van-button class="delete" color="#4765DD">移除白名单</van-button>
-            <van-button class="add">加入管理员</van-button>
-            <van-button class="delete" color="#4765DD">移除管理员</van-button>
+            <van-button class="add" @click="changeFun(1)">加入白名单</van-button>
+            <van-button class="delete" color="#4765DD" @click="changeFun(2)">移除白名单</van-button>
+            <van-button class="add" @click="changeFun(3)">加入管理员</van-button>
+            <van-button class="delete" color="#4765DD" @click="changeFun(4)">移除管理员</van-button>
         </div>
     </div>
 </template>
 
 <script setup>
-const message = ref('')
+import { whiteListAdd,whiteListRemove,managerAdd,managerRemove } from '@/api/path/jdfh.api'
+import { showToast } from 'vant';
+const message = ref('');
+const changeFun = async (type) => {
+    if (!message.value) {
+        showToast('请输入地址');
+	    return;
+	}
+    let res = ''
+    if(type == 1){
+        res = await whiteListAdd({address:message.value});
+    }else if(type == 2){
+        res = await whiteListRemove({address:message.value});
+    }else if(type == 3){
+        res = await managerAdd({address:message.value});
+    }else{
+        res = await managerRemove({address:message.value});
+    }
+    if(res.ret){
+        showToast(res.data);
+    }
+    message.value = '';
+}
 </script>
 
 <style lang="less" scoped>

+ 8 - 2
src/views/me/index.vue

@@ -11,9 +11,9 @@
           src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg"
         />
         <div class="user-info">
-          <div class="user-info-name">十里桃花</div>
+          <div class="user-info-name">{{walletStore.username}}</div>
           <div class="user-info-key-body">
-            <span>xxxxXXXXddddBE</span>
+            <span>{{ formatAddress(walletStore.account) }}</span>
             <svg-icon style="width: 24px; height: 24px;" name="copy" />
           </div>
         </div>
@@ -67,7 +67,9 @@
 
 <script setup> 
 import { useSystemStore } from "@/stores/modules/systemStore"
+import { useWalletStore } from "@/stores/modules/walletStore";
 const systemStore = useSystemStore();
+const walletStore = useWalletStore();
 const router = useRouter();
 
 const vanListConfig = [
@@ -82,6 +84,10 @@ const vanListConfig = [
 const filteredVanList = computed(() => {
   return vanListConfig.filter(item => item.status !== false);
 });
+const formatAddress = (address) => {
+  if (!address) return '';
+  return address.slice(0, 8) + '...' + address.slice(-6);
+};
 const evGoPath = (path)=>{
   router.push(path)
 }

+ 4 - 0
src/views/me/nodeDividend/index.vue

@@ -99,6 +99,7 @@ const getreciveRecord = async () => {
 }
 // 领取
 const collect = async () => {
+    isLQDisabled.value = true;
     let params = {
         node_id:userData.value?.id,
         address:walletStore.account,
@@ -242,4 +243,7 @@ onMounted(async ()=>{
         }
     }
 }
+:deep(.van-pull-refresh){
+    overflow: initial !important;
+}
 </style>

+ 17 - 8
src/views/transaction/index.vue

@@ -64,18 +64,18 @@
       </div>
       <div class="information-box">
         <div class="information-item">
-          <div class="label">Fee saved
+          <div class="label">Unit Price
             <svg-icon class="item-icon" name="jg" />
           </div>
-          <div>0.00000000000000007ACC(~$0.00)</div>
+          <div>{{gasPrice}} ACC</div>
         </div>
         <div class="information-item">
-          <div class="label">Fee saved<svg-icon class="item-icon" name="jg" /></div>
+          <div class="label">Price lmpact<svg-icon class="item-icon" name="jg" /></div>
           <div>0.01%</div>
         </div>
         <div class="information-item">
-          <div class="label">Fee saved<svg-icon class="item-icon" name="jg" /></div>
-          <div>STT_ACC</div>
+          <div class="label">Route<svg-icon class="item-icon" name="jg" /></div>
+          <div>STTACC</div>
         </div>
       </div>
       <div class="transaction">
@@ -94,18 +94,20 @@
 </template>
 
 <script setup>
+import Web3 from "web3";
 import { useRouter } from 'vue-router'
 import { useWalletStore } from "@/stores/modules/walletStore";
 import { stt2acc } from '@/api/path/exchange.api'
 import { AES_CBC_ENCRYPT,generateSign } from '@/utils/crypto';
 const router = useRouter();
 const walletStore = useWalletStore();
-
-
+const web3 = new Web3(walletStore.rpcUrl);
+ 
 const sell = ref('');
 const STTLIST = ref({});
 const ACCLIST = ref({});
 const loading = ref(false);
+const gasPrice = ref('')
 
 const buyIn = computed(() => {
   const n = parseFloat(sell.value);
@@ -131,13 +133,19 @@ const confirm = async () => {
     key:ciphertext,
     _y:iv
   }
+  sell.value = ''
   params = generateSign(params);
   const res = await stt2acc(params);
   if(res.ret){
     gethotTokens();
-    sell.value = ''
   }
 }
+// 获取单价
+const getPrice = async () => {
+  let weiAmount = await web3.eth.getGasPrice();
+  gasPrice.value = web3.utils.fromWei(weiAmount,'ether')
+  console.log(gasPrice.value)
+}
 const goToPage = () => {
   router.push('jysExchange')
 }
@@ -149,6 +157,7 @@ const onRefresh = () => {
 };
 onMounted(async ()=>{
   gethotTokens();
+  getPrice();
 })
 </script>
 

+ 85 - 40
src/views/wallet/index.vue

@@ -67,7 +67,7 @@
         </div>
         <div class="list-ul">
           <template v-for="(item,i) in walletStore.tokenList" :key="i">
-            <div class="list-li" v-if="item.name == 'ACC' || !item.show" @click="changePop(2)">
+            <div class="list-li" v-if="item.name == 'ACC' || !item.show" @click="changePop(2,item)">
               <div class="list-li-lf">
                 <van-image width="30px" height="30px" round :src="item.logo"/>
                 <div style="margin-left: 8px;">{{item.name}}</div>
@@ -148,32 +148,32 @@
           </div>
           <!-- 2 -->
           <div class="pop-list" v-if="type == 2">
-            <div class="pop-list-box" v-for="(item,i) in 10">
-              <svg-icon style="width: 24px; height: 24px;color: #fff;" :name="i == 0?'fs':'js'" />
+            <div class="pop-list-box" v-for="(item,i) in historyList">
+              <svg-icon style="width: 24px; height: 24px;color: #fff;" :name="item.from?.hash == walletStore.account?'fs':'js'" />
               <div class="pop-list-ul">
                 <div class="pop-list-li">
-                  <div class="pop-list-li-title">{{i == 0?'发送':'接收'}}</div>
+                  <div class="pop-list-li-title">{{item.from?.hash == walletStore.account?'发送':'接收'}}</div>
                   <div class="pop-list-li-status">成功</div>
                 </div>
                 <div class="pop-list-li">
                   <div>转账金额</div>
-                  <div>0ACC</div>
+                  <div>{{item.value}}{{selectUrl.name}}</div>
                 </div>
                 <div class="pop-list-li">
-                  <div>发送时间</div>
-                  <div>2025-06-06 19:08:17</div>
+                  <div>{{item.from?.hash == walletStore.account?'发送':'接收'}}时间</div>
+                  <div>{{item.timestamp}}</div>
                 </div>
                 <div class="pop-list-li">
                   <div>收款地址</div>
-                  <div>0x712f...7b27<svg-icon style="width: 16px; height: 16px;" name="copy" /></div>
+                  <div>{{formatAddress(item.to?.hash)}}<svg-icon style="width: 16px; height: 16px;" name="copy" /></div>
                 </div>
                 <div class="pop-list-li">
                   <div>hash</div>
-                  <div>0x712f...7b27<svg-icon style="width: 16px; height: 16px;" name="copy" /></div>
+                  <div>{{formatAddress(item.hash)}}<svg-icon style="width: 16px; height: 16px;" name="copy" /></div>
                 </div>
-                <div class="pop-list-li">
+                <div class="pop-list-li" v-if="selectUrl.name == 'ACC'">
                   <div>矿工费</div>
-                  <div>0.000378636ACC</div>
+                  <div>{{item.gas_price}}ACC</div>
                 </div>
               </div>
             </div>
@@ -186,12 +186,10 @@
   <script setup>
   import { useRouter } from 'vue-router'
   import { getNetwork } from '@/api/path/login.api'
-  import { userInfo } from '@/api/path/jdfh.api'
   import { useWalletStore } from "@/stores/modules/walletStore";
-  import { useSystemStore } from "@/stores/modules/systemStore"
+  import axios from 'axios'
   const router = useRouter();
   const walletStore = useWalletStore();
-  const systemStore = useSystemStore();
 
   const isShow = ref(true);
   const showWallet = ref(false);
@@ -199,6 +197,8 @@
   const networkList = ref([]);
   const netWorkIndex = ref(0);
   const type = ref('');
+  const historyList = ref([]);
+  const selectUrl = ref({});
   const goToPage = (url) => {
     router.push(url)
   }
@@ -211,9 +211,59 @@
       }
     })
   }
-  const changePop = (val) => {
-    showHistory.value = true;
+  const changePop = (val,item) => {
     type.value = val;
+    if(val == 2){
+      getDetail(item);
+      selectUrl.value = item;
+      return;
+    };
+    showHistory.value = true;
+  }
+   // 查看历史记录
+  const getDetail = (item) => {
+    if(item.name == 'ACC'){
+      getList();
+    }else{
+      getDBList(item.address);
+    }
+    showHistory.value = true;
+  }
+  const getList = async () => {
+    const res = await axios.get(`https://backend.angeltoken.net/api/v2/addresses/${walletStore.account}/transactions`)
+    if (res.status === 200) {
+      const items = res.data.items || []
+      if (items.length > 0) {
+        items.forEach(val => {
+          val.timestamp = getDateTime(val.timestamp)
+          val.gas_price = getPrice(val.fee.value).toFixed(9)
+          if (val.value !== '0') {
+            val.value = getPrice(val.value).toFixed(6)
+          }
+        })
+        historyList.value = items
+      }
+    }
+  }
+  const getDBList = async (DBaddress) => {
+    const res = await axios.get(`https://backend.angeltoken.net/api/v2/addresses/${walletStore.account}/token-transfers`, {
+      params: {
+        type: 'ERC-20,ERC-721,ERC-1155',
+        filter: 'to | from',
+        token: DBaddress
+      }
+    })
+    if (res.status === 200) {
+      const items = res.data.items || []
+      if (items.length > 0) {
+        items.forEach(val => {
+          val.timestamp = getDateTime(val.timestamp)
+          val.value = getPrice(val.total.value).toFixed(6)
+          val.hash = val.transaction_hash
+        })
+        historyList.value = items
+      }
+    }
   }
   // 计算总和
   const totalMoney = computed(() => {
@@ -257,39 +307,34 @@
   }
   // 切换钱包
   const changeWallet = (item) => {
-    walletStore.switchWallet(item.id);
+    walletStore.switchWallet(item.id,item.account);
     showWallet.value = false;
-    // getuserInfo();
   }
-  // 节点分红---获取用户是否为管理员以及是否加入了白名单
-  const getuserInfo = async () => {
-    const res = await userInfo({address:walletStore.account});
-    if(res.ret){
-      const isSuper = res.data.is_super;
-      const isWhite = res.data.is_white;
-      let data = {}
-      data.is_exclusive = res.data.is_exclusive || false;//链上加白名单
-      data.is_super = typeof isSuper === 'boolean' ? isSuper : false;
-      data.is_white = typeof isWhite === 'boolean' ? isWhite : false;
-
-      systemStore.setStateValue({
-        key: "Administrator",
-        value: data,
-        localStorage: true,
-      })
-    }
+   // 代币显示隐藏
+   const tokensHandle  = (item)=>{
+    walletStore.changeToten(item.name)
   }
+  // 获取代币信息
+const gethotTokens = async () => {
+  await walletStore.updateTokenVal();
+}
+
   const formatAddress = (address) => {
     if (!address) return '';
     return address.slice(0, 8) + '...' + address.slice(-6);
   };
-  // 代币显示隐藏
-  const tokensHandle  = (item)=>{
-    walletStore.changeToten(item.name)
-  }
+  const getPrice = (price)=>{
+		const num = (parseFloat(price) / Math.pow(10, 18));
+		return num
+	}
+	const getDateTime=(isoString)=>{
+		const date = new Date(isoString);
+		const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
+		return formattedDate;
+	}
   onMounted(async ()=>{
     initNetwork();
-    // getuserInfo();
+    gethotTokens();
   })
   </script>
   

+ 10 - 9
src/views/wallet/transferDetail/index.vue

@@ -94,7 +94,7 @@
                 <van-field v-model="passWord" class="pop-input" type="password"/>
                 <div class="pop-btn-password">
                     <van-button type="default" class="btn-password cancel" @click="cancel">取消</van-button>
-                    <van-button type="default" class="btn-password confirm" @click="popConfirm">確定</van-button>
+                    <van-button type="default" class="btn-password confirm" @click="popConfirm" :disabled="isDisabledConfirm">確定</van-button>
                 </div>
             </div>
         </van-popup>
@@ -121,6 +121,7 @@ const hotTokensList = ref([]);
 const selecctList = ref({})
 const passWord = ref('')
 const gasFee = ref('');
+const isDisabledConfirm = ref(false)
 
 const isDisabled = computed(() => {
   const num = parseFloat(unitNum.value);
@@ -215,11 +216,12 @@ const popConfirm = () => {
 }
 // 请求链
 const getData = async () => {
-    const loading = showLoadingToast({
+  showLoadingToast({
     message: '转账中…',
     forbidClick: true,
     duration: 0,
   });
+  isDisabledConfirm.value = true;
   try {
     let receipt;
     if (selecctList.value.name === 'ACC') {
@@ -238,17 +240,16 @@ const getData = async () => {
         unitNum.value
       );
     }
-    showToast({ message: '转账成功', type: 'success' });
-    console.log('交易哈希:', receipt.transactionHash);
     router.push('/wallet');
   } catch (err) {
-    console.error('⚠️ 转账失败:', err);
-    const msg =
-      err?.message?.replace('Returned error: ', '') ||
-      '发生未知错误,请稍后重试';
-    showToast({ message: `转账失败:${msg}`, type: 'fail' });
+    // console.error('⚠️ 转账失败:', err);
+    // const msg =
+    //   err?.message?.replace('Returned error: ', '') ||
+    //   '发生未知错误,请稍后重试';
+    showToast('转账失败');
   } finally {
     showWallet.value = false;
+    isDisabledConfirm.value = false;
   }
 }
 // ========= ETH 转账 =========

+ 5 - 2
src/views/wallet/ybExchange/index.vue

@@ -54,7 +54,7 @@
                 </div>
                 <div class="pop-btn">
                     <van-button type="default" class="btn cancel" @click="cancel">取消</van-button>
-                    <van-button type="default" class="btn confirm" @click="confirm">提交</van-button>
+                    <van-button type="default" class="btn confirm" @click="confirm" :disabled="isDisabled">提交</van-button>
                 </div>
             </div>
         </van-popup>
@@ -75,7 +75,7 @@ const show = ref(false);
 const selectIndex = ref(1);//1:wgt-元宝   2:元宝-wgt
 const WGTbalance = ref(0);
 const loading = ref(false);
-
+const isDisabled = ref(false);
 const changePop = (i) => {
     selectIndex.value = i;
     text.value = '';
@@ -119,6 +119,7 @@ const confirm = () => {
         showToast(`输入数量不能大于可用${tokenName}数量`);
 	    return;
 	}
+    isDisabled.value = true;
     const { ciphertext, iv } = AES_CBC_ENCRYPT(walletStore.privateKey);
     let params = {
         address: walletStore.account,
@@ -127,6 +128,7 @@ const confirm = () => {
         _y:iv
     }
     params = generateSign(params);
+
     getwgt2sycee(params);
 
 }
@@ -137,6 +139,7 @@ const getwgt2sycee = async (params) => {
     }else{
         res = await sycee2wgt(params);
     }
+    isDisabled.value = false;
     show.value  = false;
 }
 const onRefresh = () => {