artalk 2.0.4 → 2.1.1
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/README.md +7 -60
- package/dist/Artalk.css +1 -1
- package/dist/Artalk.es.js +5996 -1
- package/dist/Artalk.iife.js +266 -1
- package/dist/Artalk.js +266 -1
- package/package.json +3 -4
- package/src/api/index.ts +269 -0
- package/src/api/request.ts +125 -0
- package/src/artalk.ts +153 -0
- package/src/components/_component.ts.txt +10 -0
- package/src/components/action-btn.ts +169 -0
- package/src/components/admin/page-list.ts +194 -0
- package/src/components/admin/site-list-floater.ts +98 -0
- package/src/components/admin/site-list.ts +289 -0
- package/src/components/comment.ts +478 -0
- package/src/components/dialog.ts +63 -0
- package/src/components/editor-plugs/{_ExamplePlug.ts.txt → _example-plug.ts.txt} +0 -0
- package/src/components/editor-plugs/{EditorPlug.ts → editor-plug.ts} +3 -3
- package/src/components/editor-plugs/{EmoticonsPlug.less → emoticons-plug.less} +0 -0
- package/src/components/editor-plugs/{EmoticonsPlug.ts → emoticons-plug.ts} +9 -9
- package/src/components/editor-plugs/{PreviewPlug.less → preview-plug.less} +0 -0
- package/src/components/editor-plugs/{PreviewPlug.ts → preview-plug.ts} +10 -10
- package/src/components/{Editor.ts → editor.ts} +104 -102
- package/src/components/html/comment.html +2 -6
- package/src/components/html/list.html +0 -1
- package/src/components/html/sidebar.html +18 -4
- package/src/components/item-text-editor.ts +136 -0
- package/src/components/layer.ts +135 -0
- package/src/components/list-lite.ts +507 -0
- package/src/components/list.ts +172 -0
- package/src/components/pagination.ts +150 -0
- package/src/components/read-more-btn.ts +71 -0
- package/src/components/sidebar-view.ts +26 -0
- package/src/components/sidebar-views/comments-view.ts +66 -0
- package/src/components/sidebar-views/pages-view.ts +61 -0
- package/src/components/sidebar-views/setting-view.ts +21 -0
- package/src/components/sidebar-views/sites-view.ts +42 -0
- package/src/components/sidebar-views/transfer-view.ts +218 -0
- package/src/components/sidebar.ts +288 -0
- package/src/context.ts +42 -0
- package/src/default-conf.ts +42 -0
- package/src/lib/checker/admin-checker.ts +33 -0
- package/src/lib/checker/captcha-checker.ts +38 -0
- package/src/lib/checker/index.ts +134 -0
- package/src/lib/component.ts +3 -3
- package/src/lib/md5.js +6 -0
- package/src/lib/ui.ts +64 -74
- package/src/lib/user.ts +2 -8
- package/src/lib/utils.ts +30 -11
- package/src/main.ts +1 -1
- package/src/style/_color.less +8 -2
- package/src/style/_extend.less +81 -0
- package/src/style/_variables.less +3 -0
- package/src/style/comment.less +60 -24
- package/src/style/editor.less +3 -0
- package/src/style/item-text-editor.less +35 -0
- package/src/style/list.less +51 -32
- package/src/style/main.less +75 -1
- package/src/style/page-list.less +50 -0
- package/src/style/pagination.less +58 -0
- package/src/style/sidebar.less +274 -199
- package/src/style/site-list.less +208 -0
- package/tsconfig.json +27 -0
- package/types/artalk-config.d.ts +68 -51
- package/types/artalk-data.d.ts +38 -1
- package/types/event.d.ts +73 -0
- package/types/index.d.ts +1 -6
- package/.github/workflows/npm.yml +0 -31
- package/.github/workflows/pages.yml +0 -30
- package/dist/src/Event.d.ts +0 -59
- package/dist/types/artalk-config.d.ts +0 -79
- package/dist/types/artalk-data.d.ts +0 -153
- package/dist/types/global.d.ts +0 -1
- package/dist/types/index.d.ts +0 -8
- package/dist/types/vite-env.d.ts +0 -1
- package/example/pjax/res1.html +0 -41
- package/example/pjax/res2.html +0 -41
- package/src/Artalk.ts +0 -160
- package/src/Constant.ts +0 -6
- package/src/Context.ts +0 -34
- package/src/Event.d.ts +0 -59
- package/src/components/Comment.ts +0 -402
- package/src/components/Layer.ts +0 -138
- package/src/components/List.ts +0 -162
- package/src/components/ListLite.ts +0 -407
- package/src/components/Sidebar.ts +0 -141
- package/src/components/sidebar-views/AdminView.ts +0 -523
- package/src/components/sidebar-views/MessageView.ts +0 -48
- package/src/components/sidebar-views/SidebarView.ts +0 -24
- package/src/lib/api.ts +0 -380
- package/src/lib/checker.ts +0 -164
package/src/lib/api.ts
DELETED
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
import { CommentData, ListData, UserData, PageData, SiteData, NotifyData } from '~/types/artalk-data'
|
|
2
|
-
import Context from '../Context'
|
|
3
|
-
|
|
4
|
-
export default class Api {
|
|
5
|
-
private ctx: Context
|
|
6
|
-
private serverURL: string
|
|
7
|
-
|
|
8
|
-
constructor (ctx: Context) {
|
|
9
|
-
this.ctx = ctx
|
|
10
|
-
this.serverURL = ctx.conf.server
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
public get(offset: number, type?: string, paramsEditor?: (params: any) => void): Promise<ListData> {
|
|
14
|
-
const params: any = {
|
|
15
|
-
page_key: this.ctx.conf.pageKey,
|
|
16
|
-
limit: this.ctx.conf.readMore?.pageSize || 15,
|
|
17
|
-
offset,
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (type) {
|
|
21
|
-
params.type = type
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (this.ctx.user.checkHasBasicUserInfo()) {
|
|
25
|
-
params.name = this.ctx.user.data.nick
|
|
26
|
-
params.email = this.ctx.user.data.email
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
|
|
30
|
-
|
|
31
|
-
if (paramsEditor) paramsEditor(params)
|
|
32
|
-
|
|
33
|
-
return CommonFetch(this.ctx, `${this.serverURL}/get`, {
|
|
34
|
-
method: 'POST',
|
|
35
|
-
body: getFormData(params),
|
|
36
|
-
}).then((json) => (json.data as ListData))
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public add(comment: { nick: string, email: string, link: string, content: string, rid: number }): Promise<CommentData> {
|
|
40
|
-
const params: any = {
|
|
41
|
-
name: comment.nick,
|
|
42
|
-
email: comment.email,
|
|
43
|
-
link: comment.link,
|
|
44
|
-
content: comment.content,
|
|
45
|
-
rid: comment.rid,
|
|
46
|
-
page_key: this.ctx.conf.pageKey,
|
|
47
|
-
page_url: this.ctx.conf.pageUrl || '',
|
|
48
|
-
page_title: this.ctx.conf.pageTitle || '',
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
|
|
52
|
-
|
|
53
|
-
return CommonFetch(this.ctx, `${this.serverURL}/add`, {
|
|
54
|
-
method: 'POST',
|
|
55
|
-
body: getFormData(params),
|
|
56
|
-
}).then((json) => (json.data.comment as CommentData))
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
public login(name: string, email: string, password: string): Promise<string> {
|
|
60
|
-
const params: any = {
|
|
61
|
-
name, email, password
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
|
|
65
|
-
|
|
66
|
-
return CommonFetch(this.ctx, `${this.serverURL}/login`, {
|
|
67
|
-
method: 'POST',
|
|
68
|
-
body: getFormData(params),
|
|
69
|
-
}).then((json) => (json.data.token))
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
public userGet(name: string, email: string) {
|
|
73
|
-
const ctrl = new AbortController()
|
|
74
|
-
const { signal } = ctrl
|
|
75
|
-
|
|
76
|
-
const params: any = {
|
|
77
|
-
name, email
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
|
|
81
|
-
|
|
82
|
-
const req = CommonFetch(this.ctx, `${this.serverURL}/user-get`, {
|
|
83
|
-
method: 'POST',
|
|
84
|
-
body: getFormData(params),
|
|
85
|
-
signal,
|
|
86
|
-
}).then((json) => ({
|
|
87
|
-
user: json.data.user as UserData|null,
|
|
88
|
-
is_login: json.data.is_login as boolean,
|
|
89
|
-
unread: (json.data.unread || []) as NotifyData[],
|
|
90
|
-
unread_count: json.data.unread_count || 0,
|
|
91
|
-
}))
|
|
92
|
-
|
|
93
|
-
return {
|
|
94
|
-
req,
|
|
95
|
-
abort: () => { ctrl.abort() },
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
public vote(targetID: number, type: string) {
|
|
100
|
-
const params: any = {
|
|
101
|
-
target_id: targetID,
|
|
102
|
-
type,
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (this.ctx.user.checkHasBasicUserInfo()) {
|
|
106
|
-
params.name = this.ctx.user.data.nick
|
|
107
|
-
params.email = this.ctx.user.data.email
|
|
108
|
-
}
|
|
109
|
-
if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
|
|
110
|
-
|
|
111
|
-
return CommonFetch(this.ctx, `${this.serverURL}/vote`, {
|
|
112
|
-
method: 'POST',
|
|
113
|
-
body: getFormData(params),
|
|
114
|
-
}).then((json) => ((json.data?.vote_num || 0) as number))
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
public markRead(notifyKey: string, readAll = false) {
|
|
118
|
-
const params: any = {
|
|
119
|
-
notify_key: notifyKey,
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (readAll) {
|
|
123
|
-
delete params.notify_key
|
|
124
|
-
params.read_all = true
|
|
125
|
-
params.name = this.ctx.user.data.nick
|
|
126
|
-
params.email = this.ctx.user.data.email
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
|
|
130
|
-
|
|
131
|
-
return CommonFetch(this.ctx, `${this.serverURL}/mark-read`, {
|
|
132
|
-
method: 'POST',
|
|
133
|
-
body: getFormData(params),
|
|
134
|
-
}).then((json) => (json.success as boolean))
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
public captchaGet(): Promise<string> {
|
|
138
|
-
return CommonFetch(this.ctx, `${this.serverURL}/captcha/refresh`, {
|
|
139
|
-
method: 'GET',
|
|
140
|
-
}).then((json) => {
|
|
141
|
-
if (!!json.success && !!json.data.img_data) {
|
|
142
|
-
return json.data.img_data
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return ''
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
public captchaCheck(value: string): Promise<string> {
|
|
150
|
-
return CommonFetch(this.ctx, `${this.serverURL}/captcha/check?${new URLSearchParams({ value })}`, {
|
|
151
|
-
method: 'GET',
|
|
152
|
-
}).then((json) => {
|
|
153
|
-
if (!json.success && !!json.data.img_data) {
|
|
154
|
-
return json.data.img_data
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return ''
|
|
158
|
-
})
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
public commentEdit(data: CommentData) {
|
|
162
|
-
const params: any = {
|
|
163
|
-
...data,
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (params.is_collapsed !== undefined) params.is_collapsed = params.is_collapsed ? '1' : '0'
|
|
167
|
-
if (params.is_pending !== undefined) params.is_pending = params.is_pending ? '1' : '0'
|
|
168
|
-
|
|
169
|
-
if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
|
|
170
|
-
|
|
171
|
-
return CommonFetch(this.ctx, `${this.serverURL}/admin/comment-edit`, {
|
|
172
|
-
method: 'POST',
|
|
173
|
-
body: getFormData(params),
|
|
174
|
-
}).then((json) => (json.data.comment as CommentData))
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
public pageEdit(data: PageData) {
|
|
178
|
-
const params: any = {
|
|
179
|
-
id: data.id,
|
|
180
|
-
key: data.key,
|
|
181
|
-
title: data.title,
|
|
182
|
-
admin_only: data.admin_only ? '1' : '0',
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
|
|
186
|
-
|
|
187
|
-
return CommonFetch(this.ctx, `${this.serverURL}/admin/page-edit`, {
|
|
188
|
-
method: 'POST',
|
|
189
|
-
body: getFormData(params),
|
|
190
|
-
}).then((json) => (json.data.page as PageData))
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
public pageFetch(id: number) {
|
|
194
|
-
const params: any = {
|
|
195
|
-
id,
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return CommonFetch(this.ctx, `${this.serverURL}/admin/page-fetch`, {
|
|
199
|
-
method: 'POST',
|
|
200
|
-
body: getFormData(params),
|
|
201
|
-
}).then((json) => (json.data.page as PageData))
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
public siteGet(): Promise<SiteData[]> {
|
|
205
|
-
const params: any = {}
|
|
206
|
-
|
|
207
|
-
return CommonFetch(this.ctx, `${this.serverURL}/admin/site-get`, {
|
|
208
|
-
method: 'POST',
|
|
209
|
-
body: getFormData(params),
|
|
210
|
-
}).then((json) => (json.data.sites as SiteData[]))
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
public pageGet(siteName?: string): Promise<PageData[]> {
|
|
214
|
-
const params: any = {
|
|
215
|
-
site_name: siteName || ''
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return CommonFetch(this.ctx, `${this.serverURL}/admin/page-get`, {
|
|
219
|
-
method: 'POST',
|
|
220
|
-
body: getFormData(params),
|
|
221
|
-
}).then((json) => (json.data.pages as PageData[]))
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
public pageDel(pageKey: string, siteName?: string) {
|
|
225
|
-
const params: any = {
|
|
226
|
-
key: String(pageKey),
|
|
227
|
-
site_name: siteName || '',
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
return CommonFetch(this.ctx, `${this.serverURL}/admin/page-del`, {
|
|
231
|
-
method: 'POST',
|
|
232
|
-
body: getFormData(params),
|
|
233
|
-
}).then((json) => (json.success as boolean))
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
public siteDel(id: number, delContent = false) {
|
|
237
|
-
const params: any = {
|
|
238
|
-
id,
|
|
239
|
-
del_content: delContent ? '1' : '0'
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
return CommonFetch(this.ctx, `${this.serverURL}/admin/site-del`, {
|
|
243
|
-
method: 'POST',
|
|
244
|
-
body: getFormData(params),
|
|
245
|
-
}).then((json) => (json.success as boolean))
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
public siteAdd(name: string, urls: string) {
|
|
249
|
-
const params: any = {
|
|
250
|
-
name, urls,
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return CommonFetch(this.ctx, `${this.serverURL}/admin/site-add`, {
|
|
254
|
-
method: 'POST',
|
|
255
|
-
body: getFormData(params),
|
|
256
|
-
}).then((json) => (json.site as SiteData))
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
public siteEdit(id: number, data: {
|
|
260
|
-
name: string
|
|
261
|
-
urls: string
|
|
262
|
-
}) {
|
|
263
|
-
const params: any = {
|
|
264
|
-
id,
|
|
265
|
-
name: data.name,
|
|
266
|
-
urls: data.urls,
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return CommonFetch(this.ctx, `${this.serverURL}/admin/site-edit`, {
|
|
270
|
-
method: 'POST',
|
|
271
|
-
body: getFormData(params),
|
|
272
|
-
}).then((json) => (json.site as SiteData))
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
public commentDel(commentID: number, siteName?: string) {
|
|
276
|
-
const params: any = {
|
|
277
|
-
id: String(commentID),
|
|
278
|
-
site_name: siteName || '',
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
return CommonFetch(this.ctx, `${this.serverURL}/admin/comment-del`, {
|
|
282
|
-
method: 'POST',
|
|
283
|
-
body: getFormData(params),
|
|
284
|
-
}).then((json) => (json.success as boolean))
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/** 公共请求函数 */
|
|
289
|
-
function CommonFetch(ctx: Context, input: RequestInfo, init: RequestInit): Promise<any> {
|
|
290
|
-
if (ctx.user.data.token) {
|
|
291
|
-
const requestHeaders: HeadersInit = new Headers();
|
|
292
|
-
requestHeaders.set('Authorization', `Bearer ${ctx.user.data.token}`);
|
|
293
|
-
|
|
294
|
-
init.headers = requestHeaders
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// 15s timeout
|
|
298
|
-
return timeoutPromise(15000, fetch(input, init)).then(async (resp) => {
|
|
299
|
-
if (!resp.ok && resp.status !== 401) {
|
|
300
|
-
throw new Error(`请求响应 ${resp.status}`)
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// 解析获取响应的 json
|
|
304
|
-
let json: any = await resp.json()
|
|
305
|
-
|
|
306
|
-
// 重新发起请求
|
|
307
|
-
const recall = (resolve, reject) => {
|
|
308
|
-
CommonFetch(ctx, input, init).then(d => {
|
|
309
|
-
resolve(d)
|
|
310
|
-
}).catch(err => {
|
|
311
|
-
reject(err)
|
|
312
|
-
})
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (json.data && json.data.need_captcha) {
|
|
316
|
-
// 请求需要验证码
|
|
317
|
-
json = await (new Promise<any>((resolve, reject) => {
|
|
318
|
-
ctx.dispatchEvent('checker-captcha', {
|
|
319
|
-
imgData: json.data.img_data,
|
|
320
|
-
onSuccess: () => {
|
|
321
|
-
recall(resolve, reject)
|
|
322
|
-
},
|
|
323
|
-
onCancel: () => {
|
|
324
|
-
reject(json)
|
|
325
|
-
}
|
|
326
|
-
})
|
|
327
|
-
}))
|
|
328
|
-
} else if ((json.data && json.data.need_login) || resp.status === 401) {
|
|
329
|
-
// 请求需要管理员权限
|
|
330
|
-
json = await (new Promise<any>((resolve, reject) => {
|
|
331
|
-
ctx.dispatchEvent('checker-admin', {
|
|
332
|
-
onSuccess: () => {
|
|
333
|
-
recall(resolve, reject)
|
|
334
|
-
},
|
|
335
|
-
onCancel: () => {
|
|
336
|
-
reject(json)
|
|
337
|
-
}
|
|
338
|
-
})
|
|
339
|
-
}))
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
if (!json.success)
|
|
343
|
-
throw json // throw 相当于 reject(json)
|
|
344
|
-
else
|
|
345
|
-
return json
|
|
346
|
-
})
|
|
347
|
-
.catch(err => {
|
|
348
|
-
console.error(err)
|
|
349
|
-
|
|
350
|
-
if (err instanceof TypeError)
|
|
351
|
-
throw new Error(`网络错误`)
|
|
352
|
-
|
|
353
|
-
throw err
|
|
354
|
-
})
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
function getFormData (object: any): FormData {
|
|
358
|
-
const formData = new FormData()
|
|
359
|
-
Object.keys(object).forEach(key => formData.append(key, String(object[key])))
|
|
360
|
-
return formData
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/** TODO: 我靠,一个 timeout,都要丑陋的实现 */
|
|
364
|
-
function timeoutPromise<T>(ms: number, promise: Promise<T>): Promise<T> {
|
|
365
|
-
return new Promise((resolve, reject) => {
|
|
366
|
-
const timeoutId = setTimeout(() => {
|
|
367
|
-
reject(new Error("请求超时"))
|
|
368
|
-
}, ms);
|
|
369
|
-
promise.then(
|
|
370
|
-
(res) => {
|
|
371
|
-
clearTimeout(timeoutId);
|
|
372
|
-
resolve(res);
|
|
373
|
-
},
|
|
374
|
-
(err) => {
|
|
375
|
-
clearTimeout(timeoutId);
|
|
376
|
-
reject(err);
|
|
377
|
-
}
|
|
378
|
-
);
|
|
379
|
-
})
|
|
380
|
-
}
|
package/src/lib/checker.ts
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import Context from "../Context"
|
|
2
|
-
import * as Utils from "./utils"
|
|
3
|
-
import User from "./user"
|
|
4
|
-
import * as Ui from './ui'
|
|
5
|
-
import BuildLayer from "../components/Layer"
|
|
6
|
-
import Api from "./api"
|
|
7
|
-
import { CheckerCaptchaConf } from '../Event'
|
|
8
|
-
|
|
9
|
-
interface CheckerConf {
|
|
10
|
-
el?: HTMLElement
|
|
11
|
-
body: (that: Checker) => HTMLElement
|
|
12
|
-
request: (that: Checker, inputVal: string) => Promise<string>
|
|
13
|
-
onSuccess?: (that: Checker, data: string, inputVal: string, formEl: HTMLElement) => void
|
|
14
|
-
onError?: (that: Checker, err: any, inputVal: string, formEl: HTMLElement) => void
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const AdminChecker = {
|
|
18
|
-
request: (that, inputVal) => {
|
|
19
|
-
const data = {
|
|
20
|
-
name: that.user.data.nick,
|
|
21
|
-
email: that.user.data.email,
|
|
22
|
-
password: inputVal
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return new Api(that.ctx).login(data.name, data.email, data.password)
|
|
26
|
-
},
|
|
27
|
-
body: () => Utils.createElement('<span>敲入密码来验证管理员身份:</span>'),
|
|
28
|
-
onSuccess: (that, userToken, inputVal, formEl) => {
|
|
29
|
-
that.user.data.isAdmin = true
|
|
30
|
-
that.user.data.token = userToken
|
|
31
|
-
that.user.save()
|
|
32
|
-
that.ctx.dispatchEvent('user-changed')
|
|
33
|
-
that.ctx.dispatchEvent('list-reload')
|
|
34
|
-
},
|
|
35
|
-
onError: (that, err, inputVal, formEl) => {
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
} as CheckerConf
|
|
40
|
-
|
|
41
|
-
const CaptchaChecker = {
|
|
42
|
-
request: (that, inputVal) => (new Api(that.ctx).captchaCheck(inputVal)),
|
|
43
|
-
body: (that) => {
|
|
44
|
-
const elem = Utils.createElement(`<span><img class="atk-captcha-img" src="${that.submitCaptchaImgData || ''}" alt="验证码">敲入验证码继续:</span>`);
|
|
45
|
-
|
|
46
|
-
// 刷新验证码
|
|
47
|
-
elem.querySelector<HTMLElement>('.atk-captcha-img')!.onclick = () => {
|
|
48
|
-
const imgEl = elem.querySelector('.atk-captcha-img')
|
|
49
|
-
new Api(that.ctx).captchaGet()
|
|
50
|
-
.then((imgData) => {
|
|
51
|
-
imgEl!.setAttribute('src', imgData)
|
|
52
|
-
})
|
|
53
|
-
.catch((err) => {
|
|
54
|
-
console.error('验证码获取失败 ', err)
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
return elem
|
|
58
|
-
},
|
|
59
|
-
onSuccess: (that, msg, data, inputVal, formEl) => {
|
|
60
|
-
that.submitCaptchaVal = inputVal
|
|
61
|
-
},
|
|
62
|
-
onError: (that, err, inputVal, formEl) => {
|
|
63
|
-
formEl.querySelector<HTMLElement>('.atk-captcha-img')!.click() // 刷新验证码
|
|
64
|
-
}
|
|
65
|
-
} as CheckerConf
|
|
66
|
-
|
|
67
|
-
export default class Checker {
|
|
68
|
-
public ctx: Context
|
|
69
|
-
public user: User
|
|
70
|
-
|
|
71
|
-
public submitCaptchaVal?: string
|
|
72
|
-
public submitCaptchaImgData?: string
|
|
73
|
-
|
|
74
|
-
constructor (ctx: Context) {
|
|
75
|
-
this.ctx = ctx
|
|
76
|
-
this.user = ctx.user
|
|
77
|
-
|
|
78
|
-
this.ctx.addEventListener('checker-captcha', (conf) => {
|
|
79
|
-
if (conf.imgData) {
|
|
80
|
-
this.submitCaptchaImgData = conf.imgData
|
|
81
|
-
}
|
|
82
|
-
this.check('captcha', conf)
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
this.ctx.addEventListener('checker-admin', (conf) => {
|
|
86
|
-
this.check('admin', conf)
|
|
87
|
-
})
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
public check (name: 'admin'|'captcha', conf: CheckerCaptchaConf) {
|
|
91
|
-
const checker = {
|
|
92
|
-
admin: AdminChecker,
|
|
93
|
-
captcha: CaptchaChecker
|
|
94
|
-
}[name]
|
|
95
|
-
|
|
96
|
-
const layer = BuildLayer(this.ctx, `checker-${new Date().getTime()}`)
|
|
97
|
-
layer.setMaskClickHide(false)
|
|
98
|
-
layer.show()
|
|
99
|
-
|
|
100
|
-
const formEl = Utils.createElement()
|
|
101
|
-
formEl.appendChild(checker.body(this))
|
|
102
|
-
|
|
103
|
-
const input = Utils.createElement<HTMLInputElement>(`<input id="check" type="${(name === 'admin' ? 'password' : 'text')}" required placeholder="">`)
|
|
104
|
-
formEl.appendChild(input)
|
|
105
|
-
setTimeout(() => {
|
|
106
|
-
input.focus() // 延迟以保证有效
|
|
107
|
-
}, 80)
|
|
108
|
-
|
|
109
|
-
input.onkeyup = (evt) => {
|
|
110
|
-
if (evt.key === 'Enter' || evt.keyCode === 13) { // 按下回车键
|
|
111
|
-
evt.preventDefault();
|
|
112
|
-
(layer.getEl().querySelector<HTMLButtonElement>('button[data-action="confirm"]'))!.click()
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
let btnRawText: string|undefined
|
|
117
|
-
const dialogEl = Ui.buildDialog(formEl, (btnElem: HTMLElement) => {
|
|
118
|
-
const inputVal = input.value.trim()
|
|
119
|
-
if (!btnRawText) {
|
|
120
|
-
btnRawText = btnElem.innerText
|
|
121
|
-
}
|
|
122
|
-
const btnTextSet = (btnText: string) => {
|
|
123
|
-
btnElem.innerText = btnText
|
|
124
|
-
btnElem.classList.add('error')
|
|
125
|
-
}
|
|
126
|
-
const btnTextRestore = () => {
|
|
127
|
-
btnElem.innerText = btnRawText || ''
|
|
128
|
-
btnElem.classList.remove('error')
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
btnElem.innerText = '加载中...'
|
|
132
|
-
checker.request(this, inputVal)
|
|
133
|
-
.then(data => {
|
|
134
|
-
// 请求成功
|
|
135
|
-
layer.disposeNow()
|
|
136
|
-
if (checker.onSuccess) checker.onSuccess(this, data, inputVal, formEl)
|
|
137
|
-
if (conf.onSuccess) conf.onSuccess(inputVal, dialogEl)
|
|
138
|
-
})
|
|
139
|
-
.catch(err => {
|
|
140
|
-
btnTextSet(String(err.msg || String(err)))
|
|
141
|
-
if (checker.onError)
|
|
142
|
-
checker.onError(this, err, inputVal, formEl)
|
|
143
|
-
|
|
144
|
-
const tf = setTimeout(() => {
|
|
145
|
-
btnTextRestore()
|
|
146
|
-
}, 3000)
|
|
147
|
-
input.onfocus = () => {
|
|
148
|
-
btnTextRestore()
|
|
149
|
-
clearTimeout(tf)
|
|
150
|
-
}
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
return false
|
|
154
|
-
}, () => {
|
|
155
|
-
layer.disposeNow()
|
|
156
|
-
if (conf.onCancel) conf.onCancel()
|
|
157
|
-
return false
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
layer.getEl().append(dialogEl)
|
|
161
|
-
|
|
162
|
-
if (conf.onMount) conf.onMount(dialogEl) // onMount
|
|
163
|
-
}
|
|
164
|
-
}
|