Browse Source

Merge pull request #294 from Leizhengzi/main

feat: admin all transaction detail page render
pull/295/head
yedf2 4 years ago
committed by GitHub
parent
commit
2ec3a6ccd8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      admin/package.json
  2. 10
      admin/src/api/api_dtm.ts
  3. 3
      admin/src/components.d.ts
  4. 40
      admin/src/components/Screenfull/index.vue
  5. 2
      admin/src/components/SvgIcon/index.vue
  6. 1
      admin/src/icons/svg/fullscreen.svg
  7. 23
      admin/src/views/Dashboard/GlobalTransactions/AllTransactions.vue
  8. 106
      admin/src/views/Dashboard/GlobalTransactions/_Components/DialogTransactionDetail.vue
  9. 5
      admin/yarn.lock

3
admin/package.json

@ -28,6 +28,7 @@
"postcss-import": "^14.1.0", "postcss-import": "^14.1.0",
"postcss-nested": "^5.0.6", "postcss-nested": "^5.0.6",
"postcss-simple-vars": "^6.0.3", "postcss-simple-vars": "^6.0.3",
"screenfull": "^6.0.1",
"tailwindcss": "^3.0.24", "tailwindcss": "^3.0.24",
"typescript": "^4.5.4", "typescript": "^4.5.4",
"unplugin-vue-components": "^0.19.3", "unplugin-vue-components": "^0.19.3",
@ -36,4 +37,4 @@
"vue-router": "^4.0.13", "vue-router": "^4.0.13",
"vue-tsc": "^0.29.8" "vue-tsc": "^0.29.8"
} }
} }

10
admin/src/api/api_dtm.ts

@ -3,7 +3,7 @@ import request from '/@/utils/request'
export interface IListAllTransactionsReq { export interface IListAllTransactionsReq {
limit: number limit: number
position?: number position?: string
} }
export function listAllTransactions<T>(payload: IListAllTransactionsReq): Promise<AxiosResponse<T>> { export function listAllTransactions<T>(payload: IListAllTransactionsReq): Promise<AxiosResponse<T>> {
@ -14,6 +14,14 @@ export function listAllTransactions<T>(payload: IListAllTransactionsReq): Promis
}) })
} }
export function getTransaction<T>(payload: {gid: string}): Promise<AxiosResponse<T>> {
return request({
url: '/api/dtmsvr/query',
method: 'get',
params: payload
})
}
export function getDtmVersion(): Promise<AxiosResponse<any>> { export function getDtmVersion(): Promise<AxiosResponse<any>> {
return request({ return request({
url: '/api/dtmsvr/version', url: '/api/dtmsvr/version',

3
admin/src/components.d.ts

@ -14,11 +14,14 @@ declare module '@vue/runtime-core' {
ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider'] ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider']
AMenu: typeof import('ant-design-vue/es')['Menu'] AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AModal: typeof import('ant-design-vue/es')['Modal']
ASubMenu: typeof import('ant-design-vue/es')['SubMenu'] ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
ATable: typeof import('ant-design-vue/es')['Table'] ATable: typeof import('ant-design-vue/es')['Table']
ATag: typeof import('ant-design-vue/es')['Tag'] ATag: typeof import('ant-design-vue/es')['Tag']
ATextarea: typeof import('ant-design-vue/es')['Textarea']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
Screenfull: typeof import('./components/Screenfull/index.vue')['default']
SvgIcon: typeof import('./components/SvgIcon/index.vue')['default'] SvgIcon: typeof import('./components/SvgIcon/index.vue')['default']
} }
} }

40
admin/src/components/Screenfull/index.vue

@ -0,0 +1,40 @@
<template>
<div class="hidden-xs-only px-2">
<svg-icon v-if="!isFulScreen" class-name="cursor-pointer" icon-class="svg-fullscreen" @click="changeScreenfull(identity)" />
<svg-icon v-else class-name="cursor-pointer" icon-class="svg-exit-fullscreen" @click="changeScreenfull(identity)" />
</div>
</template>
<script setup lang='ts'>
import { notification } from 'ant-design-vue';
import { onMounted, onUnmounted, ref } from 'vue'
import screenfull from 'screenfull'
const isFulScreen = ref(false)
const changeScreenfull = (identity: string) => {
if (!screenfull.isEnabled) {
notification.open({
message: '浏览器不支持全屏',
type: 'warning'
})
} else if (identity) {
const element = document.getElementById(identity)
screenfull.toggle(element as HTMLElement)
} else {
screenfull.toggle()
}
}
const change = () => {
if (screenfull.isEnabled) isFulScreen.value = screenfull.isFullscreen
}
defineProps({
identity: {
type: String,
default: null
}
})
const emits = defineEmits(['screen'])
onMounted(() => screenfull.isEnabled && screenfull.on('change', change) && emits('screen'))
onUnmounted(() => screenfull.isEnabled && screenfull.off('change', change))
</script>

2
admin/src/components/SvgIcon/index.vue

@ -30,6 +30,8 @@ const styleExternalIcon = () => {
<style lang="postcss" scoped> <style lang="postcss" scoped>
.svg-icon { .svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em; vertical-align: -0.15em;
fill: currentColor; fill: currentColor;
overflow: hidden; overflow: hidden;

1
admin/src/icons/svg/fullscreen.svg

@ -0,0 +1 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg>

After

Width:  |  Height:  |  Size: 422 B

23
admin/src/views/Dashboard/GlobalTransactions/AllTransactions.vue

@ -9,7 +9,7 @@
</template> </template>
<template v-else-if="column.key === 'action'"> <template v-else-if="column.key === 'action'">
<span> <span>
<a class="mr-2 font-medium">Detail</a> <a class="mr-2 font-medium" @click="handleTransactionDetail(record.gid)">Detail</a>
<a class="text-red-400 font-medium">Stop</a> <a class="text-red-400 font-medium">Stop</a>
</span> </span>
</template> </template>
@ -19,13 +19,15 @@
<a-button type="text" :disabled="!canPrev" @click="handlePrevPage">Previous</a-button> <a-button type="text" :disabled="!canPrev" @click="handlePrevPage">Previous</a-button>
<a-button type="text" :disabled="!canNext" @click="handleNextPage">Next</a-button> <a-button type="text" :disabled="!canNext" @click="handleNextPage">Next</a-button>
</div> </div>
<DialogTransactionDetail ref="transactionDetail" />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { IListAllTransactions, listAllTransactions } from '/@/api/api_dtm' import { IListAllTransactionsReq, listAllTransactions } from '/@/api/api_dtm'
import { ref, onMounted, reactive, computed } from 'vue-demi' import { ref, computed } from 'vue-demi'
import { usePagination } from 'vue-request' import { usePagination } from 'vue-request'
import { TableProps } from 'ant-design-vue/es/vc-table/Table' import DialogTransactionDetail from './_Components/DialogTransactionDetail.vue';
const columns = [ const columns = [
{ {
title: 'GID', title: 'GID',
@ -75,11 +77,10 @@ type Data = {
next_position: string next_position: string
} }
const queryData = (params: IListAllTransactions) => { const queryData = (params: IListAllTransactionsReq) => {
return listAllTransactions<Data>(params) return listAllTransactions<Data>(params)
} }
const { data, run, current, loading, pageSize } = usePagination(queryData, { const { data, run, current, loading, pageSize } = usePagination(queryData, {
defaultParams: [ defaultParams: [
{ {
@ -97,20 +98,26 @@ const handlePrevPage = () => {
curPage.value -= 1; curPage.value -= 1;
const params = { const params = {
limit: pageSize.value, limit: pageSize.value,
position: pages.value[curPage.value] position: pages.value[curPage.value] as string
} }
run(params) run(params)
} }
const handleNextPage = () => { const handleNextPage = () => {
curPage.value += 1; curPage.value += 1;
pages.value[curPage.value] = data.value?.data.next_position pages.value[curPage.value] = data.value?.data.next_position as string
run({ run({
position: data.value?.data.next_position, position: data.value?.data.next_position,
limit: pageSize.value, limit: pageSize.value,
}) })
} }
const transactionDetail = ref<null | {open:(gid: string) => null}>(null)
const handleTransactionDetail = (gid: string) => {
transactionDetail.value?.open(gid)
}
</script> </script>
<style lang="postcss" scoped> <style lang="postcss" scoped>

106
admin/src/views/Dashboard/GlobalTransactions/_Components/DialogTransactionDetail.vue

@ -0,0 +1,106 @@
<template>
<div>
<a-modal v-model:visible="visible" title="Transaction Detail" width="80%">
<a-table :columns="columns" :data-source="dataSource" :pagination="false">
<template #bodyCell="{column, record}">
<template v-if="column.key === 'op'">
<span class="font-medium">{{ record.op.toUpperCase()}}</span>
</template>
<template v-if="column.key === 'status'">
<span class="font-medium">{{ record.status.toUpperCase()}}</span>
</template>
</template>
</a-table>
<div class="mt-10 relative">
<a-textarea id="qs" v-model:value="textVal" :auto-size="{ minRows: 10, maxRows: 10 }" />
<screenfull class="absolute right-2 top-3 z-50" identity="qs" />
</div>
</a-modal>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { getTransaction } from '/@/api/api_dtm';
import screenfull from '/@/components/Screenfull/index.vue';
// import VueJsonPretty from 'vue-json-pretty';
// import 'vue-json-pretty/lib/styles.css'
const dataSource = ref<Branches[]>([])
const visible = ref(false)
const textVal = ref('')
const open = async(gid: string) => {
const d = await getTransaction<Data>({gid: gid})
dataSource.value = d.data.branches
textVal.value = JSON.stringify(d.data, null, 2)
visible.value = true
}
const columns = [
{
title: 'GID',
dataIndex: 'gid',
key: 'gid'
}, {
title: 'BranchID',
dataIndex: 'branch_id',
key: 'branch_id'
}, {
title: 'Op',
dataIndex: 'op',
key: 'op'
}, {
title: 'Status',
dataIndex: 'status',
key: 'status'
}, {
title: 'CreateTime',
dataIndex: 'create_time',
key: 'create_time'
}, {
title: 'UpdateTime',
dataIndex: 'update_time',
key: 'update_time'
}
]
type Data = {
branches: {
gid: string
branch_id: string
op: string
status: string
create_time: string
update_time: string
}[]
transactions: {
ID: number
create_time: string
update_time: string
gid: string
trans_type: string
status: string
protocol: string
finish_time: string
options: string
next_cron_interval: number
next_cron_time: string
concurrent: boolean
}
}
interface Branches {
gid: string
branch_id: string
op: string
status: string
create_time: string
update_time: string
}
defineExpose({
open
})
</script>

5
admin/yarn.lock

@ -2681,6 +2681,11 @@ safe-regex@^1.1.0:
dependencies: dependencies:
ret "~0.1.10" ret "~0.1.10"
screenfull@^6.0.1:
version "6.0.1"
resolved "https://registry.npmmirror.com/screenfull/-/screenfull-6.0.1.tgz#3b71e6f06b72d817a8d3be73c45ebe71fa8da1ce"
integrity sha512-yzQW+j4zMUBQC51xxWaoDYjxOtl8Kn+xvue3p6v/fv2pIi1jH4AldgVLU8TBfFVgH2x3VXlf3+YiA/AYIPlaew==
scroll-into-view-if-needed@^2.2.25: scroll-into-view-if-needed@^2.2.25:
version "2.2.29" version "2.2.29"
resolved "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.29.tgz" resolved "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.29.tgz"

Loading…
Cancel
Save