418 lines
15 KiB
Vue
418 lines
15 KiB
Vue
<script>
|
|
/**
|
|
* 实例操作日志列表,父级提供 hostId/module;关键词提交后才生效,输入中不连续发请求。
|
|
* 后端未给可信总数时以本页是否满页决定下一页,不伪造“共 N 条”。
|
|
*/
|
|
import "~/assets/styles/MfCloudLogs.MTqtLGjA.css";
|
|
import { toDisplayString } from "vue";
|
|
import { onMounted } from "vue";
|
|
import { onBeforeUnmount } from "vue";
|
|
import { watch } from "vue";
|
|
import { createBlock } from "vue";
|
|
import { ref } from "vue";
|
|
import { withCtx } from "vue";
|
|
import { createCommentVNode } from "vue";
|
|
import { computed } from "vue";
|
|
import { isRef } from "vue";
|
|
import { createElementBlock } from "vue";
|
|
import { createElementVNode } from "vue";
|
|
import { createTextVNode } from "vue";
|
|
import { unref } from "vue";
|
|
import { defineComponent } from "vue";
|
|
import { createVNode } from "vue";
|
|
import { openBlock } from "vue";
|
|
import { withModifiers } from "vue";
|
|
import { operationMessage } from "~/lib/auth.js";
|
|
import { useApi } from "~/lib/auth.js";
|
|
import button from "primevue/button";
|
|
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
|
|
import message from "primevue/message";
|
|
import inputtext from "primevue/inputtext";
|
|
import { r as dict_r } from "~/lib/dict.js";
|
|
import datatable from "primevue/datatable";
|
|
import iconfield from "primevue/iconfield";
|
|
import inputicon from "primevue/inputicon";
|
|
import column from "primevue/column";
|
|
import ListEmpty from "~/components/ListEmpty.vue";
|
|
import { i as instance_data_i } from "~/lib/instance-data.js";
|
|
import { l as instance_data_l } from "~/lib/instance-data.js";
|
|
import { o as instance_data_o } from "~/lib/instance-data.js";
|
|
var N = {
|
|
class: `logs`,
|
|
},
|
|
ee = {
|
|
class: `logs-heading`,
|
|
},
|
|
P = {
|
|
class: `log-time`,
|
|
},
|
|
F = {
|
|
class: `log-content`,
|
|
},
|
|
I = {
|
|
key: 2,
|
|
class: `logs-foot`,
|
|
},
|
|
L = {
|
|
key: 0,
|
|
},
|
|
R = Object.assign(
|
|
_plugin_vue_export_helper_t(
|
|
defineComponent({
|
|
__name: `MfCloudLogs`,
|
|
props: {
|
|
hostId: {},
|
|
module: {
|
|
default: `mf_cloud`,
|
|
},
|
|
},
|
|
setup(m) {
|
|
let x = m,
|
|
R = useApi(),
|
|
z = ref(``),
|
|
B = ref(``),
|
|
V = ref([]),
|
|
H = ref(null),
|
|
U = ref(1),
|
|
W = ref(10),
|
|
G = ref(!1),
|
|
K = ref(``),
|
|
q = 0,
|
|
// H 为可信总数或 null;未知总数且满页时允许继续探测下一页。
|
|
J = computed(() =>
|
|
H.value === null
|
|
? V.value.length === W.value
|
|
: U.value * W.value < H.value,
|
|
);
|
|
/** 兼容数组/list/logs/log 包装,归一日志字段;请求序号隔离分页、筛选和实例切换。 */
|
|
async function Y() {
|
|
let e = ++q;
|
|
((G.value = !0), (K.value = ``));
|
|
try {
|
|
let t = await R.get(
|
|
`/${x.module}/${x.hostId}/log`,
|
|
{
|
|
page: U.value,
|
|
limit: W.value,
|
|
keywords: B.value,
|
|
},
|
|
!0,
|
|
);
|
|
if (e !== q) return;
|
|
let n = instance_data_l(t);
|
|
V.value = instance_data_i(
|
|
Array.isArray(t) ? t : (n.list ?? n.logs ?? n.log),
|
|
).map(instance_data_o);
|
|
// 总数至少应覆盖当前页已展示记录,并设合理上限;不可信则退回未知总数模式。
|
|
let r = Number(n.count ?? n.total);
|
|
H.value =
|
|
Number.isFinite(r) &&
|
|
r >= (U.value - 1) * W.value + V.value.length &&
|
|
r < 1e8
|
|
? r
|
|
: null;
|
|
} catch (t) {
|
|
if (e !== q) return;
|
|
((K.value = t instanceof Error ? t.message : `日志加载失败`),
|
|
(V.value = []),
|
|
(H.value = null));
|
|
} finally {
|
|
e === q && (G.value = !1);
|
|
}
|
|
}
|
|
// 刷新筛选始终回第一页,避免新条件在旧末页显示为空。
|
|
function X() {
|
|
return ((U.value = 1), Y());
|
|
}
|
|
// z 是输入值,B 是已提交条件;两者分离使翻页继续使用同一份已确认筛选。
|
|
function Z() {
|
|
((B.value = z.value.trim()), X());
|
|
}
|
|
function Q() {
|
|
((z.value = ``), (B.value = ``), X());
|
|
}
|
|
// 加载中不叠加翻页;向后还需存在下一页,向前至少停留在第一页。
|
|
function $(e) {
|
|
G.value ||
|
|
(e > 0 && !J.value) ||
|
|
((U.value = Math.max(1, U.value + e)), Y());
|
|
}
|
|
return (
|
|
watch(
|
|
() => [x.hostId, x.module],
|
|
() => {
|
|
((z.value = ``), (B.value = ``), (V.value = []), X());
|
|
},
|
|
),
|
|
onMounted(Y),
|
|
onBeforeUnmount(() => {
|
|
q++;
|
|
}),
|
|
// 错误与空列表分别呈现;日志正文通过文本节点展示,熔断消息仅做业务文案转换。
|
|
(t, n) => {
|
|
let r = button,
|
|
a = inputicon,
|
|
c = inputtext,
|
|
m = iconfield,
|
|
y = message,
|
|
x = ListEmpty,
|
|
A = column,
|
|
j = datatable;
|
|
return (
|
|
openBlock(),
|
|
createElementBlock(`section`, N, [
|
|
createElementVNode(`div`, ee, [
|
|
(n[3] ||= createElementVNode(
|
|
`div`,
|
|
null,
|
|
[
|
|
createElementVNode(`h4`, null, `操作日志`),
|
|
createElementVNode(
|
|
`p`,
|
|
null,
|
|
`查看实例操作记录与执行时间。`,
|
|
),
|
|
],
|
|
-1,
|
|
)),
|
|
createVNode(
|
|
r,
|
|
{
|
|
label: `刷新`,
|
|
icon: `pi pi-refresh`,
|
|
severity: `secondary`,
|
|
outlined: ``,
|
|
loading: unref(G),
|
|
onClick: Y,
|
|
},
|
|
null,
|
|
8,
|
|
[`loading`],
|
|
),
|
|
]),
|
|
createElementVNode(
|
|
`form`,
|
|
{
|
|
class: `logs-toolbar`,
|
|
onSubmit: withModifiers(Z, [`prevent`]),
|
|
},
|
|
[
|
|
createVNode(m, null, {
|
|
default: withCtx(() => [
|
|
createVNode(a, {
|
|
class: `pi pi-search`,
|
|
}),
|
|
createVNode(
|
|
c,
|
|
{
|
|
modelValue: unref(z),
|
|
"onUpdate:modelValue": (n[0] ||= (e) =>
|
|
isRef(z) ? (z.value = e) : null),
|
|
placeholder: `搜索操作内容`,
|
|
"aria-label": `搜索操作日志`,
|
|
},
|
|
null,
|
|
8,
|
|
[`modelValue`],
|
|
),
|
|
]),
|
|
_: 1,
|
|
}),
|
|
createVNode(
|
|
r,
|
|
{
|
|
type: `submit`,
|
|
label: `搜索`,
|
|
disabled: unref(G),
|
|
},
|
|
null,
|
|
8,
|
|
[`disabled`],
|
|
),
|
|
unref(B)
|
|
? (openBlock(),
|
|
createBlock(r, {
|
|
key: 0,
|
|
label: `清除筛选`,
|
|
severity: `secondary`,
|
|
text: ``,
|
|
onClick: Q,
|
|
}))
|
|
: createCommentVNode(``, !0),
|
|
],
|
|
32,
|
|
),
|
|
unref(K)
|
|
? (openBlock(),
|
|
createBlock(
|
|
y,
|
|
{
|
|
key: 0,
|
|
severity: `error`,
|
|
closable: !1,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
createTextVNode(toDisplayString(unref(K)), 1),
|
|
createVNode(r, {
|
|
label: `重试`,
|
|
severity: `secondary`,
|
|
text: ``,
|
|
onClick: Y,
|
|
}),
|
|
]),
|
|
_: 1,
|
|
},
|
|
))
|
|
: (openBlock(),
|
|
createBlock(
|
|
j,
|
|
{
|
|
key: 1,
|
|
value: unref(V),
|
|
loading: unref(G),
|
|
dataKey: `id`,
|
|
size: `small`,
|
|
scrollable: ``,
|
|
class: `logs-table`,
|
|
},
|
|
{
|
|
empty: withCtx(() => [
|
|
createVNode(
|
|
x,
|
|
{
|
|
icon: `pi pi-history`,
|
|
title: unref(G)
|
|
? `正在加载操作日志`
|
|
: unref(B)
|
|
? `未找到匹配的日志`
|
|
: `暂无操作日志`,
|
|
description: unref(B)
|
|
? `更换关键词或清除筛选后重试`
|
|
: `实例产生操作记录后会显示在这里`,
|
|
},
|
|
null,
|
|
8,
|
|
[`title`, `description`],
|
|
),
|
|
]),
|
|
default: withCtx(() => [
|
|
createVNode(
|
|
A,
|
|
{
|
|
header: `时间`,
|
|
style: {
|
|
"min-width": `180px`,
|
|
width: `22%`,
|
|
},
|
|
},
|
|
{
|
|
body: withCtx(({ data: n }) => [
|
|
createElementVNode(
|
|
`span`,
|
|
P,
|
|
toDisplayString(
|
|
n.create_time
|
|
? (`formatTime` in t
|
|
? t.formatTime
|
|
: unref(dict_r))(n.create_time)
|
|
: `—`,
|
|
),
|
|
1,
|
|
),
|
|
]),
|
|
_: 1,
|
|
},
|
|
),
|
|
createVNode(
|
|
A,
|
|
{
|
|
header: `操作内容`,
|
|
style: {
|
|
"min-width": `280px`,
|
|
},
|
|
},
|
|
{
|
|
body: withCtx(({ data: t }) => [
|
|
createElementVNode(
|
|
`span`,
|
|
F,
|
|
toDisplayString(
|
|
unref(operationMessage)(t.description),
|
|
),
|
|
1,
|
|
),
|
|
]),
|
|
_: 1,
|
|
},
|
|
),
|
|
]),
|
|
_: 1,
|
|
},
|
|
8,
|
|
[`value`, `loading`],
|
|
)),
|
|
unref(U) > 1 || unref(V).length
|
|
? (openBlock(),
|
|
createElementBlock(`div`, I, [
|
|
unref(H) === null
|
|
? createCommentVNode(``, !0)
|
|
: (openBlock(),
|
|
createElementBlock(
|
|
`span`,
|
|
L,
|
|
`共 ` + toDisplayString(unref(H)) + ` 条`,
|
|
1,
|
|
)),
|
|
createVNode(
|
|
r,
|
|
{
|
|
icon: `pi pi-angle-left`,
|
|
severity: `secondary`,
|
|
outlined: ``,
|
|
"aria-label": `上一页`,
|
|
disabled: unref(G) || unref(U) <= 1,
|
|
onClick: (n[1] ||= (e) => $(-1)),
|
|
},
|
|
null,
|
|
8,
|
|
[`disabled`],
|
|
),
|
|
createElementVNode(
|
|
`span`,
|
|
null,
|
|
`第 ` + toDisplayString(unref(U)) + ` 页`,
|
|
1,
|
|
),
|
|
createVNode(
|
|
r,
|
|
{
|
|
icon: `pi pi-angle-right`,
|
|
severity: `secondary`,
|
|
outlined: ``,
|
|
"aria-label": `下一页`,
|
|
disabled: unref(G) || !unref(J),
|
|
onClick: (n[2] ||= (e) => $(1)),
|
|
},
|
|
null,
|
|
8,
|
|
[`disabled`],
|
|
),
|
|
]))
|
|
: createCommentVNode(``, !0),
|
|
])
|
|
);
|
|
}
|
|
);
|
|
},
|
|
}),
|
|
[[`__scopeId`, `data-v-c4521240`]],
|
|
),
|
|
{
|
|
__name: `MfCloudLogs`,
|
|
},
|
|
);
|
|
export {};
|
|
export default R;
|
|
</script>
|