@befly-addon/admin 1.8.4 → 1.8.6

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.
@@ -1,13 +1,13 @@
1
1
  <template>
2
- <PagedTableDetailPage class="page-email page-table" :columns="$Data.columns" :endpoints="$Data.endpoints" :table-slot-names="['sendResult', 'sendTime']">
2
+ <PagedTableDetail class="page-email page-table" :columns="$Data.columns" :endpoints="$Data.endpoints" :table-slot-names="['sendResult', 'sendTime']">
3
3
  <template #toolLeft>
4
- <TButton theme="primary" @click="$Method.openSendDialog">
4
+ <TButton theme="primary" @click="openSendDialog">
5
5
  <template #icon>
6
6
  <ILucideSend />
7
7
  </template>
8
8
  发送邮件
9
9
  </TButton>
10
- <TButton variant="outline" @click="$Method.onVerify">
10
+ <TButton variant="outline" @click="onVerify">
11
11
  <template #icon>
12
12
  <ILucideCheckCircle />
13
13
  </template>
@@ -16,7 +16,7 @@
16
16
  </template>
17
17
 
18
18
  <template #toolRight="scope">
19
- <TButton shape="circle" @click="$Method.onReload(scope.reload)">
19
+ <TButton shape="circle" @click="onReload(scope.reload)">
20
20
  <template #icon>
21
21
  <ILucideRotateCw />
22
22
  </template>
@@ -29,17 +29,17 @@
29
29
  </template>
30
30
 
31
31
  <template #sendTime="{ row }">
32
- {{ $Method.formatTime(row.sendTime) }}
32
+ {{ formatTime(row.sendTime) }}
33
33
  </template>
34
34
 
35
35
  <template #detail="scope">
36
- <DetailPanel :data="scope.currentRow" :fields="$Data.detailFields">
36
+ <DetailPanel :data="scope.row" :fields="$Data.columns">
37
37
  <template #sendResult="slotScope">
38
38
  <TTag v-if="slotScope.value === 1" shape="round" theme="success" variant="light-outline">成功</TTag>
39
39
  <TTag v-else shape="round" theme="danger" variant="light-outline">失败</TTag>
40
40
  </template>
41
41
  <template #sendTime="slotScope">
42
- {{ $Method.formatTime(slotScope.value) }}
42
+ {{ formatTime(slotScope.value) }}
43
43
  </template>
44
44
  <template #content="slotScope">
45
45
  <div class="email-content" v-html="slotScope.value"></div>
@@ -48,7 +48,7 @@
48
48
  </template>
49
49
 
50
50
  <template #dialogs="scope">
51
- <TDialog v-model:visible="$Data.sendDialogVisible" header="发送邮件" :footer="false" width="600px">
51
+ <PageDialog v-model="$Data.sendDialogVisible" title="发送邮件" :confirm-loading="$Data.sending" @confirm="(context) => onSend(scope.reload, context)" @cancel="onCancelSend" @close="onCancelSend">
52
52
  <TForm :ref="(el) => ($From.sendForm = el)" :data="$Data.sendForm" :rules="$Data.sendRules" label-width="80px">
53
53
  <TFormItem label="收件人" name="to">
54
54
  <TInput v-model="$Data.sendForm.to" placeholder="请输入收件人邮箱" />
@@ -62,26 +62,21 @@
62
62
  <TFormItem label="内容" name="content">
63
63
  <TTextarea v-model="$Data.sendForm.content" placeholder="请输入邮件内容(支持HTML)" :autosize="{ minRows: 6, maxRows: 12 }" />
64
64
  </TFormItem>
65
- <TFormItem>
66
- <TSpace>
67
- <TButton theme="primary" :loading="$Data.sending" @click="$Method.onSend(scope.reload)">发送</TButton>
68
- <TButton variant="outline" @click="$Method.onCancelSend">取消</TButton>
69
- </TSpace>
70
- </TFormItem>
71
65
  </TForm>
72
- </TDialog>
66
+ </PageDialog>
73
67
  </template>
74
- </PagedTableDetailPage>
68
+ </PagedTableDetail>
75
69
  </template>
76
70
 
77
71
  <script setup lang="ts">
78
- import { Button as TButton, Dialog as TDialog, Form as TForm, FormItem as TFormItem, Input as TInput, MessagePlugin, Space as TSpace, Tag as TTag, Textarea as TTextarea } from "tdesign-vue-next";
72
+ import { Button as TButton, Form as TForm, FormItem as TFormItem, Input as TInput, MessagePlugin, Space as TSpace, Tag as TTag, Textarea as TTextarea } from "tdesign-vue-next";
79
73
  import ILucideRotateCw from "~icons/lucide/rotate-cw";
80
74
  import ILucideSend from "~icons/lucide/send";
81
75
  import ILucideCheckCircle from "~icons/lucide/check-circle";
82
- import DetailPanel from "@/components/DetailPanel.vue";
76
+ import PageDialog from "@/components/pageDialog.vue";
77
+ import DetailPanel from "@/components/detailPanel.vue";
83
78
  import { $Http } from "@/plugins/http";
84
- import PagedTableDetailPage from "@/components/PagedTableDetailPage.vue";
79
+ import PagedTableDetail from "@/components/pagedTableDetail.vue";
85
80
  import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
86
81
 
87
82
  const $From = $shallowRef({
@@ -95,21 +90,14 @@ const $Data = $ref({
95
90
  { colKey: "toEmail", title: "收件人" },
96
91
  { colKey: "subject", title: "主题" },
97
92
  { colKey: "sendTime", title: "发送时间" },
98
- { colKey: "sendResult", title: "发送结果" }
99
- ]),
100
- detailFields: [
101
- { colKey: "username", title: "发送人账号" },
102
- { colKey: "nickname", title: "发送人昵称" },
103
- { colKey: "toEmail", title: "收件人" },
104
- { colKey: "ccEmail", title: "抄送" },
105
- { colKey: "bccEmail", title: "密送" },
106
- { colKey: "subject", title: "主题" },
107
- { colKey: "content", title: "内容" },
108
- { colKey: "sendTime", title: "发送时间" },
109
93
  { colKey: "sendResult", title: "发送结果" },
110
- { colKey: "messageId", title: "消息ID" },
111
- { colKey: "failReason", title: "失败原因" }
112
- ],
94
+ { colKey: "nickname", title: "发送人昵称", detail: true },
95
+ { colKey: "ccEmail", title: "抄送", detail: true },
96
+ { colKey: "bccEmail", title: "密送", detail: true },
97
+ { colKey: "content", title: "内容", detail: true },
98
+ { colKey: "messageId", title: "消息ID", detail: true },
99
+ { colKey: "failReason", title: "失败原因", detail: true }
100
+ ]),
113
101
  endpoints: {
114
102
  list: {
115
103
  path: "/addon/admin/email/logList",
@@ -131,85 +119,86 @@ const $Data = $ref({
131
119
  }
132
120
  });
133
121
 
134
- // 方法
135
- const $Method = {
136
- onReload(reload) {
137
- reload({ keepSelection: true });
138
- },
122
+ function onReload(reload: (options: { keepSelection?: boolean }) => void): void {
123
+ reload({ keepSelection: true });
124
+ }
139
125
 
140
- onCancelSend() {
141
- $Data.sendDialogVisible = false;
142
- },
126
+ function onCancelSend(): void {
127
+ $Data.sendDialogVisible = false;
128
+ }
143
129
 
144
- // 打开发送弹框
145
- openSendDialog() {
146
- $Data.sendForm = {
147
- to: "",
148
- cc: "",
149
- subject: "",
150
- content: ""
151
- };
152
- $Data.sendDialogVisible = true;
153
- },
130
+ function openSendDialog(): void {
131
+ $Data.sendForm = {
132
+ to: "",
133
+ cc: "",
134
+ subject: "",
135
+ content: ""
136
+ };
137
+ $Data.sendDialogVisible = true;
138
+ }
154
139
 
155
- // 发送邮件
156
- async onSend(reload) {
157
- const valid = await $From.sendForm?.validate();
158
- if (valid !== true) return;
159
-
160
- $Data.sending = true;
161
- try {
162
- const res = await $Http.post("/addon/admin/email/send", {
163
- to: $Data.sendForm.to,
164
- subject: $Data.sendForm.subject,
165
- content: $Data.sendForm.content,
166
- cc: $Data.sendForm.cc || undefined,
167
- isHtml: true
168
- });
169
-
170
- if (res.code === 0) {
171
- MessagePlugin.success("发送成功");
172
- $Data.sendDialogVisible = false;
173
- if (reload) {
174
- reload({ keepSelection: false, resetPage: true });
175
- }
176
- } else {
177
- MessagePlugin.error(res.msg || "发送失败");
178
- }
179
- } catch (error) {
180
- MessagePlugin.error("发送失败");
181
- } finally {
182
- $Data.sending = false;
183
- }
184
- },
140
+ type PageDialogEventContext = {
141
+ close: () => void;
142
+ };
185
143
 
186
- // 验证配置
187
- async onVerify() {
188
- try {
189
- const res = await $Http.post("/addon/admin/email/verify");
190
- if (res.code === 0) {
191
- MessagePlugin.success("邮件服务配置正常");
144
+ async function onSend(reload: ((options: { keepSelection?: boolean; resetPage?: boolean }) => void) | null, context?: PageDialogEventContext): Promise<void> {
145
+ const valid = await $From.sendForm?.validate();
146
+ if (valid !== true) return;
147
+
148
+ $Data.sending = true;
149
+ try {
150
+ const res = await $Http.post("/addon/admin/email/send", {
151
+ to: $Data.sendForm.to,
152
+ subject: $Data.sendForm.subject,
153
+ content: $Data.sendForm.content,
154
+ cc: $Data.sendForm.cc || undefined,
155
+ isHtml: true
156
+ });
157
+
158
+ if (res.code === 0) {
159
+ MessagePlugin.success("发送成功");
160
+ if (context && typeof context.close === "function") {
161
+ context.close();
192
162
  } else {
193
- MessagePlugin.error(res.msg || "配置异常");
163
+ $Data.sendDialogVisible = false;
164
+ }
165
+ if (reload) {
166
+ reload({ keepSelection: false, resetPage: true });
194
167
  }
195
- } catch (error) {
196
- MessagePlugin.error("验证失败");
168
+ } else {
169
+ MessagePlugin.error(res.msg || "发送失败");
197
170
  }
198
- },
171
+ } catch (error) {
172
+ MessagePlugin.error("发送失败");
173
+ } finally {
174
+ $Data.sending = false;
175
+ }
176
+ }
199
177
 
200
- // 格式化时间
201
- formatTime(timestamp) {
202
- if (!timestamp) return "-";
203
- const date = new Date(timestamp);
204
- const year = date.getFullYear();
205
- const month = String(date.getMonth() + 1).padStart(2, "0");
206
- const day = String(date.getDate()).padStart(2, "0");
207
- const hours = String(date.getHours()).padStart(2, "0");
208
- const minutes = String(date.getMinutes()).padStart(2, "0");
209
- const seconds = String(date.getSeconds()).padStart(2, "0");
210
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
178
+ async function onVerify(): Promise<void> {
179
+ try {
180
+ const res = await $Http.post("/addon/admin/email/verify");
181
+ if (res.code === 0) {
182
+ MessagePlugin.success("邮件服务配置正常");
183
+ } else {
184
+ MessagePlugin.error(res.msg || "配置异常");
185
+ }
186
+ } catch (error) {
187
+ MessagePlugin.error("验证失败");
211
188
  }
212
- };
189
+ }
190
+
191
+ function formatTime(timestamp: unknown): string {
192
+ if (!timestamp) return "-";
193
+ const date = new Date(timestamp as never);
194
+ const year = date.getFullYear();
195
+ const month = String(date.getMonth() + 1).padStart(2, "0");
196
+ const day = String(date.getDate()).padStart(2, "0");
197
+ const hours = String(date.getHours()).padStart(2, "0");
198
+ const minutes = String(date.getMinutes()).padStart(2, "0");
199
+ const seconds = String(date.getSeconds()).padStart(2, "0");
200
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
201
+ }
213
202
  </script>
214
203
 
215
204
  <style scoped lang="scss">
@@ -1,7 +1,7 @@
1
1
  <template>
2
- <PagedTableDetailPage class="page-login-log page-table" :columns="$Data.columns" :endpoints="$Data.endpoints" :table-slot-names="['loginResult', 'loginTime', 'deviceType']">
2
+ <PagedTableDetail class="page-login-log page-table" :columns="$Data.columns" :endpoints="$Data.endpoints" :table-slot-names="['loginResult', 'loginTime', 'deviceType']">
3
3
  <template #toolRight="scope">
4
- <TButton shape="circle" @click="$Method.onReload(scope.reload)">
4
+ <TButton shape="circle" @click="onReload(scope.reload)">
5
5
  <template #icon>
6
6
  <ILucideRotateCw />
7
7
  </template>
@@ -14,7 +14,7 @@
14
14
  </template>
15
15
 
16
16
  <template #loginTime="{ row }">
17
- {{ $Method.formatTime(row.loginTime) }}
17
+ {{ formatTime(row.loginTime) }}
18
18
  </template>
19
19
 
20
20
  <template #deviceType="{ row }">
@@ -22,27 +22,27 @@
22
22
  </template>
23
23
 
24
24
  <template #detail="scope">
25
- <DetailPanel :data="scope.currentRow" :fields="$Data.detailFields">
25
+ <DetailPanel :data="scope.row" :fields="$Data.columns">
26
26
  <template #loginResult="slotScope">
27
27
  <TTag v-if="slotScope.value === 1" shape="round" theme="success" variant="light-outline">成功</TTag>
28
28
  <TTag v-else shape="round" theme="danger" variant="light-outline">失败</TTag>
29
29
  </template>
30
30
  <template #loginTime="slotScope">
31
- {{ $Method.formatTime(slotScope.value) }}
31
+ {{ formatTime(slotScope.value) }}
32
32
  </template>
33
33
  <template #deviceType="slotScope">
34
34
  <TTag shape="round" variant="light-outline">{{ slotScope.value || "desktop" }}</TTag>
35
35
  </template>
36
36
  </DetailPanel>
37
37
  </template>
38
- </PagedTableDetailPage>
38
+ </PagedTableDetail>
39
39
  </template>
40
40
 
41
41
  <script setup lang="ts">
42
42
  import { Button as TButton, Tag as TTag } from "tdesign-vue-next";
43
43
  import ILucideRotateCw from "~icons/lucide/rotate-cw";
44
- import DetailPanel from "@/components/DetailPanel.vue";
45
- import PagedTableDetailPage from "@/components/PagedTableDetailPage.vue";
44
+ import DetailPanel from "@/components/detailPanel.vue";
45
+ import PagedTableDetail from "@/components/pagedTableDetail.vue";
46
46
  import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
47
47
 
48
48
  // 响应式数据
@@ -54,26 +54,16 @@ const $Data = $ref({
54
54
  { colKey: "osName", title: "操作系统" },
55
55
  { colKey: "deviceType", title: "设备类型" },
56
56
  { colKey: "loginTime", title: "登录时间" },
57
- { colKey: "loginResult", title: "登录结果" }
58
- ]),
59
- // 详情面板显示更多字段
60
- detailFields: [
61
- { colKey: "username", title: "用户名" },
62
- { colKey: "nickname", title: "昵称" },
63
- { colKey: "ip", title: "登录IP" },
64
- { colKey: "browserName", title: "浏览器" },
65
- { colKey: "browserVersion", title: "浏览器版本" },
66
- { colKey: "osName", title: "操作系统" },
67
- { colKey: "osVersion", title: "系统版本" },
68
- { colKey: "deviceType", title: "设备类型" },
69
- { colKey: "deviceVendor", title: "设备厂商" },
70
- { colKey: "deviceModel", title: "设备型号" },
71
- { colKey: "engineName", title: "渲染引擎" },
72
- { colKey: "cpuArchitecture", title: "CPU架构" },
73
- { colKey: "loginTime", title: "登录时间" },
74
57
  { colKey: "loginResult", title: "登录结果" },
75
- { colKey: "failReason", title: "失败原因" }
76
- ],
58
+ { colKey: "nickname", title: "昵称", detail: true },
59
+ { colKey: "browserVersion", title: "浏览器版本", detail: true },
60
+ { colKey: "osVersion", title: "系统版本", detail: true },
61
+ { colKey: "deviceVendor", title: "设备厂商", detail: true },
62
+ { colKey: "deviceModel", title: "设备型号", detail: true },
63
+ { colKey: "engineName", title: "渲染引擎", detail: true },
64
+ { colKey: "cpuArchitecture", title: "CPU架构", detail: true },
65
+ { colKey: "failReason", title: "失败原因", detail: true }
66
+ ]),
77
67
  endpoints: {
78
68
  list: {
79
69
  path: "/addon/admin/loginLog/list",
@@ -82,25 +72,21 @@ const $Data = $ref({
82
72
  }
83
73
  });
84
74
 
85
- // 方法
86
- const $Method = {
87
- onReload(reload) {
88
- reload({ keepSelection: true });
89
- },
75
+ function onReload(reload: (options: { keepSelection?: boolean }) => void): void {
76
+ reload({ keepSelection: true });
77
+ }
90
78
 
91
- // 格式化时间
92
- formatTime(timestamp) {
93
- if (!timestamp) return "-";
94
- const date = new Date(timestamp);
95
- const year = date.getFullYear();
96
- const month = String(date.getMonth() + 1).padStart(2, "0");
97
- const day = String(date.getDate()).padStart(2, "0");
98
- const hours = String(date.getHours()).padStart(2, "0");
99
- const minutes = String(date.getMinutes()).padStart(2, "0");
100
- const seconds = String(date.getSeconds()).padStart(2, "0");
101
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
102
- }
103
- };
79
+ function formatTime(timestamp: unknown): string {
80
+ if (!timestamp) return "-";
81
+ const date = new Date(timestamp as never);
82
+ const year = date.getFullYear();
83
+ const month = String(date.getMonth() + 1).padStart(2, "0");
84
+ const day = String(date.getDate()).padStart(2, "0");
85
+ const hours = String(date.getHours()).padStart(2, "0");
86
+ const minutes = String(date.getMinutes()).padStart(2, "0");
87
+ const seconds = String(date.getSeconds()).padStart(2, "0");
88
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
89
+ }
104
90
  </script>
105
91
 
106
92
  <style scoped lang="scss">
@@ -1,20 +1,20 @@
1
1
  <template>
2
- <PagedTableDetailPage class="page-operate-log page-table" :columns="$Data.columns" :endpoints="$Data.endpoints" :table-slot-names="['result', 'operateTime', 'duration', 'action']">
2
+ <PagedTableDetail class="page-operate-log page-table" :columns="$Data.columns" :endpoints="$Data.endpoints" :table-slot-names="['result', 'operateTime', 'duration', 'action']">
3
3
  <template #toolLeft="scope">
4
- <TSelect v-model="$Data.filter.module" placeholder="操作模块" clearable style="width: 150px" @change="$Method.handleFilter(scope.reload)">
4
+ <TSelect v-model="$Data.filter.module" placeholder="操作模块" clearable style="width: 150px" @change="handleFilter(scope.reload)">
5
5
  <TOption v-for="item in $Data.moduleOptions" :key="item.value" :label="item.label" :value="item.value" />
6
6
  </TSelect>
7
- <TSelect v-model="$Data.filter.action" placeholder="操作类型" clearable style="width: 150px" @change="$Method.handleFilter(scope.reload)">
7
+ <TSelect v-model="$Data.filter.action" placeholder="操作类型" clearable style="width: 150px" @change="handleFilter(scope.reload)">
8
8
  <TOption v-for="item in $Data.actionOptions" :key="item.value" :label="item.label" :value="item.value" />
9
9
  </TSelect>
10
- <TSelect v-model="$Data.filter.result" placeholder="操作结果" clearable style="width: 120px" @change="$Method.handleFilter(scope.reload)">
10
+ <TSelect v-model="$Data.filter.result" placeholder="操作结果" clearable style="width: 120px" @change="handleFilter(scope.reload)">
11
11
  <TOption label="成功" :value="1" />
12
12
  <TOption label="失败" :value="0" />
13
13
  </TSelect>
14
14
  </template>
15
15
 
16
16
  <template #toolRight="scope">
17
- <TButton shape="circle" @click="$Method.onReload(scope.reload)">
17
+ <TButton shape="circle" @click="onReload(scope.reload)">
18
18
  <template #icon>
19
19
  <ILucideRotateCw />
20
20
  </template>
@@ -27,7 +27,7 @@
27
27
  </template>
28
28
 
29
29
  <template #operateTime="{ row }">
30
- {{ $Method.formatTime(row.operateTime) }}
30
+ {{ formatTime(row.operateTime) }}
31
31
  </template>
32
32
 
33
33
  <template #duration="{ row }">
@@ -39,33 +39,33 @@
39
39
  </template>
40
40
 
41
41
  <template #detail="scope">
42
- <DetailPanel :data="scope.currentRow" :fields="$Data.detailFields">
42
+ <DetailPanel :data="scope.row" :fields="$Data.columns">
43
43
  <template #result="slotScope">
44
44
  <TTag v-if="slotScope.value === 1" shape="round" theme="success" variant="light-outline">成功</TTag>
45
45
  <TTag v-else shape="round" theme="danger" variant="light-outline">失败</TTag>
46
46
  </template>
47
47
  <template #operateTime="slotScope">
48
- {{ $Method.formatTime(slotScope.value) }}
48
+ {{ formatTime(slotScope.value) }}
49
49
  </template>
50
50
  <template #duration="slotScope">
51
51
  <TTag shape="round" :theme="slotScope.value > 1000 ? 'warning' : 'default'" variant="light-outline">{{ slotScope.value }}ms</TTag>
52
52
  </template>
53
53
  <template #params="slotScope">
54
- <pre class="json-content">{{ $Method.formatJson(slotScope.value) }}</pre>
54
+ <pre class="json-content">{{ formatJson(slotScope.value) }}</pre>
55
55
  </template>
56
56
  <template #response="slotScope">
57
- <pre class="json-content">{{ $Method.formatJson(slotScope.value) }}</pre>
57
+ <pre class="json-content">{{ formatJson(slotScope.value) }}</pre>
58
58
  </template>
59
59
  </DetailPanel>
60
60
  </template>
61
- </PagedTableDetailPage>
61
+ </PagedTableDetail>
62
62
  </template>
63
63
 
64
64
  <script setup lang="ts">
65
65
  import { Button as TButton, Option as TOption, Select as TSelect, Tag as TTag } from "tdesign-vue-next";
66
66
  import ILucideRotateCw from "~icons/lucide/rotate-cw";
67
- import DetailPanel from "@/components/DetailPanel.vue";
68
- import PagedTableDetailPage from "@/components/PagedTableDetailPage.vue";
67
+ import DetailPanel from "@/components/detailPanel.vue";
68
+ import PagedTableDetail from "@/components/pagedTableDetail.vue";
69
69
  import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
70
70
 
71
71
  // 响应式数据
@@ -78,23 +78,13 @@ const $Data = $ref({
78
78
  { colKey: "ip", title: "IP地址", width: 130 },
79
79
  { colKey: "duration", title: "耗时", width: 100 },
80
80
  { colKey: "operateTime", title: "操作时间", width: 170 },
81
- { colKey: "result", title: "结果", width: 80 }
81
+ { colKey: "result", title: "结果", width: 80 },
82
+ { colKey: "nickname", title: "操作人昵称", detail: true },
83
+ { colKey: "method", title: "请求方法", detail: true },
84
+ { colKey: "params", title: "请求参数", detail: true },
85
+ { colKey: "response", title: "响应内容", detail: true },
86
+ { colKey: "remark", title: "备注", detail: true }
82
87
  ]),
83
- detailFields: [
84
- { colKey: "username", title: "操作人账号" },
85
- { colKey: "nickname", title: "操作人昵称" },
86
- { colKey: "module", title: "操作模块" },
87
- { colKey: "action", title: "操作类型" },
88
- { colKey: "method", title: "请求方法" },
89
- { colKey: "path", title: "请求路径" },
90
- { colKey: "ip", title: "IP地址" },
91
- { colKey: "params", title: "请求参数" },
92
- { colKey: "response", title: "响应内容" },
93
- { colKey: "duration", title: "耗时" },
94
- { colKey: "operateTime", title: "操作时间" },
95
- { colKey: "result", title: "操作结果" },
96
- { colKey: "remark", title: "备注" }
97
- ],
98
88
  endpoints: {
99
89
  list: {
100
90
  path: "/addon/admin/operateLog/list",
@@ -132,40 +122,35 @@ const $Data = $ref({
132
122
  ]
133
123
  });
134
124
 
135
- // 方法
136
- const $Method = {
137
- handleFilter(reload) {
138
- reload({ keepSelection: false, resetPage: true });
139
- },
125
+ function handleFilter(reload: (options: { keepSelection?: boolean; resetPage?: boolean }) => void): void {
126
+ reload({ keepSelection: false, resetPage: true });
127
+ }
140
128
 
141
- onReload(reload) {
142
- reload({ keepSelection: true });
143
- },
129
+ function onReload(reload: (options: { keepSelection?: boolean }) => void): void {
130
+ reload({ keepSelection: true });
131
+ }
144
132
 
145
- // 格式化时间
146
- formatTime(timestamp) {
147
- if (!timestamp) return "-";
148
- const date = new Date(timestamp);
149
- const year = date.getFullYear();
150
- const month = String(date.getMonth() + 1).padStart(2, "0");
151
- const day = String(date.getDate()).padStart(2, "0");
152
- const hours = String(date.getHours()).padStart(2, "0");
153
- const minutes = String(date.getMinutes()).padStart(2, "0");
154
- const seconds = String(date.getSeconds()).padStart(2, "0");
155
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
156
- },
133
+ function formatTime(timestamp: unknown): string {
134
+ if (!timestamp) return "-";
135
+ const date = new Date(timestamp as never);
136
+ const year = date.getFullYear();
137
+ const month = String(date.getMonth() + 1).padStart(2, "0");
138
+ const day = String(date.getDate()).padStart(2, "0");
139
+ const hours = String(date.getHours()).padStart(2, "0");
140
+ const minutes = String(date.getMinutes()).padStart(2, "0");
141
+ const seconds = String(date.getSeconds()).padStart(2, "0");
142
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
143
+ }
157
144
 
158
- // 格式化 JSON
159
- formatJson(value) {
160
- if (!value) return "-";
161
- try {
162
- const obj = typeof value === "string" ? JSON.parse(value) : value;
163
- return JSON.stringify(obj, null, 2);
164
- } catch {
165
- return value;
166
- }
145
+ function formatJson(value: unknown): string {
146
+ if (!value) return "-";
147
+ try {
148
+ const obj = typeof value === "string" ? JSON.parse(value) : value;
149
+ return JSON.stringify(obj, null, 2);
150
+ } catch {
151
+ return String(value);
167
152
  }
168
- };
153
+ }
169
154
  </script>
170
155
 
171
156
  <style scoped lang="scss">