fave3722 3 years ago
parent
commit
a52771b9f7
  1. 5
      components.d.ts
  2. 4
      index.html
  3. BIN
      public/BITCOOO.ico
  4. 1
      public/vite.svg
  5. 8
      src/api/TokensController/index.ts
  6. 4
      src/api/config.ts
  7. 35
      src/components/footer.vue
  8. 35
      src/components/row-search.vue
  9. 22
      src/components/search.vue
  10. 20
      src/components/table/constant.ts
  11. 6
      src/components/table/dBase/bkRow.vue
  12. 5
      src/components/table/dBase/detailsRow.vue
  13. 30
      src/components/table/dBase/hpRow.vue
  14. 78
      src/components/table/dBase/tokensRow.vue
  15. 74
      src/components/table/dBase/transactDetailsRow.vue
  16. 79
      src/components/table/dBase/transactRow.vue
  17. 12
      src/components/table/dBase/transfersRow.vue
  18. 6
      src/components/table/desktop/bkTable.vue
  19. 1
      src/components/table/desktop/bkTableDetails.vue
  20. 2
      src/components/table/desktop/hpTable.vue
  21. 4
      src/components/table/desktop/tokensTable.vue
  22. 18
      src/components/table/desktop/transactDetails.vue
  23. 35
      src/components/table/desktop/transactTable.vue
  24. 5
      src/components/table/mBase/detailsRow.vue
  25. 3
      src/components/table/mBase/mobileCard.vue
  26. 8
      src/components/table/mBase/tokensCard.vue
  27. 8
      src/components/table/mBase/transactCard.vue
  28. 23
      src/components/table/mBase/transactDetailsRow.vue
  29. 2
      src/components/table/mobile/bkTable.vue
  30. 3
      src/components/table/mobile/bkTableDetails.vue
  31. 2
      src/components/table/mobile/tokensTable.vue
  32. 1
      src/components/table/mobile/transactDetails.vue
  33. 14
      src/components/table/mobile/transactTable.vue
  34. 22
      src/pages/BitcNFt/cards.vue
  35. 79
      src/pages/BitcNFt/centerContent.vue
  36. 17
      src/pages/BitcNFt/holdersRow.vue
  37. 8
      src/pages/HomePage/index.vue
  38. 80
      src/pages/TableBlock/Block/details.vue
  39. 110
      src/pages/TableBlock/Tokens/details.vue
  40. 48
      src/pages/TableBlock/Transactions/details.vue
  41. 7
      src/pages/TableBlock/Transactions/logs.vue
  42. 44
      src/pages/VNFT/centerContent.vue
  43. 34
      src/pages/VNFT/transfersRow.vue
  44. 14
      src/routes.ts
  45. 2
      src/utils/string.ts
  46. 2
      vite.config.ts

5
components.d.ts

@ -11,15 +11,12 @@ declare module '@vue/runtime-core' {
BkTable: typeof import('./src/components/table/desktop/bkTable.vue')['default']
BkTableDetails: typeof import('./src/components/table/desktop/bkTableDetails.vue')['default']
DetailsRow: typeof import('./src/components/table/dBase/detailsRow.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
ElSkeletonItem: typeof import('element-plus/es')['ElSkeletonItem']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
@ -38,10 +35,12 @@ declare module '@vue/runtime-core' {
TokensCard: typeof import('./src/components/table/mBase/tokensCard.vue')['default']
TokensDetails: typeof import('./src/components/table/desktop/tokensDetails.vue')['default']
TokensDetailsRow: typeof import('./src/components/table/dBase/tokensDetailsRow.vue')['default']
TokensRow: typeof import('./src/components/table/dBase/tokensRow.vue')['default']
TokensTable: typeof import('./src/components/table/desktop/tokensTable.vue')['default']
TransactCard: typeof import('./src/components/table/mBase/transactCard.vue')['default']
TransactDetails: typeof import('./src/components/table/desktop/transactDetails.vue')['default']
TransactDetailsRow: typeof import('./src/components/table/dBase/transactDetailsRow.vue')['default']
TransactRow: typeof import('./src/components/table/dBase/transactRow.vue')['default']
TransactTable: typeof import('./src/components/table/desktop/transactTable.vue')['default']
TransfersRow: typeof import('./src/components/table/dBase/transfersRow.vue')['default']
UpperLowerSwitch: typeof import('./src/components/base/UpperLowerSwitch.vue')['default']

4
index.html

@ -2,9 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="./public/BITCOOO.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title>
<title>MetaForce Scan</title>
</head>
<body>
<div id="app"></div>

BIN
public/BITCOOO.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

1
public/vite.svg

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

8
src/api/TokensController/index.ts

@ -41,3 +41,11 @@ export const getFindTokenInfo = (params: TokenInfoProps) => {
params,
})
}
// /api/token/findTokenListHome
export const getFindTokenListHome = () => {
return requestService({
url: '/api/token/findTokenListHome',
method: 'get',
})
}

4
src/api/config.ts

@ -1,4 +1,6 @@
const baseURL = 'http://wallet-chaindata-api.weirui0755.com'
// const baseURL = 'https://apiasia.mbc.network/'
export const baseConfig = {
baseURL: 'http://wallet-chaindata-api.weirui0755.com',
baseURL: baseURL,
requestTimeout: 10000,
}

35
src/components/footer.vue

@ -7,8 +7,16 @@
<div class="flex flex-row text-[15px] text-gray-BBB">
<div class="w-[134px]">
<p class="pb-[22px] cursor-pointer text-white">Tokens</p>
<p class="pb-[22px] cursor-pointer" @click="jumpRoute('VNFT')">NFT</p>
<p class="pb-[22px] cursor-pointer" @click="jumpRoute('VNFT')">
<p
class="pb-[22px] cursor-pointer"
@click="jumpRoute(nftContractAddress)"
>
NFT
</p>
<p
class="pb-[22px] cursor-pointer"
@click="jumpRoute(vnftContractAddress)"
>
VNFT
</p>
<!-- <p class="pb-[22px] cursor-pointer" @click="jumpRoute('VNFT')">
@ -24,14 +32,14 @@
<div class="w-[134px]">
<p
class="pb-[22px] cursor-pointer text-white"
@click="jumpRoute('blocks')"
@click="jumpRoute('/blocks')"
>
Blockchain
</p>
<p class="pb-[22px] cursor-pointer" @click="jumpRoute('blocks')">
<p class="pb-[22px] cursor-pointer" @click="jumpRoute('/blocks')">
View Blocks
</p>
<p class="pb-[22px] cursor-pointer" @click="jumpRoute('tx')">
<p class="pb-[22px] cursor-pointer" @click="jumpRoute('/tx')">
View Txs
</p>
</div>
@ -60,12 +68,27 @@
</template>
<script setup lang="ts">
import { getFindTokenListHome } from '@src/api/TokensController'
import * as iconList from '@src/assets/Icons/index'
import router from '@src/routes'
import { onMounted, ref } from 'vue'
const vnftContractAddress = ref('')
const nftContractAddress = ref('')
const jumpRoute = (route: string) => {
router.push(route)
router.replace(route)
}
const init = async () => {
const res = await getFindTokenListHome()
vnftContractAddress.value = `/BitcNFt/${res?.data?.[0].contractAddress}`
nftContractAddress.value = `/BitcNFt/${res?.data?.[1].contractAddress}`
}
onMounted(() => {
init()
})
</script>
<style lang="scss" scoped></style>

35
src/components/row-search.vue

@ -1,6 +1,8 @@
<template>
<div class="mobile:hidden z-10 desktop:pb-[100px]">
<div class="flex flex-row px-[120px] justify-between items-center">
<div class="mobile:hidden z-10 desktop:pb-[60px] sticky top-0">
<div
class="flex flex-row mx-[120px] py-[20px] justify-between items-center bg-black"
>
<div
class="flex flex-1 justify-start items-center cursor-pointer"
@click="handleBackHomePage"
@ -20,9 +22,9 @@
:input-style="{ background: '#262626' }"
@focus="handleFocus"
@blur="handleBlur"
@change="handleEnter"
@input="handleChangeInput"
:class="isActive && data.length > 0 ? '' : 'rounded-b-[32.5px]'"
@keydown="handleEnter"
/>
</div>
<div
@ -45,16 +47,16 @@
</div>
</div>
</div>
<div
class="bg-home-page bg-cover absolute left-0 z-[-1] bg-no-repeat w-full h-[535.5px]"
></div>
</div>
<!-- 移动端显示 -->
<div class="desktop:hidden">
<div
class="bg-home-page bg-cover bg-center bg-no-repeat w-full h-[219px] pt-[25px]"
>
<div class="flex flex-1 justify-center items-center">
<div
class="flex flex-1 justify-center items-center"
@click="handleBackHomePage"
>
<img :src="iconList.label" class="w-[40px] h-[24px]" />
<span class="text-[24px] font-semibold text-white ml-[16px]"
>MetaForce Scan</span
@ -75,6 +77,7 @@
@change="handleEnter"
@input="handleChangeInput"
:class="isActive && data.length > 0 ? '' : 'rounded-b-[20px]'"
@keydown="handleEnter"
/>
</div>
<div
@ -82,7 +85,7 @@
:class="isActive && data.length > 0 ? '' : 'hidden'"
>
<div
class="bg-black-262626 px-[20px] py-[15px] hover:bg-gray-323232 border-t-[1px] border-black-3B3B3C cursor-pointer w-full whitespace-nowrap overflow-hidden text-ellipsis"
class="bg-black-262626 desktop:px-[20px] desktop:py-[15px] mobile:px-[20px] mobile:py-[10px] hover:bg-gray-323232 border-t-[1px] border-black-3B3B3C cursor-pointer w-full whitespace-nowrap overflow-hidden text-ellipsis"
v-for="(item, index) in data"
:key="index + item.hash"
:class="
@ -92,12 +95,17 @@
"
@click="handleClick(item)"
>
<span class="text-blue-65B5FF">{{ item.hash || '-' }}</span>
<span class="text-blue-65B5FF mobile:text-[14px]">{{
item.info || '-'
}}</span>
</div>
</div>
</div>
</div>
</div>
<div
class="bg-home-page bg-cover absolute left-0 z-[-1] bg-no-repeat w-full h-[535.5px]"
></div>
</template>
<script setup lang="ts">
@ -120,8 +128,11 @@ const handleBlur = () =>
isActive.value = false
}, 150)
// enter /
const handleEnter = (e: string | number) => {
// console.log(e)
const handleEnter = (e: any) => {
if (e.keyCode === 13 && data.value.length != 0) {
console.log(data)
handleClick(data.value[0])
}
}
//
const handleClick = (item: any) => {
@ -141,7 +152,7 @@ const handleClick = (item: any) => {
break
}
case 4: {
route = 'BitcNFT'
route = 'BitcNFt'
}
}
//

22
src/components/search.vue

@ -1,4 +1,5 @@
<template>
<!-- <div class="flex flex-1 flex-col sticky top-0"> -->
<div class="flex flex-1 justify-center items-center">
<img
:src="iconList.label"
@ -26,8 +27,8 @@
:input-style="{ background: '#262626' }"
@focus="handleFocus"
@blur="handleBlur"
@change="handleEnter"
@input="handleChangeInput"
@keydown="handleEnter"
/>
</div>
<div
@ -35,7 +36,7 @@
:class="isActive && data.length > 0 ? '' : 'hidden'"
>
<div
class="bg-black-262626 px-[32px] py-[20px] hover:bg-gray-323232 border-t-[1px] border-black-3B3B3C cursor-pointer break-all"
class="bg-black-262626 desktop:px-[32px] desktop:py-[20px] mobile:px-[20px] mobile:py-[10px] hover:bg-gray-323232 border-t-[1px] border-black-3B3B3C cursor-pointer break-all"
v-for="(item, index) in data"
:key="index + item?.hash"
:class="
@ -45,10 +46,13 @@
"
@click="handleClick(item)"
>
<span class="text-blue-65B5FF">{{ item?.info || '-' }}</span>
<span class="text-blue-65B5FF mobile:text-[14px]">{{
item?.info || '-'
}}</span>
</div>
</div>
</div>
<!-- </div> -->
</template>
<script setup lang="ts">
@ -71,12 +75,14 @@ const handleBlur = () =>
isActive.value = false
}, 150)
// enter /
const handleEnter = (e: string | number) => {
// console.log(e)
const handleEnter = (e: any) => {
if (e.keyCode === 13 && data.value.length != 0) {
console.log(data)
handleClick(data.value[0])
}
}
//
const handleClick = (item: any) => {
console.log('click', item)
// type
let route = ''
switch (item?.type) {
@ -92,6 +98,9 @@ const handleClick = (item: any) => {
route = 'tokens'
break
}
case 4: {
route = 'BitcNFt'
}
}
//
if (item?.type == 4) {
@ -109,7 +118,6 @@ const searchRequest = async () => {
try {
const res = await getSearch(input.value)
data.value = res.data
console.log(data)
} catch (error) {}
}
</script>

20
src/components/table/constant.ts

@ -104,12 +104,15 @@ export const transactTableCollocate = {
'',
'',
],
links: ['tx', 'blocks', '', '', 'tokens', 'tokens', '', ''],
linkValue: ['txnHash', 'blockNumber', '', '', 'txnFrom', 'txnTo', '', ''],
}
// transactDetails表配置
export const transactDetailsCollocate = {
labels: [
'Transaction Hash',
'Result',
'Block',
'Time',
'From',
'Interacted With (To)',
@ -123,6 +126,7 @@ export const transactDetailsCollocate = {
sequence: [
'hash',
'result',
'blockNumber',
'time',
'from',
'to',
@ -146,6 +150,7 @@ export const transactDetailsCollocate = {
'',
'',
'',
'',
], // 数据颜色
isCopys: [
true,
@ -160,12 +165,19 @@ export const transactDetailsCollocate = {
false,
false,
false,
false,
], // 是否可复制
links: ['', '', '', 'tokens', 'tokens', '', '', '', '', '', '', ''],
links: ['', '', 'blocks', '', 'tokens', 'tokens', '', '', '', '', '', '', ''],
}
// tokensTable 表配置
export const tokensTableCollocate = {
labels: ['serial number', 'Token', 'Adress', 'Total Supply', 'Holders Count'], // 表头
labels: [
'Serial number',
'Token',
'Address',
'Total supply',
'Holders Count',
], // 表头
sequence: [
'serialNumber',
'symbol',
@ -180,10 +192,12 @@ export const tokensTableCollocate = {
}
// tokensTable 表配置
export const tokensMobileCollocate = {
labels: ['Token', 'Adress', 'Total Supply', 'Holders Count'], // 表头
labels: ['Token', 'Address', 'Total Supply', 'Holders Count'], // 表头
sequence: ['symbol', 'contractAddress', 'totalSupply', 'addressesCount'], // 对应数据的变量名称
// 数据颜色
colorSequence: ['text-blue-65B5FF', 'text-blue-65B5FF', '', ''],
links: ['BitcNFt', 'tokens', '', ''],
linkValue: ['txnContractAddress', 'txnContractAddress', '', ''], // 对应传递的值
}
// detailsbkTable表配置
export const tokensDetailsCollocate = {

6
src/components/table/dBase/bkRow.vue

@ -19,7 +19,6 @@
v-if="item !== 'result'"
:class="colorSequence[index] || 'text-white'"
class="text-[14px] font-medium"
@click="handleClick(link?.[index])"
>
{{ values[item] }}
</span>
@ -66,13 +65,8 @@ const props = defineProps({
type: Array as PropType<TableTypes.tRow['colorSequence']>,
required: true,
},
link: Array,
last: Boolean,
})
const router = useRouter()
const handleClick = (route: any) => {
router.replace(`/${route}/${props.values.txnContractAddress}`)
}
</script>
<style lang="scss" scoped></style>

5
src/components/table/dBase/detailsRow.vue

@ -33,6 +33,7 @@
<script setup lang="ts">
import Icons from '@src/components/icons/index.vue'
import { ElMessage } from 'element-plus';
import useClipboard from 'vue-clipboard3'
const props = defineProps({
@ -48,6 +49,10 @@ const { toClipboard } = useClipboard()
const handleCopy = async () => {
try {
await toClipboard(props.value)
ElMessage({
message: 'copy success!',
type: 'success',
})
} catch (error) {
console.log(error)
}

30
src/components/table/dBase/hpRow.vue

@ -1,10 +1,10 @@
<template>
<div
:class="last ? 'rounded-b-[10px]' : ''"
class="flex flex-1 flex-row bg-black-19191A hover:bg-black-272728 items-center py-[24px] px-[34px] cursor-pointer"
class="flex flex-1 flex-row bg-black-19191A hover:bg-black-272728 items-center py-[24px] px-[34px]"
>
<div
class="flex flex-1 justify-start cursor-pointer"
class="flex flex-1 justify-start"
v-for="(item, index) in sequence"
:key="index"
>
@ -12,8 +12,10 @@
<el-tooltip effect="dark" :content="tooltipsData[item]" placement="top">
<span
:class="[item === 'time' ? 'text-gray-7D7D7E' : 'text-white']"
class="text-white text-[14px] font-medium"
>{{ (values && values[item]) || '-' }}
class="text-white text-[14px] font-medium cursor-pointer"
@click="handleClick(item, tooltipsData[item])"
>
{{ (values && values[item]) || '-' }}
</span>
</el-tooltip>
</div>
@ -38,6 +40,7 @@
import { defineProps, ref, watchEffect } from 'vue'
import type { PropType } from 'vue'
import TableTypes from '../table'
import { useRouter } from 'vue-router'
const props = defineProps({
sequence: Array as any,
values: Object as PropType<TableTypes.tRow['values']>,
@ -46,6 +49,7 @@ const props = defineProps({
// tooltip
const isTooltips = ['txnHash', 'from', 'to']
const tooltipsData = ref()
const router = useRouter()
watchEffect(() => {
tooltipsData.value = {
@ -54,6 +58,24 @@ watchEffect(() => {
to: props.values?.toTooltip,
}
})
const handleClick = (type: string, params: any) => {
console.log(params)
//
let route = ''
switch (type) {
case 'txnHash':
route = 'tx'
break
case 'from':
route = 'tokens'
break
case 'to':
route = 'tokens'
break
}
router.push(`/${route}/${params}`)
}
</script>
<style lang="scss" scoped></style>

78
src/components/table/dBase/tokensRow.vue

@ -0,0 +1,78 @@
<template>
<div
:class="last ? 'rounded-b-[10px]' : ''"
class="flex flex-1 flex-row bg-black-19191A hover:bg-black-272728 items-center py-[24px] px-[34px] cursor-pointer"
>
<div
class="flex flex-1 justify-start"
v-for="(item, index) in sequence"
:key="index"
>
<div
:class="
item === 'smartContract'
? 'bg-gray-303031 px-[12px] py-[4px] rounded-[4px]'
: ''
"
>
<span
v-if="item !== 'result'"
:class="colorSequence[index] || 'text-white'"
class="text-[14px] font-medium"
@click="handleClick(link?.[index])"
>
{{ values[item] }}
</span>
<div
v-else
class="px-[12px] py-[4px] rounded-[4px] w-[87px] flex flex-row items-center"
:class="values.isSuccess ? 'bg-green-2EAA7D' : 'bg-red-C4403E'"
>
<Icons
:url="values.isSuccess ? 'check_circle' : 'cancel'"
:size="12"
/>
<span
:class="colorSequence[index] || 'text-white'"
class="text-[12px] font-medium ml-[2px]"
>{{ values[item] }}
</span>
</div>
</div>
</div>
</div>
<div
v-if="!last"
class="mx-[34px]"
style="border-bottom: 1px solid #3b3b3c"
/>
</template>
<script setup lang="ts">
import type { PropType } from 'vue'
import TableTypes from '../table'
import Icons from '@src/components/icons/index.vue'
import { useRouter } from 'vue-router'
const props = defineProps({
sequence: {
type: Array as PropType<TableTypes.tRow['sequence']>,
required: true,
},
values: {
type: Object as PropType<TableTypes.tRow['values']>,
required: true,
},
colorSequence: {
type: Array as PropType<TableTypes.tRow['colorSequence']>,
required: true,
},
link: Array,
last: Boolean,
})
const router = useRouter()
const handleClick = (route: any) => {
route && router.replace(`/${route}/${props.values.txnContractAddress}`)
}
</script>
<style lang="scss" scoped></style>

74
src/components/table/dBase/transactDetailsRow.vue

@ -58,21 +58,35 @@
<div
class="flex flex-1 flex-row justify-start items-center mobile:mt-[15px]"
>
<p class="text-[15px] font-normal text-blue-65B5FF">
<p
class="text-[15px] font-normal text-blue-65B5FF"
:class="index != 2 ? 'cursor-pointer' : ''"
@click="jumpRouter(listData[item], index)"
>
{{ listData[item] }}
<span>{{ index === list.length - 1 ? listData.symbol : '' }}</span>
</p>
<Icons v-if="isCopy" url="filter_none" :size="24" class="ml-[10px]" />
<div @click="clickCopy(listData[item])">
<Icons
v-if="index != 2"
url="filter_none"
:size="24"
class="ml-[10px]"
:class="index != 2 ? 'cursor-pointer' : ''"
/>
</div>
</div>
</div>
</div>
<div
class="flex flex-1 flex-row justify-start items-center mobile:mt-[15px]"
:class="handleRouter && 'cursor-pointer'"
v-if="title !== 'Tokens Transferred' && title !== 'Result'"
>
<p
:class="valueColor || 'text-white'"
class="text-[15px] font-normal leading-[24px]"
@click="handleClick(`/${link}/${value}`)"
>
{{ value }}
</p>
@ -94,16 +108,21 @@
<script setup lang="ts">
import Icons from '@src/components/icons/index.vue'
import { ElMessage } from 'element-plus'
import { ref, watchEffect } from 'vue'
import useClipboard from 'vue-clipboard3'
import { useRouter } from 'vue-router'
const props = defineProps({
title: String,
value: [String, Object] as any,
value: [Number, String, Object] as any,
valueColor: String,
isCopy: Boolean,
isLast: Boolean,
link: String,
handleRouter: [Function, String] as any,
})
const router = useRouter()
const list = ref<string[]>([])
const listData = ref<any>({})
@ -112,21 +131,62 @@ const { toClipboard } = useClipboard()
const handleCopy = async () => {
try {
await toClipboard(props.value)
ElMessage({
message: 'copy success!',
type: 'success',
})
} catch (error) {
console.log(error)
}
}
const clickCopy = async (value: string) => {
try {
await toClipboard(value)
ElMessage({
message: 'copy success!',
type: 'success',
})
} catch (error) {
console.log(error)
}
}
const handleClick = (route: string) => {
props?.handleRouter && props?.handleRouter(route)
}
const jumpRouter = (route: string, i: number) => {
//
i !== 2 && router.push(`/tokens/${route}`)
// tokens Id ERC721
i === 2 &&
listData.value.tokenType === 'ERC721' &&
router.push(
`/VNFT/id=${listData.value.tokenId}?address=${listData.value.contractAddress}`
)
}
watchEffect(() => {
if (typeof props.value === 'object') {
let data = props.value[0]
let forValue
list.value = ['Form', 'To', 'For']
if (data.tokenType === 'ERC721') {
forValue = parseInt(data.tokenId)
} else {
forValue = `${props.value[0]?.amount}`
}
//
listData.value = {
Form: props.value[0]?.from,
To: props.value[0]?.to,
For: props.value[0]?.tokenId,
symbol: props.value[0]?.symbol,
Form: data?.from,
To: data?.to,
For: forValue,
symbol: data?.symbol,
tokenType: data?.tokenType,
tokenId: data?.tokenId,
contractAddress: data?.contractAddress,
}
console.log(data)
}
})
</script>

79
src/components/table/dBase/transactRow.vue

@ -0,0 +1,79 @@
<template>
<div
:class="last ? 'rounded-b-[10px]' : ''"
class="flex flex-1 flex-row bg-black-19191A hover:bg-black-272728 items-center py-[24px] px-[34px] cursor-pointer"
>
<div
class="flex flex-1 justify-start"
v-for="(item, index) in sequence"
:key="index"
>
<div
:class="
item === 'smartContract'
? 'bg-gray-303031 px-[12px] py-[4px] rounded-[4px]'
: ''
"
>
<span
v-if="item !== 'result'"
:class="colorSequence[index] || 'text-white'"
class="text-[14px] font-medium"
@click="handleClick(link?.[index], linkValue?.[index])"
>
{{ values[item] }}
</span>
<div
v-else
class="px-[12px] py-[4px] rounded-[4px] w-[87px] flex flex-row items-center"
:class="values.isSuccess ? 'bg-green-2EAA7D' : 'bg-red-C4403E'"
>
<Icons
:url="values.isSuccess ? 'check_circle' : 'cancel'"
:size="12"
/>
<span
:class="colorSequence[index] || 'text-white'"
class="text-[12px] font-medium ml-[2px]"
>{{ values[item] }}
</span>
</div>
</div>
</div>
</div>
<div
v-if="!last"
class="mx-[34px]"
style="border-bottom: 1px solid #3b3b3c"
/>
</template>
<script setup lang="ts">
import type { PropType } from 'vue'
import TableTypes from '../table'
import Icons from '@src/components/icons/index.vue'
import { useRouter } from 'vue-router'
const props = defineProps({
sequence: {
type: Array as PropType<TableTypes.tRow['sequence']>,
required: true,
},
values: {
type: Object as PropType<TableTypes.tRow['values']>,
required: true,
},
colorSequence: {
type: Array as PropType<TableTypes.tRow['colorSequence']>,
required: true,
},
link: Array,
linkValue: Array,
last: Boolean,
})
const router = useRouter()
const handleClick = (route: any, link: any) => {
route && router.replace(`/${route}/${props.values[link]}`)
}
</script>
<style lang="scss" scoped></style>

12
src/components/table/dBase/transfersRow.vue

@ -3,7 +3,12 @@
class="flex flex-1 flex-row justify-between items-center py-[16px] pl-[18px] border-b border-b-black-3B3B3C"
>
<div>
<p class="text-white text-[16px] font-medium">{{ title }}</p>
<p
class="text-white text-[16px] font-medium cursor-pointer"
@click="handleRouter(`/blocks/${blockNumber}`)"
>
{{ title }}
</p>
<p
class="text-gray-BBB text-[14px] font-normal mt-[12px] cursor-pointer"
@click="handleRouter(`/tx/${value1}`)"
@ -46,8 +51,9 @@
<script setup lang="ts">
import Icons from '@src/components/icons/index.vue'
import { useRouter } from 'vue-router'
defineProps({
const props = defineProps({
title: [String, Number],
blockNumber: [String, Number] as any,
value1: String,
value2: String,
value3: String,
@ -56,6 +62,8 @@ defineProps({
})
const router = useRouter()
const handleRouter = (route: string) => {
console.log(route)
console.log(props.blockNumber)
router.replace(route)
}
</script>

6
src/components/table/desktop/bkTable.vue

@ -93,7 +93,7 @@ const initBlock = async (page: number) => {
// websocket
const initWebSocket = () => {
ws.value = new WebSocket('ws://wallet-chaindata-api.weirui0755.com/websocket')
ws.value = new WebSocket('wss://apiasia.mbc.network/websocket')
ws.value.addEventListener('open', () => {
ws.value?.send(JSON.stringify({ type: 'add_block' }))
})
@ -105,6 +105,10 @@ const initWebSocket = () => {
...res.value[0],
timestamp: timeConvert(res.value[0]?.timestamp),
}
//
if (item?.number == currentData.value?.number) {
return
}
currentData.value = [item, ...currentData.value]
currentData.value.length = 10
} catch (error) {}

1
src/components/table/desktop/bkTableDetails.vue

@ -70,7 +70,6 @@ watchEffect(() => {
watchEffect(() => {
blockId.value = currentData.value?.number
})
const invariable = {
...detailsCollocate,
}

2
src/components/table/desktop/hpTable.vue

@ -18,7 +18,7 @@ const props = defineProps({
data: Array as any,
})
const thList = ['Txn Hash', 'From', 'To', 'Date / Time', 'Fee(MBC)']
const thList = ['Txn Hash', 'From', 'To', 'Date / Time', 'Fee (MBC)']
const sequence = ['txnHash', 'from', 'to', 'time', 'fee']
</script>

4
src/components/table/desktop/tokensTable.vue

@ -23,7 +23,7 @@
:key="item?.txnContractAddress + index"
>
<!-- :values="{ ...item, serialNumber: index + 1 }" -->
<bk-row
<tokens-row
:sequence="invariable.sequence"
:values="item"
:colorSequence="invariable.colorSequence"
@ -49,7 +49,7 @@
import { defineProps, reactive, ref, watchEffect } from 'vue'
import { Search } from '@element-plus/icons-vue'
import THeader from '../dBase/tHeader.vue'
import BkRow from '../dBase/bkRow.vue'
import TokensRow from '../dBase/tokensRow.vue'
import { tokensTableCollocate } from '../constant'
import { useRouter } from 'vue-router'
import { getFindTokenList } from '@src/api/TokensController'

18
src/components/table/desktop/transactDetails.vue

@ -2,20 +2,14 @@
<div
class="rounded-[10px] bg-black-19191A rounded-b-[10px] px-[34px] pt-[12px] pb-[28px]"
>
<div
v-for="(item, index) in invariable.labels"
:key="index"
@click="
invariable.links[index]
? handleClick(currentData?.[invariable.sequence[index]])
: ''
"
>
<div v-for="(item, index) in invariable.labels" :key="index">
<transact-details-row
:title="item"
:value="currentData?.[invariable.sequence[index]]"
:value-color="invariable.colorSequence[index]"
:is-copy="invariable.isCopys[index]"
:link="invariable.links[index]"
:handleRouter="invariable.links[index] ? handleClick : ''"
/>
</div>
</div>
@ -36,7 +30,7 @@ const invariable = {
const currentData = ref()
const router = useRouter()
const handleClick = (route: any) => {
router.replace(`/tokens/${route}`)
route && router.replace(route)
}
watchEffect(() => {
currentData.value = props.data
@ -46,9 +40,9 @@ watchEffect(() => {
)
invariable.sequence = invariable.sequence.filter((t) => t !== 'receiptList')
invariable.colorSequence = invariable.colorSequence.filter(
(t, i) => i !== 5
(t, i) => i !== 6
)
invariable.isCopys = invariable.isCopys.filter((t, i) => i !== 5)
invariable.isCopys = invariable.isCopys.filter((t, i) => i !== 6)
}
})
</script>

35
src/components/table/desktop/transactTable.vue

@ -16,15 +16,13 @@
/>
</template>
<template #default>
<div
v-for="(item, index) in currentData"
:key="item?.hash + index"
@click="routerLink(item?.txnHash)"
>
<bk-row
<div v-for="(item, index) in currentData" :key="item?.hash + index">
<transact-row
:sequence="invariable.sequence"
:values="item"
:colorSequence="invariable.colorSequence"
:link="invariable.links"
:linkValue="invariable.linkValue"
/>
</div>
</template>
@ -47,7 +45,7 @@
<script setup lang="ts">
import { reactive, ref, watchEffect } from 'vue'
import THeader from '../dBase/tHeader.vue'
import BkRow from '../dBase/bkRow.vue'
import TransactRow from '../dBase/transactRow.vue'
import { transactTableCollocate } from '../constant'
import { useRouter } from 'vue-router'
import { getFindTransactionListPage } from '@src/api/TransactionsController'
@ -85,21 +83,27 @@ const initBlock = async (page: number) => {
currentData.value = res.data.rows.map((item: any) => ({
...item,
hash: middleDecimal(item?.hash),
txnHash: item.hash,
txnHash: item?.hash,
from: middleDecimal(item?.from),
txnFrom: item?.from,
to: middleDecimal(item?.to),
txnTo: item?.to,
gasPrice: middleDecimal(item?.gasPrice),
isSuccess: item?.status === '0x1',
result: item?.status === '0x1' ? 'Success' : 'Faild',
timestamp: timeConvert(item?.timestamp),
}))
console.log(currentData.value)
//
loading.value = false
}
// websocket
const initWebSocket = () => {
ws.value = new WebSocket('ws://wallet-chaindata-api.weirui0755.com/websocket')
ws.value = new WebSocket('wss://apiasia.mbc.network/websocket')
// ws://wallet-chaindata-api.weirui0755.com/websocket
// ws.value = new WebSocket('ws://wallet-chaindata-api.weirui0755.com/websocket')
ws.value.addEventListener('open', () => {
ws.value?.send(JSON.stringify({ type: 'add_transaction' }))
@ -109,10 +113,14 @@ const initWebSocket = () => {
try {
const res = JSON.parse(e.data)
const item = res.value[0]
//
if (item?.number == currentData.value?.number) {
return
}
const value = {
...item,
hash: middleDecimal(item?.hash),
txnHash: item.hash,
txnHash: item?.hash,
from: middleDecimal(item?.from),
to: middleDecimal(item?.to),
gasPrice: middleDecimal(item?.gasPrice),
@ -136,10 +144,10 @@ watchEffect(() => {
if (window.screen.width < 1440) {
return
}
loading.value = true
initBlock(currentPage.value)
if (props?.isBlockWs && currentPage.value === 1) {
console.log('start ws')
loading.value = true
initWebSocket()
} else {
console.log('close ws')
@ -147,7 +155,10 @@ watchEffect(() => {
}
})
//
const routerLink = (id: string | number) => id && router.push(`/tx/${id}`)
const routerLink = (id: string | number) => {
console.log(id)
router.push(`/tx/${id}`)
}
</script>
<style lang="scss">

5
src/components/table/mBase/detailsRow.vue

@ -22,6 +22,7 @@
<script setup lang="ts">
import Icons from '@src/components/icons/index.vue'
import { ElMessage } from 'element-plus';
import useClipboard from 'vue-clipboard3'
const props = defineProps({
@ -36,6 +37,10 @@ const handleCopy = async () => {
const value = props.value?.toString() || ''
try {
await toClipboard(value)
ElMessage({
message: 'copy success!',
type: 'success',
})
} catch (error) {
console.log(error)
}

3
src/components/table/mBase/mobileCard.vue

@ -20,12 +20,13 @@
</template>
<script setup lang="ts">
import { defineProps } from 'vue'
import { defineProps, watchEffect } from 'vue'
import { bkTableCollocate } from '../constant'
import nowrapRow from './nowrapRow.vue'
defineProps({
cardData: Object as any,
})
const invariable = { ...bkTableCollocate }
</script>

8
src/components/table/mBase/tokensCard.vue

@ -7,7 +7,9 @@
class="flex flex-half min-w-6/12"
v-for="(item, index) in invariable.labels"
:key="index"
@click="routerLink(cardData.block)"
@click="
handleClick(invariable.links[index], invariable.linkValue[index])
"
>
<nowrap-row
:title="item"
@ -30,7 +32,9 @@ const props = defineProps({
const invariable = { ...tokensMobileCollocate }
const router = useRouter()
//
const routerLink = (id: string | number) => router.push(`/tokens/${id}`)
const handleClick = (route: any, link: any) => {
router.replace(`/${route}/${props.cardData[link]}`)
}
</script>
<style lang="scss" scoped></style>

8
src/components/table/mBase/transactCard.vue

@ -7,7 +7,9 @@
class="flex flex-half min-w-6/12"
v-for="(item, index) in invariable.labels"
:key="index"
@click="routerLink(cardData.block)"
@click="
handleClick(invariable.links[index], invariable.linkValue?.[index])
"
>
<nowrap-row
:title="item"
@ -32,7 +34,9 @@ const props = defineProps({
const invariable = { ...transactTableCollocate }
const router = useRouter()
//
const routerLink = (id: string | number) => router.push(`/tx/${id}`)
const handleClick = (route: any, link: any) => {
route && router.replace(`/${route}/${props.cardData[link]}`)
}
</script>
<style lang="scss" scoped></style>

23
src/components/table/mBase/transactDetailsRow.vue

@ -1,5 +1,5 @@
<template>
<div class="flex flex-col py-[16px]">
<div class="flex flex-col py-[16px]" @click="handleClick">
<div class="flex flex-1 flex-row max-w-[255px] items-center">
<Icons url="info" :size="14" />
<p class="ml-[7px] text-gray-BBB text-[14px] font-normal">{{ title }}</p>
@ -13,7 +13,7 @@
<div
class="flex flex-col pl-[20px]"
v-for="(item, index) in list"
:key="index + item"
:key="index"
>
<div class="flex flex-1 flex-row items-center mt-[15px]">
<p class="text-gray-BBB text-[14px] font-normal">
@ -65,14 +65,17 @@
<script setup lang="ts">
import Icons from '@src/components/icons/index.vue'
import { ElMessage } from 'element-plus'
import { ref, watchEffect } from 'vue'
import useClipboard from 'vue-clipboard3'
import { useRouter } from 'vue-router'
const props = defineProps({
title: String,
value: [String, Object] as any,
valueColor: String,
isCopy: Boolean,
link: String,
})
const list = ref<string[]>([])
const listData = ref<any>({})
@ -83,6 +86,10 @@ const handleCopy = async () => {
const value = props.value?.toString() || ''
try {
await toClipboard(value)
ElMessage({
message: 'copy success!',
type: 'success',
})
} catch (error) {
console.log(error)
}
@ -90,16 +97,26 @@ const handleCopy = async () => {
watchEffect(() => {
if (typeof props.value === 'object') {
let data = props.value[0]
let forValue
list.value = ['Form', 'To', 'For']
if (data.tokenType === 'ERC721') {
forValue = parseInt(data.tokenId)
}
//
listData.value = {
Form: props.value[0]?.from,
To: props.value[0]?.to,
For: props.value[0]?.tokenId,
For: forValue,
symbol: props.value[0]?.symbol,
}
}
})
const router = useRouter()
const handleClick = () => {
router.replace(`/${props.link}/${props.value}`)
}
</script>
<style scoped></style>

2
src/components/table/mobile/bkTable.vue

@ -71,7 +71,7 @@ const initBlock = async (page: number) => {
// websocket
const initWebSocket = () => {
ws.value = new WebSocket('ws://wallet-chaindata-api.weirui0755.com/websocket')
ws.value = new WebSocket('wss://apiasia.mbc.network/websocket')
ws.value.addEventListener('open', () => {
ws.value?.send(JSON.stringify({ type: 'add_block' }))
})

3
src/components/table/mobile/bkTableDetails.vue

@ -16,7 +16,7 @@
>
<details-row
:title="item"
:value="currentData[invariable.sequence[index]]"
:value="currentData?.[invariable.sequence?.[index]]?.toString()"
:value-color="invariable.colorSequence[index]"
:is-copy="invariable.isCopys[index]"
:is-last="index === invariable.labels.length - 1 ? true : false"
@ -72,6 +72,7 @@ const requestByBlockId = async (id: number) => {
// props.data
watchEffect(() => {
currentData.value = props.data
console.log(currentData.value)
})
//
watchEffect(() => {

2
src/components/table/mobile/tokensTable.vue

@ -13,7 +13,6 @@
v-for="(item, index) in currentData"
:key="index"
:card-data="item"
@click="routerLink(item.txnContractAddress)"
/>
<div
class="bk-pagination-m flex flex-row items-center justify-center pt-[32px]"
@ -59,7 +58,6 @@ const initBlock = async (page: number, search?: string) => {
search: search || '',
}
const res = await getFindTokenList(params)
console.log('123', res)
//
paginationState.totalPage =
Math.floor(res.data.total / invariable.pageSize + 1) * invariable.pageSize

1
src/components/table/mobile/transactDetails.vue

@ -6,6 +6,7 @@
v-for="(item, index) in invariable.labels"
:key="index"
:title="item"
:link="invariable.links[index]"
:value="currentData?.[invariable.sequence[index]]"
:value-color="invariable.colorSequence[index]"
:is-copy="invariable.isCopys[index]"

14
src/components/table/mobile/transactTable.vue

@ -4,7 +4,6 @@
v-for="(item, index) in currentData"
:key="index"
:card-data="item"
@click="routerLink(item?.txnHash)"
/>
<div
class="bk-pagination-m flex flex-row items-center justify-center pt-[32px]"
@ -62,13 +61,14 @@ const initBlock = async (page: number) => {
currentData.value = res.data.rows.map((item: any) => ({
...item,
hash: middleDecimal(item?.hash),
txnHash: item.hash,
txnHash: item?.hash,
from: middleDecimal(item?.from),
txnFrom: item?.from,
to: middleDecimal(item?.to),
txnTo: item?.to,
gasPrice: middleDecimal(item?.gasPrice),
isSuccess: item?.status === '0x1',
result: item?.status === '0x1' ? 'Success' : 'Faild',
// middleDecimal
timestamp: timeConvert(item?.timestamp),
}))
//
@ -77,7 +77,7 @@ const initBlock = async (page: number) => {
// websocket
const initWebSocket = () => {
ws.value = new WebSocket('ws://wallet-chaindata-api.weirui0755.com/websocket')
ws.value = new WebSocket('wss://apiasia.mbc.network/websocket')
ws.value.addEventListener('open', () => {
ws.value?.send(JSON.stringify({ type: 'add_transaction' }))
@ -90,9 +90,11 @@ const initWebSocket = () => {
const value = {
...item,
hash: middleDecimal(item?.hash),
txnHash: item.hash,
txnHash: item?.hash,
from: middleDecimal(item?.from),
txnFrom: item?.from,
to: middleDecimal(item?.to),
txnTo: item?.to,
gasPrice: middleDecimal(item?.gasPrice),
isSuccess: item?.status === '0x1',
result: item?.status === '0x1' ? 'Success' : 'Faild',
@ -125,7 +127,7 @@ watchEffect(() => {
}
})
//
const routerLink = (id: string | number) => router.push(`/tx/${id}`)
// const routerLink = (id: string | number) => router.push(`/tx/${id}`)
</script>
<style lang="scss">

22
src/pages/BitcNFt/cards.vue

@ -11,7 +11,9 @@
>
<p class="text-white mobile:text-[16px] font-medium">{{ value }}</p>
<div class="flex flex-row mobile:justify-end mobile:mt-[12px]">
<Icons :url="'copyAddress'" :size="32" />
<div @click="handleCopy">
<Icons :url="'copyAddress'" :size="32" />
</div>
<div @click="open">
<Icons :url="'qrCode'" :size="32" class="ml-[16px]" />
</div>
@ -57,8 +59,10 @@
<script setup lang="ts">
import Icons from '@src/components/icons/index.vue'
import { ElMessageBox } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import Qrcode from 'qrcode'
import useClipboard from 'vue-clipboard3'
const props = defineProps({
title: String,
value: String,
@ -80,6 +84,20 @@ let open = async () => {
customClass: 'bg-modal-wrap',
})
}
//
const { toClipboard } = useClipboard()
const handleCopy = async () => {
try {
await toClipboard(props?.value as string)
ElMessage({
message: 'copy success!',
type: 'success',
})
} catch (error) {
console.log(error)
}
}
</script>
<style lang="scss" scoped>

79
src/pages/BitcNFt/centerContent.vue

@ -15,7 +15,10 @@
<div class="details-tabs w-full">
<el-tabs v-model="active" class="w-full">
<el-tab-pane label="Token Transfers" name="tokenTransfers">
<div class="flex flex-1 justify-center items-center h-[210px]">
<div
class="flex flex-1 justify-center items-center h-[210px]"
v-if="transfersRows.length == 0"
>
<p class="text-white text-[14px] font-normal opacity-80">
There are no transactions for this Token Transfers.
</p>
@ -27,12 +30,20 @@
<transfers-row
v-for="(item, index) in transfersRows"
:key="`${index}${item.title}`"
:blockNumber="item.blockNumber"
:title="item.title"
:value1="item.value1"
:value2="item.value2"
:value3="item.value3"
:state="item.state"
/>
<upper-lower-switch
:current="`page${pageTransactions}`"
:class="'mt-[20px] justify-end'"
:space-class="''"
:prev="handleTransactionsPrev"
:next="handleTransactionsNext"
/>
</div>
</el-tab-pane>
<!-- Token Holders -->
@ -46,7 +57,7 @@
</p>
</div>
<div
class="mt-[10px] rounded-[10px] px-[34px] pb-[30px] mobile:hidden"
class="mt-[10px] rounded-[10px] px-[34px] pb-[30px]"
v-if="holdrersRows.length != 0"
>
<holders-row
@ -76,6 +87,7 @@ import transfersRow from '../VNFT/transfersRow.vue'
import Cards from './cards.vue'
import { getFindReceiptByAddressPage } from '@src/api/TransactionsController'
import { useRoute } from 'vue-router'
import { getFindReceiptByTokenPage } from '@src/api/TokensController'
const active = ref('tokenTransfers')
const route = useRoute()
@ -100,6 +112,10 @@ const cardOptions = reactive({
})
const holdrersRows = ref<any>([])
const transfersRows = ref<any>([])
let currentHash = ref('')
let pageTransactions = ref(1)
//
const requestInfo = async (address: string) => {
const params = {
@ -132,31 +148,72 @@ const requestHolders = async (address: string) => {
})
}
// Token Transfers
const requestTransfers = async (address: string) => {
const requestTransfers = async (address: string, page?: any) => {
const params = {
address: address,
pageNum: 1,
pageSize: 10,
filterType: 'all',
contractAddress: address,
pageNum: page || 1,
pageSize: 5,
}
const res = await getFindReceiptByTokenPage(params)
if (res.data.rows.length == 0) {
return false
}
const res = await getFindReceiptByAddressPage(params)
transfersRows.value = res.data.rows.map((item: any) => {
return {
title: `Block #${item.blockNumber}`,
value1: item?.blockHash,
blockNumber: item?.blockNumber,
value1: item?.transactionHash,
value2: item?.from,
value3: item?.to,
state: item?.status === '0x1' ? 'Success' : 'Faild',
}
})
console.log(res)
return true
}
watchEffect(() => {
let address = route.path.split('/')?.[2]
if (route.path.split('/')?.[1] != 'BitcNFt') {
return
}
let address = route.path.split('/')?.[2] || undefined
if (address == undefined) {
return
}
currentHash.value = address
requestInfo(address)
requestHolders(address)
requestTransfers(address)
})
//
const handleTransactionsPrev = async () => {
if (pageTransactions.value == 1) {
return
}
if (currentHash.value == '' || currentHash.value == undefined) {
return
}
const res = await requestTransfers(
currentHash.value,
pageTransactions.value - 1
)
if (res) {
pageTransactions.value = pageTransactions.value - 1
}
}
//
const handleTransactionsNext = async () => {
if (currentHash.value == '' || currentHash.value == undefined) {
return
}
const res = await requestTransfers(
currentHash.value,
pageTransactions.value + 1
)
if (res) {
pageTransactions.value = pageTransactions.value + 1
}
}
</script>
<style scoped></style>

17
src/pages/BitcNFt/holdersRow.vue

@ -3,11 +3,18 @@
class="flex flex-1 flex-row justify-start items-center py-[16px] pl-[18px] border-b border-b-black-3B3B3C"
>
<div>
<p class="text-white text-[16px] font-medium">{{ title }}</p>
<p
class="text-white text-[16px] font-medium cursor-pointer"
@click="handleRouter(`/tokens/${title}`)"
>
{{ title }}
</p>
<div
class="text-gray-BBB text-[14px] font-normal flex flex-row items-center mt-[12px]"
>
<p class="mr-[10px]">{{ value1 }}</p>
<p class="mr-[10px]">
{{ value1 }}
</p>
<p>{{ value2 }}</p>
<p class="ml-[10px]">{{ value3 }}</p>
</div>
@ -16,6 +23,8 @@
</template>
<script setup lang="ts">
import { useRouter } from 'vue-router'
defineProps({
title: String,
value1: String,
@ -23,6 +32,10 @@ defineProps({
value3: String,
value4: String,
})
const router = useRouter()
const handleRouter = (route: string) => {
router.replace(route)
}
</script>
<style scoped></style>

8
src/pages/HomePage/index.vue

@ -45,7 +45,7 @@
</p>
<div
class="flex flex-row justify-center items-center bg-black-19191A rounded-full desktop:py-[8px] desktop:px-[14px] mobile:py-[6px] mobile:px-[15px] cursor-pointer"
@click="jumpRoute('blocks')"
@click="jumpRoute('/tx')"
>
<p
class="text-white font-medium desktop:text-[14px] mobile:text-[12px]"
@ -95,7 +95,7 @@ let tableData = ref([])
//
const overview = reactive([
{
label: 'Block',
label: 'Blocks',
value: '',
},
{
@ -119,7 +119,7 @@ const initRequist = async () => {
//
const res = await getHomePageList()
overview[1].value = res.data.totalTransactions
overview[2].value = res.data.averageBlockTime
overview[2].value = `${res.data.averageBlockTime} s`
// tokens
const tokenRes = await getFindTokenList({})
overview[3].value = tokenRes.data.total
@ -143,7 +143,7 @@ const initRequist = async () => {
}
// websocket
const initWebSocket = () => {
ws.value = new WebSocket('ws://wallet-chaindata-api.weirui0755.com/websocket')
ws.value = new WebSocket('wss://apiasia.mbc.network/websocket')
ws.value.addEventListener('open', () => {
ws.value?.send(JSON.stringify({ type: 'add_block' }))

80
src/pages/TableBlock/Block/details.vue

@ -44,11 +44,19 @@
v-for="(item, index) in rowsData"
:key="index + item.title"
:title="item.title"
:blockNumber="item?.blockNumber"
:value1="item.value1"
:value2="item.value2"
:value3="item.value3"
:state="item.state"
/>
<upper-lower-switch
:current="`page${page}`"
:class="'mt-[20px] justify-end'"
:space-class="''"
:prev="handlePrev"
:next="handleNext"
/>
</div>
</el-tab-pane>
<!-- 待扩展 -->
@ -72,42 +80,68 @@ import BkDesktopDetails from '@src/components/table/desktop/bkTableDetails.vue'
import BkMobileDetails from '@src/components/table/mobile/bkTableDetails.vue'
import router from '@src/routes'
import { onMounted, ref } from 'vue'
import { onMounted, ref, watchEffect } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const active = ref('Block')
let detailsData = ref([])
let rowsData = ref<any>([])
let currentHash = ref('')
let page = ref(1)
const initRequest = async (hash: string) => {
//
const res = await getBlock({ hash: hash })
let blockp = {}
if (hash != undefined && /^-{0,1}\d*\.{0,1}\d+$/.test(hash)) {
// id
blockp = {
number: hash,
}
} else {
// hash
blockp = {
hash: hash,
}
}
const res = await getBlock(blockp)
detailsData.value = res.data
console.log(detailsData.value)
currentHash.value = res?.data?.number
requestDetails(res?.data?.number)
}
const requestDetails = async (id: any, page?: any) => {
// numberTransactions
const params = {
number: res?.data?.number,
pageNum: 1,
pageSize: 20,
number: id,
pageNum: page || 1,
pageSize: 5,
}
const rows = await getFindTransactionListPage(params)
console.log(rows.data)
// rows.data.rows
if (rows.data.rows.length == 0) {
return false
}
rowsData.value = rows.data.rows.map((item: any) => {
return {
...item,
title: `Block #${item.blockNumber}`,
value1: item?.blockHash || '123321',
blockNumber: item?.blockNumber,
value1: item?.hash,
value2: item?.from || 'hhh',
value3: item?.to || 'to',
state: item?.status === '0x1' ? 'Success' : 'Faild',
}
})
return true
}
onMounted(() => {
// hash hash
let hash = route.path.split('/')?.[2]
if (!hash) {
watchEffect(() => {
//
let hash = route.path.split('/')?.[2] || undefined
if (hash == undefined) {
return
}
initRequest(hash)
@ -115,6 +149,30 @@ onMounted(() => {
// 退
const goBack = () => router.replace('/blocks')
//
const handlePrev = async () => {
if (page.value == 1) {
return
}
if (currentHash.value == '' || currentHash.value == undefined) {
return
}
const res = await requestDetails(currentHash.value, page.value - 1)
if (res) {
page.value = page.value - 1
}
}
//
const handleNext = async () => {
if (currentHash.value == '' || currentHash.value == undefined) {
return
}
const res = await requestDetails(currentHash.value, page.value + 1)
if (res) {
page.value = page.value + 1
}
}
</script>
<style lang="scss">

110
src/pages/TableBlock/Tokens/details.vue

@ -68,12 +68,20 @@
<transfers-row
v-for="(item, index) in transactionsData"
:key="`${index}${item.title}`"
:blockNumber="item.blockNumber"
:title="item.title"
:value1="item.value1"
:value2="item.value2"
:value3="item.value3"
:state="item.state"
/>
<upper-lower-switch
:current="`page${pageTransactions}`"
:class="'mt-[20px] justify-end'"
:space-class="''"
:prev="handleTransactionsPrev"
:next="handleTransactionsNext"
/>
</div>
<div
class="mt-[10px] rounded-[10px] px-[20px] desktop:hidden pb-[20px] w-full"
@ -106,6 +114,7 @@
<transfers-row
v-for="(item, index) in tokensData"
:key="`${index}${item.title}`"
:blockNumber="item.blockNumber"
:title="item.title"
:value1="item.value1"
:value2="item.value2"
@ -144,12 +153,20 @@
<transfers-row
v-for="(item, index) in internalData"
:key="`${index}${item.title}`"
:blockNumber="item.blockNumber"
:title="item.title"
:value1="item.value1"
:value2="item.value2"
:value3="item.value3"
:state="item.state"
/>
<upper-lower-switch
:current="`page${pageInternal}`"
:class="'mt-[20px] justify-end'"
:space-class="''"
:prev="handleInternalPrev"
:next="handleInternalNext"
/>
</div>
<!-- 移动端 -->
<div
@ -160,6 +177,7 @@
v-for="(item, index) in internalData"
:key="`${index}${item.title}`"
:title="item.title"
:blockNumber="item?.blockNumber"
:value1="item.value1"
:value2="item.value2"
:value3="item.value3"
@ -193,43 +211,57 @@ let internalData = ref<any>([])
let transactionsData = ref<any>([])
let tokensData = ref<any>([])
let currentHash = ref('')
let pageInternal = ref(1)
let pageTransactions = ref(1)
// internal
const requestInternal = async (address: string) => {
const requestInternal = async (address: string, page?: any) => {
const params = {
address,
isContract: 1,
pageNum: 1,
pageSize: 10,
pageNum: page || 1,
pageSize: 5,
}
const res = await getFindTransactionListPage(params)
if (res.data.rows.length == 0) {
return false
}
internalData.value = res.data.rows.map((item: any) => {
return {
title: `Block #${item.blockNumber}`,
blockNumber: item?.blockNumber,
value1: item?.hash,
value2: item?.from,
value3: item?.to,
state: item?.status === '0x1' ? 'Success' : 'Faild',
}
})
return true
}
// transactionsData
const requestTransactions = async (address: string) => {
const requestTransactions = async (address: string, page?: any) => {
const params = {
address,
isContract: 2,
pageNum: 1,
pageSize: 10,
pageNum: page,
pageSize: 5,
}
const res = await getFindTransactionListPage(params)
if (res.data.rows.length == 0) {
return false
}
transactionsData.value = res.data.rows.map((item: any) => {
return {
title: `Block #${item.blockNumber}`,
title: `Block #${item?.blockNumber}`,
blockNumber: item?.blockNumber,
value1: item?.hash,
value2: item?.from,
value3: item?.to,
state: item?.status === '0x1' ? 'Success' : 'Faild',
}
})
return true
}
// tokensData
const rqeuestTokensData = async (address: string) => {
@ -243,7 +275,8 @@ const rqeuestTokensData = async (address: string) => {
tokensData.value = res.data.rows.map((item: any) => {
return {
title: `Block #${item.blockNumber}`,
value1: item?.blockHash,
blockNumber: item?.blockNumber,
value1: item?.transactionHash,
value2: item?.from,
value3: item?.to,
state: item?.status === '0x1' ? 'Success' : 'Faild',
@ -256,7 +289,11 @@ watchEffect(() => {
return
}
//
let address = route.path.split('/')?.[2]
let address = route.path.split('/')?.[2] || undefined
if (address == undefined) {
return
}
currentHash.value = address
// tab
requestInternal(address)
requestTransactions(address)
@ -269,6 +306,61 @@ const goBack = () => router.replace('/tokens')
const changeTabs = (current: string) => {
active.value = current
}
//
const handleInternalPrev = async () => {
if (pageInternal.value == 1) {
return
}
if (currentHash.value == '' || currentHash.value == undefined) {
return
}
const res = await requestInternal(currentHash.value, pageInternal.value - 1)
if (res) {
pageInternal.value = pageInternal.value - 1
}
}
//
const handleInternalNext = async () => {
if (currentHash.value == '' || currentHash.value == undefined) {
return
}
const res = await requestInternal(currentHash.value, pageInternal.value + 1)
if (res) {
pageInternal.value = pageInternal.value + 1
}
}
//
const handleTransactionsPrev = async () => {
if (pageTransactions.value == 1) {
return
}
if (currentHash.value == '' || currentHash.value == undefined) {
return
}
const res = await requestTransactions(
currentHash.value,
pageTransactions.value - 1
)
if (res) {
pageTransactions.value = pageTransactions.value - 1
}
}
//
const handleTransactionsNext = async () => {
if (currentHash.value == '' || currentHash.value == undefined) {
return
}
const res = await requestTransactions(
currentHash.value,
pageTransactions.value + 1
)
if (res) {
pageTransactions.value = pageTransactions.value + 1
}
}
</script>
<style lang="scss">

48
src/pages/TableBlock/Transactions/details.vue

@ -37,18 +37,26 @@
</p>
</div>
<div
class="mt-[10px] rounded-[10px] px-[34px] pb-[30px] mobile:hidden"
class="mt-[10px] rounded-[10px] px-[34px] pb-[30px]"
v-if="rowsData.length != 0"
>
<transfers-row
v-for="(item, index) in rowsData"
:key="`${index}${item.title}`"
:title="item.title"
:blockNumber="item.blockNumber"
:value1="item.value1"
:value2="item.value2"
:value3="item.value3"
:state="item.state"
/>
<upper-lower-switch
:current="`page${page}`"
:class="'mt-[20px] justify-end'"
:space-class="''"
:prev="handlePrev"
:next="handleNext"
/>
</div>
</el-tab-pane>
<!-- logs -->
@ -100,7 +108,7 @@ import Logs from './logs.vue'
import DesktopTransactDetails from '@src/components/table/desktop/transactDetails.vue'
import MobileTransactDetails from '@src/components/table/mobile/transactDetails.vue'
import { onMounted, ref, watchEffect } from 'vue'
import { ref, watchEffect } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { getFindReceiptByTokenPage } from '@src/api/TokensController'
import { timeConvert } from '@src/utils/string'
@ -113,6 +121,7 @@ const currentData = ref<any>()
let logsData = ref<any>()
let rowsData = ref<any>([])
// transactions
let currentHash = ref('')
let page = ref(1)
//
@ -128,6 +137,9 @@ const requestDetails = async (hash: string) => {
result: data?.status === '0x1' ? 'Success' : 'Faild',
time: timeConvert(data?.timestamp),
values: `${data?.amount} ${data?.symbol}`,
gas: parseInt(data?.gas).toString(),
gasPrice: parseInt(data?.gasPrice).toString(),
blockNumber: data?.blockNumber.toString(),
}
// to
requestTokens(res.data.to)
@ -149,15 +161,18 @@ const requestLogs = async (hash: string) => {
const requestTokens = async (address: string) => {
const params = {
pageNum: page.value,
pageSize: 20,
tokenId: '',
pageSize: 5,
contractAddress: address,
}
const res = await getFindReceiptByTokenPage(params)
// rowsData
if (res.data.rows.length == 0) {
return
}
rowsData.value = res.data.rows.map((item: any) => {
return {
title: `Block #${item.blockNumber}`,
blockNumber: item?.blockNumber,
value1: item?.transactionHash,
value2: item?.from,
value3: item?.to,
@ -166,15 +181,36 @@ const requestTokens = async (address: string) => {
})
}
watchEffect(() => {
let hash = route.path.split('/')?.[2]
if (hash == 'undefined') {
let hash = route.path.split('/')?.[2] || undefined
if (hash == undefined) {
return
}
currentHash.value = hash
requestDetails(hash)
requestLogs(hash)
})
// 退
const goBack = () => router.replace('/tx')
//
const handlePrev = () => {
if (page.value == 1) {
return
}
page.value = page.value - 1
if (currentHash.value == '' || currentHash.value == undefined) {
return
}
requestDetails(currentHash.value)
}
//
const handleNext = () => {
page.value = page.value + 1
if (currentHash.value == '' || currentHash.value == undefined) {
return
}
requestDetails(currentHash.value)
}
</script>
<style lang="scss">

7
src/pages/TableBlock/Transactions/logs.vue

@ -46,10 +46,11 @@ const props = defineProps({
})
const logsData = ref()
watchEffect(() => {
logsData.value = props.data?.[0]
logsData.value = {
...props.data?.[0],
data: parseInt(props.data?.[0].data).toString(),
}
})
console.log(props.data)
</script>
<style scoped></style>

44
src/pages/VNFT/centerContent.vue

@ -4,7 +4,7 @@
>
<Cards
:title="cardOptions.title"
:value="'Token ID:' + id"
:value="`Token ID: ${currentTokenId}`"
:options="cardOptions.options"
:total-supply="cardOptions.totalSupply"
:url="cardOptions.url"
@ -22,7 +22,7 @@
Token Transfers
</p>
<div
class="mt-[10px] bg-black-2B2B2C rounded-[10px] px-[34px] py-[30px] mobile:hidden"
class="mt-[10px] bg-black-2B2B2C rounded-[10px] px-[34px] py-[30px]"
>
<transfers-row
v-for="(item, index) in transfersRows"
@ -52,24 +52,18 @@
</template>
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { reactive, ref, watchEffect } from 'vue'
import Cards from '../BitcNFt/cards.vue'
import transfersRow from './transfersRow.vue'
import mobileRow from './mobileRow.vue'
import UpperLowerSwitch from '@src/components/base/UpperLowerSwitch.vue'
import {
getContractAddressInfoList,
getContractHoldingQuantity,
} from '@src/api/AddressController'
import { getFindReceiptByAddressPage } from '@src/api/TransactionsController'
import {
getFindReceiptByTokenPage,
getFindTokenInfo,
} from '@src/api/TokensController'
import { useRoute } from 'vue-router'
const active = ref('tokenTransfers')
const value = '0x0d2b4411d55e8684fa51b84bc3d2903a3341c2e9'
const id = '0x0000000000000000000000000000000000000000000000000000000000000006'
const route = useRoute()
const cardOptions = reactive({
title: '',
options: [
@ -87,11 +81,14 @@ const cardOptions = reactive({
})
const holdrersRows = ref<any>([])
const transfersRows = ref<any>([])
const currentTokenId = ref('')
//
const requestInfo = async () => {
const requestInfo = async (tokenId: string, address: string) => {
const params = {
tokenId: id,
contractAddress: value,
tokenId: tokenId,
contractAddress: address,
}
const res = await getFindTokenInfo(params)
const { data } = res
@ -104,12 +101,11 @@ const requestInfo = async () => {
// cardOptions.options[2].value = data.transfers
}
// Token Transfers
const requestTransfers = async () => {
const requestTransfers = async (address: string) => {
const params = {
contractAddress: value,
contractAddress: address,
pageNum: 1,
pageSize: 10,
tokenId: id,
}
const res = await getFindReceiptByTokenPage(params)
transfersRows.value = res.data.rows.map((item: any) => {
@ -123,9 +119,17 @@ const requestTransfers = async () => {
})
console.log(res)
}
onMounted(() => {
requestInfo()
requestTransfers()
watchEffect(() => {
let path = route.fullPath.split('/')[2] || undefined
let tokenId = path?.split('?')[0].split('=')[1] || undefined
let address = path?.split('?')[1].split('=')[1] || undefined
if (address == undefined || tokenId == undefined) {
return
}
currentTokenId.value = parseInt(tokenId).toString()
requestInfo(tokenId, address)
requestTransfers(address)
})
</script>

34
src/pages/VNFT/transfersRow.vue

@ -3,16 +3,34 @@
class="flex flex-1 flex-row justify-between items-center py-[16px] pl-[18px] border-b border-b-black-3B3B3C"
>
<div>
<p class="text-white text-[16px] font-medium">{{ title }}</p>
<p class="text-gray-BBB text-[14px] font-normal mt-[12px]">
<p
class="text-white text-[16px] font-medium cursor-pointer"
@click="handleRouter(`/blocks/${blockNumber}`)"
>
{{ title }}
</p>
<p
class="text-gray-BBB text-[14px] font-normal mt-[12px] cursor-pointer"
@click="handleRouter(`/tx/${value1}`)"
>
{{ value1 }}
</p>
<div
class="text-gray-BBB text-[14px] font-normal flex flex-row items-center mt-[12px]"
>
<p class="mr-[10px]">{{ value2 }}</p>
<p
class="mr-[10px] cursor-pointer"
@click="handleRouter(`/tokens/${value2}`)"
>
{{ value2 }}
</p>
<Icons url="chevron_right" :size="16" />
<p class="ml-[10px]">{{ value3 }}</p>
<p
class="ml-[10px] cursor-pointer"
@click="handleRouter(`/tokens/${value3}`)"
>
{{ value3 }}
</p>
</div>
</div>
<div
@ -32,13 +50,19 @@
<script setup lang="ts">
import Icons from '@src/components/icons/index.vue'
defineProps({
import { useRouter } from 'vue-router'
const props = defineProps({
title: String,
blockNumber: [String, Number] as any,
value1: String,
value2: String,
value3: String,
state: String,
})
const router = useRouter()
const handleRouter = (route: string) => {
router.replace(route)
}
</script>
<style scoped></style>

14
src/routes.ts

@ -7,7 +7,7 @@ import BlockDetails from './pages/TableBlock/Block/details.vue'
import transactDetails from './pages/TableBlock/Transactions/details.vue'
import tokensDetails from './pages/TableBlock/Tokens/details.vue'
import BitcNFT from './pages/BitcNFt/index.vue'
import BitcNFt from './pages/BitcNFt/index.vue'
import AliasVNFT from './pages/VNFT/index.vue'
const routes: VueRouter.RouteRecordRaw[] = [
@ -64,12 +64,12 @@ const routes: VueRouter.RouteRecordRaw[] = [
],
},
{
path: '/BitcNFT',
component: BitcNFT,
path: '/BitcNFt',
component: BitcNFt,
children: [
{
path: '/BitcNFT/:id',
component: BitcNFT,
path: '/BitcNFt/:id',
component: BitcNFt,
},
],
},
@ -91,4 +91,8 @@ const router = VueRouter.createRouter({
routes,
})
router.afterEach(() => {
window.scrollTo(0, 0)
})
export default router

2
src/utils/string.ts

@ -9,5 +9,5 @@ export const middleDecimal = (char: string) => {
}
export const timeConvert = (time: number) => {
return dayjs().format('YYYY-MM-DD hh:mm:ss')
return dayjs(time).format('YYYY-MM-DD HH:mm:ss')
}

2
vite.config.ts

@ -31,7 +31,7 @@ export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://wallet-chaindata-api.weirui0755.com/api', //实际请求地址
target: 'https://apiasia.mbc.network/api', //实际请求地址
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},

Loading…
Cancel
Save