mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 07:50:25 +08:00
160 lines
4.8 KiB
Vue
160 lines
4.8 KiB
Vue
<template>
|
|
<div id="terminalRecDialog">
|
|
<el-dialog
|
|
:title="title"
|
|
v-model="dialogVisible"
|
|
:before-close="handleClose"
|
|
:close-on-click-modal="false"
|
|
:destroy-on-close="true"
|
|
width="1000"
|
|
@open="getTermOps()"
|
|
>
|
|
<page-table ref="pageTableRef" :page-api="machineApi.termOpRecs" :lazy="true" height="100%" v-model:query-form="query" :columns="columns">
|
|
<template #action="{ data }">
|
|
<el-button @click="playRec(data)" loading-icon="loading" :loading="data.playRecLoding" type="primary" link>回放</el-button>
|
|
<el-button @click="showExecCmds(data)" type="primary" link>命令</el-button>
|
|
</template>
|
|
</page-table>
|
|
</el-dialog>
|
|
|
|
<el-dialog
|
|
:title="title"
|
|
v-model="playerDialogVisible"
|
|
:before-close="handleClosePlayer"
|
|
:close-on-click-modal="false"
|
|
:destroy-on-close="true"
|
|
width="70%"
|
|
>
|
|
<div ref="playerRef" id="rc-player"></div>
|
|
</el-dialog>
|
|
|
|
<el-dialog title="执行命令记录" v-model="execCmdsDialogVisible" :destroy-on-close="true" width="500">
|
|
<el-table :data="state.execCmds" max-height="480" stripe size="small">
|
|
<el-table-column prop="cmd" label="命令" show-overflow-tooltip min-width="150px"> </el-table-column>
|
|
<el-table-column prop="time" label="执行时间" min-width="80" show-overflow-tooltip>
|
|
<template #default="scope">
|
|
{{ formatDate(new Date(scope.row.time * 1000).toString()) }}
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { toRefs, watch, ref, reactive, nextTick, Ref } from 'vue';
|
|
import { machineApi } from './api';
|
|
import * as AsciinemaPlayer from 'asciinema-player';
|
|
import 'asciinema-player/dist/bundle/asciinema-player.css';
|
|
import PageTable from '@/components/pagetable/PageTable.vue';
|
|
import { TableColumn } from '@/components/pagetable';
|
|
import { formatDate } from '@/common/utils/format';
|
|
|
|
const props = defineProps({
|
|
visible: { type: Boolean },
|
|
machineId: { type: Number },
|
|
title: { type: String },
|
|
});
|
|
|
|
const emit = defineEmits(['update:visible', 'cancel', 'update:machineId']);
|
|
|
|
const columns = [
|
|
TableColumn.new('creator', '操作者').setMinWidth(120),
|
|
TableColumn.new('createTime', '开始时间').isTime().setMinWidth(150),
|
|
TableColumn.new('endTime', '结束时间').isTime().setMinWidth(150),
|
|
TableColumn.new('recordFilePath', '文件路径').setMinWidth(200),
|
|
TableColumn.new('action', '操作').isSlot().setMinWidth(120).fixedRight().alignCenter(),
|
|
];
|
|
|
|
const playerRef = ref(null);
|
|
const pageTableRef: Ref<any> = ref(null);
|
|
const state = reactive({
|
|
dialogVisible: false,
|
|
title: '',
|
|
query: {
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
machineId: 0,
|
|
},
|
|
playerDialogVisible: false,
|
|
execCmdsDialogVisible: false,
|
|
execCmds: [],
|
|
});
|
|
|
|
const { dialogVisible, query, playerDialogVisible, execCmdsDialogVisible } = toRefs(state);
|
|
|
|
watch(props, async (newValue: any) => {
|
|
const visible = newValue.visible;
|
|
state.dialogVisible = visible;
|
|
if (visible) {
|
|
state.query.machineId = newValue.machineId;
|
|
state.title = newValue.title;
|
|
}
|
|
});
|
|
|
|
const getTermOps = async () => {
|
|
pageTableRef.value.search();
|
|
};
|
|
|
|
const showExecCmds = (data: any) => {
|
|
state.execCmds = JSON.parse(data.execCmds);
|
|
state.execCmdsDialogVisible = true;
|
|
};
|
|
|
|
let player: any = null;
|
|
|
|
const playRec = async (rec: any) => {
|
|
try {
|
|
if (player) {
|
|
player.dispose();
|
|
}
|
|
rec.playRecLoding = true;
|
|
const content = await machineApi.termOpRec.request({
|
|
recId: rec.id,
|
|
id: rec.machineId,
|
|
});
|
|
|
|
state.playerDialogVisible = true;
|
|
nextTick(() => {
|
|
player = AsciinemaPlayer.create(`data:text/plain;base64,${content}`, playerRef.value, {
|
|
autoPlay: true,
|
|
speed: 1.0,
|
|
idleTimeLimit: 2,
|
|
// fit: false,
|
|
// terminalFontSize: 'small',
|
|
// cols: 144,
|
|
// rows: 32,
|
|
});
|
|
});
|
|
} finally {
|
|
rec.playRecLoding = false;
|
|
}
|
|
};
|
|
|
|
const handleClosePlayer = () => {
|
|
state.playerDialogVisible = false;
|
|
};
|
|
|
|
/**
|
|
* 关闭取消按钮触发的事件
|
|
*/
|
|
const handleClose = () => {
|
|
emit('update:visible', false);
|
|
emit('update:machineId', null);
|
|
emit('cancel');
|
|
};
|
|
</script>
|
|
<style lang="scss">
|
|
#terminalRecDialog {
|
|
overflow: hidden;
|
|
|
|
#rc-player {
|
|
overflow: hidden;
|
|
}
|
|
|
|
.el-overlay .el-overlay-dialog .el-dialog .el-dialog__body {
|
|
padding: 0px !important;
|
|
}
|
|
}
|
|
</style>
|