398 lines
16 KiB
Vue
398 lines
16 KiB
Vue
<script>
|
|
/** 首页工单:读取第一页最多 5 条,显示回复时间与服务端状态;请求代次隔离重试和卸载,已有数据的失败不伪装成空列表。 */
|
|
import "~/assets/styles/HomeTicketPanel.LxPesukM.css";
|
|
import { toDisplayString } from "vue";
|
|
import { renderList } from "vue";
|
|
import { onMounted } from "vue";
|
|
import { onBeforeUnmount } from "vue";
|
|
import { createBlock } from "vue";
|
|
import { ref } from "vue";
|
|
import { withCtx } from "vue";
|
|
import { createCommentVNode } from "vue";
|
|
import { createElementBlock } from "vue";
|
|
import { Fragment } 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 { normalizeStyle } from "vue";
|
|
import { NuxtLink } from "#components";
|
|
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 { n as dict_n } from "~/lib/dict.js";
|
|
import ListEmpty from "~/components/ListEmpty.vue";
|
|
import skeleton from "primevue/skeleton";
|
|
var T = [`aria-busy`],
|
|
E = {
|
|
class: `home-card-head`,
|
|
},
|
|
D = {
|
|
key: 1,
|
|
class: `home-list`,
|
|
},
|
|
O = [`inert`, `aria-disabled`],
|
|
k = {
|
|
class: `home-row-main`,
|
|
},
|
|
A = {
|
|
class: `home-row-title`,
|
|
},
|
|
j = {
|
|
class: `home-row-sub`,
|
|
},
|
|
M = {
|
|
key: 5,
|
|
class: `home-card-foot`,
|
|
},
|
|
N = Object.assign(
|
|
_plugin_vue_export_helper_t(
|
|
defineComponent({
|
|
__name: `HomeTicketPanel`,
|
|
setup(p) {
|
|
let b = useApi(),
|
|
N = ref([]),
|
|
P = ref(!0),
|
|
F = ref(!1),
|
|
I = ref(``),
|
|
L = 0;
|
|
// 仅当前请求可以更新列表与加载标记,离页时提升 L 使旧回调失效。
|
|
async function R() {
|
|
let e = ++L;
|
|
((P.value = !0), (I.value = ``));
|
|
try {
|
|
let t = await b.get(`/ticket`, {
|
|
page: 1,
|
|
limit: 5,
|
|
});
|
|
if (e !== L) return;
|
|
((N.value = t.list ?? []), (F.value = !0));
|
|
} catch (t) {
|
|
if (e !== L) return;
|
|
I.value = t instanceof Error ? t.message : `工单加载失败`;
|
|
} finally {
|
|
e === L && (P.value = !1);
|
|
}
|
|
}
|
|
return (
|
|
onMounted(R),
|
|
onBeforeUnmount(() => {
|
|
L++;
|
|
}),
|
|
// 出错时提供重试并锁定旧工单条目,创建与查看全部入口保留。
|
|
(n, r) => {
|
|
let a = NuxtLink,
|
|
p = button,
|
|
v = message,
|
|
b = skeleton,
|
|
L = ListEmpty;
|
|
return (
|
|
openBlock(),
|
|
createElementBlock(
|
|
`div`,
|
|
{
|
|
class: `home-card`,
|
|
"aria-busy": unref(P),
|
|
},
|
|
[
|
|
createElementVNode(`div`, E, [
|
|
(r[1] ||= createElementVNode(
|
|
`div`,
|
|
{
|
|
class: `home-card-title`,
|
|
},
|
|
`工单处理`,
|
|
-1,
|
|
)),
|
|
createVNode(
|
|
a,
|
|
{
|
|
to: `/tickets`,
|
|
class: `home-card-more`,
|
|
"aria-label": `全部工单`,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
...(r[0] ||= [
|
|
createElementVNode(
|
|
`i`,
|
|
{
|
|
class: `pi pi-angle-right`,
|
|
},
|
|
null,
|
|
-1,
|
|
),
|
|
]),
|
|
]),
|
|
_: 1,
|
|
},
|
|
),
|
|
]),
|
|
unref(I) && unref(F)
|
|
? (openBlock(),
|
|
createBlock(
|
|
v,
|
|
{
|
|
key: 0,
|
|
severity: `error`,
|
|
closable: !1,
|
|
role: `alert`,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
createTextVNode(toDisplayString(unref(I)), 1),
|
|
createVNode(
|
|
p,
|
|
{
|
|
label: `重新加载`,
|
|
icon: `pi pi-refresh`,
|
|
severity: `secondary`,
|
|
text: ``,
|
|
disabled: unref(P),
|
|
onClick: R,
|
|
},
|
|
null,
|
|
8,
|
|
[`disabled`],
|
|
),
|
|
]),
|
|
_: 1,
|
|
},
|
|
))
|
|
: createCommentVNode(``, !0),
|
|
unref(P) && !unref(F)
|
|
? (openBlock(),
|
|
createElementBlock(`div`, D, [
|
|
(openBlock(),
|
|
createElementBlock(
|
|
Fragment,
|
|
null,
|
|
renderList(5, (e) =>
|
|
createElementVNode(
|
|
`div`,
|
|
{
|
|
key: e,
|
|
class: `home-row-skeleton`,
|
|
},
|
|
[
|
|
createVNode(b, {
|
|
height: `14px`,
|
|
width: `55%`,
|
|
}),
|
|
createVNode(b, {
|
|
height: `12px`,
|
|
width: `35%`,
|
|
style: {
|
|
"margin-top": `8px`,
|
|
},
|
|
}),
|
|
],
|
|
),
|
|
),
|
|
64,
|
|
)),
|
|
]))
|
|
: unref(I) && !unref(F)
|
|
? (openBlock(),
|
|
createBlock(
|
|
L,
|
|
{
|
|
key: 2,
|
|
icon: `pi pi-exclamation-circle`,
|
|
title: `工单加载失败`,
|
|
description: unref(I),
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
createVNode(p, {
|
|
label: `重新加载`,
|
|
icon: `pi pi-refresh`,
|
|
severity: `secondary`,
|
|
outlined: ``,
|
|
onClick: R,
|
|
}),
|
|
]),
|
|
_: 1,
|
|
},
|
|
8,
|
|
[`description`],
|
|
))
|
|
: unref(N).length
|
|
? (openBlock(),
|
|
createElementBlock(
|
|
`div`,
|
|
{
|
|
key: 4,
|
|
class: `home-list`,
|
|
inert: unref(I) ? !0 : void 0,
|
|
"aria-disabled": !!unref(I),
|
|
},
|
|
[
|
|
(openBlock(!0),
|
|
createElementBlock(
|
|
Fragment,
|
|
null,
|
|
renderList(
|
|
unref(N),
|
|
(t) => (
|
|
openBlock(),
|
|
createBlock(
|
|
a,
|
|
{
|
|
key: t.id,
|
|
to: `/tickets/${t.id}`,
|
|
class: `home-row`,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
createElementVNode(`div`, k, [
|
|
createElementVNode(
|
|
`div`,
|
|
A,
|
|
toDisplayString(t.title),
|
|
1,
|
|
),
|
|
createElementVNode(
|
|
`div`,
|
|
j,
|
|
toDisplayString(
|
|
(`formatDate` in n
|
|
? n.formatDate
|
|
: unref(dict_n))(
|
|
t.last_reply_time ||
|
|
t.post_time,
|
|
),
|
|
),
|
|
1,
|
|
),
|
|
]),
|
|
createElementVNode(
|
|
`span`,
|
|
{
|
|
class: `ticket-status`,
|
|
style: normalizeStyle({
|
|
background:
|
|
t.color ||
|
|
`var(--p-text-muted-color)`,
|
|
}),
|
|
},
|
|
toDisplayString(t.status),
|
|
5,
|
|
),
|
|
]),
|
|
_: 2,
|
|
},
|
|
1032,
|
|
[`to`],
|
|
)
|
|
),
|
|
),
|
|
128,
|
|
)),
|
|
],
|
|
8,
|
|
O,
|
|
))
|
|
: (openBlock(),
|
|
createBlock(
|
|
L,
|
|
{
|
|
key: 3,
|
|
icon: `pi pi-inbox`,
|
|
title: `暂无工单`,
|
|
description: `有问题随时提交工单,我们会尽快处理`,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
createVNode(
|
|
a,
|
|
{
|
|
to: `/tickets/create`,
|
|
class: `home-button`,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
...(r[2] ||= [
|
|
createElementVNode(
|
|
`i`,
|
|
{
|
|
class: `pi pi-plus`,
|
|
"aria-hidden": `true`,
|
|
},
|
|
null,
|
|
-1,
|
|
),
|
|
createTextVNode(`创建工单`, -1),
|
|
]),
|
|
]),
|
|
_: 1,
|
|
},
|
|
),
|
|
]),
|
|
_: 1,
|
|
},
|
|
)),
|
|
unref(N).length || (unref(P) && !unref(F))
|
|
? (openBlock(),
|
|
createElementBlock(`div`, M, [
|
|
createVNode(
|
|
a,
|
|
{
|
|
to: `/tickets`,
|
|
class: `home-button secondary`,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
...(r[3] ||= [createTextVNode(`查看全部`, -1)]),
|
|
]),
|
|
_: 1,
|
|
},
|
|
),
|
|
createVNode(
|
|
a,
|
|
{
|
|
to: `/tickets/create`,
|
|
class: `home-button`,
|
|
},
|
|
{
|
|
default: withCtx(() => [
|
|
...(r[4] ||= [
|
|
createElementVNode(
|
|
`i`,
|
|
{
|
|
class: `pi pi-plus`,
|
|
"aria-hidden": `true`,
|
|
},
|
|
null,
|
|
-1,
|
|
),
|
|
createTextVNode(`创建工单`, -1),
|
|
]),
|
|
]),
|
|
_: 1,
|
|
},
|
|
),
|
|
]))
|
|
: createCommentVNode(``, !0),
|
|
],
|
|
8,
|
|
T,
|
|
)
|
|
);
|
|
}
|
|
);
|
|
},
|
|
}),
|
|
[[`__scopeId`, `data-v-bacdfa58`]],
|
|
),
|
|
{
|
|
__name: `HomeTicketPanel`,
|
|
},
|
|
);
|
|
export {};
|
|
export default N;
|
|
</script>
|