@whyour/qinglong 0.3.2 → 0.4.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/README-en.md +47 -88
- package/README.md +48 -87
- package/package.json +5 -1
- package/sample/notify.js +19 -9
- package/sample/notify.py +89 -47
- package/shell/api.sh +15 -15
- package/shell/otask.sh +1 -1
- package/shell/update.sh +12 -13
- package/static/build/api/system.js +1 -2
- package/static/build/api/user.js +5 -1
- package/static/build/config/serverEnv.js +1 -1
- package/static/build/data/dependence.js +1 -1
- package/static/build/data/notify.js +2 -0
- package/static/build/data/open.js +1 -8
- package/static/build/loaders/express.js +1 -9
- package/static/build/loaders/initFile.js +24 -6
- package/static/build/loaders/sentry.js +7 -1
- package/static/build/schedule/addCron.js +2 -2
- package/static/build/schedule/health.js +2 -2
- package/static/build/services/cron.js +50 -44
- package/static/build/services/dependence.js +82 -79
- package/static/build/services/env.js +1 -1
- package/static/build/services/notify.js +5 -5
- package/static/build/services/open.js +1 -1
- package/static/build/services/schedule.js +42 -40
- package/static/build/services/subscription.js +7 -13
- package/static/build/services/system.js +2 -2
- package/static/build/shared/pLimit.js +16 -0
- package/static/build/shared/runCron.js +29 -0
- package/static/dist/{1571.a97c18af.async.js → 1571.68121491.async.js} +3 -3
- package/static/dist/{9371.27629d57.async.js → 1654.e06fbac5.async.js} +1 -1
- package/static/dist/2260.d9fbd460.async.js +1 -0
- package/static/dist/2536.a60b8e3c.async.js +1 -0
- package/static/dist/{2618.2d258f44.async.js → 2618.1484edc2.async.js} +2 -2
- package/static/dist/2715.80e099e1.async.js +1 -0
- package/static/dist/{3490.8aaeafbb.async.js → 3490.8d2d9399.async.js} +1 -1
- package/static/dist/3639.58c3a3f1.async.js +5 -0
- package/static/dist/3800.5488ae14.async.js +2 -0
- package/static/dist/3820.faa46a6a.async.js +1 -0
- package/static/dist/4124.8cba8410.async.js +1 -0
- package/static/dist/4163.a1d279c3.async.js +1 -0
- package/static/dist/4346.5ab6fdc1.async.js +1 -0
- package/static/dist/{4378.70f18b85.async.js → 4378.70083a42.async.js} +2 -2
- package/static/dist/4491.96ee9a9f.async.js +4 -0
- package/static/dist/4804.183d71af.async.js +27 -0
- package/static/dist/4925.eca85085.async.js +1 -0
- package/static/dist/5008.c612bbdb.async.js +11 -0
- package/static/dist/5035.2489750b.async.js +67 -0
- package/static/dist/5310.6c4eff46.async.js +1 -0
- package/static/dist/5484.826c5ee3.async.js +1 -0
- package/static/dist/5969.87aeb075.async.js +1 -0
- package/static/dist/6304.51c52839.async.js +1 -0
- package/static/dist/6433.69941426.async.js +22 -0
- package/static/dist/6661.5cda5ce0.async.js +1 -0
- package/static/dist/6805.798ec30a.async.js +1 -0
- package/static/dist/{412.7e4d2d42.async.js → 7382.305c10b2.async.js} +2 -2
- package/static/dist/{7393.b7603b10.async.js → 7393.d9ed4b3a.async.js} +1 -1
- package/static/dist/7567.a224d0a6.async.js +5 -0
- package/static/dist/{7742.eec663d7.async.js → 7742.dd8a0112.async.js} +2 -2
- package/static/dist/8037.386b415d.async.js +1 -0
- package/static/dist/8297.e6ac1ce9.async.js +1 -0
- package/static/dist/8432.5bbc2cdd.async.js +1 -0
- package/static/dist/858.d51fc4e2.async.js +1 -0
- package/static/dist/8612.84caf0a5.async.js +1 -0
- package/static/dist/{8966.d92806db.async.js → 8657.805a96f7.async.js} +2 -2
- package/static/dist/8844.8525fd2e.async.js +81 -0
- package/static/dist/9065.6684b5d0.async.js +1 -0
- package/static/dist/921.198cefa6.async.js +6 -0
- package/static/dist/{9504.06cb7ea5.async.js → 9504.6d4e29e7.async.js} +1 -1
- package/static/dist/9673.18a70227.async.js +3 -0
- package/static/dist/986.ab6a48a4.async.js +1 -0
- package/static/dist/index.html +1 -1
- package/static/dist/layouts__index.285d8505.chunk.css +1 -0
- package/static/dist/layouts__index.3db43e0b.async.js +1 -0
- package/static/dist/src__pages__404.8794c158.async.js +1 -0
- package/static/dist/{src__pages__config__index.b5bde963.async.js → src__pages__config__index.7fb61af5.async.js} +3 -3
- package/static/dist/{src__pages__crontab__index.be4295e5.async.js → src__pages__crontab__index.5cfa7d5b.async.js} +2 -2
- package/static/dist/src__pages__crontab__logModal.44ad577c.async.js +2 -0
- package/static/dist/src__pages__crontab__modal.6d17fdcf.async.js +5 -0
- package/static/dist/src__pages__crontab__viewCreateModal.3db14204.async.js +4 -0
- package/static/dist/src__pages__crontab__viewManageModal.9f899650.async.js +4 -0
- package/static/dist/src__pages__dependence__index.3b140a79.async.js +2 -0
- package/static/dist/src__pages__dependence__logModal.e49658d5.async.js +4 -0
- package/static/dist/src__pages__dependence__modal.94ff002a.async.js +5 -0
- package/static/dist/{src__pages__diff__index.200be0dc.async.js → src__pages__diff__index.240e4991.async.js} +3 -3
- package/static/dist/{src__pages__env__editNameModal.9898b16a.async.js → src__pages__env__editNameModal.047bb3ba.async.js} +2 -2
- package/static/dist/src__pages__env__index.48602d18.async.js +2 -0
- package/static/dist/src__pages__env__modal.8b48ffa4.async.js +5 -0
- package/static/dist/src__pages__error__index.c0477141.async.js +4 -0
- package/static/dist/{src__pages__initialization__index.bcf87634.chunk.css → src__pages__initialization__index.66819338.chunk.css} +1 -1
- package/static/dist/src__pages__initialization__index.978a7f09.async.js +21 -0
- package/static/dist/src__pages__log__index.ae245070.async.js +1 -0
- package/static/dist/src__pages__login__index.8eb4df8e.async.js +2 -0
- package/static/dist/{src__pages__script__editModal.9a8934a1.async.js → src__pages__script__editModal.02b12902.async.js} +2 -2
- package/static/dist/{src__pages__script__editNameModal.42003a2f.async.js → src__pages__script__editNameModal.2773cb7b.async.js} +2 -2
- package/static/dist/{src__pages__script__index.670d9577.async.js → src__pages__script__index.679510cd.async.js} +3 -3
- package/static/dist/{src__pages__script__renameModal.3b9285b0.async.js → src__pages__script__renameModal.ea3b6689.async.js} +2 -2
- package/static/dist/{src__pages__script__saveModal.475c369d.async.js → src__pages__script__saveModal.312a0beb.async.js} +2 -2
- package/static/dist/{src__pages__script__setting.d41d33ae.async.js → src__pages__script__setting.11abc6ae.async.js} +2 -2
- package/static/dist/src__pages__setting__about.1460b7fa.async.js +1 -0
- package/static/dist/{src__pages__setting__appModal.4edca962.async.js → src__pages__setting__appModal.74267529.async.js} +2 -2
- package/static/dist/src__pages__setting__checkUpdate.ce2e30bb.async.js +4 -0
- package/static/dist/src__pages__setting__index.9fcd6dc2.async.js +2 -0
- package/static/dist/src__pages__setting__loginLog.0708083b.async.js +18 -0
- package/static/dist/src__pages__setting__notification.15a286d0.async.js +21 -0
- package/static/dist/src__pages__setting__other.00a69cf4.async.js +1 -0
- package/static/dist/src__pages__setting__security.62b6b562.async.js +4 -0
- package/static/dist/src__pages__subscription__index.708b6c8f.async.js +2 -0
- package/static/dist/src__pages__subscription__logModal.3a1a8e58.async.js +2 -0
- package/static/dist/src__pages__subscription__modal.c034f25a.async.js +4 -0
- package/static/dist/umi.cb44a99a.js +11 -0
- package/version.yaml +10 -5
- package/static/dist/1655.37556417.async.js +0 -4
- package/static/dist/1766.e0c12c07.async.js +0 -27
- package/static/dist/2260.04ae2823.async.js +0 -1
- package/static/dist/2715.30714799.async.js +0 -1
- package/static/dist/3639.62e1ddf6.async.js +0 -5
- package/static/dist/3820.ad340d47.async.js +0 -1
- package/static/dist/4011.3a02258a.async.js +0 -22
- package/static/dist/4124.6a5a1531.async.js +0 -1
- package/static/dist/4163.5180a456.async.js +0 -1
- package/static/dist/4180.e830b6e6.async.js +0 -2
- package/static/dist/4925.4425d963.async.js +0 -1
- package/static/dist/5008.8fcc2d24.async.js +0 -11
- package/static/dist/5310.9c3e0c09.async.js +0 -1
- package/static/dist/5319.dd84246e.async.js +0 -1
- package/static/dist/5484.ac83d6b4.async.js +0 -1
- package/static/dist/5544.6baaab99.async.js +0 -81
- package/static/dist/6304.613145ef.async.js +0 -1
- package/static/dist/6661.f5843bf4.async.js +0 -1
- package/static/dist/6794.4c503d6d.async.js +0 -5
- package/static/dist/6805.f5be6007.async.js +0 -1
- package/static/dist/7461.ed40fa5f.async.js +0 -1
- package/static/dist/7466.15597d4f.async.js +0 -1
- package/static/dist/7938.4e3377e7.async.js +0 -67
- package/static/dist/8037.61d0095e.async.js +0 -1
- package/static/dist/8297.3d6c376d.async.js +0 -1
- package/static/dist/8352.e0fbb494.async.js +0 -1
- package/static/dist/8432.30267db1.async.js +0 -1
- package/static/dist/8447.d0f63993.async.js +0 -1
- package/static/dist/9065.0806f3e5.async.js +0 -1
- package/static/dist/9280.aacaa172.async.js +0 -6
- package/static/dist/9673.a1545ea3.async.js +0 -3
- package/static/dist/986.c108246f.async.js +0 -1
- package/static/dist/layouts__index.3de47467.chunk.css +0 -1
- package/static/dist/layouts__index.a6451a2c.async.js +0 -1
- package/static/dist/src__pages__404.b5140a4b.async.js +0 -1
- package/static/dist/src__pages__crontab__logModal.0f6a4945.async.js +0 -2
- package/static/dist/src__pages__crontab__modal.cb176c70.async.js +0 -5
- package/static/dist/src__pages__crontab__viewCreateModal.f2b8a69a.async.js +0 -4
- package/static/dist/src__pages__crontab__viewManageModal.b86bbb79.async.js +0 -4
- package/static/dist/src__pages__dependence__index.c17201d7.async.js +0 -2
- package/static/dist/src__pages__dependence__logModal.42c56e18.async.js +0 -4
- package/static/dist/src__pages__dependence__modal.58620a62.async.js +0 -5
- package/static/dist/src__pages__env__index.c79218f4.async.js +0 -2
- package/static/dist/src__pages__env__modal.07f411f1.async.js +0 -5
- package/static/dist/src__pages__error__index.2f9d7c50.async.js +0 -4
- package/static/dist/src__pages__initialization__index.af82f7e1.async.js +0 -21
- package/static/dist/src__pages__log__index.5e63a6b7.async.js +0 -1
- package/static/dist/src__pages__login__index.44d624a7.async.js +0 -2
- package/static/dist/src__pages__setting__about.7ca2707b.async.js +0 -1
- package/static/dist/src__pages__setting__checkUpdate.dd497877.async.js +0 -4
- package/static/dist/src__pages__setting__index.4a85066e.async.js +0 -2
- package/static/dist/src__pages__setting__loginLog.c8ddd712.async.js +0 -18
- package/static/dist/src__pages__setting__notification.e124b7ae.async.js +0 -21
- package/static/dist/src__pages__setting__other.a58b5fae.async.js +0 -1
- package/static/dist/src__pages__setting__security.aabc2d21.async.js +0 -4
- package/static/dist/src__pages__subscription__index.04531731.async.js +0 -2
- package/static/dist/src__pages__subscription__logModal.b86a5c9b.async.js +0 -2
- package/static/dist/src__pages__subscription__modal.ea198f81.async.js +0 -4
- package/static/dist/umi.29bfaff2.js +0 -11
- /package/static/dist/{8352.d2d0a2c7.chunk.css → 8612.d2d0a2c7.chunk.css} +0 -0
- /package/static/dist/{7394.59dcf306.chunk.css → 9439.59dcf306.chunk.css} +0 -0
package/README-en.md
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
<img width="150" src="https://user-images.githubusercontent.com/22700758/191449379-f9f56204-0e31-4a16-be5a-331f52696a73.png">
|
|
4
|
-
</a>
|
|
5
|
-
</p>
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img width="100" src="https://user-images.githubusercontent.com/22700758/191449379-f9f56204-0e31-4a16-be5a-331f52696a73.png">
|
|
6
3
|
|
|
7
|
-
<h1 align="center">
|
|
4
|
+
<h1 align="center">Qinglong</h1>
|
|
8
5
|
|
|
9
|
-
|
|
6
|
+
[简体中文](./README.md) | English
|
|
10
7
|
|
|
11
8
|
Timed task management platform supporting Python3, JavaScript, Shell, Typescript
|
|
12
9
|
|
|
13
|
-
[![
|
|
10
|
+
[![npm version][npm-version-image]][npm-version-url] [![docker pulls][docker-pulls-image]][docker-pulls-url] [![docker stars][docker-stars-image]][docker-stars-url] [![docker image size][docker-image-size-image]][docker-image-size-url]
|
|
14
11
|
|
|
12
|
+
[npm-version-image]: https://img.shields.io/npm/v/@whyour/qinglong?style=flat
|
|
13
|
+
[npm-version-url]: https://www.npmjs.com/package/@whyour/qinglong?activeTab=readme
|
|
15
14
|
[docker-pulls-image]: https://img.shields.io/docker/pulls/whyour/qinglong?style=flat
|
|
16
15
|
[docker-pulls-url]: https://hub.docker.com/r/whyour/qinglong
|
|
17
|
-
[docker-version-image]: https://img.shields.io/docker/v/whyour/qinglong?style=flat
|
|
18
|
-
[docker-version-url]: https://hub.docker.com/r/whyour/qinglong/tags?page=1&ordering=last_updated
|
|
19
16
|
[docker-stars-image]: https://img.shields.io/docker/stars/whyour/qinglong?style=flat
|
|
20
17
|
[docker-stars-url]: https://hub.docker.com/r/whyour/qinglong
|
|
21
18
|
[docker-image-size-image]: https://img.shields.io/docker/image-size/whyour/qinglong?style=flat
|
|
22
19
|
[docker-image-size-url]: https://hub.docker.com/r/whyour/qinglong
|
|
23
|
-
</div>
|
|
24
20
|
|
|
25
|
-
[
|
|
21
|
+
[Demo](http://demo.dlww.cc:4433/) / [Issues](https://github.com/whyour/qinglong/issues) / [Telegram Channel](https://t.me/jiao_long) / [Buy Me a Coffee](https://www.buymeacoffee.com/qinglong)
|
|
26
22
|
|
|
27
|
-
[
|
|
23
|
+
[演示](http://demo.dlww.cc:4433/) / [反馈](https://github.com/whyour/qinglong/issues) / [Telegram 频道](https://t.me/jiao_long) / [打赏开发者](https://user-images.githubusercontent.com/22700758/244744295-29cd0cd1-c8bb-4ea1-adf6-29bd390ad4dd.jpg)
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+

|
|
28
27
|
|
|
29
28
|
## Features
|
|
30
29
|
|
|
@@ -38,95 +37,59 @@ Timed task management platform supporting Python3, JavaScript, Shell, Typescript
|
|
|
38
37
|
|
|
39
38
|
## Deployment
|
|
40
39
|
|
|
41
|
-
###
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
# To be refined, see the development steps first (not supported on windows yet)
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Podman Deployment
|
|
48
|
-
|
|
49
|
-
1. podman installation
|
|
40
|
+
### Docker (Recommended)
|
|
50
41
|
|
|
51
42
|
```bash
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
2. start the container
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
podman run -dit \
|
|
59
|
-
--network bridge \
|
|
43
|
+
# curl -sSL get.docker.com | sh
|
|
44
|
+
docker run -dit \
|
|
60
45
|
-v $PWD/ql/data:/ql/data \
|
|
61
46
|
-p 5700:5700 \
|
|
62
47
|
--name qinglong \
|
|
63
48
|
--hostname qinglong \
|
|
64
|
-
|
|
49
|
+
--restart unless-stopped \
|
|
50
|
+
whyour/qinglong:latest
|
|
65
51
|
```
|
|
66
52
|
|
|
67
|
-
### Docker
|
|
68
|
-
|
|
69
|
-
1. docker installation
|
|
53
|
+
### Docker-compose (Recommended)
|
|
70
54
|
|
|
71
55
|
```bash
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
2. configure domestic mirror sources
|
|
56
|
+
# curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
|
|
57
|
+
mkdir qinglong
|
|
58
|
+
wget https://raw.githubusercontent.com/whyour/qinglong/master/docker/docker-compose.yml
|
|
76
59
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"registry-mirrors": [
|
|
82
|
-
"https://0b27f0a81a00f3560fbdc00ddd2f99e0.mirror.swr.myhuaweicloud.com",
|
|
83
|
-
"https://ypzju6vq.mirror.aliyuncs.com",
|
|
84
|
-
"https://registry.docker-cn.com",
|
|
85
|
-
"http://hub-mirror.c.163.com",
|
|
86
|
-
"https://docker.mirrors.ustc.edu.cn"
|
|
87
|
-
]
|
|
88
|
-
}
|
|
89
|
-
EOF
|
|
90
|
-
systemctl daemon-reload
|
|
91
|
-
systemctl restart docker
|
|
60
|
+
# start
|
|
61
|
+
docker-compose up -d
|
|
62
|
+
# stop
|
|
63
|
+
docker-compose down
|
|
92
64
|
```
|
|
93
65
|
|
|
94
|
-
|
|
66
|
+
### Podman (Recommended)
|
|
95
67
|
|
|
96
68
|
```bash
|
|
97
|
-
|
|
69
|
+
# https://podman.io/getting-started/installation
|
|
70
|
+
podman run -dit \
|
|
71
|
+
--network bridge \
|
|
98
72
|
-v $PWD/ql/data:/ql/data \
|
|
99
73
|
-p 5700:5700 \
|
|
100
74
|
--name qinglong \
|
|
101
75
|
--hostname qinglong \
|
|
102
|
-
|
|
103
|
-
whyour/qinglong:latest
|
|
76
|
+
docker.io/whyour/qinglong:latest
|
|
104
77
|
```
|
|
105
78
|
|
|
106
|
-
###
|
|
79
|
+
### Local
|
|
107
80
|
|
|
108
|
-
|
|
81
|
+
It is recommended to use a pure system installation to avoid losing the original system data, you need to install node/npm/python3/pip3 yourself
|
|
109
82
|
|
|
110
83
|
```bash
|
|
111
|
-
|
|
84
|
+
npm install -g @whyour/qinglong
|
|
85
|
+
qinglong
|
|
86
|
+
# Add the environment variables QL_DIR and QL_DATA_DIR when prompted
|
|
87
|
+
export QL_DIR=""
|
|
88
|
+
export QL_DATA_DIR=""
|
|
89
|
+
# Run again
|
|
90
|
+
qinglong
|
|
112
91
|
```
|
|
113
92
|
|
|
114
|
-
2. start the container
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
mkdir qinglong
|
|
118
|
-
wget https://raw.githubusercontent.com/whyour/qinglong/master/docker/docker-compose.yml
|
|
119
|
-
|
|
120
|
-
# start
|
|
121
|
-
docker-compose up -d
|
|
122
|
-
# stop
|
|
123
|
-
docker-compose down
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
3. access
|
|
127
|
-
|
|
128
|
-
Open your browser and visit http://{ip}:5700
|
|
129
|
-
|
|
130
93
|
## Use
|
|
131
94
|
|
|
132
95
|
1. built-in commands
|
|
@@ -181,16 +144,6 @@ task -l <file_path>
|
|
|
181
144
|
* account_number: Specify the account number of an environment variable to be executed when the task is executed
|
|
182
145
|
* max_time: Timeout, suffix "s" for seconds (default), "m" for minutes, "h" for hours, "d" for days
|
|
183
146
|
|
|
184
|
-
## Links
|
|
185
|
-
|
|
186
|
-
- [nevinee](https://gitee.com/evine)
|
|
187
|
-
- [crontab-ui](https://github.com/alseambusher/crontab-ui)
|
|
188
|
-
- [Ant Design](https://ant.design)
|
|
189
|
-
- [Ant Design Pro](https://pro.ant.design/)
|
|
190
|
-
- [Umijs](https://umijs.org)
|
|
191
|
-
- [darkreader](https://github.com/darkreader/darkreader)
|
|
192
|
-
- [admin-server](https://github.com/sunpu007/admin-server)
|
|
193
|
-
|
|
194
147
|
## Development
|
|
195
148
|
|
|
196
149
|
```bash
|
|
@@ -205,9 +158,15 @@ $ pnpm start
|
|
|
205
158
|
|
|
206
159
|
Open your browser and visit http://127.0.0.1:5700
|
|
207
160
|
|
|
208
|
-
##
|
|
161
|
+
## Links
|
|
209
162
|
|
|
210
|
-
[
|
|
163
|
+
- [nevinee](https://gitee.com/evine)
|
|
164
|
+
- [crontab-ui](https://github.com/alseambusher/crontab-ui)
|
|
165
|
+
- [Ant Design](https://ant.design)
|
|
166
|
+
- [Ant Design Pro](https://pro.ant.design/)
|
|
167
|
+
- [Umijs](https://umijs.org)
|
|
168
|
+
- [darkreader](https://github.com/darkreader/darkreader)
|
|
169
|
+
- [admin-server](https://github.com/sunpu007/admin-server)
|
|
211
170
|
|
|
212
171
|
## Name Origin
|
|
213
172
|
|
package/README.md
CHANGED
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
<
|
|
2
|
-
|
|
3
|
-
<img width="150" src="https://user-images.githubusercontent.com/22700758/191449379-f9f56204-0e31-4a16-be5a-331f52696a73.png">
|
|
4
|
-
</a>
|
|
5
|
-
</p>
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img width="100" src="https://user-images.githubusercontent.com/22700758/191449379-f9f56204-0e31-4a16-be5a-331f52696a73.png">
|
|
6
3
|
|
|
7
4
|
<h1 align="center">青龙</h1>
|
|
8
5
|
|
|
9
|
-
|
|
6
|
+
简体中文 | [English](./README-en.md)
|
|
10
7
|
|
|
11
8
|
支持 Python3、JavaScript、Shell、Typescript 的定时任务管理平台
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
Timed task management platform supporting Python3, JavaScript, Shell, Typescript
|
|
14
11
|
|
|
12
|
+
[![npm version][npm-version-image]][npm-version-url] [![docker pulls][docker-pulls-image]][docker-pulls-url] [![docker stars][docker-stars-image]][docker-stars-url] [![docker image size][docker-image-size-image]][docker-image-size-url]
|
|
13
|
+
|
|
14
|
+
[npm-version-image]: https://img.shields.io/npm/v/@whyour/qinglong?style=flat
|
|
15
|
+
[npm-version-url]: https://www.npmjs.com/package/@whyour/qinglong?activeTab=readme
|
|
15
16
|
[docker-pulls-image]: https://img.shields.io/docker/pulls/whyour/qinglong?style=flat
|
|
16
17
|
[docker-pulls-url]: https://hub.docker.com/r/whyour/qinglong
|
|
17
|
-
[docker-version-image]: https://img.shields.io/docker/v/whyour/qinglong?style=flat
|
|
18
|
-
[docker-version-url]: https://hub.docker.com/r/whyour/qinglong/tags?page=1&ordering=last_updated
|
|
19
18
|
[docker-stars-image]: https://img.shields.io/docker/stars/whyour/qinglong?style=flat
|
|
20
19
|
[docker-stars-url]: https://hub.docker.com/r/whyour/qinglong
|
|
21
20
|
[docker-image-size-image]: https://img.shields.io/docker/image-size/whyour/qinglong?style=flat
|
|
22
21
|
[docker-image-size-url]: https://hub.docker.com/r/whyour/qinglong
|
|
23
|
-
</div>
|
|
24
22
|
|
|
25
|
-
[
|
|
23
|
+
[Demo](http://demo.dlww.cc:4433/) / [Issues](https://github.com/whyour/qinglong/issues) / [Telegram Channel](https://t.me/jiao_long) / [Buy Me a Coffee](https://www.buymeacoffee.com/qinglong)
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
[演示](http://demo.dlww.cc:4433/) / [反馈](https://github.com/whyour/qinglong/issues) / [Telegram 频道](https://t.me/jiao_long) / [打赏开发者](https://user-images.githubusercontent.com/22700758/244744295-29cd0cd1-c8bb-4ea1-adf6-29bd390ad4dd.jpg)
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+

|
|
28
29
|
|
|
29
30
|
## 功能
|
|
30
31
|
|
|
@@ -38,99 +39,63 @@
|
|
|
38
39
|
|
|
39
40
|
## 部署
|
|
40
41
|
|
|
41
|
-
###
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
# 待完善,可先参考开发步骤 (windows暂时不支持)
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### podman 部署
|
|
48
|
-
|
|
49
|
-
1. podman 安装
|
|
42
|
+
### docker (推荐)
|
|
50
43
|
|
|
51
44
|
```bash
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
2. 启动容器
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
podman run -dit \
|
|
59
|
-
--network bridge \
|
|
45
|
+
# curl -sSL get.docker.com | sh
|
|
46
|
+
docker run -dit \
|
|
60
47
|
-v $PWD/ql/data:/ql/data \
|
|
61
48
|
-p 5700:5700 \
|
|
62
49
|
# 部署路径非必须,以斜杠开头和结尾,比如 /test/
|
|
63
50
|
-e QlBaseUrl="/" \
|
|
64
51
|
--name qinglong \
|
|
65
52
|
--hostname qinglong \
|
|
66
|
-
|
|
53
|
+
--restart unless-stopped \
|
|
54
|
+
whyour/qinglong:latest
|
|
67
55
|
```
|
|
68
56
|
|
|
69
|
-
### docker
|
|
70
|
-
|
|
71
|
-
1. docker 安装
|
|
57
|
+
### docker-compose (推荐)
|
|
72
58
|
|
|
73
59
|
```bash
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
2. 配置国内镜像源
|
|
60
|
+
# curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
|
|
61
|
+
mkdir qinglong
|
|
62
|
+
wget https://raw.githubusercontent.com/whyour/qinglong/master/docker/docker-compose.yml
|
|
78
63
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"registry-mirrors": [
|
|
84
|
-
"https://0b27f0a81a00f3560fbdc00ddd2f99e0.mirror.swr.myhuaweicloud.com",
|
|
85
|
-
"https://ypzju6vq.mirror.aliyuncs.com",
|
|
86
|
-
"https://registry.docker-cn.com",
|
|
87
|
-
"http://hub-mirror.c.163.com",
|
|
88
|
-
"https://docker.mirrors.ustc.edu.cn"
|
|
89
|
-
]
|
|
90
|
-
}
|
|
91
|
-
EOF
|
|
92
|
-
systemctl daemon-reload
|
|
93
|
-
systemctl restart docker
|
|
64
|
+
# 启动
|
|
65
|
+
docker-compose up -d
|
|
66
|
+
# 停止
|
|
67
|
+
docker-compose down
|
|
94
68
|
```
|
|
95
69
|
|
|
96
|
-
|
|
70
|
+
### podman (推荐)
|
|
97
71
|
|
|
98
72
|
```bash
|
|
99
|
-
|
|
73
|
+
# https://podman.io/getting-started/installation
|
|
74
|
+
podman run -dit \
|
|
75
|
+
--network bridge \
|
|
100
76
|
-v $PWD/ql/data:/ql/data \
|
|
101
77
|
-p 5700:5700 \
|
|
102
78
|
# 部署路径非必须,以斜杠开头和结尾,比如 /test/
|
|
103
79
|
-e QlBaseUrl="/" \
|
|
104
80
|
--name qinglong \
|
|
105
81
|
--hostname qinglong \
|
|
106
|
-
|
|
107
|
-
whyour/qinglong:latest
|
|
82
|
+
docker.io/whyour/qinglong:latest
|
|
108
83
|
```
|
|
109
84
|
|
|
110
|
-
###
|
|
85
|
+
### 本机
|
|
111
86
|
|
|
112
|
-
|
|
87
|
+
建议使用纯净系统安装,避免系统原有数据丢失,需要自己安装 node/npm/python3/pip3
|
|
113
88
|
|
|
114
89
|
```bash
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
wget https://raw.githubusercontent.com/whyour/qinglong/master/docker/docker-compose.yml
|
|
123
|
-
|
|
124
|
-
# 启动
|
|
125
|
-
docker-compose up -d
|
|
126
|
-
# 停止
|
|
127
|
-
docker-compose down
|
|
90
|
+
npm install -g @whyour/qinglong
|
|
91
|
+
qinglong
|
|
92
|
+
# 根据提示增加环境变量 QL_DIR 和 QL_DATA_DIR
|
|
93
|
+
export QL_DIR=""
|
|
94
|
+
export QL_DATA_DIR=""
|
|
95
|
+
# 再次执行
|
|
96
|
+
qinglong
|
|
128
97
|
```
|
|
129
98
|
|
|
130
|
-
3. 访问
|
|
131
|
-
|
|
132
|
-
打开你的浏览器,访问 http://{ip}:5700
|
|
133
|
-
|
|
134
99
|
## 使用
|
|
135
100
|
|
|
136
101
|
1. 内置命令
|
|
@@ -184,16 +149,6 @@ task -l <file_path>
|
|
|
184
149
|
* account_number: 任务执行时指定某个环境变量需要执行的账号序号
|
|
185
150
|
* max_time: 超时时间,后缀"s"代表秒(默认值), "m"代表分, "h"代表小时, "d"代表天
|
|
186
151
|
|
|
187
|
-
## 链接
|
|
188
|
-
|
|
189
|
-
- [nevinee](https://gitee.com/evine)
|
|
190
|
-
- [crontab-ui](https://github.com/alseambusher/crontab-ui)
|
|
191
|
-
- [Ant Design](https://ant.design)
|
|
192
|
-
- [Ant Design Pro](https://pro.ant.design/)
|
|
193
|
-
- [Umijs](https://umijs.org)
|
|
194
|
-
- [darkreader](https://github.com/darkreader/darkreader)
|
|
195
|
-
- [admin-server](https://github.com/sunpu007/admin-server)
|
|
196
|
-
|
|
197
152
|
## 开发
|
|
198
153
|
|
|
199
154
|
```bash
|
|
@@ -208,9 +163,15 @@ $ pnpm start
|
|
|
208
163
|
|
|
209
164
|
打开你的浏览器,访问 http://127.0.0.1:5700
|
|
210
165
|
|
|
211
|
-
##
|
|
166
|
+
## 链接
|
|
212
167
|
|
|
213
|
-
[
|
|
168
|
+
- [nevinee](https://gitee.com/evine)
|
|
169
|
+
- [crontab-ui](https://github.com/alseambusher/crontab-ui)
|
|
170
|
+
- [Ant Design](https://ant.design)
|
|
171
|
+
- [Ant Design Pro](https://pro.ant.design/)
|
|
172
|
+
- [Umijs](https://umijs.org)
|
|
173
|
+
- [darkreader](https://github.com/darkreader/darkreader)
|
|
174
|
+
- [admin-server](https://github.com/sunpu007/admin-server)
|
|
214
175
|
|
|
215
176
|
## 名称来源
|
|
216
177
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whyour/qinglong",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Timed task management platform supporting Python3, JavaScript, Shell, Typescript",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -80,10 +80,12 @@
|
|
|
80
80
|
"chokidar": "^3.5.3",
|
|
81
81
|
"cors": "^2.8.5",
|
|
82
82
|
"cron-parser": "^4.2.1",
|
|
83
|
+
"cross-spawn": "^7.0.3",
|
|
83
84
|
"dayjs": "^1.11.2",
|
|
84
85
|
"dotenv": "^16.0.0",
|
|
85
86
|
"express": "^4.17.3",
|
|
86
87
|
"express-jwt": "^6.1.1",
|
|
88
|
+
"express-rate-limit": "^6.7.0",
|
|
87
89
|
"express-urlrewrite": "^1.4.0",
|
|
88
90
|
"form-data": "^4.0.0",
|
|
89
91
|
"got": "^11.8.2",
|
|
@@ -97,6 +99,7 @@
|
|
|
97
99
|
"nedb": "^1.8.0",
|
|
98
100
|
"node-schedule": "^2.1.0",
|
|
99
101
|
"nodemailer": "^6.7.2",
|
|
102
|
+
"p-limit": "3.1.0",
|
|
100
103
|
"protobufjs": "^7.2.3",
|
|
101
104
|
"pstree.remy": "^1.1.8",
|
|
102
105
|
"reflect-metadata": "^0.1.13",
|
|
@@ -118,6 +121,7 @@
|
|
|
118
121
|
"@sentry/react": "^7.12.1",
|
|
119
122
|
"@types/body-parser": "^1.19.2",
|
|
120
123
|
"@types/cors": "^2.8.12",
|
|
124
|
+
"@types/cross-spawn": "^6.0.2",
|
|
121
125
|
"@types/express": "^4.17.13",
|
|
122
126
|
"@types/express-jwt": "^6.0.4",
|
|
123
127
|
"@types/js-yaml": "^4.0.5",
|
package/sample/notify.js
CHANGED
|
@@ -76,6 +76,10 @@ let DD_BOT_TOKEN = '';
|
|
|
76
76
|
//密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串
|
|
77
77
|
let DD_BOT_SECRET = '';
|
|
78
78
|
|
|
79
|
+
// =======================================企业微信基础设置===========================================
|
|
80
|
+
// 企业微信反向代理地址
|
|
81
|
+
//(环境变量名 QYWX_ORIGIN)
|
|
82
|
+
let QYWX_ORIGIN = '';
|
|
79
83
|
// =======================================企业微信机器人通知设置区域===========================================
|
|
80
84
|
//此处填你企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
|
|
81
85
|
//(环境变量名 QYWX_KEY)
|
|
@@ -230,6 +234,12 @@ if (process.env.DD_BOT_TOKEN) {
|
|
|
230
234
|
}
|
|
231
235
|
}
|
|
232
236
|
|
|
237
|
+
if (process.env.QYWX_ORIGIN) {
|
|
238
|
+
QYWX_ORIGIN = process.env.QYWX_ORIGIN;
|
|
239
|
+
} else {
|
|
240
|
+
QYWX_ORIGIN = 'https://qyapi.weixin.qq.com';
|
|
241
|
+
}
|
|
242
|
+
|
|
233
243
|
if (process.env.QYWX_KEY) {
|
|
234
244
|
QYWX_KEY = process.env.QYWX_KEY;
|
|
235
245
|
}
|
|
@@ -298,11 +308,11 @@ async function sendNotify(
|
|
|
298
308
|
desp += author; //增加作者信息,防止被贩卖等
|
|
299
309
|
|
|
300
310
|
// 根据标题跳过一些消息推送,环境变量:SKIP_PUSH_TITLE 用回车分隔
|
|
301
|
-
let skipTitle = process.env.SKIP_PUSH_TITLE
|
|
302
|
-
if(skipTitle) {
|
|
303
|
-
if(skipTitle.split('\n').includes(text)) {
|
|
304
|
-
console.info(text +
|
|
305
|
-
return
|
|
311
|
+
let skipTitle = process.env.SKIP_PUSH_TITLE;
|
|
312
|
+
if (skipTitle) {
|
|
313
|
+
if (skipTitle.split('\n').includes(text)) {
|
|
314
|
+
console.info(text + '在SKIP_PUSH_TITLE环境变量内,跳过推送!');
|
|
315
|
+
return;
|
|
306
316
|
}
|
|
307
317
|
}
|
|
308
318
|
|
|
@@ -692,7 +702,7 @@ function ddBotNotify(text, desp) {
|
|
|
692
702
|
function qywxBotNotify(text, desp) {
|
|
693
703
|
return new Promise((resolve) => {
|
|
694
704
|
const options = {
|
|
695
|
-
url:
|
|
705
|
+
url: `${QYWX_ORIGIN}/cgi-bin/webhook/send?key=${QYWX_KEY}`,
|
|
696
706
|
json: {
|
|
697
707
|
msgtype: 'text',
|
|
698
708
|
text: {
|
|
@@ -754,7 +764,7 @@ function qywxamNotify(text, desp) {
|
|
|
754
764
|
if (QYWX_AM) {
|
|
755
765
|
const QYWX_AM_AY = QYWX_AM.split(',');
|
|
756
766
|
const options_accesstoken = {
|
|
757
|
-
url:
|
|
767
|
+
url: `${QYWX_ORIGIN}/cgi-bin/gettoken`,
|
|
758
768
|
json: {
|
|
759
769
|
corpid: `${QYWX_AM_AY[0]}`,
|
|
760
770
|
corpsecret: `${QYWX_AM_AY[1]}`,
|
|
@@ -819,7 +829,7 @@ function qywxamNotify(text, desp) {
|
|
|
819
829
|
};
|
|
820
830
|
}
|
|
821
831
|
options = {
|
|
822
|
-
url:
|
|
832
|
+
url: `${QYWX_ORIGIN}/cgi-bin/message/send?access_token=${accesstoken}`,
|
|
823
833
|
json: {
|
|
824
834
|
touser: `${ChangeUserId(desp)}`,
|
|
825
835
|
agentid: `${QYWX_AM_AY[3]}`,
|
|
@@ -1113,4 +1123,4 @@ module.exports = {
|
|
|
1113
1123
|
};
|
|
1114
1124
|
|
|
1115
1125
|
// prettier-ignore
|
|
1116
|
-
function Env(t,s){return new class{constructor(t,s){this.name=t,this.data=null,this.dataFile="box.dat",this.logs=[],this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,s),this.log(""
|
|
1126
|
+
function Env(t, s) { return new class { constructor(t, s) { this.name = t, this.data = null, this.dataFile = "box.dat", this.logs = [], this.logSeparator = "\n", this.startTime = (new Date).getTime(), Object.assign(this, s), this.log("", `\ud83d\udd14${this.name}, \u5f00\u59cb!`) } isNode() { return "undefined" != typeof module && !!module.exports } isQuanX() { return "undefined" != typeof $task } isSurge() { return "undefined" != typeof $httpClient && "undefined" == typeof $loon } isLoon() { return "undefined" != typeof $loon } getScript(t) { return new Promise(s => { $.get({ url: t }, (t, e, i) => s(i)) }) } runScript(t, s) { return new Promise(e => { let i = this.getdata("@chavy_boxjs_userCfgs.httpapi"); i = i ? i.replace(/\n/g, "").trim() : i; let o = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout"); o = o ? 1 * o : 20, o = s && s.timeout ? s.timeout : o; const [h, a] = i.split("@"), r = { url: `http://${a}/v1/scripting/evaluate`, body: { script_text: t, mock_type: "cron", timeout: o }, headers: { "X-Key": h, Accept: "*/*" } }; $.post(r, (t, s, i) => e(i)) }).catch(t => this.logErr(t)) } loaddata() { if (!this.isNode()) return {}; { this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); const t = this.path.resolve(this.dataFile), s = this.path.resolve(process.cwd(), this.dataFile), e = this.fs.existsSync(t), i = !e && this.fs.existsSync(s); if (!e && !i) return {}; { const i = e ? t : s; try { return JSON.parse(this.fs.readFileSync(i)) } catch (t) { return {} } } } } writedata() { if (this.isNode()) { this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); const t = this.path.resolve(this.dataFile), s = this.path.resolve(process.cwd(), this.dataFile), e = this.fs.existsSync(t), i = !e && this.fs.existsSync(s), o = JSON.stringify(this.data); e ? this.fs.writeFileSync(t, o) : i ? this.fs.writeFileSync(s, o) : this.fs.writeFileSync(t, o) } } lodash_get(t, s, e) { const i = s.replace(/\[(\d+)\]/g, ".$1").split("."); let o = t; for (const t of i) if (o = Object(o)[t], void 0 === o) return e; return o } lodash_set(t, s, e) { return Object(t) !== t ? t : (Array.isArray(s) || (s = s.toString().match(/[^.[\]]+/g) || []), s.slice(0, -1).reduce((t, e, i) => Object(t[e]) === t[e] ? t[e] : t[e] = Math.abs(s[i + 1]) >> 0 == +s[i + 1] ? [] : {}, t)[s[s.length - 1]] = e, t) } getdata(t) { let s = this.getval(t); if (/^@/.test(t)) { const [, e, i] = /^@(.*?)\.(.*?)$/.exec(t), o = e ? this.getval(e) : ""; if (o) try { const t = JSON.parse(o); s = t ? this.lodash_get(t, i, "") : s } catch (t) { s = "" } } return s } setdata(t, s) { let e = !1; if (/^@/.test(s)) { const [, i, o] = /^@(.*?)\.(.*?)$/.exec(s), h = this.getval(i), a = i ? "null" === h ? null : h || "{}" : "{}"; try { const s = JSON.parse(a); this.lodash_set(s, o, t), e = this.setval(JSON.stringify(s), i) } catch (s) { const h = {}; this.lodash_set(h, o, t), e = this.setval(JSON.stringify(h), i) } } else e = $.setval(t, s); return e } getval(t) { return this.isSurge() || this.isLoon() ? $persistentStore.read(t) : this.isQuanX() ? $prefs.valueForKey(t) : this.isNode() ? (this.data = this.loaddata(), this.data[t]) : this.data && this.data[t] || null } setval(t, s) { return this.isSurge() || this.isLoon() ? $persistentStore.write(t, s) : this.isQuanX() ? $prefs.setValueForKey(t, s) : this.isNode() ? (this.data = this.loaddata(), this.data[s] = t, this.writedata(), !0) : this.data && this.data[s] || null } initGotEnv(t) { this.got = this.got ? this.got : require("got"), this.cktough = this.cktough ? this.cktough : require("tough-cookie"), this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar, t && (t.headers = t.headers ? t.headers : {}, void 0 === t.headers.Cookie && void 0 === t.cookieJar && (t.cookieJar = this.ckjar)) } get(t, s = (() => { })) { t.headers && (delete t.headers["Content-Type"], delete t.headers["Content-Length"]), this.isSurge() || this.isLoon() ? $httpClient.get(t, (t, e, i) => { !t && e && (e.body = i, e.statusCode = e.status), s(t, e, i) }) : this.isQuanX() ? $task.fetch(t).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t)) : this.isNode() && (this.initGotEnv(t), this.got(t).on("redirect", (t, s) => { try { const e = t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString(); this.ckjar.setCookieSync(e, null), s.cookieJar = this.ckjar } catch (t) { this.logErr(t) } }).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t))) } post(t, s = (() => { })) { if (t.body && t.headers && !t.headers["Content-Type"] && (t.headers["Content-Type"] = "application/x-www-form-urlencoded"), delete t.headers["Content-Length"], this.isSurge() || this.isLoon()) $httpClient.post(t, (t, e, i) => { !t && e && (e.body = i, e.statusCode = e.status), s(t, e, i) }); else if (this.isQuanX()) t.method = "POST", $task.fetch(t).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t)); else if (this.isNode()) { this.initGotEnv(t); const { url: e, ...i } = t; this.got.post(e, i).then(t => { const { statusCode: e, statusCode: i, headers: o, body: h } = t; s(null, { status: e, statusCode: i, headers: o, body: h }, h) }, t => s(t)) } } time(t) { let s = { "M+": (new Date).getMonth() + 1, "d+": (new Date).getDate(), "H+": (new Date).getHours(), "m+": (new Date).getMinutes(), "s+": (new Date).getSeconds(), "q+": Math.floor(((new Date).getMonth() + 3) / 3), S: (new Date).getMilliseconds() }; /(y+)/.test(t) && (t = t.replace(RegExp.$1, ((new Date).getFullYear() + "").substr(4 - RegExp.$1.length))); for (let e in s) new RegExp("(" + e + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? s[e] : ("00" + s[e]).substr(("" + s[e]).length))); return t } msg(s = t, e = "", i = "", o) { const h = t => !t || !this.isLoon() && this.isSurge() ? t : "string" == typeof t ? this.isLoon() ? t : this.isQuanX() ? { "open-url": t } : void 0 : "object" == typeof t && (t["open-url"] || t["media-url"]) ? this.isLoon() ? t["open-url"] : this.isQuanX() ? t : void 0 : void 0; $.isMute || (this.isSurge() || this.isLoon() ? $notification.post(s, e, i, h(o)) : this.isQuanX() && $notify(s, e, i, h(o))), this.logs.push("", "==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="), this.logs.push(s), e && this.logs.push(e), i && this.logs.push(i) } log(...t) { t.length > 0 ? this.logs = [...this.logs, ...t] : console.log(this.logs.join(this.logSeparator)) } logErr(t, s) { const e = !this.isSurge() && !this.isQuanX() && !this.isLoon(); e ? $.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t.stack) : $.log("", `\u2757\ufe0f${this.name}, \u9519\u8bef!`, t) } wait(t) { return new Promise(s => setTimeout(s, t)) } done(t = {}) { const s = (new Date).getTime(), e = (s - this.startTime) / 1e3; this.log("", `\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${e} \u79d2`), this.log(), (this.isSurge() || this.isQuanX() || this.isLoon()) && $done(t) } }(t, s) }
|