smart-admin-web 10.25.0 → 10.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.d.ts +170 -5
- package/dist/api/index.js +206 -116
- package/dist/api/index.js.map +1 -1
- package/dist/api/schema.d.ts +1477 -113
- package/dist/assets/icons/ph-subset.json.js +1 -1
- package/dist/components/FilePathUpload/index.vue.d.ts +35 -0
- package/dist/components/FilePathUpload/index.vue.js +47 -0
- package/dist/components/FilePathUpload/index.vue.js.map +1 -0
- package/dist/components/FilePathUpload/index2.vue.js +5 -0
- package/dist/components/FilePathUpload/index2.vue.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +302 -294
- package/dist/index.js.map +1 -1
- package/dist/layouts/NoticeBell.vue.js +2 -2
- package/dist/layouts/NoticeBell2.vue.js +203 -146
- package/dist/layouts/NoticeBell2.vue.js.map +1 -1
- package/dist/lib/runtime.js +1 -1
- package/dist/locales/en-US.d.ts +144 -0
- package/dist/locales/en-US.js +139 -0
- package/dist/locales/en-US.js.map +1 -1
- package/dist/locales/kernelMenuTitles.js +10 -0
- package/dist/locales/kernelMenuTitles.js.map +1 -1
- package/dist/locales/zh-CN.d.ts +144 -0
- package/dist/locales/zh-CN.js +139 -0
- package/dist/locales/zh-CN.js.map +1 -1
- package/dist/router/viewRegistry.js +8 -8
- package/dist/router/viewRegistry.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/utils/error.js +22 -18
- package/dist/utils/error.js.map +1 -1
- package/dist/utils/filePathUpload.d.ts +14 -0
- package/dist/utils/filePathUpload.js +84 -0
- package/dist/utils/filePathUpload.js.map +1 -0
- package/dist/views/system/file-path/access.d.ts +15 -0
- package/dist/views/system/file-path/access.js +49 -0
- package/dist/views/system/file-path/access.js.map +1 -0
- package/dist/views/system/file-path/components/PathForm.vue.d.ts +18 -0
- package/dist/views/system/file-path/components/PathForm.vue.js +8 -0
- package/dist/views/system/file-path/components/PathForm.vue.js.map +1 -0
- package/dist/views/system/file-path/components/PathForm2.vue.js +529 -0
- package/dist/views/system/file-path/components/PathForm2.vue.js.map +1 -0
- package/dist/views/system/file-path/components/PathTab.vue.d.ts +3 -0
- package/dist/views/system/file-path/components/PathTab.vue.js +8 -0
- package/dist/views/system/file-path/components/PathTab.vue.js.map +1 -0
- package/dist/views/system/file-path/components/PathTab2.vue.js +226 -0
- package/dist/views/system/file-path/components/PathTab2.vue.js.map +1 -0
- package/dist/views/system/file-path/components/ServerForm.vue.d.ts +20 -0
- package/dist/views/system/file-path/components/ServerForm.vue.js +8 -0
- package/dist/views/system/file-path/components/ServerForm.vue.js.map +1 -0
- package/dist/views/system/file-path/components/ServerForm2.vue.js +328 -0
- package/dist/views/system/file-path/components/ServerForm2.vue.js.map +1 -0
- package/dist/views/system/file-path/components/ServerTab.vue.d.ts +7 -0
- package/dist/views/system/file-path/components/ServerTab.vue.js +8 -0
- package/dist/views/system/file-path/components/ServerTab.vue.js.map +1 -0
- package/dist/views/system/file-path/components/ServerTab2.vue.js +181 -0
- package/dist/views/system/file-path/components/ServerTab2.vue.js.map +1 -0
- package/dist/views/system/file-path/index.vue.d.ts +3 -0
- package/dist/views/system/file-path/index.vue.js +8 -0
- package/dist/views/system/file-path/index.vue.js.map +1 -0
- package/dist/views/system/file-path/index2.vue.js +61 -0
- package/dist/views/system/file-path/index2.vue.js.map +1 -0
- package/dist/views/system/file-path/rules.d.ts +61 -0
- package/dist/views/system/file-path/rules.js +53 -0
- package/dist/views/system/file-path/rules.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import o from "./NoticeBell2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import t from "../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const
|
|
4
|
+
const m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-4cd418d9"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
m as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=NoticeBell.vue.js.map
|
|
@@ -1,117 +1,146 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { useRouter as
|
|
3
|
-
import { useMessage as
|
|
4
|
-
import { Icon as
|
|
5
|
-
import { useIntervalFn as
|
|
6
|
-
import { useI18n as
|
|
7
|
-
import { noticeApi as
|
|
8
|
-
import { noticeBus as
|
|
9
|
-
import { useNoticeAction as
|
|
10
|
-
import { NoticeType as
|
|
11
|
-
import
|
|
12
|
-
import { translateError as
|
|
13
|
-
import { fmtDateTime as
|
|
14
|
-
const
|
|
1
|
+
import { defineComponent as se, ref as d, reactive as ie, computed as q, openBlock as s, createElementBlock as p, Fragment as R, createVNode as o, unref as t, withCtx as l, createElementVNode as h, toDisplayString as r, createTextVNode as f, renderList as V, normalizeClass as O, createCommentVNode as x, createBlock as S, createSlots as ce } from "vue";
|
|
2
|
+
import { useRouter as re } from "vue-router";
|
|
3
|
+
import { useMessage as ue, NPopover as de, NButton as z, NTabs as pe, NTab as fe, NBadge as G, NSpin as me, NScrollbar as ye, NEmpty as ve, NTag as he, NEllipsis as ge, NText as H, NModal as _e, NSpace as we } from "naive-ui";
|
|
4
|
+
import { Icon as B } from "@iconify/vue";
|
|
5
|
+
import { useIntervalFn as ke } from "@vueuse/core";
|
|
6
|
+
import { useI18n as be } from "vue-i18n";
|
|
7
|
+
import { noticeApi as N } from "../api/index.js";
|
|
8
|
+
import { noticeBus as Ne } from "../composables/useRealtime.js";
|
|
9
|
+
import { useNoticeAction as Te } from "../composables/useNoticeAction.js";
|
|
10
|
+
import { NoticeType as y } from "../types/api.js";
|
|
11
|
+
import Ae from "../components/MarkdownEditor/MarkdownView.vue.js";
|
|
12
|
+
import { translateError as J } from "../utils/error.js";
|
|
13
|
+
import { fmtDateTime as Ce } from "../utils/format.js";
|
|
14
|
+
const Re = { class: "notice-panel" }, xe = { class: "notice-head" }, Se = { class: "notice-title" }, ze = {
|
|
15
15
|
key: 0,
|
|
16
16
|
class: "notice-empty"
|
|
17
|
-
},
|
|
17
|
+
}, Be = {
|
|
18
18
|
key: 1,
|
|
19
19
|
class: "notice-list"
|
|
20
|
-
},
|
|
20
|
+
}, Me = ["onClick"], Ee = {
|
|
21
21
|
key: 0,
|
|
22
22
|
class: "dot"
|
|
23
|
-
},
|
|
23
|
+
}, Ue = { class: "notice-body" }, Ve = { class: "line1" }, $e = { class: "notice-foot" }, Xe = /* @__PURE__ */ se({
|
|
24
24
|
__name: "NoticeBell",
|
|
25
|
-
setup(
|
|
26
|
-
const { t:
|
|
27
|
-
|
|
25
|
+
setup(Ie) {
|
|
26
|
+
const { t: i } = be(), K = re(), $ = ue(), M = Te(), u = [
|
|
27
|
+
{
|
|
28
|
+
key: "message",
|
|
29
|
+
types: [y.Message],
|
|
30
|
+
label: "app.notice.tabMessage",
|
|
31
|
+
empty: "app.notice.emptyMessage"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
key: "notice",
|
|
35
|
+
types: [y.Notice, y.Announcement],
|
|
36
|
+
label: "app.notice.tabNotice",
|
|
37
|
+
empty: "app.notice.empty"
|
|
38
|
+
}
|
|
39
|
+
], I = (e) => [...u.find((n) => n.key === e).types], E = d(0), c = d(u[0].key), g = ie({ message: 0, notice: 0 }), L = q(() => u.find((e) => e.key === c.value)), T = d([]), A = d(!1), _ = d(!1);
|
|
40
|
+
async function P() {
|
|
41
|
+
const e = await Promise.all(u.map((n) => N.unreadCount([...n.types])));
|
|
42
|
+
u.forEach((n, v) => g[n.key] = e[v]);
|
|
43
|
+
}
|
|
44
|
+
async function w() {
|
|
28
45
|
try {
|
|
29
|
-
|
|
46
|
+
E.value = await N.unreadCount(), _.value && await P();
|
|
30
47
|
} catch {
|
|
31
48
|
}
|
|
32
49
|
}
|
|
33
|
-
async function
|
|
34
|
-
|
|
50
|
+
async function U() {
|
|
51
|
+
const e = c.value;
|
|
52
|
+
A.value = !0;
|
|
35
53
|
try {
|
|
36
|
-
const { items:
|
|
37
|
-
|
|
54
|
+
const { items: n } = await N.mine({ page: 1, pageSize: 10, types: I(e) });
|
|
55
|
+
e === c.value && (T.value = n);
|
|
38
56
|
} catch {
|
|
39
|
-
|
|
57
|
+
e === c.value && (T.value = []);
|
|
40
58
|
} finally {
|
|
41
|
-
|
|
59
|
+
e === c.value && (A.value = !1);
|
|
42
60
|
}
|
|
43
61
|
}
|
|
44
|
-
function
|
|
45
|
-
|
|
62
|
+
async function Q(e) {
|
|
63
|
+
var n;
|
|
64
|
+
if (e) {
|
|
65
|
+
A.value = !0;
|
|
66
|
+
try {
|
|
67
|
+
await P();
|
|
68
|
+
} catch {
|
|
69
|
+
}
|
|
70
|
+
c.value = ((n = u.find((v) => g[v.key] > 0)) == null ? void 0 : n.key) ?? u[0].key, U();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function W(e) {
|
|
74
|
+
c.value = e, U();
|
|
46
75
|
}
|
|
47
|
-
const
|
|
48
|
-
async function
|
|
49
|
-
if (!
|
|
76
|
+
const C = d(!1), k = d(null);
|
|
77
|
+
async function X(e) {
|
|
78
|
+
if (!e.isRead)
|
|
50
79
|
try {
|
|
51
|
-
await
|
|
52
|
-
} catch (
|
|
53
|
-
|
|
80
|
+
await N.markRead(e.id), e.isRead = !0, await w();
|
|
81
|
+
} catch (n) {
|
|
82
|
+
$.error(J(n));
|
|
54
83
|
}
|
|
55
84
|
}
|
|
56
|
-
async function
|
|
57
|
-
|
|
85
|
+
async function Y(e) {
|
|
86
|
+
k.value = e, C.value = !0, await X(e);
|
|
58
87
|
}
|
|
59
|
-
const
|
|
60
|
-
async function
|
|
61
|
-
|
|
88
|
+
const b = d(null);
|
|
89
|
+
async function Z(e, n) {
|
|
90
|
+
b.value = n;
|
|
62
91
|
try {
|
|
63
|
-
await
|
|
92
|
+
await M.run(e) && (C.value = !1, _.value = !1);
|
|
64
93
|
} finally {
|
|
65
|
-
|
|
94
|
+
b.value = null;
|
|
66
95
|
}
|
|
67
96
|
}
|
|
68
|
-
async function
|
|
97
|
+
async function ee() {
|
|
69
98
|
try {
|
|
70
|
-
await
|
|
71
|
-
} catch (
|
|
72
|
-
|
|
99
|
+
await N.markAllRead(I(c.value)), await Promise.all([w(), U()]);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
$.error(J(e));
|
|
73
102
|
}
|
|
74
103
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
104
|
+
function te() {
|
|
105
|
+
_.value = !1, K.push("/personal/notice");
|
|
77
106
|
}
|
|
78
|
-
const
|
|
79
|
-
function
|
|
80
|
-
if (!
|
|
81
|
-
const
|
|
82
|
-
return
|
|
107
|
+
const ae = (e) => e === y.Announcement ? "warning" : e === y.Message ? "success" : "info", ne = (e) => e === y.Announcement ? i("notice.typeAnnouncement") : e === y.Message ? i("notice.typeMessage") : i("notice.typeNotice"), le = q(() => L.value.types.length > 1);
|
|
108
|
+
function D(e) {
|
|
109
|
+
if (!e) return "";
|
|
110
|
+
const n = e.replace(/!\[[^\]]*\]\([^)]*\)/g, "").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/[#>*_`~-]/g, "").replace(/\s+/g, " ").trim();
|
|
111
|
+
return n.length > 60 ? n.slice(0, 60) + "…" : n;
|
|
83
112
|
}
|
|
84
|
-
return
|
|
85
|
-
|
|
86
|
-
}),
|
|
87
|
-
var
|
|
88
|
-
return
|
|
89
|
-
|
|
90
|
-
show:
|
|
113
|
+
return Ne.on(() => {
|
|
114
|
+
w();
|
|
115
|
+
}), ke(w, 3e4), w(), (e, n) => {
|
|
116
|
+
var v, F, j;
|
|
117
|
+
return s(), p(R, null, [
|
|
118
|
+
o(t(de), {
|
|
119
|
+
show: _.value,
|
|
91
120
|
"onUpdate:show": [
|
|
92
|
-
|
|
93
|
-
|
|
121
|
+
n[0] || (n[0] = (a) => _.value = a),
|
|
122
|
+
Q
|
|
94
123
|
],
|
|
95
124
|
trigger: "click",
|
|
96
125
|
placement: "bottom-end",
|
|
97
126
|
"show-arrow": !1,
|
|
98
127
|
style: { padding: "0" }
|
|
99
128
|
}, {
|
|
100
|
-
trigger:
|
|
101
|
-
|
|
102
|
-
value:
|
|
129
|
+
trigger: l(() => [
|
|
130
|
+
o(t(G), {
|
|
131
|
+
value: E.value,
|
|
103
132
|
max: 99,
|
|
104
|
-
show:
|
|
133
|
+
show: E.value > 0,
|
|
105
134
|
offset: [0, 5]
|
|
106
135
|
}, {
|
|
107
|
-
default:
|
|
108
|
-
|
|
136
|
+
default: l(() => [
|
|
137
|
+
o(t(z), {
|
|
109
138
|
quaternary: "",
|
|
110
139
|
circle: "",
|
|
111
|
-
"aria-label":
|
|
140
|
+
"aria-label": t(i)("app.notice.title")
|
|
112
141
|
}, {
|
|
113
|
-
default:
|
|
114
|
-
|
|
142
|
+
default: l(() => [
|
|
143
|
+
o(t(B), {
|
|
115
144
|
icon: "ph:bell",
|
|
116
145
|
width: 19
|
|
117
146
|
})
|
|
@@ -122,95 +151,123 @@ const he = { class: "notice-panel" }, ve = { class: "notice-head" }, ye = { clas
|
|
|
122
151
|
_: 1
|
|
123
152
|
}, 8, ["value", "show"])
|
|
124
153
|
]),
|
|
125
|
-
default:
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
154
|
+
default: l(() => [
|
|
155
|
+
h("div", Re, [
|
|
156
|
+
h("div", xe, [
|
|
157
|
+
h("span", Se, r(t(i)("app.notice.title")), 1),
|
|
158
|
+
o(t(z), {
|
|
130
159
|
text: "",
|
|
131
160
|
size: "tiny",
|
|
132
|
-
disabled:
|
|
133
|
-
onClick:
|
|
161
|
+
disabled: g[c.value] === 0,
|
|
162
|
+
onClick: ee
|
|
134
163
|
}, {
|
|
135
|
-
icon:
|
|
136
|
-
|
|
164
|
+
icon: l(() => [
|
|
165
|
+
o(t(B), {
|
|
137
166
|
icon: "ph:checks",
|
|
138
167
|
width: 15
|
|
139
168
|
})
|
|
140
169
|
]),
|
|
141
|
-
default:
|
|
142
|
-
|
|
170
|
+
default: l(() => [
|
|
171
|
+
f(" " + r(t(i)("app.notice.markAllRead")), 1)
|
|
143
172
|
]),
|
|
144
173
|
_: 1
|
|
145
174
|
}, 8, ["disabled"])
|
|
146
175
|
]),
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
176
|
+
o(t(pe), {
|
|
177
|
+
value: c.value,
|
|
178
|
+
type: "line",
|
|
179
|
+
size: "small",
|
|
180
|
+
"tabs-padding": 16,
|
|
181
|
+
class: "notice-tabs",
|
|
182
|
+
"onUpdate:value": W
|
|
183
|
+
}, {
|
|
184
|
+
default: l(() => [
|
|
185
|
+
(s(), p(R, null, V(u, (a) => o(t(fe), {
|
|
186
|
+
key: a.key,
|
|
187
|
+
name: a.key
|
|
188
|
+
}, {
|
|
189
|
+
default: l(() => [
|
|
190
|
+
f(r(t(i)(a.label)) + " ", 1),
|
|
191
|
+
o(t(G), {
|
|
192
|
+
value: g[a.key],
|
|
193
|
+
max: 99,
|
|
194
|
+
show: g[a.key] > 0,
|
|
195
|
+
class: "tab-badge"
|
|
196
|
+
}, null, 8, ["value", "show"])
|
|
197
|
+
]),
|
|
198
|
+
_: 2
|
|
199
|
+
}, 1032, ["name"])), 64))
|
|
200
|
+
]),
|
|
201
|
+
_: 1
|
|
202
|
+
}, 8, ["value"]),
|
|
203
|
+
o(t(me), { show: A.value }, {
|
|
204
|
+
default: l(() => [
|
|
205
|
+
o(t(ye), { style: { "max-height": "360px" } }, {
|
|
206
|
+
default: l(() => [
|
|
207
|
+
T.value.length === 0 ? (s(), p("div", ze, [
|
|
208
|
+
o(t(ve), {
|
|
209
|
+
description: t(i)(L.value.empty),
|
|
154
210
|
size: "small"
|
|
155
211
|
}, null, 8, ["description"])
|
|
156
|
-
])) : (
|
|
157
|
-
(
|
|
158
|
-
var
|
|
159
|
-
return
|
|
212
|
+
])) : (s(), p("ul", Be, [
|
|
213
|
+
(s(!0), p(R, null, V(T.value, (a) => {
|
|
214
|
+
var m;
|
|
215
|
+
return s(), p("li", {
|
|
160
216
|
key: a.id,
|
|
161
|
-
class:
|
|
162
|
-
onClick: (
|
|
217
|
+
class: O(["notice-item", a.isRead ? "read" : "unread"]),
|
|
218
|
+
onClick: (oe) => Y(a)
|
|
163
219
|
}, [
|
|
164
|
-
a.isRead ?
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
220
|
+
a.isRead ? x("", !0) : (s(), p("span", Ee)),
|
|
221
|
+
h("div", Ue, [
|
|
222
|
+
h("div", Ve, [
|
|
223
|
+
le.value ? (s(), S(t(he), {
|
|
224
|
+
key: 0,
|
|
225
|
+
type: ae(a.type),
|
|
169
226
|
size: "tiny",
|
|
170
227
|
bordered: !1,
|
|
171
228
|
round: ""
|
|
172
229
|
}, {
|
|
173
|
-
default:
|
|
174
|
-
|
|
230
|
+
default: l(() => [
|
|
231
|
+
f(r(ne(a.type)), 1)
|
|
175
232
|
]),
|
|
176
233
|
_: 2
|
|
177
|
-
}, 1032, ["type"]),
|
|
178
|
-
|
|
179
|
-
class:
|
|
234
|
+
}, 1032, ["type"])) : x("", !0),
|
|
235
|
+
o(t(ge), {
|
|
236
|
+
class: O(["item-title", { unread: !a.isRead }])
|
|
180
237
|
}, {
|
|
181
|
-
default:
|
|
182
|
-
|
|
238
|
+
default: l(() => [
|
|
239
|
+
f(r(a.title), 1)
|
|
183
240
|
]),
|
|
184
241
|
_: 2
|
|
185
242
|
}, 1032, ["class"]),
|
|
186
|
-
(
|
|
187
|
-
key:
|
|
243
|
+
(m = a.actions) != null && m.length ? (s(), S(t(B), {
|
|
244
|
+
key: 1,
|
|
188
245
|
icon: "ph:lightning",
|
|
189
246
|
width: 13,
|
|
190
247
|
class: "item-actions-mark"
|
|
191
|
-
})) :
|
|
248
|
+
})) : x("", !0)
|
|
192
249
|
]),
|
|
193
|
-
|
|
250
|
+
D(a.content) ? (s(), S(t(H), {
|
|
194
251
|
key: 0,
|
|
195
252
|
depth: "3",
|
|
196
253
|
class: "item-snippet"
|
|
197
254
|
}, {
|
|
198
|
-
default:
|
|
199
|
-
|
|
255
|
+
default: l(() => [
|
|
256
|
+
f(r(D(a.content)), 1)
|
|
200
257
|
]),
|
|
201
258
|
_: 2
|
|
202
|
-
}, 1024)) :
|
|
203
|
-
|
|
259
|
+
}, 1024)) : x("", !0),
|
|
260
|
+
o(t(H), {
|
|
204
261
|
depth: "3",
|
|
205
262
|
class: "item-time"
|
|
206
263
|
}, {
|
|
207
|
-
default:
|
|
208
|
-
|
|
264
|
+
default: l(() => [
|
|
265
|
+
f(r(t(Ce)(a.publishTime, { seconds: !1 })), 1)
|
|
209
266
|
]),
|
|
210
267
|
_: 2
|
|
211
268
|
}, 1024)
|
|
212
269
|
])
|
|
213
|
-
], 10,
|
|
270
|
+
], 10, Me);
|
|
214
271
|
}), 128))
|
|
215
272
|
]))
|
|
216
273
|
]),
|
|
@@ -219,20 +276,20 @@ const he = { class: "notice-panel" }, ve = { class: "notice-head" }, ye = { clas
|
|
|
219
276
|
]),
|
|
220
277
|
_: 1
|
|
221
278
|
}, 8, ["show"]),
|
|
222
|
-
|
|
223
|
-
|
|
279
|
+
h("div", $e, [
|
|
280
|
+
o(t(z), {
|
|
224
281
|
text: "",
|
|
225
282
|
size: "small",
|
|
226
|
-
onClick:
|
|
283
|
+
onClick: te
|
|
227
284
|
}, {
|
|
228
|
-
icon:
|
|
229
|
-
|
|
285
|
+
icon: l(() => [
|
|
286
|
+
o(t(B), {
|
|
230
287
|
icon: "ph:arrow-right",
|
|
231
288
|
width: 14
|
|
232
289
|
})
|
|
233
290
|
]),
|
|
234
|
-
default:
|
|
235
|
-
|
|
291
|
+
default: l(() => [
|
|
292
|
+
f(r(t(i)("app.notice.viewAll")) + " ", 1)
|
|
236
293
|
]),
|
|
237
294
|
_: 1
|
|
238
295
|
})
|
|
@@ -241,38 +298,38 @@ const he = { class: "notice-panel" }, ve = { class: "notice-head" }, ye = { clas
|
|
|
241
298
|
]),
|
|
242
299
|
_: 1
|
|
243
300
|
}, 8, ["show"]),
|
|
244
|
-
|
|
245
|
-
show:
|
|
246
|
-
"onUpdate:show":
|
|
301
|
+
o(t(_e), {
|
|
302
|
+
show: C.value,
|
|
303
|
+
"onUpdate:show": n[1] || (n[1] = (a) => C.value = a),
|
|
247
304
|
preset: "card",
|
|
248
|
-
title: ((
|
|
305
|
+
title: ((v = k.value) == null ? void 0 : v.title) || t(i)("notice.detailTitle"),
|
|
249
306
|
style: { width: "640px", "max-width": "92vw" }
|
|
250
|
-
},
|
|
251
|
-
default:
|
|
307
|
+
}, ce({
|
|
308
|
+
default: l(() => {
|
|
252
309
|
var a;
|
|
253
310
|
return [
|
|
254
|
-
|
|
255
|
-
value: (a =
|
|
311
|
+
o(Ae, {
|
|
312
|
+
value: (a = k.value) == null ? void 0 : a.content
|
|
256
313
|
}, null, 8, ["value"])
|
|
257
314
|
];
|
|
258
315
|
}),
|
|
259
316
|
_: 2
|
|
260
317
|
}, [
|
|
261
|
-
(
|
|
318
|
+
(j = (F = k.value) == null ? void 0 : F.actions) != null && j.length ? {
|
|
262
319
|
name: "footer",
|
|
263
|
-
fn:
|
|
264
|
-
|
|
265
|
-
default:
|
|
266
|
-
(
|
|
267
|
-
key:
|
|
320
|
+
fn: l(() => [
|
|
321
|
+
o(t(we), { justify: "end" }, {
|
|
322
|
+
default: l(() => [
|
|
323
|
+
(s(!0), p(R, null, V(k.value.actions, (a, m) => (s(), S(t(z), {
|
|
324
|
+
key: m,
|
|
268
325
|
size: "small",
|
|
269
|
-
type:
|
|
270
|
-
loading:
|
|
271
|
-
disabled:
|
|
272
|
-
onClick: (
|
|
326
|
+
type: t(M).buttonType(a),
|
|
327
|
+
loading: b.value === m,
|
|
328
|
+
disabled: b.value !== null && b.value !== m,
|
|
329
|
+
onClick: (oe) => Z(a, m)
|
|
273
330
|
}, {
|
|
274
|
-
default:
|
|
275
|
-
|
|
331
|
+
default: l(() => [
|
|
332
|
+
f(r(t(M).label(a)), 1)
|
|
276
333
|
]),
|
|
277
334
|
_: 2
|
|
278
335
|
}, 1032, ["type", "loading", "disabled", "onClick"]))), 128))
|
|
@@ -288,6 +345,6 @@ const he = { class: "notice-panel" }, ve = { class: "notice-head" }, ye = { clas
|
|
|
288
345
|
}
|
|
289
346
|
});
|
|
290
347
|
export {
|
|
291
|
-
|
|
348
|
+
Xe as default
|
|
292
349
|
};
|
|
293
350
|
//# sourceMappingURL=NoticeBell2.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NoticeBell2.vue.js","sources":["../../src/layouts/NoticeBell.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 顶栏消息通知铃铛。富面板(n-popover):无页签单列表 + 正文弹层。\n// 未读=圆点+加粗+淡主色底,已读=整行变淡;\"读没读\"是过滤器不是分类,不做成页签(筛选在个人通知页)。\n// 未读数每 30s 轮询;面板展开时拉取列表。\n// 通知带动作列表时,正文弹层底部渲染成按钮(useNoticeAction):铃铛里直接\"办\",不必先跳到目标页面找按钮。\nimport { ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport {\n NPopover,\n NBadge,\n NButton,\n NTag,\n NEllipsis,\n NScrollbar,\n NSpace,\n NText,\n NEmpty,\n NModal,\n NSpin,\n useMessage,\n} from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useIntervalFn } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { noticeApi } from '#/api'\nimport { noticeBus } from '#/composables/useRealtime'\nimport { useNoticeAction } from '#/composables/useNoticeAction'\nimport { NoticeType, type NoticeAction, type NoticeMineItem } from '#/types/api'\nimport MarkdownView from '#/components/MarkdownEditor/MarkdownView.vue'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\n\nconst { t } = useI18n()\nconst router = useRouter()\nconst message = useMessage()\nconst noticeAction = useNoticeAction()\n\nconst unread = ref(0)\nconst items = ref<NoticeMineItem[]>([])\nconst loading = ref(false)\nconst panelShow = ref(false)\n\nasync function fetchUnread() {\n try {\n unread.value = await noticeApi.unreadCount()\n } catch {\n /* 轮询失败静默,下次自愈 */\n }\n}\n// 无页签单列表:恒拉最近一页混排,未读靠条目样式强调;筛选能力在\"查看全部\"的个人通知页。\nasync function fetchList() {\n loading.value = true\n try {\n const { items: list } = await noticeApi.mine({ page: 1, pageSize: 10 })\n items.value = list\n } catch {\n items.value = []\n } finally {\n loading.value = false\n }\n}\nfunction onShow(show: boolean) {\n if (show) fetchList()\n}\n\n// 正文弹层:内容随列表取回,直接渲染(Markdown,不能纯文本直出);点条目即标记已读。\nconst showNotice = ref(false)\nconst viewNotice = ref<NoticeMineItem | null>(null)\nasync function markRead(item: NoticeMineItem) {\n if (item.isRead) return\n try {\n await noticeApi.markRead(item.id)\n item.isRead = true\n await fetchUnread()\n } catch (e) {\n message.error(translateError(e))\n }\n}\nasync function openNotice(item: NoticeMineItem) {\n viewNotice.value = item\n showNotice.value = true\n await markRead(item)\n}\n// 动作:成功后关掉弹层与面板(页面跳转时尤其要关,否则面板盖在新页面上)。\nconst running = ref<number | null>(null)\nasync function onAction(a: NoticeAction, index: number) {\n running.value = index\n try {\n if (await noticeAction.run(a)) {\n showNotice.value = false\n panelShow.value = false\n }\n } finally {\n running.value = null\n }\n}\nasync function markAllRead() {\n try {\n await noticeApi.markAllRead()\n await Promise.all([fetchUnread(), fetchList()])\n } catch (e) {\n message.error(translateError(e))\n }\n}\nfunction viewAll() {\n panelShow.value = false\n router.push('/personal/notice')\n}\n\n// 类型 → 标签色/文案。新增类型在此补一行即可。\nconst tagType = (ty: NoticeType) =>\n ty === NoticeType.Announcement ? 'warning' : ty === NoticeType.Message ? 'success' : 'info'\nconst typeLabel = (ty: NoticeType) =>\n ty === NoticeType.Announcement\n ? t('notice.typeAnnouncement')\n : ty === NoticeType.Message\n ? t('notice.typeMessage')\n : t('notice.typeNotice')\n\n// 正文摘要:去掉常见 Markdown 记号,压空白,截断。ponytail: 正则够用,要精准渲染再引 md 解析。\nfunction snippet(md?: string | null) {\n if (!md) return ''\n const s = md\n .replace(/!\\[[^\\]]*\\]\\([^)]*\\)/g, '') // 图片\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1') // 链接留文字\n .replace(/[#>*_`~-]/g, '') // 记号\n .replace(/\\s+/g, ' ')\n .trim()\n return s.length > 60 ? s.slice(0, 60) + '…' : s\n}\n\n// 双腿:实时推送到达即刷新未读(SignalR 开启时,即时);30s 轮询兜底(实时关闭/连接掉线时)。\n// VueUse 的 useEventBus.on 在组件卸载时自动退订。\nnoticeBus.on(() => {\n fetchUnread()\n})\nuseIntervalFn(fetchUnread, 30000)\nfetchUnread()\n</script>\n\n<template>\n <n-popover\n v-model:show=\"panelShow\"\n trigger=\"click\"\n placement=\"bottom-end\"\n :show-arrow=\"false\"\n style=\"padding: 0\"\n @update:show=\"onShow\"\n >\n <template #trigger>\n <!-- offset 的 y 把徽标整体下移:默认它以按钮右上角为中心、一半在按钮顶边之上,\n 顶栏面板 overflow:hidden,两三位数(99+)的胶囊顶边会被切平 -->\n <n-badge :value=\"unread\" :max=\"99\" :show=\"unread > 0\" :offset=\"[0, 5]\">\n <n-button quaternary circle :aria-label=\"t('app.notice.title')\">\n <Icon icon=\"ph:bell\" :width=\"19\" />\n </n-button>\n </n-badge>\n </template>\n\n <div class=\"notice-panel\">\n <div class=\"notice-head\">\n <span class=\"notice-title\">{{ t('app.notice.title') }}</span>\n <n-button text size=\"tiny\" :disabled=\"unread === 0\" @click=\"markAllRead\">\n <template #icon><Icon icon=\"ph:checks\" :width=\"15\" /></template>\n {{ t('app.notice.markAllRead') }}\n </n-button>\n </div>\n\n <n-spin :show=\"loading\">\n <n-scrollbar style=\"max-height: 360px\">\n <div v-if=\"items.length === 0\" class=\"notice-empty\">\n <n-empty :description=\"t('app.notice.empty')\" size=\"small\" />\n </div>\n <ul v-else class=\"notice-list\">\n <li\n v-for=\"n in items\"\n :key=\"n.id\"\n :class=\"['notice-item', n.isRead ? 'read' : 'unread']\"\n @click=\"openNotice(n)\"\n >\n <span v-if=\"!n.isRead\" class=\"dot\" />\n <div class=\"notice-body\">\n <div class=\"line1\">\n <n-tag :type=\"tagType(n.type)\" size=\"tiny\" :bordered=\"false\" round>\n {{ typeLabel(n.type) }}\n </n-tag>\n <n-ellipsis class=\"item-title\" :class=\"{ unread: !n.isRead }\">\n {{ n.title }}\n </n-ellipsis>\n <Icon\n v-if=\"n.actions?.length\"\n icon=\"ph:lightning\"\n :width=\"13\"\n class=\"item-actions-mark\"\n />\n </div>\n <n-text v-if=\"snippet(n.content)\" depth=\"3\" class=\"item-snippet\">\n {{ snippet(n.content) }}\n </n-text>\n <n-text depth=\"3\" class=\"item-time\">\n {{ fmtDateTime(n.publishTime, { seconds: false }) }}\n </n-text>\n </div>\n </li>\n </ul>\n </n-scrollbar>\n </n-spin>\n\n <div class=\"notice-foot\">\n <n-button text size=\"small\" @click=\"viewAll\">\n {{ t('app.notice.viewAll') }}\n <template #icon><Icon icon=\"ph:arrow-right\" :width=\"14\" /></template>\n </n-button>\n </div>\n </div>\n </n-popover>\n\n <n-modal\n v-model:show=\"showNotice\"\n preset=\"card\"\n :title=\"viewNotice?.title || t('notice.detailTitle')\"\n style=\"width: 640px; max-width: 92vw\"\n >\n <MarkdownView :value=\"viewNotice?.content\" />\n <template v-if=\"viewNotice?.actions?.length\" #footer>\n <n-space justify=\"end\">\n <n-button\n v-for=\"(a, i) in viewNotice.actions\"\n :key=\"i\"\n size=\"small\"\n :type=\"noticeAction.buttonType(a)\"\n :loading=\"running === i\"\n :disabled=\"running !== null && running !== i\"\n @click=\"onAction(a, i)\"\n >\n {{ noticeAction.label(a) }}\n </n-button>\n </n-space>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.notice-panel {\n width: 360px;\n max-width: 92vw;\n}\n.notice-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px 4px;\n}\n.notice-title {\n font-weight: 600;\n font-size: 15px;\n}\n.notice-empty {\n padding: 32px 0;\n}\n.notice-list {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.notice-item {\n position: relative;\n display: flex;\n gap: 8px;\n padding: 12px 16px;\n cursor: pointer;\n border-top: 1px solid var(--separator);\n transition: background-color var(--transition-fast);\n}\n.notice-item:hover {\n background-color: var(--hover);\n}\n/* 未读:整行淡主色底(明暗主题都成立);已读:整行变淡 */\n.notice-item.unread {\n background-color: color-mix(in srgb, var(--signal) 5%, transparent);\n}\n.notice-item.unread:hover {\n background-color: color-mix(in srgb, var(--signal) 10%, transparent);\n}\n.notice-item.read {\n opacity: 0.55;\n}\n.dot {\n position: absolute;\n left: 6px;\n top: 18px;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--signal);\n}\n.notice-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.line1 {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n.item-title {\n flex: 1;\n min-width: 0;\n font-size: 14px;\n}\n.item-title.unread {\n font-weight: 600;\n}\n.item-actions-mark {\n flex-shrink: 0;\n color: var(--signal);\n}\n.item-snippet {\n font-size: 13px;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.item-time {\n font-size: 12.5px;\n}\n.notice-foot {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--separator);\n}\n</style>\n"],"names":["t","useI18n","router","useRouter","message","useMessage","noticeAction","useNoticeAction","unread","ref","items","loading","panelShow","fetchUnread","noticeApi","fetchList","list","onShow","show","showNotice","viewNotice","markRead","item","e","translateError","openNotice","running","onAction","a","index","markAllRead","viewAll","tagType","ty","NoticeType","typeLabel","snippet","md","s","noticeBus","useIntervalFn","_createVNode","_unref","NPopover","$event","NBadge","NButton","Icon","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_createTextVNode","NSpin","NScrollbar","_openBlock","_createElementBlock","_hoisted_4","NEmpty","_hoisted_5","_Fragment","_renderList","n","_normalizeClass","_hoisted_7","_hoisted_8","_hoisted_9","NTag","NEllipsis","_a","_createBlock","NText","fmtDateTime","_hoisted_10","NModal","MarkdownView","_c","_b","NSpace","i"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NoticeBell2.vue.js","sources":["../../src/layouts/NoticeBell.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 顶栏消息通知铃铛。富面板(n-popover):按类型分页签的列表 + 正文弹层。\n// 页签按\"消息从哪来\"分:消息(业务系统推给个人的)与通知(管理员发的通知、公告);\n// \"读没读\"是过滤器不是分类,不做成页签(筛选在个人通知页)。\n// 未读=圆点+加粗+淡主色底,已读=整行变淡。总未读数每 30s 轮询;面板展开时取各页签未读数与当前页签列表。\n// 通知带动作列表时,正文弹层底部渲染成按钮(useNoticeAction):铃铛里直接\"办\",不必先跳到目标页面找按钮。\nimport { computed, reactive, ref } from 'vue'\nimport { useRouter } from 'vue-router'\nimport {\n NPopover,\n NBadge,\n NButton,\n NTabs,\n NTab,\n NTag,\n NEllipsis,\n NScrollbar,\n NSpace,\n NText,\n NEmpty,\n NModal,\n NSpin,\n useMessage,\n} from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useIntervalFn } from '@vueuse/core'\nimport { useI18n } from 'vue-i18n'\nimport { noticeApi } from '#/api'\nimport { noticeBus } from '#/composables/useRealtime'\nimport { useNoticeAction } from '#/composables/useNoticeAction'\nimport { NoticeType, type NoticeAction, type NoticeMineItem } from '#/types/api'\nimport MarkdownView from '#/components/MarkdownEditor/MarkdownView.vue'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\n\nconst { t } = useI18n()\nconst router = useRouter()\nconst message = useMessage()\nconst noticeAction = useNoticeAction()\n\n// 页签顺序即打开面板时的优先级:先停在第一个有未读的页签,都没有就停第一个。\nconst TABS = [\n {\n key: 'message',\n types: [NoticeType.Message],\n label: 'app.notice.tabMessage',\n empty: 'app.notice.emptyMessage',\n },\n {\n key: 'notice',\n types: [NoticeType.Notice, NoticeType.Announcement],\n label: 'app.notice.tabNotice',\n empty: 'app.notice.empty',\n },\n] as const\ntype TabKey = (typeof TABS)[number]['key']\nconst typesOf = (key: TabKey) => [...TABS.find(x => x.key === key)!.types]\n\nconst unread = ref(0)\nconst tab = ref<TabKey>(TABS[0].key)\nconst tabUnread = reactive<Record<TabKey, number>>({ message: 0, notice: 0 })\nconst current = computed(() => TABS.find(x => x.key === tab.value)!)\nconst items = ref<NoticeMineItem[]>([])\nconst loading = ref(false)\nconst panelShow = ref(false)\n\n// 页签未读数只在面板开着时取:轮询只数总数,请求量不随页签数翻倍。\nasync function fetchTabUnread() {\n const counts = await Promise.all(TABS.map(x => noticeApi.unreadCount([...x.types])))\n TABS.forEach((x, i) => (tabUnread[x.key] = counts[i]!))\n}\nasync function fetchUnread() {\n try {\n unread.value = await noticeApi.unreadCount()\n if (panelShow.value) await fetchTabUnread()\n } catch {\n /* 轮询失败静默,下次自愈 */\n }\n}\n// 每个页签拉最近一页,未读靠条目样式强调;筛选能力在\"查看全部\"的个人通知页。\nasync function fetchList() {\n const key = tab.value\n loading.value = true\n try {\n const { items: list } = await noticeApi.mine({ page: 1, pageSize: 10, types: typesOf(key) })\n // 快速切页签时,先发的请求可能后回来,不能覆盖当前页签的列表。\n if (key === tab.value) items.value = list\n } catch {\n if (key === tab.value) items.value = []\n } finally {\n if (key === tab.value) loading.value = false\n }\n}\nasync function onShow(show: boolean) {\n if (!show) return\n loading.value = true\n try {\n await fetchTabUnread()\n } catch {\n /* 取不到页签数就停在第一个页签 */\n }\n tab.value = TABS.find(x => tabUnread[x.key] > 0)?.key ?? TABS[0].key\n fetchList()\n}\nfunction onTab(key: TabKey) {\n tab.value = key\n fetchList()\n}\n\n// 正文弹层:内容随列表取回,直接渲染(Markdown,不能纯文本直出);点条目即标记已读。\nconst showNotice = ref(false)\nconst viewNotice = ref<NoticeMineItem | null>(null)\nasync function markRead(item: NoticeMineItem) {\n if (item.isRead) return\n try {\n await noticeApi.markRead(item.id)\n item.isRead = true\n await fetchUnread()\n } catch (e) {\n message.error(translateError(e))\n }\n}\nasync function openNotice(item: NoticeMineItem) {\n viewNotice.value = item\n showNotice.value = true\n await markRead(item)\n}\n// 动作:成功后关掉弹层与面板(页面跳转时尤其要关,否则面板盖在新页面上)。\nconst running = ref<number | null>(null)\nasync function onAction(a: NoticeAction, index: number) {\n running.value = index\n try {\n if (await noticeAction.run(a)) {\n showNotice.value = false\n panelShow.value = false\n }\n } finally {\n running.value = null\n }\n}\nasync function markAllRead() {\n try {\n await noticeApi.markAllRead(typesOf(tab.value))\n await Promise.all([fetchUnread(), fetchList()])\n } catch (e) {\n message.error(translateError(e))\n }\n}\nfunction viewAll() {\n panelShow.value = false\n router.push('/personal/notice')\n}\n\n// 类型 → 标签色/文案。新增类型在此补一行即可。\nconst tagType = (ty: NoticeType) =>\n ty === NoticeType.Announcement ? 'warning' : ty === NoticeType.Message ? 'success' : 'info'\nconst typeLabel = (ty: NoticeType) =>\n ty === NoticeType.Announcement\n ? t('notice.typeAnnouncement')\n : ty === NoticeType.Message\n ? t('notice.typeMessage')\n : t('notice.typeNotice')\n// 页签里只有一种类型时标签不带信息,不显示。\nconst showTag = computed(() => current.value.types.length > 1)\n\n// 正文摘要:去掉常见 Markdown 记号,压空白,截断。ponytail: 正则够用,要精准渲染再引 md 解析。\nfunction snippet(md?: string | null) {\n if (!md) return ''\n const s = md\n .replace(/!\\[[^\\]]*\\]\\([^)]*\\)/g, '') // 图片\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1') // 链接留文字\n .replace(/[#>*_`~-]/g, '') // 记号\n .replace(/\\s+/g, ' ')\n .trim()\n return s.length > 60 ? s.slice(0, 60) + '…' : s\n}\n\n// 双腿:实时推送到达即刷新未读(SignalR 开启时,即时);30s 轮询兜底(实时关闭/连接掉线时)。\n// VueUse 的 useEventBus.on 在组件卸载时自动退订。\nnoticeBus.on(() => {\n fetchUnread()\n})\nuseIntervalFn(fetchUnread, 30000)\nfetchUnread()\n</script>\n\n<template>\n <n-popover\n v-model:show=\"panelShow\"\n trigger=\"click\"\n placement=\"bottom-end\"\n :show-arrow=\"false\"\n style=\"padding: 0\"\n @update:show=\"onShow\"\n >\n <template #trigger>\n <!-- offset 的 y 把徽标整体下移:默认它以按钮右上角为中心、一半在按钮顶边之上,\n 顶栏面板 overflow:hidden,两三位数(99+)的胶囊顶边会被切平 -->\n <n-badge :value=\"unread\" :max=\"99\" :show=\"unread > 0\" :offset=\"[0, 5]\">\n <n-button quaternary circle :aria-label=\"t('app.notice.title')\">\n <Icon icon=\"ph:bell\" :width=\"19\" />\n </n-button>\n </n-badge>\n </template>\n\n <div class=\"notice-panel\">\n <div class=\"notice-head\">\n <span class=\"notice-title\">{{ t('app.notice.title') }}</span>\n <n-button text size=\"tiny\" :disabled=\"tabUnread[tab] === 0\" @click=\"markAllRead\">\n <template #icon><Icon icon=\"ph:checks\" :width=\"15\" /></template>\n {{ t('app.notice.markAllRead') }}\n </n-button>\n </div>\n\n <n-tabs\n :value=\"tab\"\n type=\"line\"\n size=\"small\"\n :tabs-padding=\"16\"\n class=\"notice-tabs\"\n @update:value=\"onTab\"\n >\n <n-tab v-for=\"x in TABS\" :key=\"x.key\" :name=\"x.key\">\n {{ t(x.label) }}\n <n-badge\n :value=\"tabUnread[x.key]\"\n :max=\"99\"\n :show=\"tabUnread[x.key] > 0\"\n class=\"tab-badge\"\n />\n </n-tab>\n </n-tabs>\n\n <n-spin :show=\"loading\">\n <n-scrollbar style=\"max-height: 360px\">\n <div v-if=\"items.length === 0\" class=\"notice-empty\">\n <n-empty :description=\"t(current.empty)\" size=\"small\" />\n </div>\n <ul v-else class=\"notice-list\">\n <li\n v-for=\"n in items\"\n :key=\"n.id\"\n :class=\"['notice-item', n.isRead ? 'read' : 'unread']\"\n @click=\"openNotice(n)\"\n >\n <span v-if=\"!n.isRead\" class=\"dot\" />\n <div class=\"notice-body\">\n <div class=\"line1\">\n <n-tag v-if=\"showTag\" :type=\"tagType(n.type)\" size=\"tiny\" :bordered=\"false\" round>\n {{ typeLabel(n.type) }}\n </n-tag>\n <n-ellipsis class=\"item-title\" :class=\"{ unread: !n.isRead }\">\n {{ n.title }}\n </n-ellipsis>\n <Icon\n v-if=\"n.actions?.length\"\n icon=\"ph:lightning\"\n :width=\"13\"\n class=\"item-actions-mark\"\n />\n </div>\n <n-text v-if=\"snippet(n.content)\" depth=\"3\" class=\"item-snippet\">\n {{ snippet(n.content) }}\n </n-text>\n <n-text depth=\"3\" class=\"item-time\">\n {{ fmtDateTime(n.publishTime, { seconds: false }) }}\n </n-text>\n </div>\n </li>\n </ul>\n </n-scrollbar>\n </n-spin>\n\n <div class=\"notice-foot\">\n <n-button text size=\"small\" @click=\"viewAll\">\n {{ t('app.notice.viewAll') }}\n <template #icon><Icon icon=\"ph:arrow-right\" :width=\"14\" /></template>\n </n-button>\n </div>\n </div>\n </n-popover>\n\n <n-modal\n v-model:show=\"showNotice\"\n preset=\"card\"\n :title=\"viewNotice?.title || t('notice.detailTitle')\"\n style=\"width: 640px; max-width: 92vw\"\n >\n <MarkdownView :value=\"viewNotice?.content\" />\n <template v-if=\"viewNotice?.actions?.length\" #footer>\n <n-space justify=\"end\">\n <n-button\n v-for=\"(a, i) in viewNotice.actions\"\n :key=\"i\"\n size=\"small\"\n :type=\"noticeAction.buttonType(a)\"\n :loading=\"running === i\"\n :disabled=\"running !== null && running !== i\"\n @click=\"onAction(a, i)\"\n >\n {{ noticeAction.label(a) }}\n </n-button>\n </n-space>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.notice-panel {\n width: 360px;\n max-width: 92vw;\n}\n.notice-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px 4px;\n}\n.notice-title {\n font-weight: 600;\n font-size: 15px;\n}\n.tab-badge {\n margin-left: 6px;\n}\n.notice-empty {\n padding: 32px 0;\n}\n.notice-list {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.notice-item {\n position: relative;\n display: flex;\n gap: 8px;\n padding: 12px 16px;\n cursor: pointer;\n border-top: 1px solid var(--separator);\n transition: background-color var(--transition-fast);\n}\n.notice-item:hover {\n background-color: var(--hover);\n}\n/* 未读:整行淡主色底(明暗主题都成立);已读:整行变淡 */\n.notice-item.unread {\n background-color: color-mix(in srgb, var(--signal) 5%, transparent);\n}\n.notice-item.unread:hover {\n background-color: color-mix(in srgb, var(--signal) 10%, transparent);\n}\n.notice-item.read {\n opacity: 0.55;\n}\n.dot {\n position: absolute;\n left: 6px;\n top: 18px;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--signal);\n}\n.notice-body {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.line1 {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n.item-title {\n flex: 1;\n min-width: 0;\n font-size: 14px;\n}\n.item-title.unread {\n font-weight: 600;\n}\n.item-actions-mark {\n flex-shrink: 0;\n color: var(--signal);\n}\n.item-snippet {\n font-size: 13px;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.item-time {\n font-size: 12.5px;\n}\n.notice-foot {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--separator);\n}\n</style>\n"],"names":["t","useI18n","router","useRouter","message","useMessage","noticeAction","useNoticeAction","TABS","NoticeType","typesOf","key","x","unread","ref","tab","tabUnread","reactive","current","computed","items","loading","panelShow","fetchTabUnread","counts","noticeApi","i","fetchUnread","fetchList","list","onShow","show","_a","onTab","showNotice","viewNotice","markRead","item","e","translateError","openNotice","running","onAction","a","index","markAllRead","viewAll","tagType","ty","typeLabel","showTag","snippet","md","s","noticeBus","useIntervalFn","_createVNode","_unref","NPopover","$event","NBadge","NButton","Icon","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_toDisplayString","_createTextVNode","NTabs","_createElementBlock","_Fragment","_renderList","NTab","NSpin","NScrollbar","_openBlock","_hoisted_4","NEmpty","_hoisted_5","n","_normalizeClass","_hoisted_7","_hoisted_8","_hoisted_9","_createBlock","NTag","NEllipsis","NText","fmtDateTime","_hoisted_10","NModal","MarkdownView","_c","_b","NSpace"],"mappings":"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"}
|