Files
console-dev/app/components/mfcloud/MfCloudLogs.vue
T

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>