浏览代码

新增magictoken

875428575@qq.com 2 年之前
父节点
当前提交
9484be3044

+ 1 - 0
.env.development

@@ -1,3 +1,4 @@
 VUE_APP_ENV = 'dev'
 
 VUE_APP_BASE_URL = '/api'
+

+ 7 - 0
src/App.vue

@@ -14,6 +14,7 @@
         <v-tab key="pending" @change="pendingChange">Pending</v-tab>
         <v-tab key="address" @change="addressChange">Address</v-tab>
         <v-tab key="chain" @change="chainChange">Chain</v-tab>
+        <v-tab key="magicToken" @change="chainChange">MagicToken</v-tab>
       </v-tabs>
 
       <v-spacer></v-spacer>
@@ -79,6 +80,10 @@
         <v-tab-item key="chain">
           <Chain_Page :chain="chain" ref="chain"></Chain_Page>
         </v-tab-item>
+        <v-tab-item key="magicToken">
+          <MagicToken :chain="chain" ref="magicToken"></MagicToken>
+        </v-tab-item>
+
       </v-tabs-items>
     </v-main>
   </v-app>
@@ -93,6 +98,7 @@ import Pending from '@/components/Pending'
 import houliang from '@/components/hl/houliang'
 import Hddress from '@/components/Address.vue'
 import Chain_Page from '@/components/Chain'
+import MagicToken from '@/components/MagicToken'
 
 import HttpKit from "@/plugins/kit/HttpKit";
 import Chain from '@/plugins/model/Chain.js'
@@ -107,6 +113,7 @@ export default {
     houliang,
     Hddress,
     Chain_Page,
+    MagicToken
   },
   data: () => ({
     tab: 'history',

+ 135 - 0
src/components/MagicToken.vue

@@ -0,0 +1,135 @@
+<template>
+  <v-card elevation="1">
+    <!-- 顶部组件 -->
+    <Top :query='query' :page='page' :table='table' :visible="editDialog.visible"></Top>
+
+    <!-- 中间表格组件 -->
+    <Table :query='query' :page='page' :table='table' :magicTokenModel="magicTokenModel" :explorer="chain.explorer"
+           :editDialog="editDialog" ref="table"></Table>
+  </v-card>
+</template>
+
+<script>
+import Top from '@/components/viewer/magicToken/Top.vue'
+import Table from '@/components/viewer/magicToken/Table.vue'
+import TxModel from '@/plugins/model/TxModel'
+import MagicTokenModel from '@/plugins/model/MagicTokenModel.js'
+
+
+export default {
+  name: 'MagicToken',
+  components: {Top, Table},
+  props: ['chain'],
+  data: () => ({
+    magicTokenModel: undefined,
+    editDialog: {
+      item: {},
+      visible: false,
+      addOrUpdate: true,
+    },
+    query: {
+      tx: {},
+    },
+    page: {
+      name: 'MagicToken Page'
+    },
+    table: {
+      search: '',
+      loading: false,
+      groupBy: '',
+      groupDesc: true,
+      sortBy: [],
+      sortDesc: [],
+      pageSize: 500,
+      pageNum: 1,
+      pageLength: 1,
+      data: [
+        //     {
+        //   'id':1,
+        //   'hash':'0x1a97a8fe340933a8b050dd3d1c823116d31178a253a74ea5a42ea909b37901c4',
+        //   'name': '测试数据',
+        //   'Explorer':'Explorer'
+        // }
+      ],
+      headers: [
+        {text: 'Option', value: 'option', width: '5%'},
+        {text: 'Hash', value: 'hash', width: '10%'},
+        {text: 'Name', value: 'name', width: '10%'},
+        {text: 'Symbol', value: 'symbol', width: '10%'},
+        {text: '审批状态', value: 'explorer', width: '10%'},
+      ]
+    },
+  }),
+  methods: {
+    // 获取数据
+    async generateTableData() {
+      this.createAddressModel()
+
+      this.table.loading = true
+      this.table.data.length = 0
+
+      const rst = await this.magicTokenModel.findApprovalTokenByChainId(this.chain.id, this.query.tx.hash, this.query.tx.auth, new Date().getTime())
+      if (rst.state) {
+        this.$msgkit.normal(rst.msg)
+        this.table.data = rst.data
+      }
+
+      this.table.loading = false
+    },
+    createAddressModel() {
+      if (!this.magicTokenModel) this.magicTokenModel = new MagicTokenModel(this.chain.id, TxModel.MODULES.MAGICTOKEN)
+    },
+    //设置 新增按钮编辑
+    showVisible() {
+      this.editDialog.item = { chain: "",hash: "", decimals: 0, name: "",
+        symbol: "", totalAmountStr: "", totalValueStr: "",priceStr:"",
+        auth:{
+          auth:'',
+          timestamp: new Date().getTime()
+        }
+      }
+      this.editDialog.visible = true
+      this.editDialog.addOrUpdate = true
+    },
+    // 按钮设定审批状态
+    async butSetMagicApprolval(hash, magicApproval, auth) {
+      const rst = await this.magicTokenModel.makeMagicApproval(this.chain.id, hash, magicApproval, auth, new Date().getTime())
+      if (rst.state) {
+        this.$msgkit.success(rst.msg)
+      }else{
+        this.$msgkit.error(rst.msg)
+      }
+    },
+
+
+    async generatePageCount() {
+
+    },
+
+    async prePackQuery() {
+      // await this.$refs.table.remButClick()
+
+    },
+    async packQuery() {
+      await this.prePackQuery()//查询数据之前移除 多余的临时标签
+      await this.generateTableData()//拿到数据
+      // this.generatePageCount()
+      await this.afterPackQuery()//添加标签 ,添加点击按钮事件
+    },
+    async afterPackQuery() {
+    },
+  },
+  provide() {
+    return {
+      packQuery: this.packQuery,
+      showVisible: this.showVisible,
+      butSetMagicApprolval: this.butSetMagicApprolval
+    }
+  },
+  async mounted() {
+    await this.packQuery()
+  },
+
+
+}
+</script>

+ 252 - 0
src/components/viewer/magicToken/Table.vue

@@ -0,0 +1,252 @@
+<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
+                    :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>
+        <template v-slot:item.hash="{ item }">
+          <div>
+            <a :href="explorer + '/token/'+item.hash "> {{ item.hash }}</a>
+          </div>
+        </template>
+        <template v-slot:item.name="{ item }">
+          <div>
+            {{ item.name }}
+          </div>
+        </template>
+        <template v-slot:item.symbol="{ item }">
+          <div>
+            {{ item.symbol }}
+          </div>
+        </template>
+        <template v-slot:item.explorer="{ item }">
+          <div>
+            <v-row>
+              <!-- tx信息过滤 -->
+              <v-col cols="24" md="6">
+                <v-select
+                    v-model='item.magicApproval'
+                    :items='["PASS","PENDING","REJECT"]'
+                    label="审批状态"
+                ></v-select>
+              </v-col>
+              <v-col cols="24" md="2" style="margin-top:11px;">
+                <v-btn @click="upButClick(item)">更 新</v-btn>
+              </v-col>
+            </v-row>
+
+          </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>
+
+    <!-- 新增 -->
+    <v-dialog v-model="editDialog.visible" max-width="800">
+      <v-card elevation="0">
+        <v-card-title>{{ editDialog.addOrUpdate ? '新增' : '编辑' }} MagicToken</v-card-title>
+        <v-card-text>
+          <v-row>
+            <v-col cols="12">
+              <v-text-field v-if="editDialog.addOrUpdate" label="hash" v-model="editDialog.item.hash"></v-text-field>
+              <v-text-field v-else 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="name" v-model="editDialog.item.name"></v-text-field>
+            </v-col>
+          </v-row>
+          <v-row>
+            <v-col cols="12">
+              <v-text-field label="symbol" v-model="editDialog.item.symbol"></v-text-field>
+            </v-col>
+          </v-row>
+          <v-row>
+            <v-col cols="12">
+              <v-text-field label="decimals" v-model="editDialog.item.decimals"></v-text-field>
+            </v-col>
+          </v-row>
+<!--          <v-row>-->
+<!--            <v-col cols="12">-->
+<!--              <v-select-->
+<!--                  v-model='editDialog.item.magicApproval'-->
+<!--                  :items='["PASS","PENDING","REJECT"]'-->
+<!--                  label="审批状态"-->
+<!--              ></v-select>-->
+<!--            </v-col>-->
+<!--          </v-row>-->
+        </v-card-text>
+        <v-card-actions>
+          <v-spacer></v-spacer>
+          <v-btn text color="primary" @click="addOrUpdateAddress">提交</v-btn>
+        </v-card-actions>
+      </v-card>
+    </v-dialog>
+  </div>
+</template>
+
+<script>
+import TradeInfo from '@/components/viewer/magicToken/table/TradeInfoDetails'
+import BooleanViewer from '@/components/viewer/magicToken/table/BooleanViewer'
+import HashKit from '@/plugins/kit/HashKit'
+import HttpKit from '@/plugins/kit/HttpKit'
+import TimeKit from '@/plugins/kit/TimeKit'
+import MagicTokenModel from "@/plugins/model/MagicTokenModel";
+import jquery from 'jquery'
+
+export default {
+  name: 'Table',
+  components: {BooleanViewer, TradeInfo},
+  props: ['query', 'page', 'table', 'magicTokenModel', 'explorer', 'editDialog'],
+  inject: ['packQuery', 'showVisible', 'butSetMagicApprolval'],
+  data: () => ({
+    hashKit: HashKit,
+    httpKit: HttpKit,
+    timeKit: TimeKit,
+    transferDetailsDialog: {
+      data: [],
+      visible: false
+    },
+    tempPage: 1,
+    dblclickRowUrl: "https://tools.blocksec.com/tx/eth/",
+  }),
+  methods: {
+    async addOrUpdateAddress() {
+
+      const {hash, symbol,name,decimals} = this.editDialog.item
+      const updateMagicToken = {hash, symbol,name,decimals}
+      const rst1 = await this.magicTokenModel.updateMagicTokenModelBaseModel(updateMagicToken)
+      if (rst1.state) {
+        this.$msgkit.success((this.editDialog.addOrUpdate ? '添加' : '更新') + '成功')
+
+        this.editDialog.visible = false
+      } else {
+        this.$msgkit.error(`rst1: ${rst1.msg}`)
+      }
+    },
+
+
+    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
+      this.editDialog.addOrUpdate = false
+    },
+
+    upButClick(item) {
+      console.log('---', item)
+      this.butSetMagicApprolval(item.hash, item.magicApproval, '')
+    },
+
+    remButClick() {
+      jquery(".v-row-group__header td.text-start").unbind('click')
+      // console.log("移除点击事件:remButClick")
+    },
+  },
+  async mounted() {
+  }
+}
+</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>

+ 78 - 0
src/components/viewer/magicToken/Top.vue

@@ -0,0 +1,78 @@
+<template>
+  <div class="top-container">
+    <v-row>
+      <!-- tx信息过滤 -->
+<!--      <v-col cols="18" md="2">-->
+<!--        <v-text-field required label="magicToken.Hash" v-model="query.tx.hash"/>-->
+<!--      </v-col>-->
+<!--      <v-col cols="18" md="2">-->
+<!--        <v-text-field required label="magicToken.Auth" v-model="query.tx.auth"/>-->
+<!--      </v-col>-->
+<!--      <v-col cols="18" md="2">-->
+<!--        <v-select-->
+<!--            v-model="query.tx.magicApprolval"-->
+<!--            :items='["PASS","PENDING","REJECT"]'-->
+<!--            label="审批状态"-->
+<!--        ></v-select>-->
+<!--&lt;!&ndash;        <v-text-field required label="magicToken.HagicApprolval" v-model="query.tx.magicApprolval"/>&ndash;&gt;-->
+<!--      </v-col>-->
+
+      <v-col cols="18" md="6">
+<!--        <v-btn outlined x-large tile color="primary" @click="butClickSetMagicApprolval()">-->
+<!--          <v-icon left>mdi-cloud-search-outline</v-icon>-->
+<!--          标记审批状态-->
+<!--        </v-btn >-->
+        <v-btn style='margin-left: 5px;' outlined x-large tile color="primary" @click="generateTableDataAgain()">
+          <v-icon left>mdi-cloud-search-outline</v-icon>
+          刷新
+        </v-btn>
+        <v-btn style='margin-left: 5px;' outlined x-large tile color="primary" @click="addClick()">
+          <v-icon left>mdi-cloud-search-outline</v-icon>
+          新增
+        </v-btn>
+      </v-col>
+
+    </v-row>
+
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'Top',
+  props: ['query', 'page', 'table', 'visible'],
+  inject: ['packQuery', 'showVisible','butSetMagicApprolval'],
+  methods: {
+    async butClickSetMagicApprolval(){
+      await this.butSetMagicApprolval()
+    },
+    async generateTableDataAgain() {
+      await this.packQuery()
+    },
+    addClick() {
+      this.showVisible()
+    },
+  },
+  async mounted() {
+    let prevFlushTime = 0
+    setInterval(async function (top) {
+      if (top.query.autoFlushTime > 0) {
+        let now = parseInt(new Date().getTime() / 1000)
+
+        if (now - top.query.autoFlushTime > prevFlushTime) {
+          await top.generateTableDataAgain()
+
+          prevFlushTime = now
+        }
+      }
+    }, 1000, this)
+  }
+}
+</script>
+
+<style scoped>
+.top-container {
+  width: 95%;
+  margin: auto;
+}
+</style>

+ 15 - 0
src/components/viewer/magicToken/table/BooleanViewer.vue

@@ -0,0 +1,15 @@
+<template>
+  <span v-if="value" class="teal--text">yes</span>
+  <span v-else class="pink--text">no</span>
+</template>
+
+<script>
+export default {
+  name: 'BooleanViewer',
+  props: ['value']
+}
+</script>
+
+<style scoped>
+
+</style>

+ 98 - 0
src/components/viewer/magicToken/table/TradeInfoDetails.vue

@@ -0,0 +1,98 @@
+<template>
+  <div>
+    <v-container>
+      <div v-for="trade in item.transferList">
+        <v-row>
+          <!--token symbol-->
+          <!-- 没有名字的 -->
+          <v-chip v-if="!trade.tokenSymbol"
+                  label class="ma-2 tradeLabel" @click="httpKit.jumpToExplorer(trade.token, 'token')">
+            <div class="tokenName">{{ '**' + hashKit.headAndEnd2(trade.token) }}</div>
+            <div class="tokenAmount">{{ trade.amount }} </div>
+          </v-chip>
+          <!-- 有名字的和Ethereum/EthereumPow -->
+          <v-chip v-else
+                  label class="ma-2 tradeLabel" :color="hashKit.generateColorByHash(trade.token)"
+                  @click="httpKit.jumpToExplorer(trade.token, 'token')">
+            <div class="tokenName">{{ trade.tokenSymbol === '' ? '[no name]' : trade.tokenSymbol }}</div>
+            <div class="tokenAmount">{{ numKit.getSubFloat(trade.amount, 4) }}</div>
+          </v-chip>
+
+
+          <!--from-->
+          <div>
+            <v-chip v-if="trade.from === item.from"
+                    label class="ma-2" color="green lighten-3" @click="httpKit.jumpToExplorer(trade.from)">
+              {{ '[F] ' + hashKit.headAndEnd2(trade.from) }}
+            </v-chip>
+            <v-chip v-else-if="trade.from === item.to"
+                    label class="ma-2" color="indigo lighten-4" @click="httpKit.jumpToExplorer(trade.from)">
+              <div v-if="!trade.fromName">{{ '[T] ' + hashKit.headAndEnd2(trade.from) }}</div>
+              <div v-else>{{ '[T] ' + trade.fromName }}</div>
+            </v-chip>
+            <v-chip v-else
+                    label class="ma-2" :color="hashKit.generateColorByHash(trade.from)"
+                    @click="httpKit.jumpToExplorer(trade.from)">
+              <div v-if="!trade.fromName">{{ hashKit.headAndEnd2(trade.from) }}</div>
+              <div v-else>{{ trade.fromName }}</div>
+            </v-chip>
+          </div>
+          <v-icon>mdi-arrow-expand-right</v-icon>
+          <!--to-->
+          <div>
+            <v-chip v-if="trade.to === item.from"
+                    label class="ma-2" color="green lighten-3" @click="httpKit.jumpToExplorer(trade.to)">
+              {{ '[F] ' + hashKit.headAndEnd2(trade.to) }}
+            </v-chip>
+            <v-chip v-else-if="trade.to === item.to"
+                    label class="ma-2" color="indigo lighten-4" @click="httpKit.jumpToExplorer(trade.to)">
+              <div v-if="!trade.toName">{{ '[T] ' + hashKit.headAndEnd2(trade.to) }}</div>
+              <div v-else>{{'[T] ' +  trade.toName }}</div>
+            </v-chip>
+            <v-chip v-else
+                    label class="ma-2" :color="hashKit.generateColorByHash(trade.to)" @click="httpKit.jumpToExplorer(trade.to)">
+              <div v-if="!trade.toName">{{ hashKit.headAndEnd2(trade.to) }}</div>
+              <div v-else>{{ trade.toName }}</div>
+            </v-chip>
+          </div>
+        </v-row>
+        <v-row>
+          <v-divider></v-divider>
+        </v-row>
+      </div>
+    </v-container>
+  </div>
+</template>
+
+<script>
+import NumKit from '@/plugins/kit/NumKit'
+import HashKit from '@/plugins/kit/HashKit'
+import HttpKit from '@/plugins/kit/HttpKit'
+
+export default {
+  name: 'TradeInfo',
+  props: ['item'],
+  data: () => ({
+    numKit: NumKit,
+    hashKit: HashKit,
+    httpKit: HttpKit
+  })
+}
+</script>
+
+<style>
+.tradeLabel {
+  width: 250px;
+}
+div.tokenName {
+  text-align: left;
+  width: 100%;
+}
+div.tokenAmount {
+  text-align: right;
+  width: 100%;
+}
+span.v-chip__content {
+  width: 100%;
+}
+</style>

+ 55 - 0
src/plugins/model/MagicTokenModel.js

@@ -0,0 +1,55 @@
+import http from 'axios'
+
+export default class MagicTokenModel {
+    static MODULES = {
+        unknown: 'unknown'
+    }
+
+    constructor(chainId, module) {
+        if (!chainId || !module) throw "Must have [chainId, module]."
+
+        this.chainId = chainId
+        this.module = module
+    }
+
+
+    async makeMagicApproval(chainId,hash,magicApproval,auth,timestamp) {
+        // const url = '/chain/getAll'
+        const url = `/token/makeMagicApproval`
+        const rst = await http.post(url, {
+            chainId: chainId,
+            hash:hash,
+            magicApproval:magicApproval,
+            auth:{
+                auth:auth,
+                timestamp:timestamp,
+            }
+        })
+        return rst.data
+    }
+
+
+    async findApprovalTokenByChainId(chainId,auth,timestamp) {
+        const url = `/token/findApprovalTokenByChainId`
+        const rst = await http.post(url, {
+            chainId: chainId,
+            auth:{
+                auth:auth,
+                timestamp:timestamp
+            }
+        })
+        return rst.data
+    }
+
+
+    async updateMagicTokenModelBaseModel(magicTokenModelBaseItem) {
+        const url = `/token/appendOrUpdate`
+
+        magicTokenModelBaseItem.chainId = this.chainId
+        const rst = await http.post(url, magicTokenModelBaseItem)
+
+        return rst.data
+    }
+
+
+}

+ 1 - 0
src/plugins/model/TxModel.js

@@ -6,6 +6,7 @@ export default class TxModel {
         PENDING: 'pending',
         ADDRESS: 'address',
         CHAIN: 'chain',
+        MAGICTOKEN:'magicToken'
     }
 
     constructor(chainId, module) {

+ 2 - 1
vue.config.js

@@ -6,7 +6,8 @@ module.exports = {
   devServer: {
     proxy: {
       '/api': {
-        target:'http://127.0.0.1:8888',
+        // target:'http://127.0.0.1:8888',
+        target:'http://web.410eth.com:8888',
         changeOrigin:true,
         pathRewrite:{
           '^/api': ''