| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552 |
- <template>
- <div class="table-container">
- <v-card elevation="0">
- <!-- 表格上功能区 -->
- <v-card-title>
- <v-container id="dataTableHeader">
- <v-row>
- <v-col cols="4">
- {{ page.name }}
- </v-col>
- <v-col cols="8">
- <v-text-field hide-details single-line label="Local Search" append-icon="mdi-magnify"
- v-model="table.search"/>
- </v-col>
- </v-row>
- </v-container>
- </v-card-title>
- <!-- 顶部分页 -->
- <div class="mt-2">
- <v-row>
- <v-col cols="2"></v-col>
- <v-col cols="2">
- <v-text-field required type="number" label="page" v-model="tempPage" @change="inputPageNum"/>
- </v-col>
- <v-col cols="4">
- <v-pagination color="teal" :disabled="table.loading" :length="table.pageLength" v-model="table.pageNum"
- @input="generateTableDataAgain"></v-pagination>
- </v-col>
- </v-row>
- </div>
- <!-- 表格主体 -->
- <v-data-table calculate-widths multi-sort hide-default-footer
- class="history-table"
- @current-items="currentItems"
- @input="input"
- @item-selected="itemSelected"
- @item-expanded="itemExpanded"
- @page-count="pageCount"
- @pagination="pagination"
- @toggle-select-all="toggleSelectAll"
- @update:expanded="updateExpanded"
- @update:group-by="updateGroupBy"
- @update:group-desc="updateGroupEesc"
- @update:items-per-page="updateItemsPerPage"
- @update:multi-sort="updateMultiSort"
- @update:must-sort="updateMustSort"
- @update:options="updateOptions"
- @update:page="updatePage"
- @update:sort-by="updateSortBy"
- @update:sort-desc="updateSortDesc"
- @toggle="toggle"
- @dblclick:row="dblclickRow"
- :group-by="table.groupBy" :group-desc="table.groupDesc"
- :headers="table.headers" :items="table.data" :search="table.search" :loading="table.loading"
- :items-per-page="table.pageSize"
- :sort-by="table.sortBy" :sort-desc="table.sortDesc">
- <!-- 操作区 -->
- <template v-slot:item.option="{ item }">
- <div>
- <v-row>
- <v-col cols="5">
- <v-btn large icon elevation="0" color="primary" @click="editItem(item)">
- <v-icon>mdi-table-edit</v-icon>
- </v-btn>
- </v-col>
- </v-row>
- </div>
- </template>
- <!-- Block -->
- <template v-slot:item.block="{ item }">
- <div>
- {{ item.block }}
- </div>
- </template>
- <!-- Hash -->
- <template v-slot:item.hash="{ item }">
- <v-btn v-if="item.hash.indexOf('0x') !== -1" outlined text target="_blank"
- @click="httpKit.jumpToExplorer(item.hash, 'tx')">
- {{ hashKit.head5(item.hash) + '..' }}
- </v-btn>
- <v-chip v-else label target="_blank">
- {{ hashKit.head5(item.hash) + '..' }}
- </v-chip>
- </template>
- <!-- From -->
- <template v-slot:item.from="{ item }">
- <v-chip v-if="!item.fromName" label color="indigo lighten-3" @click="httpKit.jumpToExplorer(item.to)">
- {{ hashKit.headAndEnd2(item.from) }}
- </v-chip>
- <v-chip v-else label color="green lighten-3" target="_blank" @click="httpKit.jumpToExplorer(item.from)">
- {{ item.fromName }}
- </v-chip>
- </template>
- <!-- to -->
- <template v-slot:item.to="{ item }">
- <v-chip v-if="!item.toName" label color="indigo lighten-4" @click="httpKit.jumpToExplorer(item.to)">
- {{ hashKit.headAndEnd2(item.to) }}
- </v-chip>
- <v-chip v-else label color="indigo lighten-4" @click="httpKit.jumpToExplorer(item.to)">
- {{ item.toName }}
- </v-chip>
- </template>
- <template v-slot:item.type="{ item }">
- <div v-if="item.type !== undefined && item.type !== ''">
- {{ item.type }}
- </div>
- <div v-else>
- [type]
- </div>
- </template>
- <template v-slot:item.index="{ item }">
- <div v-if="item.index !== undefined">
- {{ item.index }}
- </div>
- <div v-else>
- [index]
- </div>
- </template>
- <template v-slot:item.status="{ item }">
- <div v-if="item.status !== undefined">
- {{ item.status }}
- </div>
- <div v-else>
- [status]
- </div>
- </template>
- <template v-slot:item.ping="{ item }">
- <div v-if="item.ping !== undefined">
- {{ item.ping }}
- </div>
- <div v-else>
- [ping]
- </div>
- </template>
- <template v-slot:item.isMev="{ item }">
- <BooleanViewer :value="item.isMev"></BooleanViewer>
- </template>
- <template v-slot:item.isBot="{ item }">
- <BooleanViewer :value="item.isBot"></BooleanViewer>
- </template>
- <template v-slot:item.maybeBot="{ item }">
- <BooleanViewer :value="item.maybeBot"></BooleanViewer>
- </template>
- <template v-slot:item.timestamp="{ item }">
- {{ formatTimeBySixBitTimestamp(item.timestamp) }}
- </template>
- <template v-slot:item.comment="{ item }">
- <div v-if="item.comment">
- <span class="memo-span">{{ item.comment }}</span>
- </div>
- <div v-else>
- [comment]
- </div>
- </template>
- <!--tradeInfo-->
- <template v-slot:item.transferList="{ item }">
- <div v-if="page.name === 'Pending Page'">
- <div class="tradeInfoBtn" @click="showTradeInfo(item)">
- <v-chip v-for="tokenAddress in item.tokenAddressList" :key='tokenAddress'
- :color="item.tokenMap[tokenAddress] ? hashKit.generateColorByHash(tokenAddress) : undefined"
- class="tokenChip">
- {{
- item.tokenMap[tokenAddress] ? item.tokenMap[tokenAddress] : '**' + hashKit.headAndEnd2(tokenAddress)
- }}
- </v-chip>
- </div>
- </div>
- <div v-else>
- <TradeInfo :item="item"></TradeInfo>
- </div>
- </template>
- </v-data-table>
- <!-- 底部分页 -->
- <div class="mt-2">
- <v-row>
- <v-col cols="2"></v-col>
- <v-col cols="2">
- <v-text-field type="number" required label="page" v-model="tempPage" @change="inputPageNum"/>
- </v-col>
- <v-col cols="4">
- <v-pagination :disabled="table.loading" :length="table.pageLength" v-model="table.pageNum"
- @input="generateTableDataAgain"></v-pagination>
- </v-col>
- </v-row>
- </div>
- </v-card>
- <!-- 展示transfer的详情 -->
- <v-dialog v-model="transferDetailsDialog.visible" max-width="800">
- <v-card elevation="0">
- <v-card-title>交易详情</v-card-title>
- <v-card-text>
- <TradeInfo :item="transferDetailsDialog.data"></TradeInfo>
- </v-card-text>
- <v-card-actions>
- <v-spacer></v-spacer>
- <v-btn text color="primary" @click="transferDetailsDialog.visible = false">我知道了</v-btn>
- </v-card-actions>
- </v-card>
- </v-dialog>
- <!-- 编辑框 -->
- <v-dialog v-model="editDialog.visible" max-width="1200">
- <v-card elevation="0">
- <v-card-title>编辑详情</v-card-title>
- <v-card-text>
- <v-row>
- <v-col cols="12">
- <v-text-field disabled label="hash" v-model="editDialog.item.hash"></v-text-field>
- </v-col>
- </v-row>
- <v-row>
- <v-col cols="12">
- <v-text-field label="comment" v-model="editDialog.item.comment"></v-text-field>
- </v-col>
- </v-row>
- <v-row>
- <v-col cols="6">
- <v-text-field disabled label="from" v-model="editDialog.item.from"></v-text-field>
- </v-col>
- <v-col cols="6">
- <v-text-field label="fromName" v-model="editDialog.item.fromName"></v-text-field>
- </v-col>
- </v-row>
- <v-row>
- <v-col cols="6">
- <v-text-field disabled label="to" v-model="editDialog.item.to"></v-text-field>
- </v-col>
- <v-col cols="6">
- <v-text-field label="toName" v-model="editDialog.item.toName"></v-text-field>
- </v-col>
- </v-row>
- </v-card-text>
- <v-card-actions>
- <v-spacer></v-spacer>
- <v-btn text color="primary" @click="updateAdapter">提交编辑</v-btn>
- </v-card-actions>
- </v-card>
- </v-dialog>
- </div>
- </template>
- <script>
- import TradeInfo from '@/components/viewer/history/table/TradeInfoDetails'
- import BooleanViewer from '@/components/viewer/history/table/BooleanViewer'
- import HashKit from '@/plugins/kit/HashKit'
- import HttpKit from '@/plugins/kit/HttpKit'
- import TimeKit from '@/plugins/kit/TimeKit'
- import AddressModel from "@/plugins/model/AddressModel";
- import jquery from 'jquery'
- export default {
- name: 'Table',
- components: {BooleanViewer, TradeInfo},
- props: ['query', 'page', 'table', 'tx'],
- inject: ['packQuery'],
- data: () => ({
- hashKit: HashKit,
- httpKit: HttpKit,
- timeKit: TimeKit,
- transferDetailsDialog: {
- data: [],
- visible: false
- },
- editDialog: {
- item: {},
- visible: false
- },
- tempPage: 1,
- addressModel: undefined,
- dblclickRowUrl: "https://tools.blocksec.com/tx/eth/",
- }),
- methods: {
- async deleteByHash(hash_code, item) {
- if (confirm('要删吗?\n' + hash_code)) {
- console.log(JSON.stringify(item))
- this.$msgkit.warning('还没有做,别急啊')
- // const rst = await EthMev.deleteByHash(hash_code)
- //
- // if (rst.data.state) {
- // this.$msgkit.success(rst.data.msg)
- //
- // await this.pullData()
- // } else {
- // this.$msgkit.error(rst.data.msg)
- // }
- }
- },
- async updateAdapter() {
- this.createAddressModel()
- const updateItem = this.editDialog.item
- const txBaseItem = {
- hash: updateItem.hash,
- comment: updateItem.comment
- }
- const fromAddrBaseItem = {
- hash: updateItem.from,
- name: updateItem.fromName
- }
- const toAddrBaseItem = {
- hash: updateItem.to,
- name: updateItem.toName
- }
- const rst1 = await this.tx.updateTxBaseModel(txBaseItem)
- const rst2 = await this.addressModel.updateAddressBaseModel(fromAddrBaseItem)
- const rst3 = await this.addressModel.updateAddressBaseModel(toAddrBaseItem)
- if (rst1.state && rst2.state && rst3.state) {
- this.$msgkit.success('更新成功')
- this.editDialog.visible = false
- } else {
- this.$msgkit.error(`rst1: ${rst1.msg}, rst2: ${rst2.msg}, rst3: ${rst3.msg}`)
- }
- },
- showTradeInfo(item) {
- this.transferDetailsDialog.data = item
- this.transferDetailsDialog.visible = true
- },
- async inputPageNum() {
- this.table.pageNum = parseInt(this.tempPage)
- await this.generateTableDataAgain()
- },
- async generateTableDataAgain() {
- this.tempPage = this.table.pageNum
- this.table.data = []
- await this.packQuery()
- },
- formatTimeBySixBitTimestamp(sixBitTimestamp) {
- let lastThreeBit = (sixBitTimestamp + '').slice(-3)
- return this.timeKit.getTime(sixBitTimestamp) + lastThreeBit
- },
- editItem(item) {
- this.editDialog.item = item
- this.editDialog.visible = true
- },
- createAddressModel() {
- if (!this.addressModel) this.addressModel = new AddressModel(this.tx.chainId, AddressModel.MODULES.unknown)
- },
- currentItems(val) {
- console.log("currentItems:", val)
- },
- input(val) {
- console.log("input:", val)
- },
- itemSelected(val) {
- console.log("itemSelected:", val)
- },
- pageCount(val) {
- console.log("pageCount:", val)
- },
- pagination(val) {
- console.log("pagination:", val)
- if (val.itemsLength === 0) {
- this.remButRegroupAll()
- }
- if (val.itemsLength > 0) {
- this.addButRegroup()
- }
- },
- toggleSelectAll(val) {
- console.log("toggleSelectAll:", val)
- },
- updateExpanded(val) {
- console.log("updateExpanded:", val)
- },
- updateGroupBy(val) {
- console.log("updateGroupBy:", val)
- },
- updateGroupEesc(val) {
- console.log("updateGroupEesc:", val)
- },
- updateItemsPerPage(val) {
- console.log("updateItemsPerPage:", val)
- },
- updateMultiSort(val) {
- console.log("updateMultiSort:", val)
- },
- updateMustSort(val) {
- console.log("updateMustSort:", val)
- },
- updateOptions(val) {
- console.log("updateOptions:", val)
- },
- updatePage(val) {
- console.log("updatePage:", val)
- },
- updateSortBy(val) {
- console.log("updateSortBy:", val)
- },
- updateSortDesc(val) {
- console.log("updateSortDesc:", val)
- },
- itemExpanded(item, val) {
- console.log("itemExpanded:", item, val)
- },
- toggle(val) {
- console.log("toggle:", val)
- },
- dblclickRow(event, value) {
- console.log("dblclickRow:", event, value)
- },
- //赋予按钮第二个点击事件
- addButClick(explorer) {
- jquery(".history-table div.v-data-table__wrapper table tbody").on("click", ".v-row-group__header td.text-start", function (dom) {
- console.log("当前访问:", this.tx, dom)
- //需要移除临时 并已经作废的标签
- var array_del = jquery("a.temporary_label")
- for (var d = 0; d < array_del.length; d++) {
- var a = array_del.eq(d)[0]
- var tr = jquery(jquery(a).parent().parent())[0]
- var className = tr.className
- if (className.indexOf("v-row-group__header") === -1) {
- jquery(a).remove()
- }
- }
- var array = jquery(".history-table div.v-data-table__wrapper table tbody .v-row-group__header td.text-start");
- for (var i = 0; i < array.length; i++) {
- //思路:根据 jq 拿到对应的td 然后循环遍历 动态添加元素标签
- var td = array.eq(i)[0]
- var innerText = td.innerText
- var but_x = jquery(td).children()[1]
- if (jquery(td).children().length > 2) {
- } else {
- //添加
- var href = explorer + "/block/" + innerText.split(": ")[1];
- var a = '<a class="temporary_label" href="' + href + '" target="_blank"> 跳转 </a>';
- jquery(but_x).before(a)
- }
- }
- })
- },
- //添加跳转标签
- addButRegroup(explorer) {
- var array = jquery(".history-table div.v-data-table__wrapper table tbody .v-row-group__header td.text-start");
- console.log(array)
- for (var i = 0; i < array.length; i++) {
- //思路:根据 jq 拿到对应的td 然后循环遍历 动态添加元素标签
- var td = array.eq(i)[0]
- var innerText = td.innerText
- var but_x = jquery(td).children()[1]
- if (jquery(td).children().length > 2) {
- } else {
- //添加
- var href = explorer + "/block/" + innerText.split(": ")[1];
- var a = '<a class="temporary_label" href="' + href + '" target="_blank"> 跳转 </a>';
- jquery(but_x).before(a)
- }
- }
- },
- //需要移除临时 并已经作废的标签
- remButRegroup() {
- var array_del = jquery("a.temporary_label")
- for (var d = 0; d < array_del.length; d++) {
- var a = array_del.eq(d)[0]
- var tr = jquery(jquery(a).parent().parent())[0]
- var className = tr.className
- if (className.indexOf("v-row-group__header") === -1) {
- jquery(a).remove()
- }
- }
- },
- remButRegroupAll() {
- var array_del = jquery("a.temporary_label")
- for (var d = 0; d < array_del.length; d++) {
- var a = array_del.eq(d)[0]
- jquery(a).remove()
- }
- },
- showIfHide(boo) {
- var array = jquery("a.temporary_label")
- if (array.length > 0) {
- var a = array[0]
- if (boo)
- jquery(a).hide()
- else
- jquery(a).show()
- }
- },
- },
- async mounted() {
- // let vm = new Vue({
- // el: "td.text-start",
- // click: () => {
- // console.log('点击')
- // }
- // });
- // $("td.text-start").on("click",this,function (){
- // console.log('点击')
- // });
- }
- }
- </script>
- <style scoped>
- .table-container {
- width: 100%;
- }
- #dataTableHeader {
- max-width: none;
- }
- .tokenChip {
- margin-top: 5px;
- margin-left: 5px;
- margin-bottom: 5px;
- }
- .tradeInfoBtn {
- padding: 15px !important;
- border: grey 2px solid;
- }
- .tradeInfoBtn:hover {
- background: beige;
- }
- .memo-span {
- width: 200px;
- display: block;
- padding: 10px;
- }
- </style>
|