feat: 新增终端回放记录&其他小优化

This commit is contained in:
meilin.huang
2022-08-29 21:43:24 +08:00
parent 7761fe0288
commit 2f88b48973
87 changed files with 599 additions and 360 deletions

View File

@@ -13,7 +13,7 @@
"countup.js": "^2.0.7",
"cropperjs": "^1.5.11",
"echarts": "^5.3.3",
"element-plus": "^2.2.14",
"element-plus": "^2.2.15",
"jsencrypt": "^3.2.1",
"jsoneditor": "^9.9.0",
"lodash": "^4.17.21",
@@ -38,6 +38,7 @@
"@typescript-eslint/parser": "^4.23.0",
"@vitejs/plugin-vue": "^2.3.3",
"@vue/compiler-sfc": "^3.0.11",
"asciinema-player": "^3.0.1",
"dotenv": "^10.0.0",
"eslint": "^8.5.0",
"eslint-plugin-vue": "^8.2.0",

View File

@@ -7,3 +7,4 @@ declare module '*.vue' {
declare module 'codemirror';
declare module 'sql-formatter';
declare module 'jsoneditor';
declare module 'asciinema-player';

View File

@@ -163,7 +163,17 @@ export const staticRoutes: Array<RouteRecordRaw> = [
title: '终端 | {name}',
// 是否根据query对标题名进行参数替换即最终显示为终端_机器名
titleRename: true,
icon: 'iconfont icon-caidan',
},
},
{
path: '/machine/terminal-rec',
name: 'machineTerminalRec',
component: () => import('@/views/ops/machine/MachineRec.vue'),
meta: {
// 将路径 'xxx?name=名字' 里的name字段值替换到title里
title: '终端回放 | {name}',
// 是否根据query对标题名进行参数替换即最终显示为终端_机器名
titleRename: true,
},
},
];

View File

@@ -24,7 +24,7 @@
</el-form-item>
<el-form-item prop="host" label="host:" required>
<el-col :span="18">
<el-input v-model.trim="form.host" placeholder="请输入主机ip" auto-complete="off"></el-input>
<el-input :disabled="form.id" v-model.trim="form.host" placeholder="请输入主机ip" auto-complete="off"></el-input>
</el-col>
<el-col style="text-align: center" :span="1">:</el-col>
<el-col :span="5">

View File

@@ -66,7 +66,7 @@
:percentage="progressNum"
/>
<div style="height: 45vh; overflow: auto">
<el-tree v-if="tree.visible" ref="fileTree" :load="loadNode" :props="props" lazy node-key="id" :expand-on-click-node="true">
<el-tree v-if="tree.visible" ref="fileTree" :highlight-current="true" :load="loadNode" :props="props" lazy node-key="id" :expand-on-click-node="true">
<template #default="{ node, data }">
<span class="custom-tree-node">
<el-dropdown size="small" @visible-change="getFilePath(data, $event)" trigger="contextmenu">

View File

@@ -12,7 +12,7 @@
</el-form-item>
<el-form-item prop="ip" label="ip:" required>
<el-col :span="18">
<el-input v-model.trim="form.ip" placeholder="主机ip" auto-complete="off"></el-input>
<el-input :disabled="form.id" v-model.trim="form.ip" placeholder="主机ip" auto-complete="off"></el-input>
</el-col>
<el-col style="text-align: center" :span="1">:</el-col>
<el-col :span="5">
@@ -52,6 +52,10 @@
<el-input type="textarea" v-model="form.remark"></el-input>
</el-form-item>
<el-form-item prop="enableRecorder" label="终端回放:">
<el-checkbox v-model="form.enableRecorder" :true-label="1" :false-label="-1"></el-checkbox>
</el-form-item>
<el-form-item prop="enableSshTunnel" label="SSH隧道:">
<el-col :span="3">
<el-checkbox @change="getSshTunnelMachines" v-model="form.enableSshTunnel" :true-label="1" :false-label="-1"></el-checkbox>
@@ -122,6 +126,7 @@ export default defineComponent({
remark: '',
enableSshTunnel: null,
sshTunnelMachineId: null,
enableRecorder: -1,
},
pwd: '',
btnLoading: false,

View File

@@ -74,10 +74,10 @@
</template>
</el-table-column>
<el-table-column prop="creator" label="创建者" min-width="80"></el-table-column>
<el-table-column label="操作" min-width="280" fixed="right">
<el-table-column label="操作" min-width="335" fixed="right">
<template #default="scope">
<span v-auth="'machine:terminal'">
<el-link
v-auth="'machine:terminal'"
:disabled="scope.row.status == -1"
type="primary"
@click="showTerminal(scope.row)"
@@ -86,9 +86,16 @@
:underline="false"
>终端</el-link
>
<el-divider v-auth="'machine:terminal'" direction="vertical" border-style="dashed" />
<el-divider direction="vertical" border-style="dashed" />
</span>
<span v-auth="'machine:update'" v-if="scope.row.enableRecorder == 1">
<el-link @click="showRec(scope.row)" plain :underline="false" size="small">终端回放</el-link>
<el-divider direction="vertical" border-style="dashed" />
</span>
<span v-auth="'machine:file'">
<el-link
v-auth="'machine:file'"
type="success"
:disabled="scope.row.status == -1"
@click="fileManage(scope.row)"
@@ -97,7 +104,9 @@
:underline="false"
>文件</el-link
>
<el-divider v-auth="'machine:file'" direction="vertical" border-style="dashed" />
<el-divider direction="vertical" border-style="dashed" />
</span>
<el-link
:disabled="scope.row.status == -1"
type="warning"
@@ -108,10 +117,12 @@
>脚本</el-link
>
<el-divider direction="vertical" border-style="dashed" />
<el-link @click="showProcess(scope.row)" :disabled="scope.row.status == -1" plain :underline="false" size="small"
>进程</el-link
>
<el-divider direction="vertical" border-style="dashed" />
<el-link
:disabled="!scope.row.hasCli || scope.row.status == -1"
type="danger"
@@ -155,6 +166,8 @@
:machineId="machineStatsDialog.machineId"
:title="machineStatsDialog.title"
></machine-stats>
<!-- <machine-rec v-model:visible="machineRecDialog.visible" :title="machineRecDialog.title" :machine-id="machineRecDialog.machineId" /> -->
</div>
</template>
@@ -169,6 +182,7 @@ import FileManage from './FileManage.vue';
import MachineEdit from './MachineEdit.vue';
import ProcessList from './ProcessList.vue';
import MachineStats from './MachineStats.vue';
// import MachineRec from './MachineRec.vue';
export default defineComponent({
name: 'MachineList',
@@ -178,6 +192,7 @@ export default defineComponent({
FileManage,
MachineEdit,
MachineStats,
// MachineRec,
},
setup() {
const router = useRouter();
@@ -223,6 +238,11 @@ export default defineComponent({
data: null,
title: '新增机器',
},
machineRecDialog: {
visible: false,
machineId: 0,
title: '',
},
});
onMounted(async () => {
@@ -338,6 +358,17 @@ export default defineComponent({
state.processDialog.visible = true;
};
const showRec = (row: any) => {
const { href } = router.resolve({
path: `/machine/terminal-rec`,
query: {
id: row.id,
name: `${row.name}[${row.ip}]-终端回放记录`,
},
});
window.open(href, '_blank');
};
return {
...toRefs(state),
choose,
@@ -352,6 +383,7 @@ export default defineComponent({
submitSuccess,
fileManage,
search,
showRec,
handlePageChange,
};
},

View File

@@ -0,0 +1,120 @@
<template>
<div>
<div class="toolbar">
<span style="dispaly: inline-block" class="ml10">{{ title }}</span>
<el-divider direction="vertical" border-style="dashed" />
<el-select @change="getUsers" v-model="operateDate" placeholder="操作日期" filterable>
<el-option v-for="item in operateDates" :key="item" :label="item" :value="item"> </el-option>
</el-select>
<el-select class="ml10" @change="getRecs" filterable v-model="user" placeholder="请选择操作人">
<el-option v-for="item in users" :key="item" :label="item" :value="item"> </el-option>
</el-select>
<el-select class="ml10" @change="playRec" filterable v-model="rec" placeholder="请选择操作记录">
<el-option v-for="item in recs" :key="item" :label="item" :value="item"> </el-option>
</el-select>
<el-divider direction="vertical" border-style="dashed" />
快捷键-> space[空格键]: 暂停/播放 | f: 全屏/取消全屏
</div>
<div ref="playerRef" id="rc-player"></div>
</div>
</template>
<script lang="ts">
import { toRefs, onMounted, ref, reactive, defineComponent } from 'vue';
import { machineApi } from './api';
import * as AsciinemaPlayer from 'asciinema-player';
import 'asciinema-player/dist/bundle/asciinema-player.css';
import { useRoute } from 'vue-router';
export default defineComponent({
name: 'MachineRec',
components: {},
props: {
visible: { type: Boolean },
machineId: { type: Number },
title: { type: String },
},
setup(props: any, context) {
const route = useRoute();
const playerRef = ref(null);
const state = reactive({
dialogVisible: false,
title: '',
machineId: 0,
operateDates: [],
users: [],
recs: [],
operateDate: '',
user: '',
rec: '',
});
onMounted(() => {
state.machineId = Number.parseInt(route.query.id as string);
state.title = route.query.name as string;
getOperateDate();
});
const getOperateDate = async () => {
const res = await machineApi.recDirNames.request({ path: state.machineId });
state.operateDates = res as any;
};
const getUsers = async (operateDate: string) => {
state.users = [];
state.user = '';
state.recs = [];
state.rec = '';
const res = await machineApi.recDirNames.request({ path: `${state.machineId}/${operateDate}` });
state.users = res as any;
};
const getRecs = async (user: string) => {
state.recs = [];
state.rec = '';
const res = await machineApi.recDirNames.request({ path: `${state.machineId}/${state.operateDate}/${user}` });
state.recs = res as any;
};
let player: any = null;
const playRec = async (rec: string) => {
if (player) {
player.dispose();
}
const content = await machineApi.recDirNames.request({
isFile: '1',
path: `${state.machineId}/${state.operateDate}/${state.user}/${rec}`,
});
player = AsciinemaPlayer.create(`data:text/plain;base64,${content}`, playerRef.value, {
autoPlay: true,
speed: 1.0,
idleTimeLimit: 2,
});
};
/**
* 关闭取消按钮触发的事件
*/
const handleClose = () => {
context.emit('update:visible', false);
context.emit('update:machineId', null);
context.emit('cancel');
state.operateDates = [];
state.users = [];
state.recs = [];
state.operateDate = '';
state.user = '';
state.rec = '';
};
return {
...toRefs(state),
playerRef,
getUsers,
getRecs,
playRec,
handleClose,
};
},
});
</script>

View File

@@ -33,5 +33,6 @@ export const machineApi = {
addConf: Api.create("/machines/{machineId}/files", 'post'),
// 删除配置的文件or目录
delConf: Api.create("/machines/{machineId}/files/{id}", 'delete'),
terminal: Api.create("/api/machines/{id}/terminal", 'get')
terminal: Api.create("/api/machines/{id}/terminal", 'get'),
recDirNames: Api.create("/machines/rec/names", 'get')
}

View File

@@ -7,6 +7,13 @@
resolved "https://registry.npmmirror.com/@babel/parser/download/@babel/parser-7.16.6.tgz"
integrity sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==
"@babel/runtime@^7.15.4":
version "7.18.9"
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"
integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
dependencies:
regenerator-runtime "^0.13.4"
"@ctrl/tinycolor@^3.4.1":
version "3.4.1"
resolved "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz"
@@ -426,7 +433,7 @@ ansi-regex@^5.0.1:
resolved "https://registry.nlark.com/ansi-regex/download/ansi-regex-5.0.1.tgz"
integrity sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ=
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.nlark.com/ansi-styles/download/ansi-styles-4.3.0.tgz"
integrity sha1-7dgDYornHATIWuegkG7a00tkiTc=
@@ -451,6 +458,14 @@ array-union@^2.1.0:
resolved "https://registry.npm.taobao.org/array-union/download/array-union-2.1.0.tgz?cache=0&sync_timestamp=1614624262896&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-union%2Fdownload%2Farray-union-2.1.0.tgz"
integrity sha1-t5hCCtvrHego2ErNii4j0+/oXo0=
asciinema-player@^3.0.1:
version "3.0.1"
resolved "https://registry.npmmirror.com/asciinema-player/-/asciinema-player-3.0.1.tgz#4ea9e6ee2cc5c1f956bfb562950279dcfad3e737"
integrity sha512-plm/C/MhOtZWysrfcT/rzxOuu8vxvvDSvF50pqZS6KpJUDmATedAhO54zktbE/g7RiaaYfzgX8xjRhlQdgISwA==
dependencies:
"@babel/runtime" "^7.15.4"
solid-js "^1.3.0"
async-validator@^4.2.5:
version "4.2.5"
resolved "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz"
@@ -531,15 +546,6 @@ clipboard@^2.0.6:
select "^1.1.2"
tiny-emitter "^2.0.0"
cliui@^7.0.2:
version "7.0.4"
resolved "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.0"
wrap-ansi "^7.0.0"
codemirror@^5.65.5:
version "5.65.5"
resolved "https://registry.npmmirror.com/codemirror/-/codemirror-5.65.5.tgz"
@@ -593,6 +599,11 @@ csstype@^2.6.8:
resolved "https://registry.npmmirror.com/csstype/download/csstype-2.6.19.tgz?cache=0&sync_timestamp=1637224514674&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fcsstype%2Fdownload%2Fcsstype-2.6.19.tgz"
integrity sha512-ZVxXaNy28/k3kJg0Fou5MiYpp88j7H9hLZp8PDC3jV0WFjfH5E9xHb56L0W59cPbKbcHXeP4qyT8PrHp8t6LcQ==
csstype@^3.1.0:
version "3.1.0"
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2"
integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==
dayjs@^1.11.3:
version "1.11.3"
resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.3.tgz"
@@ -610,11 +621,6 @@ deep-is@^0.1.3:
resolved "https://registry.nlark.com/deep-is/download/deep-is-0.1.4.tgz"
integrity sha1-pvLc5hL63S7x9Rm3NVHxfoUZmDE=
define-lazy-prop@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz"
@@ -652,10 +658,10 @@ echarts@^5.3.3:
tslib "2.3.0"
zrender "5.3.2"
element-plus@^2.2.14:
version "2.2.14"
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.2.14.tgz#161f2cbf2c12608a570af303f8191c7d7eae725b"
integrity sha512-V5Pis0OHhePg1RgVogZrcefaVl8vjVn4Pn9Qsh/t2CbFgjg9kKOYFqf/tuP3ObSXGm3X89hpe0W+nLVAsaFnpw==
element-plus@^2.2.15:
version "2.2.15"
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.2.15.tgz#862bb6ecbd15b2d82d79dcf56bbbc30010771132"
integrity sha512-SMIx8xKB1YawT9JocyFhbs3Av2rXFfxrCVTLMYS0DK0xnW+fKvwjZngLfwF6MyRzXIuzNW17XFtu0iP3tlJHbA==
dependencies:
"@ctrl/tinycolor" "^3.4.1"
"@element-plus/icons-vue" "^2.0.6"
@@ -673,11 +679,6 @@ element-plus@^2.2.14:
memoize-one "^6.0.0"
normalize-wheel-es "^1.2.0"
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
enquirer@^2.3.5:
version "2.3.6"
resolved "https://registry.npm.taobao.org/enquirer/download/enquirer-2.3.6.tgz"
@@ -811,11 +812,6 @@ esbuild@^0.14.27:
esbuild-windows-64 "0.14.38"
esbuild-windows-arm64 "0.14.38"
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
escape-html@^1.0.3:
version "1.0.3"
resolved "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz"
@@ -1058,11 +1054,6 @@ functional-red-black-tree@^1.0.1:
resolved "https://registry.npm.taobao.org/functional-red-black-tree/download/functional-red-black-tree-1.0.1.tgz?cache=0&sync_timestamp=1577806294691&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffunctional-red-black-tree%2Fdownload%2Ffunctional-red-black-tree-1.0.1.tgz"
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.npmmirror.com/glob-parent/download/glob-parent-5.1.2.tgz"
@@ -1182,21 +1173,11 @@ is-core-module@^2.8.1:
dependencies:
has "^1.0.3"
is-docker@^2.0.0, is-docker@^2.1.1:
version "2.2.1"
resolved "https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz"
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
is-fullwidth-code-point@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.npmmirror.com/is-glob/download/is-glob-4.0.3.tgz"
@@ -1209,13 +1190,6 @@ is-number@^7.0.0:
resolved "https://registry.nlark.com/is-number/download/is-number-7.0.0.tgz"
integrity sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=
is-wsl@^2.2.0:
version "2.2.0"
resolved "https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
dependencies:
is-docker "^2.0.0"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.npm.taobao.org/isexe/download/isexe-2.0.0.tgz"
@@ -1419,15 +1393,6 @@ once@^1.3.0:
dependencies:
wrappy "1"
open@^8.4.0:
version "8.4.0"
resolved "https://registry.npmmirror.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8"
integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==
dependencies:
define-lazy-prop "^2.0.0"
is-docker "^2.1.1"
is-wsl "^2.2.0"
optionator@^0.9.1:
version "0.9.1"
resolved "https://registry.npm.taobao.org/optionator/download/optionator-0.9.1.tgz"
@@ -1532,16 +1497,16 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
regenerator-runtime@^0.13.4:
version "0.13.9"
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
regexpp@^3.1.0, regexpp@^3.2.0:
version "3.2.0"
resolved "https://registry.nlark.com/regexpp/download/regexpp-3.2.0.tgz?cache=0&sync_timestamp=1623668872577&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fregexpp%2Fdownload%2Fregexpp-3.2.0.tgz"
integrity sha1-BCWido2PI7rXDKS5BGH6LxIT4bI=
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.nlark.com/resolve-from/download/resolve-from-4.0.0.tgz"
@@ -1568,16 +1533,6 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
rollup-plugin-visualizer@^5.8.0:
version "5.8.0"
resolved "https://registry.npmmirror.com/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.8.0.tgz#32f2fe23d4299e977c06c59c07255590354e3445"
integrity sha512-pY6j/7qHz5I9rB7d/bQoA5gX+2FbV3MBG055wrsFxDn550bgl0FNViRj6wDHh85PMswv+JVdZjhnMBzz/hdAHA==
dependencies:
nanoid "^3.3.4"
open "^8.4.0"
source-map "^0.7.3"
yargs "^17.5.1"
rollup@^2.59.0:
version "2.61.1"
resolved "https://registry.npmmirror.com/rollup/download/rollup-2.61.1.tgz"
@@ -1643,6 +1598,13 @@ slash@^3.0.0:
resolved "https://registry.nlark.com/slash/download/slash-3.0.0.tgz"
integrity sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=
solid-js@^1.3.0:
version "1.5.1"
resolved "https://registry.npmmirror.com/solid-js/-/solid-js-1.5.1.tgz#b4281cf92cb00b235e62ef890d87ea996a9b9fa3"
integrity sha512-Y6aKystIxnrB0quV5nhqNuJV+l2Fk3/PQy1mMya/bzxlGiMHAym7v1NaqEgqDIvctbkxOi5dBj0ER/ewrH060g==
dependencies:
csstype "^3.1.0"
sortablejs@^1.13.0:
version "1.14.0"
resolved "https://registry.nlark.com/sortablejs/download/sortablejs-1.14.0.tgz?cache=0&sync_timestamp=1625423971526&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsortablejs%2Fdownload%2Fsortablejs-1.14.0.tgz"
@@ -1663,11 +1625,6 @@ source-map@^0.6.1:
resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz"
integrity sha1-dHIq8y6WFOnCh6jQu95IteLxomM=
source-map@^0.7.3:
version "0.7.4"
resolved "https://registry.npmmirror.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656"
integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
sourcemap-codec@^1.4.4:
version "1.4.8"
resolved "https://registry.npm.taobao.org/sourcemap-codec/download/sourcemap-codec-1.4.8.tgz"
@@ -1680,16 +1637,7 @@ sql-formatter@^9.2.0:
dependencies:
argparse "^2.0.1"
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmmirror.com/strip-ansi/download/strip-ansi-6.0.1.tgz"
integrity sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk=
@@ -1857,15 +1805,6 @@ word-wrap@^1.2.3:
resolved "https://registry.npm.taobao.org/word-wrap/download/word-wrap-1.2.3.tgz"
integrity sha1-YQY29rH3A4kb00dxzLF/uTtHB5w=
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.nlark.com/wrappy/download/wrappy-1.0.2.tgz?cache=0&sync_timestamp=1619133505879&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fwrappy%2Fdownload%2Fwrappy-1.0.2.tgz"
@@ -1881,34 +1820,11 @@ xterm@^4.19.0:
resolved "https://registry.npmmirror.com/xterm/-/xterm-4.19.0.tgz"
integrity sha512-c3Cp4eOVsYY5Q839dR5IejghRPpxciGmLWWaP9g+ppfMeBChMeLa1DCA+pmX/jyDZ+zxFOmlJL/82qVdayVoGQ==
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.nlark.com/yallist/download/yallist-4.0.0.tgz"
integrity sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=
yargs-parser@^21.0.0:
version "21.1.1"
resolved "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^17.5.1:
version "17.5.1"
resolved "https://registry.npmmirror.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e"
integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==
dependencies:
cliui "^7.0.2"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.0.0"
zrender@5.3.2:
version "5.3.2"
resolved "https://registry.npmmirror.com/zrender/-/zrender-5.3.2.tgz"

View File

@@ -7,6 +7,8 @@ server:
enable: false
key-file: ./default.key
cert-file: ./default.pem
# 机器终端操作回放文件存储路径
machine-rec-path: ./rec
jwt:
# jwt key不设置默认使用随机字符串
key:

View File

@@ -47,7 +47,7 @@ func InitRouter() *gin.Engine {
// 设置静态资源
if staticConfs := serverConfig.Static; staticConfs != nil {
for _, scs := range *staticConfs {
router.Static(scs.RelativePath, scs.Root)
router.StaticFS(scs.RelativePath, http.Dir(scs.Root))
}
}
// 设置静态文件

View File

@@ -13,6 +13,7 @@ type MachineForm struct {
Remark string `json:"remark"`
EnableSshTunnel int8 `json:"enableSshTunnel"` // 是否启用ssh隧道
SshTunnelMachineId uint64 `json:"sshTunnelMachineId"` // ssh隧道机器id
EnableRecorder int8 `json:"enableRecorder"` // 是否启用终端回放记录
}
type MachineRunForm struct {

View File

@@ -1,6 +1,7 @@
package api
import (
"encoding/base64"
"fmt"
"mayfly-go/internal/devops/api/form"
"mayfly-go/internal/devops/api/vo"
@@ -8,11 +9,17 @@ import (
"mayfly-go/internal/devops/domain/entity"
"mayfly-go/internal/devops/infrastructure/machine"
"mayfly-go/pkg/biz"
"mayfly-go/pkg/config"
"mayfly-go/pkg/ctx"
"mayfly-go/pkg/ginx"
"mayfly-go/pkg/utils"
"mayfly-go/pkg/ws"
"os"
"path"
"sort"
"strconv"
"syscall"
"time"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
@@ -145,15 +152,15 @@ func (m *Machine) KillProcess(rc *ctx.ReqCtx) {
func (m *Machine) WsSSH(g *gin.Context) {
wsConn, err := ws.Upgrader.Upgrade(g.Writer, g.Request, nil)
defer func() {
if wsConn != nil {
if err := recover(); err != nil {
wsConn.WriteMessage(websocket.TextMessage, []byte(err.(error).Error()))
}
wsConn.Close()
}
}()
if err != nil {
panic(biz.NewBizErr("升级websocket失败"))
}
biz.ErrIsNilAppendErr(err, "升级websocket失败: %s")
// 权限校验
rc := ctx.NewReqCtxWithGin(g).WithRequiredPermission(ctx.NewPermission("machine:terminal"))
if err = ctx.PermissionHandler(rc); err != nil {
@@ -166,12 +173,52 @@ func (m *Machine) WsSSH(g *gin.Context) {
cols := ginx.QueryInt(g, "cols", 80)
rows := ginx.QueryInt(g, "rows", 40)
mts, err := machine.NewTerminalSession(utils.RandString(16), wsConn, cli, rows, cols)
var recorder *machine.Recorder
if cli.GetMachine().EnableRecorder == 1 {
mask := syscall.Umask(0)
defer syscall.Umask(mask)
now := time.Now()
// 回放文件路径为: 基础配置路径/机器id/操作日期/操作者账号/操作时间.cast
recPath := fmt.Sprintf("%s/%d/%s/%s", config.Conf.Server.GetMachineRecPath(), cli.GetMachine().Id, now.Format("20060102"), rc.LoginAccount.Username)
os.MkdirAll(recPath, 0766)
fileName := path.Join(recPath, fmt.Sprintf("%s.cast", now.Format("20060102_150405")))
f, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0766)
biz.ErrIsNilAppendErr(err, "创建终端回放记录文件失败: %s")
defer f.Close()
recorder = machine.NewRecorder(f)
}
mts, err := machine.NewTerminalSession(utils.RandString(16), wsConn, cli, rows, cols, recorder)
biz.ErrIsNilAppendErr(err, "\033[1;31m连接失败: %s\033[0m")
mts.Start()
defer mts.Stop()
}
// 获取机器终端回放记录的相应文件夹名或文件内容
func (m *Machine) MachineRecDirNames(rc *ctx.ReqCtx) {
readPath := rc.GinCtx.Query("path")
biz.NotEmpty(readPath, "path不能为空")
path_ := path.Join(config.Conf.Server.GetMachineRecPath(), readPath)
// 如果是读取文件内容,则读取对应回放记录文件内容,否则读取文件夹名列表。小小偷懒一会不想再加个接口
isFile := rc.GinCtx.Query("isFile")
if isFile == "1" {
bytes, err := os.ReadFile(path_)
biz.ErrIsNilAppendErr(err, "还未有相应终端操作记录: %s")
rc.ResData = base64.StdEncoding.EncodeToString(bytes)
return
}
files, err := os.ReadDir(path_)
biz.ErrIsNilAppendErr(err, "还未有相应终端操作记录: %s")
var names []string
for _, f := range files {
names = append(names, f.Name())
}
sort.Sort(sort.Reverse(sort.StringSlice(names)))
rc.ResData = names
}
func GetMachineId(g *gin.Context) uint64 {
machineId, _ := strconv.Atoi(g.Param("machineId"))
biz.IsTrue(machineId != 0, "machineId错误")

View File

@@ -2,8 +2,8 @@ package api
import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"mayfly-go/internal/devops/api/form"
"mayfly-go/internal/devops/api/vo"
"mayfly-go/internal/devops/application"
@@ -98,7 +98,7 @@ func (m *MachineFile) ReadFileContent(rc *ctx.ReqCtx) {
path := strings.Split(readPath, "/")
rc.Download(sftpFile, path[len(path)-1])
} else {
datas, err := ioutil.ReadAll(sftpFile)
datas, err := io.ReadAll(sftpFile)
biz.ErrIsNilAppendErr(err, "读取文件内容失败: %s")
rc.ResData = string(datas)
}

View File

@@ -34,6 +34,7 @@ type MachineVO struct {
ModifierId *int64 `json:"modifierId"`
HasCli bool `json:"hasCli" gorm:"-"`
Remark *string `json:"remark"`
EnableRecorder int8 `json:"enableRecorder"`
}
type MachineScriptVO struct {

View File

@@ -19,6 +19,7 @@ type Machine struct {
Remark string `json:"remark"` // 备注
EnableSshTunnel int8 `json:"enableSshTunnel"` // 是否启用ssh隧道
SshTunnelMachineId uint64 `json:"sshTunnelMachineId"` // ssh隧道机器id
EnableRecorder int8 `json:"enableRecorder"` // 是否启用终端回放记录
}
const (

View File

@@ -0,0 +1,67 @@
package machine
import (
"encoding/json"
"io"
"sync"
"time"
)
type RecType string
const (
InputType RecType = "i"
OutPutType RecType = "o"
)
type RecHeader struct {
Version int `json:"version"`
Width int `json:"width"`
Height int `json:"height"`
Timestamp int64 `json:"timestamp"`
Env struct {
Shell string `json:"SHELL"`
Term string `json:"TERM"`
} `json:"env"`
}
func defaultRecHeader() *RecHeader {
recHeader := new(RecHeader)
recHeader.Version = 2
recHeader.Env.Shell = "/bin/bash"
recHeader.Env.Term = "xterm-256color"
return recHeader
}
type Recorder struct {
StartTime time.Time
Writer io.Writer
sync.Mutex
}
func NewRecorder(writer io.Writer) *Recorder {
return &Recorder{
StartTime: time.Now(),
Writer: writer,
}
}
func (rec *Recorder) WriteHeader(height, width int) {
header := defaultRecHeader()
header.Timestamp = rec.StartTime.Unix()
header.Height = height
header.Width = width
b, _ := json.Marshal(header)
rec.Writer.Write(b)
rec.Writer.Write([]byte("\r\n"))
}
func (rec *Recorder) WriteData(rectype RecType, data string) {
recData := make([]interface{}, 3)
recData[0] = float64(time.Since(rec.StartTime).Microseconds()) / float64(1000000)
recData[1] = rectype
recData[2] = data
b, _ := json.Marshal(recData)
rec.Writer.Write(b)
rec.Writer.Write([]byte("\r\n"))
}

View File

@@ -21,13 +21,14 @@ type TerminalSession struct {
ID string
wsConn *websocket.Conn
terminal *Terminal
recorder *Recorder
ctx context.Context
cancel context.CancelFunc
dataChan chan rune
tick *time.Ticker
}
func NewTerminalSession(sessionId string, ws *websocket.Conn, cli *Cli, rows, cols int) (*TerminalSession, error) {
func NewTerminalSession(sessionId string, ws *websocket.Conn, cli *Cli, rows, cols int, recorder *Recorder) (*TerminalSession, error) {
terminal, err := NewTerminal(cli)
if err != nil {
return nil, err
@@ -41,12 +42,17 @@ func NewTerminalSession(sessionId string, ws *websocket.Conn, cli *Cli, rows, co
return nil, err
}
if recorder != nil {
recorder.WriteHeader(rows-5, cols)
}
ctx, cancel := context.WithCancel(context.Background())
tick := time.NewTicker(time.Millisecond * time.Duration(60))
ts := &TerminalSession{
ID: sessionId,
wsConn: ws,
terminal: terminal,
recorder: recorder,
ctx: ctx,
cancel: cancel,
dataChan: make(chan rune),
@@ -65,9 +71,6 @@ func (r TerminalSession) Stop() {
global.Log.Debug("close machine ssh terminal session")
r.tick.Stop()
r.cancel()
if r.wsConn != nil {
r.wsConn.Close()
}
if r.terminal != nil {
if err := r.terminal.Close(); err != nil {
global.Log.Errorf("关闭机器ssh终端失败: %s", err.Error())
@@ -108,6 +111,12 @@ func (ts TerminalSession) writeToWebsocket() {
global.Log.Error("机器ssh终端发送消息至websocket失败: ", err)
return
}
// 如果记录器存在,则记录操作回放信息
if ts.recorder != nil {
ts.recorder.Lock()
ts.recorder.WriteData(OutPutType, s)
ts.recorder.Unlock()
}
buf = []byte{}
}
case data := <-ts.dataChan:

View File

@@ -43,9 +43,11 @@ func InitMachineRouter(router *gin.RouterGroup) {
})
saveMachine := ctx.NewLogInfo("保存机器信息").WithSave(true)
saveMachineP := ctx.NewPermission("machine:update")
machines.POST("", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).
WithLog(saveMachine).
WithRequiredPermission(saveMachineP).
Handle(m.SaveMachine)
})
@@ -69,5 +71,12 @@ func InitMachineRouter(router *gin.RouterGroup) {
})
machines.GET(":machineId/terminal", m.WsSSH)
// 获取机器终端回放记录的相应文件夹名或文件名,目前具有保存机器信息的权限标识才有权限查看终端回放
machines.GET("rec/names", func(c *gin.Context) {
ctx.NewReqCtxWithGin(c).
WithRequiredPermission(saveMachineP).
Handle(m.MachineRecDirNames)
})
}
}

View File

@@ -113,6 +113,7 @@ CREATE TABLE `t_machine` (
`password` varchar(3200) COLLATE utf8mb4_bin DEFAULT NULL,
`enable_ssh_tunnel` tinyint(2) DEFAULT NULL COMMENT '是否启用ssh隧道',
`ssh_tunnel_machine_id` bigint(20) DEFAULT NULL COMMENT 'ssh隧道的机器id',
`enable_recorder` tinyint(2) DEFAULT NULL COMMENT '是否启用终端回放记录',
`status` tinyint(2) NOT NULL COMMENT '状态: 1:启用; -1:禁用',
`remark` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
`need_monitor` tinyint(2) DEFAULT NULL,

View File

@@ -4,7 +4,7 @@ import "fmt"
const (
AppName = "mayfly-go"
Version = "v1.2.8"
Version = "v1.2.9"
)
func GetAppInfo() string {

View File

@@ -9,12 +9,22 @@ type Server struct {
Tls *Tls `yaml:"tls"`
Static *[]*Static `yaml:"static"`
StaticFile *[]*StaticFile `yaml:"static-file"`
MachineRecPath string `yaml:"machine-rec-path"` // 机器终端操作回放文件存储路径
}
func (s *Server) GetPort() string {
return fmt.Sprintf(":%d", s.Port)
}
// 获取终端回访记录存放基础路径, 如果配置文件未配置,则默认为./rec
func (s *Server) GetMachineRecPath() string {
path := s.MachineRecPath
if path == "" {
return "./rec"
}
return path
}
type Static struct {
RelativePath string `yaml:"relative-path"`
Root string `yaml:"root"`

View File

@@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
@@ -204,7 +203,7 @@ func request(rw *RequestWrapper) *ResponseWrapper {
return wrapper
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
wrapper.Body = []byte(fmt.Sprintf("读取HTTP请求返回值失败-%s", err.Error()))
return wrapper

View File

@@ -2,14 +2,14 @@ package utils
import (
"errors"
"io/ioutil"
"os"
"gopkg.in/yaml.v3"
)
// 从指定路径加载yaml文件
func LoadYml(path string, out interface{}) error {
yamlFileBytes, readErr := ioutil.ReadFile(path)
yamlFileBytes, readErr := os.ReadFile(path)
if readErr != nil {
return readErr
}

View File

@@ -1 +1 @@
import{_ as s,u as n,b as l,e as c,h as e,g as d,w as f,$ as m,Q as u,R as _,d as p,B as h}from"./index.1661515638242.js";var x="assets/401.1661515638242.png";const v={name:"401",setup(){const t=n();return{onSetAuth:()=>{m(),t.push("/login")}}}},o=t=>(u("data-v-6ec92039"),t=t(),_(),t),g={class:"error"},y={class:"error-flex"},b={class:"left"},C={class:"left-item"},B=o(()=>e("div",{class:"left-item-animation left-item-num"},"401",-1)),w=o(()=>e("div",{class:"left-item-animation left-item-title"},"\u60A8\u672A\u88AB\u6388\u6743\u6216\u767B\u5F55\u8D85\u65F6\uFF0C\u6CA1\u6709\u64CD\u4F5C\u6743\u9650",-1)),A=o(()=>e("div",{class:"left-item-animation left-item-msg"},null,-1)),S={class:"left-item-animation left-item-btn"},F=h("\u91CD\u65B0\u767B\u5F55"),k=o(()=>e("div",{class:"right"},[e("img",{src:x})],-1));function I(t,r,$,a,z,D){const i=l("el-button");return p(),c("div",g,[e("div",y,[e("div",b,[e("div",C,[B,w,A,e("div",S,[d(i,{type:"primary",round:"",onClick:a.onSetAuth},{default:f(()=>[F]),_:1},8,["onClick"])])])]),k])])}var V=s(v,[["render",I],["__scopeId","data-v-6ec92039"]]);export{V as default};
import{_ as s,u as n,b as l,e as c,h as e,g as d,w as f,$ as m,Q as u,R as _,d as p,B as h}from"./index.1661780212532.js";var x="assets/401.1661780212532.png";const v={name:"401",setup(){const t=n();return{onSetAuth:()=>{m(),t.push("/login")}}}},o=t=>(u("data-v-6ec92039"),t=t(),_(),t),g={class:"error"},y={class:"error-flex"},b={class:"left"},C={class:"left-item"},B=o(()=>e("div",{class:"left-item-animation left-item-num"},"401",-1)),w=o(()=>e("div",{class:"left-item-animation left-item-title"},"\u60A8\u672A\u88AB\u6388\u6743\u6216\u767B\u5F55\u8D85\u65F6\uFF0C\u6CA1\u6709\u64CD\u4F5C\u6743\u9650",-1)),A=o(()=>e("div",{class:"left-item-animation left-item-msg"},null,-1)),S={class:"left-item-animation left-item-btn"},F=h("\u91CD\u65B0\u767B\u5F55"),k=o(()=>e("div",{class:"right"},[e("img",{src:x})],-1));function I(t,r,$,a,z,D){const i=l("el-button");return p(),c("div",g,[e("div",y,[e("div",b,[e("div",C,[B,w,A,e("div",S,[d(i,{type:"primary",round:"",onClick:a.onSetAuth},{default:f(()=>[F]),_:1},8,["onClick"])])])]),k])])}var V=s(v,[["render",I],["__scopeId","data-v-6ec92039"]]);export{V as default};

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -1 +1 @@
import{_ as s,u as n,b as l,e as c,h as e,g as d,w as m,Q as f,R as u,d as _,B as p}from"./index.1661515638242.js";var h="assets/404.1661515638242.png";const x={name:"404",setup(){const t=n();return{onGoHome:()=>{t.push("/")}}}},o=t=>(f("data-v-69e91ac8"),t=t(),u(),t),v={class:"error"},g={class:"error-flex"},y={class:"left"},F={class:"left-item"},b=o(()=>e("div",{class:"left-item-animation left-item-num"},"404",-1)),C=o(()=>e("div",{class:"left-item-animation left-item-title"},"\u5730\u5740\u8F93\u5165\u6709\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165\u5730\u5740~",-1)),B=o(()=>e("div",{class:"left-item-animation left-item-msg"},"\u60A8\u53EF\u4EE5\u5148\u68C0\u67E5\u7F51\u5740\uFF0C\u7136\u540E\u91CD\u65B0\u8F93\u5165",-1)),E={class:"left-item-animation left-item-btn"},w=p("\u8FD4\u56DE\u9996\u9875"),k=o(()=>e("div",{class:"right"},[e("img",{src:h})],-1));function D(t,a,I,r,z,G){const i=l("el-button");return _(),c("div",v,[e("div",g,[e("div",y,[e("div",F,[b,C,B,e("div",E,[d(i,{type:"primary",round:"",onClick:r.onGoHome},{default:m(()=>[w]),_:1},8,["onClick"])])])]),k])])}var N=s(x,[["render",D],["__scopeId","data-v-69e91ac8"]]);export{N as default};
import{_ as s,u as n,b as l,e as c,h as e,g as d,w as m,Q as f,R as u,d as _,B as p}from"./index.1661780212532.js";var h="assets/404.1661780212532.png";const x={name:"404",setup(){const t=n();return{onGoHome:()=>{t.push("/")}}}},o=t=>(f("data-v-69e91ac8"),t=t(),u(),t),v={class:"error"},g={class:"error-flex"},y={class:"left"},F={class:"left-item"},b=o(()=>e("div",{class:"left-item-animation left-item-num"},"404",-1)),C=o(()=>e("div",{class:"left-item-animation left-item-title"},"\u5730\u5740\u8F93\u5165\u6709\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165\u5730\u5740~",-1)),B=o(()=>e("div",{class:"left-item-animation left-item-msg"},"\u60A8\u53EF\u4EE5\u5148\u68C0\u67E5\u7F51\u5740\uFF0C\u7136\u540E\u91CD\u65B0\u8F93\u5165",-1)),E={class:"left-item-animation left-item-btn"},w=p("\u8FD4\u56DE\u9996\u9875"),k=o(()=>e("div",{class:"right"},[e("img",{src:h})],-1));function D(t,a,I,r,z,G){const i=l("el-button");return _(),c("div",v,[e("div",g,[e("div",y,[e("div",F,[b,C,B,e("div",E,[d(i,{type:"primary",round:"",onClick:r.onGoHome},{default:m(()=>[w]),_:1},8,["onClick"])])])]),k])])}var N=s(x,[["render",D],["__scopeId","data-v-69e91ac8"]]);export{N as default};

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -1 +1 @@
import{p as r}from"./index.1661515638242.js";class s{constructor(t,e){this.url=t,this.method=e}setUrl(t){return this.url=t,this}setMethod(t){return this.method=t,this}getUrl(){return r.getApiUrl(this.url)}request(t=null,e=null){return r.send(this,t,e)}requestWithHeaders(t,e){return r.sendWithHeaders(this,t,e)}static create(t,e){return new s(t,e)}}export{s as A};
import{p as r}from"./index.1661780212532.js";class s{constructor(t,e){this.url=t,this.method=e}setUrl(t){return this.url=t,this}setMethod(t){return this.method=t,this}getUrl(){return r.getApiUrl(this.url)}request(t=null,e=null){return r.send(this,t,e)}requestWithHeaders(t,e){return r.sendWithHeaders(this,t,e)}static create(t,e){return new s(t,e)}}export{s as A};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
var Zt=Object.defineProperty,Ot=Object.defineProperties;var Dt=Object.getOwnPropertyDescriptors;var Wt=Object.getOwnPropertySymbols;var Kt=Object.prototype.hasOwnProperty,zt=Object.prototype.propertyIsEnumerable;var Ft=(Ie,le,Ge)=>le in Ie?Zt(Ie,le,{enumerable:!0,configurable:!0,writable:!0,value:Ge}):Ie[le]=Ge,kt=(Ie,le)=>{for(var Ge in le||(le={}))Kt.call(le,Ge)&&Ft(Ie,Ge,le[Ge]);if(Wt)for(var Ge of Wt(le))zt.call(le,Ge)&&Ft(Ie,Ge,le[Ge]);return Ie},Et=(Ie,le)=>Ot(Ie,Dt(le));import{m as ut}from"./api.16615156382426.js";import{P as Xt}from"./ProjectEnvSelect.1661515638242.js";import{i as Tt,a as Pt,b as Jt}from"./assert.1661515638242.js";import{f as Yt}from"./format.1661515638242.js";import{a6 as Ut,A as Gt,t as _t,q as Mt,r as Ht,o as Qt,a7 as qt,v as ei,_ as Vt,m as ti,d as qe,e as gt,h as tt,l as ii,b as Ye,g as Be,w as We,F as It,j as bt,k as mt,i as Rt,z as ni,E as ft,B as yt}from"./index.1661515638242.js";import"./Api.1661515638242.js";import"./api.16615156382424.js";var jt={exports:{}};/*!
var Zt=Object.defineProperty,Ot=Object.defineProperties;var Dt=Object.getOwnPropertyDescriptors;var Wt=Object.getOwnPropertySymbols;var Kt=Object.prototype.hasOwnProperty,zt=Object.prototype.propertyIsEnumerable;var Ft=(Ie,le,Ge)=>le in Ie?Zt(Ie,le,{enumerable:!0,configurable:!0,writable:!0,value:Ge}):Ie[le]=Ge,kt=(Ie,le)=>{for(var Ge in le||(le={}))Kt.call(le,Ge)&&Ft(Ie,Ge,le[Ge]);if(Wt)for(var Ge of Wt(le))zt.call(le,Ge)&&Ft(Ie,Ge,le[Ge]);return Ie},Et=(Ie,le)=>Ot(Ie,Dt(le));import{m as ut}from"./api.16617802125326.js";import{P as Xt}from"./ProjectEnvSelect.1661780212532.js";import{i as Tt,a as Pt,b as Jt}from"./assert.1661780212532.js";import{f as Yt}from"./format.1661780212532.js";import{a6 as Ut,A as Gt,t as _t,q as Mt,r as Ht,o as Qt,a7 as qt,v as ei,_ as Vt,m as ti,d as qe,e as gt,h as tt,l as ii,b as Ye,g as Be,w as We,F as It,j as bt,k as mt,i as Rt,z as ni,E as ft,B as yt}from"./index.1661780212532.js";import"./Api.1661780212532.js";import"./api.16617802125324.js";var jt={exports:{}};/*!
* jsoneditor.js
*
* @brief

View File

@@ -1 +1 @@
var P=Object.defineProperty,V=Object.defineProperties;var w=Object.getOwnPropertyDescriptors;var v=Object.getOwnPropertySymbols;var B=Object.prototype.hasOwnProperty,$=Object.prototype.propertyIsEnumerable;var h=(o,e,n)=>e in o?P(o,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):o[e]=n,j=(o,e)=>{for(var n in e||(e={}))B.call(e,n)&&h(o,n,e[n]);if(v)for(var n of v(e))$.call(e,n)&&h(o,n,e[n]);return o},_=(o,e)=>V(o,w(e));import{p as g}from"./api.16615156382424.js";import{A as S,r as F,o as A,t as N,_ as q,b as p,d as r,e as u,g as s,w as a,F as b,j as y,k as E,h as I,i as k,a5 as U}from"./index.1661515638242.js";const z=S({name:"ProjectEnvSelect",props:{visible:{type:Boolean},data:{type:Object},title:{type:String},machineId:{type:Number},isCommon:{type:Boolean}},setup(o,{emit:e}){const n=F({projects:[],envs:[],projectId:null,envId:null});A(async()=>{n.projects=await g.accountProjects.request(null)});const c=async l=>{e("update:projectId",l),e("changeProjectEnv",n.projectId,null),n.envId=null,n.envs=await g.projectEnvs.request({projectId:l})},d=l=>{e("update:envId",l),e("changeProjectEnv",n.projectId,l)};return _(j({},N(n)),{changeProject:c,changeEnv:d})}}),D={style:{float:"left"}},L={style:{float:"right",color:"#8492a6","font-size":"13px"}};function M(o,e,n,c,d,l){const i=p("el-option"),f=p("el-select"),m=p("el-form-item"),C=p("el-form");return r(),u("div",null,[s(C,{class:"search-form","label-position":"right",inline:!0},{default:a(()=>[s(m,{prop:"project",label:"\u9879\u76EE","label-width":"40px"},{default:a(()=>[s(f,{modelValue:o.projectId,"onUpdate:modelValue":e[0]||(e[0]=t=>o.projectId=t),placeholder:"\u8BF7\u9009\u62E9\u9879\u76EE",onChange:o.changeProject,filterable:""},{default:a(()=>[(r(!0),u(b,null,y(o.projects,t=>(r(),E(i,{key:t.id,label:`${t.name} [${t.remark}]`,value:t.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue","onChange"])]),_:1}),s(m,{prop:"env",label:"env","label-width":"33px"},{default:a(()=>[s(f,{style:{width:"80px"},modelValue:o.envId,"onUpdate:modelValue":e[1]||(e[1]=t=>o.envId=t),placeholder:"\u73AF\u5883",onChange:o.changeEnv,filterable:""},{default:a(()=>[(r(!0),u(b,null,y(o.envs,t=>(r(),E(i,{key:t.id,label:t.name,value:t.id},{default:a(()=>[I("span",D,k(t.name),1),I("span",L,k(t.remark),1)]),_:2},1032,["label","value"]))),128))]),_:1},8,["modelValue","onChange"])]),_:1}),U(o.$slots,"default")]),_:3})])}var H=q(z,[["render",M]]);export{H as P};
var P=Object.defineProperty,V=Object.defineProperties;var w=Object.getOwnPropertyDescriptors;var v=Object.getOwnPropertySymbols;var B=Object.prototype.hasOwnProperty,$=Object.prototype.propertyIsEnumerable;var h=(o,e,n)=>e in o?P(o,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):o[e]=n,j=(o,e)=>{for(var n in e||(e={}))B.call(e,n)&&h(o,n,e[n]);if(v)for(var n of v(e))$.call(e,n)&&h(o,n,e[n]);return o},_=(o,e)=>V(o,w(e));import{p as g}from"./api.16617802125324.js";import{A as S,r as F,o as A,t as N,_ as q,b as p,d as r,e as u,g as s,w as a,F as b,j as y,k as E,h as I,i as k,a5 as U}from"./index.1661780212532.js";const z=S({name:"ProjectEnvSelect",props:{visible:{type:Boolean},data:{type:Object},title:{type:String},machineId:{type:Number},isCommon:{type:Boolean}},setup(o,{emit:e}){const n=F({projects:[],envs:[],projectId:null,envId:null});A(async()=>{n.projects=await g.accountProjects.request(null)});const c=async l=>{e("update:projectId",l),e("changeProjectEnv",n.projectId,null),n.envId=null,n.envs=await g.projectEnvs.request({projectId:l})},d=l=>{e("update:envId",l),e("changeProjectEnv",n.projectId,l)};return _(j({},N(n)),{changeProject:c,changeEnv:d})}}),D={style:{float:"left"}},L={style:{float:"right",color:"#8492a6","font-size":"13px"}};function M(o,e,n,c,d,l){const i=p("el-option"),f=p("el-select"),m=p("el-form-item"),C=p("el-form");return r(),u("div",null,[s(C,{class:"search-form","label-position":"right",inline:!0},{default:a(()=>[s(m,{prop:"project",label:"\u9879\u76EE","label-width":"40px"},{default:a(()=>[s(f,{modelValue:o.projectId,"onUpdate:modelValue":e[0]||(e[0]=t=>o.projectId=t),placeholder:"\u8BF7\u9009\u62E9\u9879\u76EE",onChange:o.changeProject,filterable:""},{default:a(()=>[(r(!0),u(b,null,y(o.projects,t=>(r(),E(i,{key:t.id,label:`${t.name} [${t.remark}]`,value:t.id},null,8,["label","value"]))),128))]),_:1},8,["modelValue","onChange"])]),_:1}),s(m,{prop:"env",label:"env","label-width":"33px"},{default:a(()=>[s(f,{style:{width:"80px"},modelValue:o.envId,"onUpdate:modelValue":e[1]||(e[1]=t=>o.envId=t),placeholder:"\u73AF\u5883",onChange:o.changeEnv,filterable:""},{default:a(()=>[(r(!0),u(b,null,y(o.envs,t=>(r(),E(i,{key:t.id,label:t.name,value:t.id},{default:a(()=>[I("span",D,k(t.name),1),I("span",L,k(t.remark),1)]),_:2},1032,["label","value"]))),128))]),_:1},8,["modelValue","onChange"])]),_:1}),U(o.$slots,"default")]),_:3})])}var H=q(z,[["render",M]]);export{H as P};

View File

@@ -1 +1 @@
var i=Object.defineProperty;var a=Object.getOwnPropertySymbols;var m=Object.prototype.hasOwnProperty,h=Object.prototype.propertyIsEnumerable;var s=(n,e,t)=>e in n?i(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,o=(n,e)=>{for(var t in e||(e={}))m.call(e,t)&&s(n,t,e[t]);if(a)for(var t of a(e))h.call(e,t)&&s(n,t,e[t]);return n};import{S as c}from"./SshTerminal.1661515638242.js";import{_ as p,A as d,S as l,r as u,o as f,t as _,b as g,e as I,g as S,d as v}from"./index.1661515638242.js";const $=d({name:"SshTerminalPage",components:{SshTerminal:c},props:{machineId:{type:Number}},setup(){const n=l(),e=u({machineId:0,height:700});return f(()=>{e.height=window.innerHeight+5,e.machineId=Number.parseInt(n.query.id)}),o({},_(e))}});function b(n,e,t,N,T,k){const r=g("ssh-terminal");return v(),I("div",null,[S(r,{ref:"terminal",machineId:n.machineId,height:n.height+"px"},null,8,["machineId","height"])])}var B=p($,[["render",b]]);export{B as default};
var i=Object.defineProperty;var a=Object.getOwnPropertySymbols;var m=Object.prototype.hasOwnProperty,h=Object.prototype.propertyIsEnumerable;var s=(n,e,t)=>e in n?i(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,o=(n,e)=>{for(var t in e||(e={}))m.call(e,t)&&s(n,t,e[t]);if(a)for(var t of a(e))h.call(e,t)&&s(n,t,e[t]);return n};import{S as c}from"./SshTerminal.1661780212532.js";import{_ as p,A as d,S as l,r as u,o as f,t as _,b as g,e as I,g as S,d as v}from"./index.1661780212532.js";const $=d({name:"SshTerminalPage",components:{SshTerminal:c},props:{machineId:{type:Number}},setup(){const n=l(),e=u({machineId:0,height:700});return f(()=>{e.height=window.innerHeight+5,e.machineId=Number.parseInt(n.query.id)}),o({},_(e))}});function b(n,e,t,N,T,k){const r=g("ssh-terminal");return v(),I("div",null,[S(r,{ref:"terminal",machineId:n.machineId,height:n.height+"px"},null,8,["machineId","height"])])}var B=p($,[["render",b]]);export{B as default};

View File

@@ -1 +1 @@
var k=Object.defineProperty,B=Object.defineProperties;var N=Object.getOwnPropertyDescriptors;var f=Object.getOwnPropertySymbols;var z=Object.prototype.hasOwnProperty,A=Object.prototype.propertyIsEnumerable;var h=(e,t,a)=>t in e?k(e,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):e[t]=a,w=(e,t)=>{for(var a in t||(t={}))z.call(t,a)&&h(e,a,t[a]);if(f)for(var a of f(t))A.call(t,a)&&h(e,a,t[a]);return e},C=(e,t)=>B(e,N(t));import{l as S,b as $}from"./api.16615156382422.js";import{_ as j,A as L,r as P,o as T,t as U,b as n,d as p,e as b,g as o,w as u,h as I,F as M,j as R,k as c,B as d,i as G,z as F}from"./index.1661515638242.js";import"./Api.1661515638242.js";const H=L({name:"SyslogList",components:{},setup(){const e=P({query:{pageNum:1,pageSize:10,name:null},total:0,logs:[],accounts:[]});T(()=>{t()});const t=async()=>{let r=await S.list.request(e.query);e.logs=r.list,e.total=r.total},a=r=>{e.query.pageNum=r,t()},m=r=>{$.list.request({username:r}).then(g=>{e.accounts=g.list})};return C(w({},U(e)),{search:t,handlePageChange:a,getAccount:m})}}),J={class:"role-list"},K={style:{float:"right"}},O=d("\u6210\u529F"),Q=d("\u5931\u8D25");function W(e,t,a,m,r,g){const i=n("el-option"),_=n("el-select"),v=n("el-button"),s=n("el-table-column"),y=n("el-tag"),q=n("el-table"),D=n("el-pagination"),E=n("el-row"),V=n("el-card");return p(),b("div",J,[o(V,null,{default:u(()=>[I("div",K,[o(_,{remote:"","remote-method":e.getAccount,modelValue:e.query.creatorId,"onUpdate:modelValue":t[0]||(t[0]=l=>e.query.creatorId=l),filterable:"",placeholder:"\u8BF7\u8F93\u5165\u5E76\u9009\u62E9\u8D26\u53F7",clearable:"",class:"mr5"},{default:u(()=>[(p(!0),b(M,null,R(e.accounts,l=>(p(),c(i,{key:l.id,label:l.username,value:l.id},null,8,["label","value"]))),128))]),_:1},8,["remote-method","modelValue"]),o(_,{modelValue:e.query.type,"onUpdate:modelValue":t[1]||(t[1]=l=>e.query.type=l),filterable:"",placeholder:"\u8BF7\u9009\u62E9\u64CD\u4F5C\u7ED3\u679C",clearable:"",class:"mr5"},{default:u(()=>[o(i,{label:"\u6210\u529F",value:1}),o(i,{label:"\u5931\u8D25",value:2})]),_:1},8,["modelValue"]),o(v,{onClick:e.search,type:"success",icon:"search"},null,8,["onClick"])]),o(q,{data:e.logs,style:{width:"100%"}},{default:u(()=>[o(s,{prop:"creator",label:"\u64CD\u4F5C\u4EBA","min-width":"100","show-overflow-tooltip":""}),o(s,{prop:"createTime",label:"\u64CD\u4F5C\u65F6\u95F4","min-width":"160"},{default:u(l=>[d(G(e.$filters.dateFormat(l.row.createTime)),1)]),_:1}),o(s,{prop:"type",label:"\u7ED3\u679C","min-width":"65"},{default:u(l=>[l.row.type==1?(p(),c(y,{key:0,type:"success",size:"small"},{default:u(()=>[O]),_:1})):F("",!0),l.row.type==2?(p(),c(y,{key:1,type:"danger",size:"small"},{default:u(()=>[Q]),_:1})):F("",!0)]),_:1}),o(s,{prop:"description",label:"\u63CF\u8FF0","min-width":"160","show-overflow-tooltip":""}),o(s,{prop:"reqParam",label:"\u8BF7\u6C42\u4FE1\u606F","min-width":"300","show-overflow-tooltip":""}),o(s,{prop:"resp",label:"\u54CD\u5E94\u4FE1\u606F","min-width":"200","show-overflow-tooltip":""})]),_:1},8,["data"]),o(E,{style:{"margin-top":"20px"},type:"flex",justify:"end"},{default:u(()=>[o(D,{style:{"text-align":"right"},onCurrentChange:e.handlePageChange,total:e.total,layout:"prev, pager, next, total, jumper","current-page":e.query.pageNum,"onUpdate:current-page":t[2]||(t[2]=l=>e.query.pageNum=l),"page-size":e.query.pageSize},null,8,["onCurrentChange","total","current-page","page-size"])]),_:1})]),_:1})])}var ee=j(H,[["render",W]]);export{ee as default};
var k=Object.defineProperty,B=Object.defineProperties;var N=Object.getOwnPropertyDescriptors;var f=Object.getOwnPropertySymbols;var z=Object.prototype.hasOwnProperty,A=Object.prototype.propertyIsEnumerable;var h=(e,t,a)=>t in e?k(e,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):e[t]=a,w=(e,t)=>{for(var a in t||(t={}))z.call(t,a)&&h(e,a,t[a]);if(f)for(var a of f(t))A.call(t,a)&&h(e,a,t[a]);return e},C=(e,t)=>B(e,N(t));import{l as S,b as $}from"./api.16617802125322.js";import{_ as j,A as L,r as P,o as T,t as U,b as n,d as p,e as b,g as o,w as u,h as I,F as M,j as R,k as c,B as d,i as G,z as F}from"./index.1661780212532.js";import"./Api.1661780212532.js";const H=L({name:"SyslogList",components:{},setup(){const e=P({query:{pageNum:1,pageSize:10,name:null},total:0,logs:[],accounts:[]});T(()=>{t()});const t=async()=>{let r=await S.list.request(e.query);e.logs=r.list,e.total=r.total},a=r=>{e.query.pageNum=r,t()},m=r=>{$.list.request({username:r}).then(g=>{e.accounts=g.list})};return C(w({},U(e)),{search:t,handlePageChange:a,getAccount:m})}}),J={class:"role-list"},K={style:{float:"right"}},O=d("\u6210\u529F"),Q=d("\u5931\u8D25");function W(e,t,a,m,r,g){const i=n("el-option"),_=n("el-select"),v=n("el-button"),s=n("el-table-column"),y=n("el-tag"),q=n("el-table"),D=n("el-pagination"),E=n("el-row"),V=n("el-card");return p(),b("div",J,[o(V,null,{default:u(()=>[I("div",K,[o(_,{remote:"","remote-method":e.getAccount,modelValue:e.query.creatorId,"onUpdate:modelValue":t[0]||(t[0]=l=>e.query.creatorId=l),filterable:"",placeholder:"\u8BF7\u8F93\u5165\u5E76\u9009\u62E9\u8D26\u53F7",clearable:"",class:"mr5"},{default:u(()=>[(p(!0),b(M,null,R(e.accounts,l=>(p(),c(i,{key:l.id,label:l.username,value:l.id},null,8,["label","value"]))),128))]),_:1},8,["remote-method","modelValue"]),o(_,{modelValue:e.query.type,"onUpdate:modelValue":t[1]||(t[1]=l=>e.query.type=l),filterable:"",placeholder:"\u8BF7\u9009\u62E9\u64CD\u4F5C\u7ED3\u679C",clearable:"",class:"mr5"},{default:u(()=>[o(i,{label:"\u6210\u529F",value:1}),o(i,{label:"\u5931\u8D25",value:2})]),_:1},8,["modelValue"]),o(v,{onClick:e.search,type:"success",icon:"search"},null,8,["onClick"])]),o(q,{data:e.logs,style:{width:"100%"}},{default:u(()=>[o(s,{prop:"creator",label:"\u64CD\u4F5C\u4EBA","min-width":"100","show-overflow-tooltip":""}),o(s,{prop:"createTime",label:"\u64CD\u4F5C\u65F6\u95F4","min-width":"160"},{default:u(l=>[d(G(e.$filters.dateFormat(l.row.createTime)),1)]),_:1}),o(s,{prop:"type",label:"\u7ED3\u679C","min-width":"65"},{default:u(l=>[l.row.type==1?(p(),c(y,{key:0,type:"success",size:"small"},{default:u(()=>[O]),_:1})):F("",!0),l.row.type==2?(p(),c(y,{key:1,type:"danger",size:"small"},{default:u(()=>[Q]),_:1})):F("",!0)]),_:1}),o(s,{prop:"description",label:"\u63CF\u8FF0","min-width":"160","show-overflow-tooltip":""}),o(s,{prop:"reqParam",label:"\u8BF7\u6C42\u4FE1\u606F","min-width":"300","show-overflow-tooltip":""}),o(s,{prop:"resp",label:"\u54CD\u5E94\u4FE1\u606F","min-width":"200","show-overflow-tooltip":""})]),_:1},8,["data"]),o(E,{style:{"margin-top":"20px"},type:"flex",justify:"end"},{default:u(()=>[o(D,{style:{"text-align":"right"},onCurrentChange:e.handlePageChange,total:e.total,layout:"prev, pager, next, total, jumper","current-page":e.query.pageNum,"onUpdate:current-page":t[2]||(t[2]=l=>e.query.pageNum=l),"page-size":e.query.pageSize},null,8,["onCurrentChange","total","current-page","page-size"])]),_:1})]),_:1})])}var ee=j(H,[["render",W]]);export{ee as default};

View File

@@ -1 +1 @@
import{A as s}from"./Api.1661515638242.js";const t={list:s.create("/sys/resources","get"),detail:s.create("/sys/resources/{id}","get"),save:s.create("/sys/resources","post"),update:s.create("/sys/resources/{id}","put"),del:s.create("/sys/resources/{id}","delete"),changeStatus:s.create("/sys/resources/{id}/{status}","put")},c={list:s.create("/sys/roles","get"),save:s.create("/sys/roles","post"),update:s.create("/sys/roles/{id}","put"),del:s.create("/sys/roles/{id}","delete"),roleResourceIds:s.create("/sys/roles/{id}/resourceIds","get"),roleResources:s.create("/sys/roles/{id}/resources","get"),saveResources:s.create("/sys/roles/{id}/resources","post")},r={list:s.create("/sys/accounts","get"),save:s.create("/sys/accounts","post"),update:s.create("/sys/accounts/{id}","put"),del:s.create("/sys/accounts/{id}","delete"),changeStatus:s.create("/sys/accounts/change-status/{id}/{status}","put"),roleIds:s.create("/sys/accounts/{id}/roleIds","get"),roles:s.create("/sys/accounts/{id}/roles","get"),resources:s.create("/sys/accounts/{id}/resources","get"),saveRoles:s.create("/sys/accounts/roles","post")},a={list:s.create("/sys/configs","get"),save:s.create("/sys/configs","post"),getValue:s.create("/sys/configs/value","get")},o={list:s.create("/syslogs","get")};export{c as a,r as b,a as c,o as l,t as r};
import{A as s}from"./Api.1661780212532.js";const t={list:s.create("/sys/resources","get"),detail:s.create("/sys/resources/{id}","get"),save:s.create("/sys/resources","post"),update:s.create("/sys/resources/{id}","put"),del:s.create("/sys/resources/{id}","delete"),changeStatus:s.create("/sys/resources/{id}/{status}","put")},c={list:s.create("/sys/roles","get"),save:s.create("/sys/roles","post"),update:s.create("/sys/roles/{id}","put"),del:s.create("/sys/roles/{id}","delete"),roleResourceIds:s.create("/sys/roles/{id}/resourceIds","get"),roleResources:s.create("/sys/roles/{id}/resources","get"),saveResources:s.create("/sys/roles/{id}/resources","post")},r={list:s.create("/sys/accounts","get"),save:s.create("/sys/accounts","post"),update:s.create("/sys/accounts/{id}","put"),del:s.create("/sys/accounts/{id}","delete"),changeStatus:s.create("/sys/accounts/change-status/{id}/{status}","put"),roleIds:s.create("/sys/accounts/{id}/roleIds","get"),roles:s.create("/sys/accounts/{id}/roles","get"),resources:s.create("/sys/accounts/{id}/resources","get"),saveRoles:s.create("/sys/accounts/roles","post")},a={list:s.create("/sys/configs","get"),save:s.create("/sys/configs","post"),getValue:s.create("/sys/configs/value","get")},o={list:s.create("/syslogs","get")};export{c as a,r as b,a as c,o as l,t as r};

View File

@@ -1 +1 @@
import{A as e}from"./Api.1661515638242.js";const c={list:e.create("/machines","get"),getMachinePwd:e.create("/machines/{id}/pwd","get"),info:e.create("/machines/{id}/sysinfo","get"),stats:e.create("/machines/{id}/stats","get"),process:e.create("/machines/{id}/process","get"),killProcess:e.create("/machines/{id}/process","delete"),closeCli:e.create("/machines/{id}/close-cli","delete"),saveMachine:e.create("/machines","post"),changeStatus:e.create("/machines/{id}/{status}","put"),del:e.create("/machines/{id}","delete"),scripts:e.create("/machines/{machineId}/scripts","get"),runScript:e.create("/machines/{machineId}/scripts/{scriptId}/run","get"),saveScript:e.create("/machines/{machineId}/scripts","post"),deleteScript:e.create("/machines/{machineId}/scripts/{scriptId}","delete"),files:e.create("/machines/{id}/files","get"),lsFile:e.create("/machines/{machineId}/files/{fileId}/read-dir","get"),rmFile:e.create("/machines/{machineId}/files/{fileId}/remove","delete"),uploadFile:e.create("/machines/{machineId}/files/{fileId}/upload?token={token}","post"),fileContent:e.create("/machines/{machineId}/files/{fileId}/read","get"),createFile:e.create("/machines/{machineId}/files/{id}/create-file","post"),updateFileContent:e.create("/machines/{machineId}/files/{id}/write","post"),addConf:e.create("/machines/{machineId}/files","post"),delConf:e.create("/machines/{machineId}/files/{id}","delete"),terminal:e.create("/api/machines/{id}/terminal","get")};export{c as m};
import{A as e}from"./Api.1661780212532.js";const c={list:e.create("/machines","get"),getMachinePwd:e.create("/machines/{id}/pwd","get"),info:e.create("/machines/{id}/sysinfo","get"),stats:e.create("/machines/{id}/stats","get"),process:e.create("/machines/{id}/process","get"),killProcess:e.create("/machines/{id}/process","delete"),closeCli:e.create("/machines/{id}/close-cli","delete"),saveMachine:e.create("/machines","post"),changeStatus:e.create("/machines/{id}/{status}","put"),del:e.create("/machines/{id}","delete"),scripts:e.create("/machines/{machineId}/scripts","get"),runScript:e.create("/machines/{machineId}/scripts/{scriptId}/run","get"),saveScript:e.create("/machines/{machineId}/scripts","post"),deleteScript:e.create("/machines/{machineId}/scripts/{scriptId}","delete"),files:e.create("/machines/{id}/files","get"),lsFile:e.create("/machines/{machineId}/files/{fileId}/read-dir","get"),rmFile:e.create("/machines/{machineId}/files/{fileId}/remove","delete"),uploadFile:e.create("/machines/{machineId}/files/{fileId}/upload?token={token}","post"),fileContent:e.create("/machines/{machineId}/files/{fileId}/read","get"),createFile:e.create("/machines/{machineId}/files/{id}/create-file","post"),updateFileContent:e.create("/machines/{machineId}/files/{id}/write","post"),addConf:e.create("/machines/{machineId}/files","post"),delConf:e.create("/machines/{machineId}/files/{id}","delete"),terminal:e.create("/api/machines/{id}/terminal","get"),recDirNames:e.create("/machines/rec/names","get")};export{c as m};

View File

@@ -1 +1 @@
import{A as e}from"./Api.1661515638242.js";const c={accountProjects:e.create("/accounts/projects","get"),projects:e.create("/projects","get"),saveProject:e.create("/projects","post"),delProject:e.create("/projects","delete"),projectEnvs:e.create("/projects/{projectId}/envs","get"),saveProjectEnv:e.create("/projects/{projectId}/envs","post"),projectMems:e.create("/projects/{projectId}/members","get"),saveProjectMem:e.create("/projects/{projectId}/members","post"),deleteProjectMem:e.create("/projects/{projectId}/members/{accountId}","delete")};export{c as p};
import{A as e}from"./Api.1661780212532.js";const c={accountProjects:e.create("/accounts/projects","get"),projects:e.create("/projects","get"),saveProject:e.create("/projects","post"),delProject:e.create("/projects","delete"),projectEnvs:e.create("/projects/{projectId}/envs","get"),saveProjectEnv:e.create("/projects/{projectId}/envs","post"),projectMems:e.create("/projects/{projectId}/members","get"),saveProjectMem:e.create("/projects/{projectId}/members","post"),deleteProjectMem:e.create("/projects/{projectId}/members/{accountId}","delete")};export{c as p};

View File

@@ -1 +1 @@
import{A as e}from"./Api.1661515638242.js";const s={redisList:e.create("/redis","get"),getRedisPwd:e.create("/redis/{id}/pwd","get"),redisInfo:e.create("/redis/{id}/info","get"),clusterInfo:e.create("/redis/{id}/cluster-info","get"),saveRedis:e.create("/redis","post"),delRedis:e.create("/redis/{id}","delete"),scan:e.create("/redis/{id}/scan","post"),getStringValue:e.create("/redis/{id}/string-value","get"),saveStringValue:e.create("/redis/{id}/string-value","post"),getHashValue:e.create("/redis/{id}/hash-value","get"),hscan:e.create("/redis/{id}/hscan","get"),hget:e.create("/redis/{id}/hget","get"),hdel:e.create("/redis/{id}/hdel","delete"),saveHashValue:e.create("/redis/{id}/hash-value","post"),getSetValue:e.create("/redis/{id}/set-value","get"),saveSetValue:e.create("/redis/{id}/set-value","post"),del:e.create("/redis/{id}/scan/{cursor}/{count}","delete"),delKey:e.create("/redis/{id}/key","delete")};export{s as r};
import{A as e}from"./Api.1661780212532.js";const s={redisList:e.create("/redis","get"),getRedisPwd:e.create("/redis/{id}/pwd","get"),redisInfo:e.create("/redis/{id}/info","get"),clusterInfo:e.create("/redis/{id}/cluster-info","get"),saveRedis:e.create("/redis","post"),delRedis:e.create("/redis/{id}","delete"),scan:e.create("/redis/{id}/scan","post"),getStringValue:e.create("/redis/{id}/string-value","get"),saveStringValue:e.create("/redis/{id}/string-value","post"),getHashValue:e.create("/redis/{id}/hash-value","get"),hscan:e.create("/redis/{id}/hscan","get"),hget:e.create("/redis/{id}/hget","get"),hdel:e.create("/redis/{id}/hdel","delete"),saveHashValue:e.create("/redis/{id}/hash-value","post"),getSetValue:e.create("/redis/{id}/set-value","get"),saveSetValue:e.create("/redis/{id}/set-value","post"),del:e.create("/redis/{id}/scan/{cursor}/{count}","delete"),delKey:e.create("/redis/{id}/key","delete")};export{s as r};

View File

@@ -1 +1 @@
import{A as o}from"./Api.1661515638242.js";const m={mongoList:o.create("/mongos","get"),saveMongo:o.create("/mongos","post"),deleteMongo:o.create("/mongos/{id}","delete"),databases:o.create("/mongos/{id}/databases","get"),collections:o.create("/mongos/{id}/collections","get"),runCommand:o.create("/mongos/{id}/run-command","post"),findCommand:o.create("/mongos/{id}/command/find","post"),updateByIdCommand:o.create("/mongos/{id}/command/update-by-id","post"),deleteByIdCommand:o.create("/mongos/{id}/command/delete-by-id","post"),insertCommand:o.create("/mongos/{id}/command/insert","post")};export{m};
import{A as o}from"./Api.1661780212532.js";const m={mongoList:o.create("/mongos","get"),saveMongo:o.create("/mongos","post"),deleteMongo:o.create("/mongos/{id}","delete"),databases:o.create("/mongos/{id}/databases","get"),collections:o.create("/mongos/{id}/collections","get"),runCommand:o.create("/mongos/{id}/run-command","post"),findCommand:o.create("/mongos/{id}/command/find","post"),updateByIdCommand:o.create("/mongos/{id}/command/update-by-id","post"),deleteByIdCommand:o.create("/mongos/{id}/command/delete-by-id","post"),insertCommand:o.create("/mongos/{id}/command/insert","post")};export{m};

View File

Before

Width:  |  Height:  |  Size: 458 KiB

After

Width:  |  Height:  |  Size: 458 KiB

View File

@@ -1 +1 @@
import{E as u}from"./Enum.1661515638242.js";var d={ResourceTypeEnum:new u().add("MENU","\u83DC\u5355",1).add("PERMISSION","\u6743\u9650",2),accountStatus:new u().add("ENABLE","\u6B63\u5E38",1).add("DISABLE","\u7981\u7528",-1),logType:new u().add("UPDATE","\u4FEE\u6539",2).add("DELETE","\u5220\u9664",3).add("SYS_LOG","\u7CFB\u7EDF",4).add("ERR_LOG","\u5F02\u5E38",5)};export{d as e};
import{E as u}from"./Enum.1661780212532.js";var d={ResourceTypeEnum:new u().add("MENU","\u83DC\u5355",1).add("PERMISSION","\u6743\u9650",2),accountStatus:new u().add("ENABLE","\u6B63\u5E38",1).add("DISABLE","\u7981\u7528",-1),logType:new u().add("UPDATE","\u4FEE\u6539",2).add("DELETE","\u5220\u9664",3).add("SYS_LOG","\u7CFB\u7EDF",4).add("ERR_LOG","\u5F02\u5E38",5)};export{d as e};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
.login-content-form[data-v-aa711bf4]{margin-top:20px}.login-content-form .login-content-code[data-v-aa711bf4]{display:flex;align-items:center;justify-content:space-around}.login-content-form .login-content-code .login-content-code-img[data-v-aa711bf4]{width:100%;height:40px;line-height:40px;background-color:#fff;border:1px solid #dcdfe6;color:#333;font-size:16px;font-weight:700;letter-spacing:5px;text-indent:5px;text-align:center;cursor:pointer;transition:all ease .2s;border-radius:4px;user-select:none}.login-content-form .login-content-code .login-content-code-img[data-v-aa711bf4]:hover{border-color:#c0c4cc;transition:all ease .2s}.login-content-form .login-content-submit[data-v-aa711bf4]{width:100%;letter-spacing:2px;font-weight:300;margin-top:15px}.login-container[data-v-46973cfa]{width:100%;height:100%;background:url(./bg-login.1661515638242.png) no-repeat;background-size:100% 100%}.login-container .login-logo[data-v-46973cfa]{position:absolute;top:30px;left:50%;height:50px;display:flex;align-items:center;font-size:20px;color:var(--color-primary);letter-spacing:2px;width:90%;transform:translate(-50%)}.login-container .login-content[data-v-46973cfa]{width:500px;padding:20px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%) translateZ(0);background-color:#fffffffc;box-shadow:0 2px 12px 0 var(--color-primary-light-5);border-radius:4px;transition:height .2s linear;height:480px;overflow:hidden;z-index:1}.login-container .login-content .login-content-main[data-v-46973cfa]{margin:0 auto;width:80%}.login-container .login-content .login-content-main .login-content-title[data-v-46973cfa]{color:#333;font-weight:500;font-size:22px;text-align:center;letter-spacing:4px;margin:15px 0 30px;white-space:nowrap}.login-container .login-content-mobile[data-v-46973cfa]{height:418px}.login-container .login-copyright[data-v-46973cfa]{position:absolute;left:50%;transform:translate(-50%);bottom:30px;text-align:center;color:#fff;font-size:12px;opacity:.8}.login-container .login-copyright .login-copyright-company[data-v-46973cfa],.login-container .login-copyright .login-copyright-msg[data-v-46973cfa]{white-space:nowrap}
.login-content-form[data-v-aa711bf4]{margin-top:20px}.login-content-form .login-content-code[data-v-aa711bf4]{display:flex;align-items:center;justify-content:space-around}.login-content-form .login-content-code .login-content-code-img[data-v-aa711bf4]{width:100%;height:40px;line-height:40px;background-color:#fff;border:1px solid #dcdfe6;color:#333;font-size:16px;font-weight:700;letter-spacing:5px;text-indent:5px;text-align:center;cursor:pointer;transition:all ease .2s;border-radius:4px;user-select:none}.login-content-form .login-content-code .login-content-code-img[data-v-aa711bf4]:hover{border-color:#c0c4cc;transition:all ease .2s}.login-content-form .login-content-submit[data-v-aa711bf4]{width:100%;letter-spacing:2px;font-weight:300;margin-top:15px}.login-container[data-v-46973cfa]{width:100%;height:100%;background:url(./bg-login.1661780212532.png) no-repeat;background-size:100% 100%}.login-container .login-logo[data-v-46973cfa]{position:absolute;top:30px;left:50%;height:50px;display:flex;align-items:center;font-size:20px;color:var(--color-primary);letter-spacing:2px;width:90%;transform:translate(-50%)}.login-container .login-content[data-v-46973cfa]{width:500px;padding:20px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%) translateZ(0);background-color:#fffffffc;box-shadow:0 2px 12px 0 var(--color-primary-light-5);border-radius:4px;transition:height .2s linear;height:480px;overflow:hidden;z-index:1}.login-container .login-content .login-content-main[data-v-46973cfa]{margin:0 auto;width:80%}.login-container .login-content .login-content-main .login-content-title[data-v-46973cfa]{color:#333;font-weight:500;font-size:22px;text-align:center;letter-spacing:4px;margin:15px 0 30px;white-space:nowrap}.login-container .login-content-mobile[data-v-46973cfa]{height:418px}.login-container .login-copyright[data-v-46973cfa]{position:absolute;left:50%;transform:translate(-50%);bottom:30px;text-align:center;color:#fff;font-size:12px;opacity:.8}.login-container .login-copyright .login-copyright-company[data-v-46973cfa],.login-container .login-copyright .login-copyright-msg[data-v-46973cfa]{white-space:nowrap}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,4 +1,4 @@
import{P as Et}from"./index.1661515638242.js";import{a as Dt}from"./assert.1661515638242.js";var xt="0123456789abcdefghijklmnopqrstuvwxyz";function A(r){return xt.charAt(r)}function Rt(r,t){return r&t}function G(r,t){return r|t}function ut(r,t){return r^t}function at(r,t){return r&~t}function Bt(r){if(r==0)return-1;var t=0;return(r&65535)==0&&(r>>=16,t+=16),(r&255)==0&&(r>>=8,t+=8),(r&15)==0&&(r>>=4,t+=4),(r&3)==0&&(r>>=2,t+=2),(r&1)==0&&++t,t}function At(r){for(var t=0;r!=0;)r&=r-1,++t;return t}var _="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Tt="=";function tt(r){var t,e,i="";for(t=0;t+3<=r.length;t+=3)e=parseInt(r.substring(t,t+3),16),i+=_.charAt(e>>6)+_.charAt(e&63);for(t+1==r.length?(e=parseInt(r.substring(t,t+1),16),i+=_.charAt(e<<2)):t+2==r.length&&(e=parseInt(r.substring(t,t+2),16),i+=_.charAt(e>>2)+_.charAt((e&3)<<4));(i.length&3)>0;)i+=Tt;return i}function lt(r){var t="",e,i=0,n=0;for(e=0;e<r.length&&r.charAt(e)!=Tt;++e){var s=_.indexOf(r.charAt(e));s<0||(i==0?(t+=A(s>>2),n=s&3,i=1):i==1?(t+=A(n<<2|s>>4),n=s&15,i=2):i==2?(t+=A(n),t+=A(s>>2),n=s&3,i=3):(t+=A(n<<2|s>>4),t+=A(s&15),i=0))}return i==1&&(t+=A(n<<2)),t}var C,Ot={decode:function(r){var t;if(C===void 0){var e="0123456789ABCDEF",i=` \f
import{P as Et}from"./index.1661780212532.js";import{a as Dt}from"./assert.1661780212532.js";var xt="0123456789abcdefghijklmnopqrstuvwxyz";function A(r){return xt.charAt(r)}function Rt(r,t){return r&t}function G(r,t){return r|t}function ut(r,t){return r^t}function at(r,t){return r&~t}function Bt(r){if(r==0)return-1;var t=0;return(r&65535)==0&&(r>>=16,t+=16),(r&255)==0&&(r>>=8,t+=8),(r&15)==0&&(r>>=4,t+=4),(r&3)==0&&(r>>=2,t+=2),(r&1)==0&&++t,t}function At(r){for(var t=0;r!=0;)r&=r-1,++t;return t}var _="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Tt="=";function tt(r){var t,e,i="";for(t=0;t+3<=r.length;t+=3)e=parseInt(r.substring(t,t+3),16),i+=_.charAt(e>>6)+_.charAt(e&63);for(t+1==r.length?(e=parseInt(r.substring(t,t+1),16),i+=_.charAt(e<<2)):t+2==r.length&&(e=parseInt(r.substring(t,t+2),16),i+=_.charAt(e>>2)+_.charAt((e&3)<<4));(i.length&3)>0;)i+=Tt;return i}function lt(r){var t="",e,i=0,n=0;for(e=0;e<r.length&&r.charAt(e)!=Tt;++e){var s=_.indexOf(r.charAt(e));s<0||(i==0?(t+=A(s>>2),n=s&3,i=1):i==1?(t+=A(n<<2|s>>4),n=s&15,i=2):i==2?(t+=A(n),t+=A(s>>2),n=s&3,i=3):(t+=A(n<<2|s>>4),t+=A(s&15),i=0))}return i==1&&(t+=A(n<<2)),t}var C,Ot={decode:function(r){var t;if(C===void 0){var e="0123456789ABCDEF",i=` \f
\r \xA0\u2028\u2029`;for(C={},t=0;t<16;++t)C[e.charAt(t)]=t;for(e=e.toLowerCase(),t=10;t<16;++t)C[e.charAt(t)]=t;for(t=0;t<i.length;++t)C[i.charAt(t)]=-1}var n=[],s=0,h=0;for(t=0;t<r.length;++t){var o=r.charAt(t);if(o=="=")break;if(o=C[o],o!=-1){if(o===void 0)throw new Error("Illegal character at offset "+t);s|=o,++h>=2?(n[n.length]=s,s=0,h=0):s<<=4}}if(h)throw new Error("Hex encoding incomplete: 4 bits missing");return n}},P,st={decode:function(r){var t;if(P===void 0){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=`= \f
\r \xA0\u2028\u2029`;for(P=Object.create(null),t=0;t<64;++t)P[e.charAt(t)]=t;for(P["-"]=62,P._=63,t=0;t<i.length;++t)P[i.charAt(t)]=-1}var n=[],s=0,h=0;for(t=0;t<r.length;++t){var o=r.charAt(t);if(o=="=")break;if(o=P[o],o!=-1){if(o===void 0)throw new Error("Illegal character at offset "+t);s|=o,++h>=4?(n[n.length]=s>>16,n[n.length]=s>>8&255,n[n.length]=s&255,s=0,h=0):s<<=6}}switch(h){case 1:throw new Error("Base64 encoding incomplete: at least 2 bits missing");case 2:n[n.length]=s>>10;break;case 3:n[n.length]=s>>16,n[n.length]=s>>8&255;break}return n},re:/-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/,unarmor:function(r){var t=st.re.exec(r);if(t)if(t[1])r=t[1];else if(t[2])r=t[2];else throw new Error("RegExp out of sync");return st.decode(r)}},H=1e13,k=function(){function r(t){this.buf=[+t||0]}return r.prototype.mulAdd=function(t,e){var i=this.buf,n=i.length,s,h;for(s=0;s<n;++s)h=i[s]*t+e,h<H?e=0:(e=0|h/H,h-=e*H),i[s]=h;e>0&&(i[s]=e)},r.prototype.sub=function(t){var e=this.buf,i=e.length,n,s;for(n=0;n<i;++n)s=e[n]-t,s<0?(s+=H,t=1):t=0,e[n]=s;for(;e[e.length-1]===0;)e.pop()},r.prototype.toString=function(t){if((t||10)!=10)throw new Error("only base 10 is supported");for(var e=this.buf,i=e[e.length-1].toString(),n=e.length-2;n>=0;--n)i+=(H+e[n]).toString().substring(1);return i},r.prototype.valueOf=function(){for(var t=this.buf,e=0,i=t.length-1;i>=0;--i)e=e*H+t[i];return e},r.prototype.simplify=function(){var t=this.buf;return t.length==1?t[0]:this},r}(),mt="\u2026",Vt=/^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/,It=/^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;function F(r,t){return r.length>t&&(r=r.substring(0,t)+mt),r}var rt=function(){function r(t,e){this.hexDigits="0123456789ABCDEF",t instanceof r?(this.enc=t.enc,this.pos=t.pos):(this.enc=t,this.pos=e)}return r.prototype.get=function(t){if(t===void 0&&(t=this.pos++),t>=this.enc.length)throw new Error("Requesting byte offset "+t+" on a stream of length "+this.enc.length);return typeof this.enc=="string"?this.enc.charCodeAt(t):this.enc[t]},r.prototype.hexByte=function(t){return this.hexDigits.charAt(t>>4&15)+this.hexDigits.charAt(t&15)},r.prototype.hexDump=function(t,e,i){for(var n="",s=t;s<e;++s)if(n+=this.hexByte(this.get(s)),i!==!0)switch(s&15){case 7:n+=" ";break;case 15:n+=`
`;break;default:n+=" "}return n},r.prototype.isASCII=function(t,e){for(var i=t;i<e;++i){var n=this.get(i);if(n<32||n>176)return!1}return!0},r.prototype.parseStringISO=function(t,e){for(var i="",n=t;n<e;++n)i+=String.fromCharCode(this.get(n));return i},r.prototype.parseStringUTF=function(t,e){for(var i="",n=t;n<e;){var s=this.get(n++);s<128?i+=String.fromCharCode(s):s>191&&s<224?i+=String.fromCharCode((s&31)<<6|this.get(n++)&63):i+=String.fromCharCode((s&15)<<12|(this.get(n++)&63)<<6|this.get(n++)&63)}return i},r.prototype.parseStringBMP=function(t,e){for(var i="",n,s,h=t;h<e;)n=this.get(h++),s=this.get(h++),i+=String.fromCharCode(n<<8|s);return i},r.prototype.parseTime=function(t,e,i){var n=this.parseStringISO(t,e),s=(i?Vt:It).exec(n);return s?(i&&(s[1]=+s[1],s[1]+=+s[1]<70?2e3:1900),n=s[1]+"-"+s[2]+"-"+s[3]+" "+s[4],s[5]&&(n+=":"+s[5],s[6]&&(n+=":"+s[6],s[7]&&(n+="."+s[7]))),s[8]&&(n+=" UTC",s[8]!="Z"&&(n+=s[8],s[9]&&(n+=":"+s[9]))),n):"Unrecognized time: "+n},r.prototype.parseInteger=function(t,e){for(var i=this.get(t),n=i>127,s=n?255:0,h,o="";i==s&&++t<e;)i=this.get(t);if(h=e-t,h===0)return n?-1:0;if(h>4){for(o=i,h<<=3;((+o^s)&128)==0;)o=+o<<1,--h;o="("+h+` bit)

View File

@@ -15,8 +15,8 @@
<link type="favicon" rel="shortcut icon" href="favicon.ico" />
<title>mayfly</title>
<script type="module" crossorigin src="assets/index.1661515638242.js"></script>
<link rel="stylesheet" href="assets/index.16615156382428.css">
<script type="module" crossorigin src="assets/index.1661780212532.js"></script>
<link rel="stylesheet" href="assets/index.16617802125328.css">
</head>
<body>
<div id="app"></div>