Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b8265d77f | ||
|
|
ceecc95c29 | ||
|
|
27c48446ce | ||
|
|
1d65c0e8d6 | ||
|
|
6b09c1ffac | ||
|
|
07d8e7e0b1 | ||
|
|
e80e41266a | ||
|
|
640d543487 | ||
|
|
aef3cee03c | ||
|
|
a9d843d885 | ||
|
|
bcc9d19916 | ||
|
|
23d2d40613 | ||
|
|
f873a4aeb9 | ||
|
|
a49495268f | ||
|
|
389b1bdd2e | ||
|
|
09c903ec2d | ||
|
|
b4c0455f70 | ||
|
|
6f59fe2b37 | ||
|
|
365853fade | ||
|
|
837ce742e0 | ||
|
|
11bf29fad7 | ||
|
|
350e898bda | ||
|
|
3c29788980 | ||
|
|
09ff58362b | ||
|
|
7cb6c148dd | ||
|
|
e8cca6ea15 | ||
|
|
a067234c64 | ||
|
|
b74463d9e5 | ||
|
|
28f85b4d45 | ||
|
|
e8567524ac | ||
|
|
c0dcee45d4 | ||
|
|
d51343ba8d | ||
|
|
777a1961d0 | ||
|
|
706cb057bc | ||
|
|
31c0356acc | ||
|
|
47de9769d0 | ||
|
|
ebb7ad0207 | ||
|
|
750c0983f1 | ||
|
|
f005466293 | ||
|
|
aacf9e05b9 | ||
|
|
62fba81406 | ||
|
|
c644757135 | ||
|
|
53a0dcce2f | ||
|
|
b1a948dd2a | ||
|
|
e19fdb2ad2 | ||
|
|
b9e2f2cf48 | ||
|
|
2de7e6b2d0 | ||
|
|
a2716ed8b8 | ||
|
|
73d60a0907 | ||
|
|
15c26a6e1f | ||
|
|
09ce9b811e | ||
|
|
05737663a2 | ||
|
|
9820a1e1f3 | ||
|
|
f4965c8256 | ||
|
|
4892083ee9 | ||
|
|
8f8295cb68 | ||
|
|
0be4513349 | ||
|
|
c7219a7516 | ||
|
|
f5704f470a | ||
|
|
9b19fd1e9d | ||
|
|
3e81d886f6 | ||
|
|
f1d31d1c10 | ||
|
|
44b811507d | ||
|
|
3c28140c32 | ||
|
|
a12148671a | ||
|
|
3a9199e176 | ||
|
|
3d5c444db0 | ||
|
|
6c385014cc | ||
|
|
f0a1c0ab06 | ||
|
|
4ebf15f3c1 | ||
|
|
b325a3e9a0 | ||
|
|
c3dd34dac9 | ||
|
|
3eceb3c719 | ||
|
|
f1cbde414f | ||
|
|
9bc02bdfcb | ||
|
|
e34a26c009 | ||
|
|
3fc032daa9 | ||
|
|
006554cd0a | ||
|
|
42468e9711 | ||
|
|
da5b04cdb3 | ||
|
|
66486b8810 | ||
|
|
c9883cafb9 | ||
|
|
a83b5fa489 | ||
|
|
49f44a00b2 | ||
|
|
807a860d07 | ||
|
|
3df445e98c | ||
|
|
e53abb7c79 | ||
|
|
4ca8bc06d8 | ||
|
|
76d4752776 | ||
|
|
95fcaada2b | ||
|
|
327af9f3fa | ||
|
|
066ae11ad7 | ||
|
|
f5c377dab8 | ||
|
|
963b7fdb82 | ||
|
|
8f66b5e04b | ||
|
|
0b98c6acc0 | ||
|
|
dfae93bbed | ||
|
|
1a440e1f67 | ||
|
|
270e2253a4 | ||
|
|
a9a3b524eb | ||
|
|
e4799f0045 | ||
|
|
9e6d2c1043 | ||
|
|
691fb2a380 | ||
|
|
f39bf33922 | ||
|
|
14ff3fea9a | ||
|
|
246829869a | ||
|
|
5f2fa2f033 | ||
|
|
6c52e87396 | ||
|
|
a4b0bb3e9c | ||
|
|
44b79ab946 | ||
|
|
1a39ed726d | ||
|
|
4c4fa9b2c7 | ||
|
|
708110c498 | ||
|
|
227efb5471 | ||
|
|
17cbb4b663 | ||
|
|
35ecc4c894 | ||
|
|
d976abdb84 | ||
|
|
bd78b87d6f | ||
|
|
a0869708aa | ||
|
|
bf53df1dc3 | ||
|
|
6f63e1c837 | ||
|
|
3e2234c1cd | ||
|
|
42208ac101 | ||
|
|
b247364d16 | ||
|
|
d8b86bd302 | ||
|
|
1ec66adda0 | ||
|
|
d3d0ee73a0 | ||
|
|
e757b471fd | ||
|
|
60c8843734 | ||
|
|
f779053040 | ||
|
|
6becac74d0 | ||
|
|
e64a73eb67 | ||
|
|
cffa82226d | ||
|
|
6626afa6b6 | ||
|
|
6d35063027 | ||
|
|
09d6db68ff | ||
|
|
f33145d02a | ||
|
|
a74e4f1a13 | ||
|
|
9344a831be | ||
|
|
4fd7e89ff8 | ||
|
|
d0a2774f65 | ||
|
|
fb563396fe | ||
|
|
73ad9f49ef | ||
|
|
10e6bf81f9 | ||
|
|
274b49d66f | ||
|
|
ab6749056a | ||
|
|
3be2e354c4 | ||
|
|
0c825c65d4 | ||
|
|
c6836f3654 | ||
|
|
c6a5db7740 | ||
|
|
179f34fad2 | ||
|
|
161096fbb2 | ||
|
|
69412300b6 | ||
|
|
329751350d | ||
|
|
90675e3ae8 | ||
|
|
238125eb8d | ||
|
|
d30f02b1c0 | ||
|
|
d9ec47f8ea | ||
|
|
6020915993 | ||
|
|
07ed4f7922 | ||
|
|
13b6d7f98d | ||
|
|
3752d42de8 | ||
|
|
847bcd746c | ||
|
|
e1e46457e7 | ||
|
|
a2751deac6 | ||
|
|
74c11e7539 | ||
|
|
cb0ee30c6b | ||
|
|
c518c0c1e6 | ||
|
|
8827c45df1 | ||
|
|
b91518136b | ||
|
|
b46cb2501b | ||
|
|
c1823e7a83 | ||
|
|
84d5f4e5e2 | ||
|
|
ff7416f858 | ||
|
|
b6b4cb1ce4 | ||
|
|
617d5df294 | ||
|
|
ff87ea8e39 | ||
|
|
36581ded16 | ||
|
|
333682325c | ||
|
|
1a1d9e8adf | ||
|
|
020e7b0944 | ||
|
|
e15bd00524 | ||
|
|
de1e2dbcbb | ||
|
|
7b24f1dedf | ||
|
|
ce94a35ed7 | ||
|
|
8a0c66ceff | ||
|
|
a92e172d26 | ||
|
|
a7bcc4d4fb | ||
|
|
19cfd3daf4 | ||
|
|
b82bac40fc | ||
|
|
21d61d9cd2 | ||
|
|
76e7359c69 | ||
|
|
82047f4504 | ||
|
|
c970acbe8b | ||
|
|
988d2caced | ||
|
|
c5111929a3 | ||
|
|
b6b72e0273 | ||
|
|
0d43439200 | ||
|
|
da0e68f95c | ||
|
|
fbea823ba1 | ||
|
|
7adf56ce0a | ||
|
|
7f394b327b | ||
|
|
7fe673068b | ||
|
|
f16d48b432 | ||
|
|
192df21da4 | ||
|
|
02e0f10016 | ||
|
|
24e8dc4e9f | ||
|
|
dbeef1cee4 | ||
|
|
096eb7c73e | ||
|
|
69820bfcb9 | ||
|
|
3c3b7c4389 | ||
|
|
822ebf4888 | ||
|
|
3b6c43ee23 | ||
|
|
c711423ef9 | ||
|
|
948c37c039 | ||
|
|
1f8e3cfb7a | ||
|
|
7b875c81d1 | ||
|
|
3fb1d874d5 | ||
|
|
601c60fca7 | ||
|
|
d052f75a1c | ||
|
|
51c81e19af | ||
|
|
480cbb73ea | ||
|
|
4a1e4c1d68 | ||
|
|
76c763b84d | ||
|
|
ed0aa017db | ||
|
|
a314d4dc54 | ||
|
|
4bfae38176 | ||
|
|
1f047e25c7 | ||
|
|
ff81448611 | ||
|
|
83cf140fa1 | ||
|
|
8fc1cd0430 | ||
|
|
7ff7907e11 | ||
|
|
4611defe36 | ||
|
|
eb89807cf1 | ||
|
|
bea9a0a56d | ||
|
|
fc2df7e501 | ||
|
|
bab3e80aec | ||
|
|
a556813b01 | ||
|
|
e90f922b58 | ||
|
|
7671564ea3 | ||
|
|
402dc5d970 | ||
|
|
51b0668b5d | ||
|
|
8686551e71 | ||
|
|
437e2c602a | ||
|
|
fe00d39bc1 | ||
|
|
5cb7998f12 | ||
|
|
6cec43bee6 | ||
|
|
6e81d130ed | ||
|
|
e8ba2326aa | ||
|
|
a070df069b | ||
|
|
fe133d3ec2 | ||
|
|
ddfeb37114 | ||
|
|
53d1ac1d4a | ||
|
|
bc7c720218 | ||
|
|
b12cc3f306 | ||
|
|
af41e894bf | ||
|
|
ddf67bee70 | ||
|
|
9899b76262 | ||
|
|
fc4c591709 | ||
|
|
db891c7342 | ||
|
|
60eac561bb | ||
|
|
abffa2933b | ||
|
|
fd5f6ca32d | ||
|
|
7f225bb18e | ||
|
|
cf847d44d7 | ||
|
|
b7a81e0dce | ||
|
|
256cf56426 | ||
|
|
4780ff8698 | ||
|
|
5b95c1a2f4 | ||
|
|
54c5905a58 | ||
|
|
e37b248c8c | ||
|
|
8dd524e89e | ||
|
|
5625149766 | ||
|
|
900924d196 | ||
|
|
2b687331b5 | ||
|
|
281e856864 | ||
|
|
1f64d92dd2 | ||
|
|
a02eada324 | ||
|
|
bda9339299 | ||
|
|
2044aa1662 | ||
|
|
e82fee0d26 | ||
|
|
5dd0fec953 | ||
|
|
adf4b9ea5a | ||
|
|
ebd20c6db5 | ||
|
|
cfd32089ff | ||
|
|
d75c4a222e | ||
|
|
ca721c78e6 | ||
|
|
120d9a55c8 | ||
|
|
177ee3a6fb | ||
|
|
270af9260d | ||
|
|
6e0078e1d8 | ||
|
|
a4f28cca30 | ||
|
|
8aa0d11cbb | ||
|
|
e043b6b8d7 | ||
|
|
aaf7578290 | ||
|
|
cd3b487fa8 | ||
|
|
3ffc4090e0 | ||
|
|
fa28bbb83f | ||
|
|
8e11641a7c | ||
|
|
76a544fb1f | ||
|
|
02805363ac | ||
|
|
2732b14eae | ||
|
|
14b6a74666 | ||
|
|
9d35088cce | ||
|
|
f35852b696 | ||
|
|
f5c9616bac | ||
|
|
0f45799fee | ||
|
|
c251ed9f1b | ||
|
|
e88930e13a | ||
|
|
c55e8699b4 | ||
|
|
d030a60721 | ||
|
|
16749d1fa1 | ||
|
|
c5de9ce9eb | ||
|
|
aed1ee2001 | ||
|
|
ce84a9c9f0 | ||
|
|
46256439da | ||
|
|
8edc30babc | ||
|
|
b3c52ea50e | ||
|
|
61b14fe82b | ||
|
|
fd1a75bc0a | ||
|
|
955e7a01db | ||
|
|
dc3e570067 | ||
|
|
ff91e2aa38 | ||
|
|
b076a43f30 | ||
|
|
0879eb2f95 | ||
|
|
ae8829dbc8 | ||
|
|
30255dc679 | ||
|
|
b2a3e4e225 | ||
|
|
1416344b06 | ||
|
|
53b0af2321 | ||
|
|
f2bed9ac33 | ||
|
|
960c82ec36 | ||
|
|
ead88d05f4 | ||
|
|
d0fb55318f | ||
|
|
daa5847859 | ||
|
|
a353ff1303 | ||
|
|
8ff928d9d6 | ||
|
|
35b16ff3e1 | ||
|
|
6bd687301e | ||
|
|
5e01dd1639 | ||
|
|
27d6234409 | ||
|
|
99710eb670 | ||
|
|
437306c064 | ||
|
|
f0be23879d | ||
|
|
8632d7686b | ||
|
|
ee9b049db4 | ||
|
|
18dc7f7e2c | ||
|
|
8461218d63 | ||
|
|
466e406f74 | ||
|
|
74ee6c1bba | ||
|
|
50c025bd09 | ||
|
|
0d5300abda | ||
|
|
4611735283 | ||
|
|
ba7b632046 | ||
|
|
522a4f903e | ||
|
|
8dc00d36eb | ||
|
|
ec60a96172 | ||
|
|
e9efc70f7c | ||
|
|
e0b78932a7 | ||
|
|
d3a2ba9837 | ||
|
|
8edb7833a8 | ||
|
|
73076c3a54 | ||
|
|
ef78a26c7a | ||
|
|
7f7fba0425 | ||
|
|
5936f917b3 | ||
|
|
7697891807 | ||
|
|
28b4227215 | ||
|
|
c371d9d5bd | ||
|
|
a8cc42b915 | ||
|
|
2fb512a176 | ||
|
|
4df637172b | ||
|
|
431ef6accc | ||
|
|
daa4a3e7b8 | ||
|
|
688e71b0a4 | ||
|
|
4600358cd1 | ||
|
|
7f35ebd8cb | ||
|
|
a520586db5 | ||
|
|
0f2b9439e9 | ||
|
|
12f5c8183d | ||
|
|
dc146446b4 | ||
|
|
22a85eb7d4 | ||
|
|
70b5c10865 | ||
|
|
ea86ac9ae4 | ||
|
|
48489263f7 | ||
|
|
a124696295 | ||
|
|
56bef72beb | ||
|
|
e8a5a4a60b | ||
|
|
64ca363f96 | ||
|
|
ef045736dc | ||
|
|
2d650aca2f | ||
|
|
4331fc2661 | ||
|
|
0cac5d9fc0 | ||
|
|
2027b2139c | ||
|
|
2f794f549f | ||
|
|
c7229b7461 | ||
|
|
572b6ccf85 | ||
|
|
cbfa8a7110 | ||
|
|
f4d9bbb746 | ||
|
|
5e84721435 | ||
|
|
b7e8a3c1a1 | ||
|
|
ea1bd27aa8 | ||
|
|
5611c5acb6 | ||
|
|
821c625fb9 | ||
|
|
0ba1d59929 | ||
|
|
937cfb6a06 | ||
|
|
08c31096b5 | ||
|
|
b361c50c9a | ||
|
|
927427f353 | ||
|
|
2d1a95594f | ||
|
|
439d23df2d | ||
|
|
a197f51c6a | ||
|
|
3f668dcc4b | ||
|
|
1bdfb4996e | ||
|
|
84703a8971 | ||
|
|
b55a993b35 | ||
|
|
6485e3b48e | ||
|
|
4af940647d | ||
|
|
bfc549a669 | ||
|
|
cb96b18579 | ||
|
|
0d918fbb69 | ||
|
|
fcdcf6da60 | ||
|
|
ce46076867 | ||
|
|
7d8db0a518 | ||
|
|
a2a35ed4d2 | ||
|
|
074580a26b | ||
|
|
8cede9c087 | ||
|
|
f83dec5f80 | ||
|
|
3ae6dd917b | ||
|
|
3a5c4f6302 | ||
|
|
b557e9717a | ||
|
|
f916e24bf4 | ||
|
|
ea9c66f7b2 | ||
|
|
6c19a3d321 | ||
|
|
459fa036be | ||
|
|
be5fda9ba3 | ||
|
|
90a0e04590 | ||
|
|
55124ed7e8 | ||
|
|
54e85596a9 | ||
|
|
a1e4dfbbd0 | ||
|
|
ed72eeee2d | ||
|
|
9e9e548026 | ||
|
|
2b57a65c59 | ||
|
|
43a36b3701 | ||
|
|
c1519c11ae | ||
|
|
a7f2d852af | ||
|
|
fbb388badc | ||
|
|
23f8efd8d7 | ||
|
|
34a066baf0 | ||
|
|
b78d8bc3b6 | ||
|
|
b91374bdf3 | ||
|
|
1453d1a84b | ||
|
|
bffc45535d | ||
|
|
a1f168b298 | ||
|
|
46063d6b57 | ||
|
|
a52deaf83c | ||
|
|
6ba86a50d3 | ||
|
|
7ec6fb7090 | ||
|
|
f5a0284932 | ||
|
|
70393639d9 | ||
|
|
ee8b2d816b | ||
|
|
34cc9e7458 | ||
|
|
d6e585220d | ||
|
|
a56bea7a97 | ||
|
|
15a70aeadb | ||
|
|
dcf78ad6ef | ||
|
|
2a8fbb7b86 | ||
|
|
47edf4c4d4 | ||
|
|
fb3a4aa3d0 | ||
|
|
2f5ff4bbd8 | ||
|
|
0c7c6471d8 | ||
|
|
f561357d10 | ||
|
|
a89aff5a2d | ||
|
|
018d261eb2 | ||
|
|
31ba9f5c5f | ||
|
|
4bc97394dc | ||
|
|
84df8567c5 | ||
|
|
f0c0a140ec |
@@ -1,4 +1,12 @@
|
||||
#idea file
|
||||
.idea
|
||||
|
||||
dist
|
||||
# develop temp folder.
|
||||
tmp
|
||||
|
||||
# build execute file
|
||||
tank
|
||||
tank.exe
|
||||
|
||||
# mac
|
||||
.DS_Store
|
||||
@@ -4,16 +4,277 @@
|
||||
每次版本升级时需要修改以下内容。
|
||||
|
||||
1. build/pack/build.bat
|
||||
set VERSION_NAME=tank-x.x.x
|
||||
VERSION_NAME=tank-x.x.x
|
||||
|
||||
2. build/pack/build.sh
|
||||
VERSION_NAME=tank-x.x.x
|
||||
|
||||
3. rest/config.go
|
||||
3. build/pack/cross-build.sh
|
||||
VERSION_NAME=tank-x.x.x
|
||||
|
||||
4. core/config.go
|
||||
VERSION = x.x.x
|
||||
|
||||
4. tank-front 修改 vuex/index.js
|
||||
versionName: 'x.x.x'
|
||||
5. readme.md 修改 eyeblue/tank:x.x.x
|
||||
eyeblue/tank:x.x.x
|
||||
|
||||
|
||||
## 新版本发布流程
|
||||
1.docker版本的发布。[参考](https://blog.eyeblue.cn/home/article/510f9316-9ca1-40fe-b1b3-5285505a527d)
|
||||
|
||||
```
|
||||
cd tank根目录
|
||||
# 停止旧版本,并删除旧版本
|
||||
docker container stop xxx
|
||||
docker container prune
|
||||
# 构建新版本 (最后的.不能少)
|
||||
docker build -t eyeblue/tank:x.x.x .
|
||||
# 本地测试
|
||||
docker run --name dockermysql -p 13306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=tank -e MYSQL_USER=tank -e MYSQL_PASSWORD=tank123 -v ~/data/dockermysql:/var/lib/mysql -e TZ=Asia/Shanghai -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
docker run --name tank -p 6010:6010 --link dockermysql:mysql -v ~/data/dockermatter:/data/build/matter -d eyeblue/tank:x.x.x
|
||||
# 没问题后,推送到远程
|
||||
docker push eyeblue/tank:x.x.x
|
||||
```
|
||||
|
||||
2.linux版本的发布。
|
||||
|
||||
a. 执行`src/tank/build/pack/build.sh`脚本
|
||||
b. 上传 tank-x.x.x.linux-amd64.tar.gz 到蓝眼云盘
|
||||
c. 在github上发布新版本。
|
||||
|
||||
3.windows版本发布
|
||||
|
||||
a. 执行`src/tank/build/pack/build.bat`脚本
|
||||
b. 上传 tank-x.x.x.windows-x86_64.zip 到蓝眼云盘
|
||||
c. 在github上发布新版本。
|
||||
|
||||
3.更新tank-doc 下载内容
|
||||
|
||||
## useful commands
|
||||
go get xxx/xxx
|
||||
go mod tidy
|
||||
|
||||
tank-4.1.1 2024-10-6
|
||||
1. 修复已知问题
|
||||
|
||||
tank-4.1.0 2024-7-27
|
||||
1. 删除用户后,空间一并删除。 #222
|
||||
2. 增加批量绑定空间成员功能。 #227
|
||||
3. 共享空间增加回收站逻辑。 #232
|
||||
4. 修复用户修改空间单位问题。 #233 #253
|
||||
5. 增强搜索功能,会进行dfs深度优先搜索。 #239
|
||||
|
||||
|
||||
1. When delete user, it's space will be deleted #222
|
||||
2. Batch creating space member #227
|
||||
3. Add feature of recycle bin for space #232
|
||||
4. Fix issue of changing unit #233 #253
|
||||
5. Enhance the search ability, using dfs #239
|
||||
|
||||
|
||||
tank-4.0.4 2024-4-29
|
||||
1. 修复已知问题
|
||||
|
||||
tank-4.0.3 2024-3-26
|
||||
1. 修复已知问题
|
||||
|
||||
tank-4.0.2 2023-11-10
|
||||
1. 修复BUG https://github.com/eyebluecn/tank/issues/229
|
||||
2. 新增了分享提取码快速提取
|
||||
3. 分享文件默认按照创建时间倒序排列。
|
||||
|
||||
1. Fix BUG https://github.com/eyebluecn/tank/issues/229
|
||||
2. Fast share using code.
|
||||
3. Share list order by create time desc.
|
||||
|
||||
|
||||
tank-4.0.1 2023-09-09
|
||||
1.修复一些文件扫描的bug https://github.com/eyebluecn/tank/issues/221 https://github.com/eyebluecn/tank/issues/220
|
||||
|
||||
1.Fix scan bug. https://github.com/eyebluecn/tank/issues/221 https://github.com/eyebluecn/tank/issues/220
|
||||
|
||||
|
||||
tank-4.0.0 2023-08-13
|
||||
1.增加空间概念,可以多人共同维护一个共享空间中的文件 #201
|
||||
2.新增粘贴上传文件功能 #188
|
||||
3.文件大小单位选择体验优化 #179
|
||||
4.支持使用url的方式抓取文件
|
||||
5.一些UI优化
|
||||
|
||||
1.Add space, supports multi users maintaining a shared space. #201
|
||||
2.Add the feature of uploading by pasting files. #188
|
||||
3.Human readable file size unit. #179
|
||||
4.Add the feature of uploading by url.
|
||||
6.Some user experience enhancement.
|
||||
|
||||
|
||||
tank-4.0.0.beta1 2023-07-22
|
||||
1. Shared space
|
||||
2. Copy and paste upload
|
||||
3. Crawl upload
|
||||
4. Space size selection control upgrade
|
||||
5. Some style modifications
|
||||
|
||||
|
||||
1. 共享空间
|
||||
2. 文件复制粘贴上传
|
||||
3. 文件抓取上传
|
||||
4. 空间大小选择控件升级
|
||||
5. 一些样式修改
|
||||
|
||||
|
||||
|
||||
tank-3.1.5 2022-03-21
|
||||
1. Support Sqlite.
|
||||
2. Upgrade webpack.
|
||||
|
||||
1. 支持Sqlite
|
||||
2. 升级了前端的webpack
|
||||
|
||||
|
||||
tank-3.1.4 2022-03-20
|
||||
1. Support Sqlite.
|
||||
2. Upgrade webpack.
|
||||
|
||||
1. 支持Sqlite
|
||||
2. 升级了前端的webpack
|
||||
|
||||
|
||||
|
||||
tank-3.1.3 2022-03-10
|
||||
1. Add kkfileview 3.x support
|
||||
2. Fix search bug https://github.com/eyebluecn/tank/issues/148
|
||||
3. Fix bug of totalSize in dashboard
|
||||
|
||||
1. 添加了kkfileview 3.x的预览支持
|
||||
2. 修复了一个搜索的bug https://github.com/eyebluecn/tank/issues/148
|
||||
3. 修复了文件大小统计的bug
|
||||
|
||||
|
||||
tank-3.1.2 2021-01-02
|
||||
1. Add scan manually once feature
|
||||
2. Add disable recycle bin feature
|
||||
3. WebDAV use hard delete now
|
||||
4. Support Chinese Username
|
||||
5. Normal user cannot change itself space limit
|
||||
6. Support the order sort by filename, size and update time
|
||||
7. Hide the side menu on phone by default
|
||||
8. Friendly hint for large file upload.
|
||||
9. Cancel during uploading.
|
||||
|
||||
1. 添加了手动扫描一次的功能
|
||||
2. 添加了禁用回收站功能
|
||||
3. WebDAV中的删除采用硬删除
|
||||
4. 支持中文的用户名
|
||||
5. 普通用户不能再修改自己的空间限制
|
||||
6. 文件支持按照名称排序,按照大小排序,按照修改日期排序
|
||||
7. 手机端默认隐藏左边菜单
|
||||
8. 大文件上传友好性提示
|
||||
9. 可以取消文件上传
|
||||
|
||||
|
||||
tank-3.1.1 2020-09-08
|
||||
1. Add upload folder feature.
|
||||
2. Fix the share auth bug.
|
||||
|
||||
1. 添加了文件夹上传功能
|
||||
2. 修复了分享时需要登陆的问题
|
||||
|
||||
tank-3.1.0
|
||||
1. Reconstruct frontend by typescript+react+antd.
|
||||
2. Enhance the webdav ability.
|
||||
3. Add charset in mysql config.
|
||||
4. Add preview_config.
|
||||
5. Add delete user feature.
|
||||
6. Add Scan config.
|
||||
7. Add recycle bin feature.
|
||||
|
||||
1. 前后进行了一次完全的重构。 采用Typescript+React+Antd
|
||||
2. 增强了WebDav的能力,现在能够适配更多的WebDav客户端了
|
||||
3. 数据库配置项中添加了编码支持,可以支持emoji了
|
||||
4. 添加了预览引擎配置,用户可以使用自己的引擎来预览特定格式文件
|
||||
5. 添加了删除用户的功能,删除用户后会清空用户所有的文件和痕迹
|
||||
6. 添加了扫描功能,可以定时同步物理文件到蓝眼云盘中
|
||||
7. 增加回收站功能
|
||||
|
||||
|
||||
2019-10-13
|
||||
tank-3.0.6
|
||||
1. Fix the Bug of limit size.
|
||||
2. Add the drag feature for uploading files.
|
||||
3. Fix the page bug of list.
|
||||
|
||||
2019-08-13
|
||||
tank-3.0.5
|
||||
1. Fix the Bug of sharing. [#56](https://github.com/eyebluecn/tank/issues/56)
|
||||
|
||||
2019-06-11
|
||||
tank-3.0.4
|
||||
1. Use relative assets in tank-front.
|
||||
2. Fix the total size check bug.
|
||||
3. Add feature. Creating user.
|
||||
|
||||
2019-05-31
|
||||
tank-3.0.3
|
||||
1. Add default utf8 charset when creating tables.
|
||||
2. Fix some i18n bug
|
||||
3. Add a document link in the preference page.
|
||||
|
||||
|
||||
2019-05-27
|
||||
tank-3.0.2
|
||||
1. fix https://github.com/eyebluecn/tank/issues/51
|
||||
2. fix https://github.com/eyebluecn/tank/issues/52
|
||||
3. fix i18n issue for moving files.
|
||||
|
||||
|
||||
2019-05-23
|
||||
tank-3.0.0
|
||||
1. 分享文件夹
|
||||
2. 使用口令提取分享的文件
|
||||
3. 允许用户自行注册
|
||||
4. 本地文件映射功能
|
||||
5. 存放的物理文件,按照物理目录排布
|
||||
6. 允许用户名进行登录
|
||||
7. 访问日志只保留7天数据
|
||||
8. 下载文件夹,下载文件夹大小设上限
|
||||
9. 支持Webdav
|
||||
10. 增加用户文件总大小,增加用户文件总大小限制
|
||||
11. 加入管理员变身功能。使用用户的身份进行登录。
|
||||
12. i18n
|
||||
|
||||
|
||||
2019-01-07
|
||||
tank-2.0.0
|
||||
1. 添加了图片文件裁剪图的缓存,全面提升缩略图的访问速度。
|
||||
2. 添加了用户访问时的日志,可以追踪到每个ip的访问,下载情况
|
||||
3. 添加常用文件的预览功能,图片,音频,视频,文档一键预览。
|
||||
4. 添加了大盘统计功能,每日访问情况,每日PV,UV一目了然。日环比,周环比数据清晰呈现。
|
||||
5. 安装过程全面升级,采用可视化的安装过程,真正做到了傻瓜式安装。安装过程中可以创建数据库表,可以指定管理员账号。
|
||||
6. UI风格进行了微调,色调更加沉稳大气,布局更加紧致。
|
||||
7. 搜索功能全面增强,可以从自己所有的文件中按名字搜索。
|
||||
8. 上传功能全面增强,可支持最多1000个文件同时上传,上传过程不会因为切换页面而打断。
|
||||
9. 网站的应用数据和普通文件可以分开管理,在网站偏好中可以自行设置其可见性。
|
||||
10. Docker全面瘦身,剥离了对MySQL的强依赖,使得Docker部署更为容易。
|
||||
11. 后端逻辑全面重新梳理,MVC过程更加严谨。日志,全局异常更加规范。做到每个错误可追踪。
|
||||
12. 对mysql的支持更全面,支持mysql5.5及以上版本。
|
||||
|
||||
|
||||
2018-07-25
|
||||
tank-1.0.5
|
||||
1. 添加了根据url抓取文件的功能。
|
||||
|
||||
|
||||
2018-07-03
|
||||
tank-1.0.4
|
||||
1. 添加了文件分段功能,支持断点续传。
|
||||
|
||||
|
||||
2018-04-12
|
||||
tank-1.0.3
|
||||
1. 添加了多文件同时上传的功能.
|
||||
2. 开发情况下有可能上传的文件路径没有权限,添加了更多提示.
|
||||
|
||||
|
||||
|
||||
2018-01-19
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# use golang 1.22.5
|
||||
FROM golang:1.22.5
|
||||
|
||||
# maintainer. Author's name and email.
|
||||
MAINTAINER eyeblue "eyebluecn@126.com"
|
||||
|
||||
# work directory.
|
||||
WORKDIR /data
|
||||
|
||||
# Copy this project to /data
|
||||
COPY . /data
|
||||
|
||||
# in order to make docker stateless. Prepare a volumn
|
||||
VOLUME /data/build/matter
|
||||
|
||||
# proxy
|
||||
ENV GOPROXY=https://goproxy.cn
|
||||
|
||||
# Handle time-zone
|
||||
ENV TZ=Asia/Shanghai
|
||||
RUN apt-get install -y tzdata
|
||||
|
||||
# prepare the config file
|
||||
RUN go build \
|
||||
&& cp -r /data/tank /data/build
|
||||
|
||||
# use 6010 as default.
|
||||
EXPOSE 6010
|
||||
|
||||
# tank as execute file.
|
||||
ENTRYPOINT ["/data/build/tank"]
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 蓝眼
|
||||
Copyright (c) 2017 eyebluecn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,190 +1,52 @@
|
||||
[](https://github.com/eyebluecn/tank)
|
||||
[](https://github.com/eyebluecn/tank)
|
||||
|
||||
# 蓝眼云盘
|
||||
[English Version](https://tank-doc.eyeblue.cn/en)
|
||||
|
||||
##### [在线Demo](http://tank.eyeblue.cn) (体验账号: demo@tank.eyeblue.cn 密码:123456)
|
||||
# 蓝眼云盘(4.2.0)
|
||||
[在线Demo](https://tanker.eyeblue.cn) (体验账号: demo 密码:123456)
|
||||
|
||||
##### [配套前端tank-front](https://github.com/eyebluecn/tank-front)
|
||||
蓝眼云盘是蓝眼开源系列代表作品之一,致力于打造精致,优雅,简约的云盘。核心功能如下:
|
||||
1. 文件列表
|
||||
2. 文件/文件夹上传 + 拖拽上传 + 分片/断点续传
|
||||
3. 共享空间
|
||||
3. 文件分享
|
||||
4. 文件监控统计
|
||||
5. 回收站
|
||||
6. 多用户
|
||||
7. [WebDav](https://tank-doc.eyeblue.cn/advance/webdav.html)
|
||||
8. [扫描磁盘任务](https://tank-doc.eyeblue.cn/advance/scan.html)
|
||||
9. [在线预览及自定义配置预览引擎](https://tank-doc.eyeblue.cn/advance/preview.html)
|
||||
10. 支持Sqlite和Mysql数据库用以存储文件元信息,Sqlite可以做到开箱即用。
|
||||
|
||||
|
||||
### 简介
|
||||
蓝眼云盘是 [蓝眼系列开源软件](https://github.com/eyebluecn) 之一,也是蓝眼系列其他软件的基础服务软件。蓝眼云盘具有以下几大特色:
|
||||
|
||||
**1. 软件体积小,跨平台,运行简单**
|
||||
|
||||
- 蓝眼云盘[安装包](https://github.com/eyebluecn/tank/releases) 6M左右,在`windows` `linux` `mac OS`操作系统中均可安装运行;
|
||||
|
||||
- 蓝眼云盘为绿色软件,将安装包解压缩,修改配置文件后即可一行命令立即运行。
|
||||
|
||||
**2. 使用方便,核心功能齐全**
|
||||
|
||||
- 蓝眼云盘主要支持pc web端,同时手机web也具有不错的响应性支持。
|
||||
|
||||
- 蓝眼云盘实现了云盘(如:[百度云盘](https://pan.baidu.com/),[微云](https://www.weiyun.com/))的核心功能:文件夹管理,文件管理,上传文件,下载文件,文件分享等。
|
||||
|
||||
- 蓝眼云盘提供能账号管理系统,超级管理员可以管理用户,查看用户文件,普通用户只能查看自己的文件,修改自己的资料。上面提供的体验账号就是一个普通用户的账号。
|
||||
|
||||
**3. 支持接口编程**
|
||||
|
||||
- 蓝眼云盘提供了[编程接口](https://github.com/eyebluecn/tank/blob/master/build/doc/alien_zh.md),实现了云存储(如:[七牛云](https://www.qiniu.com),[阿里云OSS](https://www.aliyun.com/product/oss))的核心功能,可以使用编程接口上传文件,作为其他网站、系统、app的资源存储器。可以在下载图片时对图片做缩放裁剪处理,可以有效地节省客户端流量。
|
||||
|
||||
- 蓝眼系列开源软件之二的[《蓝眼博客》](https://github.com/eyebluecn/blog)正是使用蓝眼云盘作为第三方资源存储器。蓝眼博客中的所有图片,附件均是存储在蓝眼云盘中。
|
||||
|
||||
**4. 前后端分离,文档丰富**
|
||||
|
||||
- 蓝眼云盘有详细的[后台api文档](https://github.com/eyebluecn/tank/blob/master/build/doc/api_zh.md),对于学习前端的童鞋而言可以快速部署一个正式而又具有丰富接口的后端供学习使用。
|
||||
|
||||
- 后端技术栈使用 `golang`,没有使用任何web框架;初始化安装,生命周期控制,路由管理,路由匹配,日志管理,依赖注入,错误处理,panic拦截,打包,安装脚本等功能全采用纯手动打造,绿色环保,因此代码更精炼,更具有探讨学习的价值。
|
||||
|
||||
如果您觉得蓝眼云盘对您有帮助,请不要吝惜您的star <i class="fa fa-star"></i>
|
||||
[更多内容请移步至文档](https://tank-doc.eyeblue.cn/)
|
||||
|
||||
### 软件截图
|
||||
|
||||

|
||||
#### PC端截图
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
### 安装
|
||||

|
||||
|
||||
** a) 准备工作 **
|
||||
#### 手机端截图
|
||||
|
||||
1. 一台windows/linux服务器,当然你可以使用自己的电脑充当这台服务器
|
||||

|
||||
|
||||
2. [安装好Mysql数据库](https://www.mysql.com/downloads/)
|
||||
|
||||
3. [在这里](https://github.com/eyebluecn/tank/releases)下载服务器对应的安装包
|
||||
## [安装文档](https://tank-doc.eyeblue.cn/basic/install.html)
|
||||
|
||||
4. 在服务器上解压缩,修改配置文件`conf/tank.json`,各项说明如下:
|
||||
|
||||
```
|
||||
{
|
||||
//服务器运行的端口,默认6010。如果配置为80,则可直接用http打开
|
||||
"ServerPort": 6010,
|
||||
//日志是否需要打印到控制台,默认false,主要用于调试
|
||||
"LogToConsole": false,
|
||||
//Mysql端口,默认3306
|
||||
"MysqlPort": 3306,
|
||||
//Mysql主机
|
||||
"MysqlHost": "127.0.0.1",
|
||||
//Mysql数据库名称
|
||||
"MysqlSchema": "tank",
|
||||
//Mysql用户名,建议为蓝眼云盘创建一个用户,不建议使用root
|
||||
"MysqlUserName": "tank",
|
||||
//Mysql密码
|
||||
"MysqlPassword": "tank123",
|
||||
//超级管理员用户名,只能是字母和数字
|
||||
"AdminUsername": "admin",
|
||||
//超级管理员邮箱,作为登录的账号
|
||||
"AdminEmail": "admin@tank.eyeblue.cn",
|
||||
//超级管理员密码
|
||||
"AdminPassword": "123456"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
** b) 运行 **
|
||||
|
||||
- windows平台直接双击应用目录下的`tank.exe`。
|
||||
|
||||
- linux平台执行
|
||||
|
||||
```
|
||||
cd 应用目录路径
|
||||
./tank
|
||||
```
|
||||
|
||||
如果你希望关闭shell窗口后,应用依然运行,请使用以下脚本启动和停止
|
||||
### 快速运行
|
||||
安装依赖
|
||||
```shell
|
||||
# 启动应用
|
||||
cd 应用目录路径/service
|
||||
./startup.sh
|
||||
|
||||
# 停止应用
|
||||
cd 应用目录路径/service
|
||||
./shutdown.sh
|
||||
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
** c) 验证 **
|
||||
|
||||
浏览器中打开 http://127.0.0.1:6010 (127.0.0.1请使用服务器所在ip,6010请使用`tank.json`中配置的`ServerPort`) 可以看到登录页面,并且使用配置文件中的邮箱和密码登录成功后可以看到全部文件(见上文截图)即表示安装成功。
|
||||
|
||||
|
||||
### 使用源代码自行打包
|
||||
|
||||
|
||||
**前端项目打包**
|
||||
1. clone  [tank-front](https://github.com/eyebluecn/tank-front)
|
||||
|
||||
2. 安装依赖项
|
||||
运行main文件即可:
|
||||
```shell
|
||||
./main.go
|
||||
```
|
||||
npm install
|
||||
```
|
||||
3. 执行打包命令
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
4. 通过前面三步可以在`dist`文件夹下得到打包后的静态文件,将`dist`目录下的所有文件拷贝到后端项目的`build/html`文件夹下。(下文的工程目录中也有说明)
|
||||
|
||||
**后端项目打包**
|
||||
|
||||
1. clone  [tank](https://github.com/eyebluecn/tank)
|
||||
|
||||
2. 安装Golang,环境变量`GOPATH`配置到工程目录,建议工程目录结构如下:
|
||||
|
||||
```
|
||||
golang #环境变量GOPATH所在路径
|
||||
├── bin #编译生成的可执行文件目录
|
||||
├── pkg #编译生成第三方库
|
||||
├── src #golang工程源代码
|
||||
│ ├── github.com #来自github的第三方库
|
||||
│ ├── golang.org #来自golang.org的第三方库
|
||||
│ ├── tank #clone下来的tank根目录
|
||||
│ │ ├── build #用来辅助打包的文件夹
|
||||
│ │ │ ├── conf #默认的配置文件
|
||||
│ │ │ ├── doc #文档
|
||||
│ │ │ ├── html #前端静态资源,从项目tank-front编译获得
|
||||
│ │ │ ├── pack #打包的脚本
|
||||
│ │ │ ├── service #将tank当作服务启动的脚本
|
||||
│ │ ├── dist #运行打包脚本后获得的安装包目录
|
||||
│ │ ├── rest #golang源代码
|
||||
|
||||
```
|
||||
|
||||
3. 准备项目依赖的第三方库
|
||||
|
||||
- golang.org/x
|
||||
- github.com/disintegration/imaging
|
||||
- github.com/json-iterator/go
|
||||
- github.com/go-sql-driver/mysql
|
||||
- github.com/jinzhu/gorm
|
||||
- github.com/nu7hatch/gouuid
|
||||
|
||||
其中`golang.org/x`国内无法下载,请从[这里](https://github.com/eyebluecn/golang.org)下载,并按上文推荐的目录结构放置。其余依赖项均可通过安装脚本自动下载。
|
||||
|
||||
4. 打包
|
||||
|
||||
- windows平台双击运行 `tank/build/pack/build.bat`,成功之后可在`tank/dist`下看到`tank-x.x.x`文件夹,该文件夹即为最终安装包。
|
||||
|
||||
- linux平台运行如下命令:
|
||||
```
|
||||
cd tank/build/pack/
|
||||
./build.sh
|
||||
```
|
||||
成功之后可在`tank/dist`下看到`tank-x.x.x.linux-amd64.tar.gz`
|
||||
|
||||
利用得到的安装包即可参考上文的`安装`一节进行安装。
|
||||
|
||||
|
||||
### 相关文档
|
||||
|
||||
[蓝眼云盘后端api](https://github.com/eyebluecn/tank/blob/master/build/doc/api_zh.md)
|
||||
|
||||
[蓝眼云盘编程接口](https://github.com/eyebluecn/tank/blob/master/build/doc/alien_zh.md)
|
||||
|
||||
[快速使用Let's Encrypt开启个人网站的https](https://blog.eyeblue.cn/home/article/9f580b3f-5679-4a9d-be6f-4d9f0dd417af)
|
||||
|
||||
### Contribution
|
||||
|
||||
@@ -192,6 +54,19 @@ cd tank/build/pack/
|
||||
|
||||
如果您也想参与进来,请尽情的fork, star, post issue, pull requests
|
||||
|
||||
当然你可以加入钉钉群(一群已满员)一起直接交流,在钉钉群中可以获取最新beta版本。
|
||||
|
||||

|
||||
|
||||
群号:44754005
|
||||
|
||||
|
||||
### Support
|
||||
IDE for this project is supported by [Jetbrains](https://jb.gg/OpenSourceSupport).
|
||||
|
||||
[](https://jb.gg/OpenSourceSupport)
|
||||
|
||||
|
||||
### License
|
||||
|
||||
[MIT](http://opensource.org/licenses/MIT)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| master | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
We strongly encourage you to report security vulnerabilities to
|
||||
our private security mailing list: security@cilium.io - first, before
|
||||
disclosing them in any public forums.
|
||||
|
||||
This is a private mailing list where only members of the Cilium internal
|
||||
security team are subscribed to, and is treated as top priority.
|
||||
@@ -1,12 +0,0 @@
|
||||
server{
|
||||
listen 80;
|
||||
server_name tank.zicpo.cn;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:6010;
|
||||
proxy_set_header host $host;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_pass_request_headers on;
|
||||
client_max_body_size 2048m;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,4 @@
|
||||
{
|
||||
"ServerPort": 6010,
|
||||
"LogToConsole": false,
|
||||
"MysqlPort": 3306,
|
||||
"MysqlHost": "127.0.0.1",
|
||||
"MysqlSchema": "tank",
|
||||
"MysqlUserName": "tank",
|
||||
"MysqlPassword": "tank123",
|
||||
"AdminUsername": "admin",
|
||||
"AdminEmail": "admin@tank.eyeblue.cn",
|
||||
"AdminPassword": "123456"
|
||||
"MatterPath": ""
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# Eyeblue Tank
|
||||
|
||||
> The document is comming...
|
||||
@@ -1,3 +0,0 @@
|
||||
# 蓝眼云盘
|
||||
|
||||
> 详细文档正在撰写中,敬请期待...
|
||||
@@ -1,132 +0,0 @@
|
||||
# 蓝眼云盘编程接口
|
||||
|
||||
- 蓝眼云盘提供了[编程接口](https://github.com/eyebluecn/tank/blob/master/build/doc/alien_zh.md),实现了云存储(如:[七牛云](https://www.qiniu.com),[阿里云OSS](https://www.aliyun.com/product/oss))的核心功能,可以使用编程接口上传文件,作为其他网站、系统、app的资源存储器。可以在下载图片时对图片做缩放裁剪处理,可以有效地节省客户端流量。
|
||||
|
||||
- 蓝眼系列开源软件之二的[《蓝眼博客》](https://github.com/eyebluecn/blog)正是使用蓝眼博客作为第三方资源存储器。蓝眼博客中的所有图片,附件均是存储在蓝眼云盘中。
|
||||
|
||||
所有的编程接口均定义在`alien_controller`中,主要包括以下几个接口:
|
||||
|
||||
`/api/alien/fetch/upload/token` 获取上传token
|
||||
|
||||
`/api/alien/fetch/download/token` 获取下载token
|
||||
|
||||
`/api/alien/confirm` 来蓝眼云盘确认文件
|
||||
|
||||
`/api/alien/upload` 使用form表单上传文件
|
||||
|
||||
`/api/alien/download/{uuid}/{filename}` 下载文件
|
||||
|
||||
### 上传时序图
|
||||
|
||||

|
||||
|
||||
### 下载时序图
|
||||
|
||||

|
||||
|
||||
### 接口详情
|
||||
|
||||
#### /api/alien/fetch/upload/token
|
||||
功能:一个蓝眼云盘受信任的用户请求一个`UploadToken`,用于给另一个用户向蓝眼云盘上传文件。
|
||||
|
||||
一般的使用场景是`应用服务器`向`蓝眼云盘`请求`UploadToken`,然后将此`UploadToken`交由`浏览器`去向`蓝眼云盘`上传文件。
|
||||
|
||||
参数 | 类型 | 描述
|
||||
--------- | ---- | -----------
|
||||
email | `string` | 【必填】邮箱,用于确定请求者身份
|
||||
password | `string` | 【必填】密码,用于确定请求者身份
|
||||
filename | `string` | 【必填】即将上传的文件名,不能包含以下特殊符号:`< > \| * ? / \`
|
||||
expire | `int` | 【选填】UploadToken过期时间,单位:s。默认 86400s 即24h
|
||||
privacy | `bool` | 【必填】文件的共有性。`true`表示文件私有,下载时必须要DownloadToken. `false`表示文件公有,任何人可以通过下载链接直接下载
|
||||
size | `int` | 【必填】文件的大小。单位:byte
|
||||
dir | `string` | 【必填】文件存放的路径。不能为空,必须以`/`开头,不能出现连续的`//`,不能包含以下特殊符号:`< > \| * ? \`。举例:`/app/blog/20180101121212001`
|
||||
|
||||
#### /api/alien/upload
|
||||
|
||||
功能:浏览器拿着`UploadToken`通过FormData向蓝眼云盘上传文件。
|
||||
|
||||
一般的使用场景是`应用服务器`向`蓝眼云盘`请求`UploadToken`,然后将此`UploadToken`交由`浏览器`去向`蓝眼云盘`上传文件。由于在请求`UploadToken`的时候已经传入了文件元信息,因此这里的文件信息必须要和`/api/alien/fetch/upload/token`传入的参数信息一致。
|
||||
|
||||
参数 | 类型 | 描述
|
||||
--------- | ---- | -----------
|
||||
uploadTokenUuid | `string` | 【必填】uploadToken标识,`/api/alien/fetch/upload/token`请求返回对象中的`uuid`
|
||||
file | `file` | 【必填】文件,在浏览器中是通过`<input type="file" name="file"/>`来选择的
|
||||
|
||||
#### /api/alien/confirm
|
||||
|
||||
功能:`应用服务器`向蓝眼云盘确认某个文件是否确实已经上传好了。
|
||||
|
||||
参数 | 类型 | 描述
|
||||
--------- | ---- | -----------
|
||||
email | `string` | 【必填】邮箱,用于确定请求者身份
|
||||
password | `string` | 【必填】密码,用于确定请求者身份
|
||||
matterUuid | `string` | 【必填】浏览器上传完毕后,蓝眼云盘返回给浏览器的`uuid`
|
||||
|
||||
#### /api/alien/fetch/download/token
|
||||
|
||||
功能:一个蓝眼云盘受信任的用户请求一个`DownloadToken`,用于给另一个用户下载蓝眼云盘上的私有文件。
|
||||
|
||||
一般的使用场景是`应用服务器`向`蓝眼云盘`请求`DownloadToken`,然后将此`DownloadToken`交由`浏览器`去向`蓝眼云盘`下载文件。
|
||||
|
||||
参数 | 类型 | 描述
|
||||
--------- | ---- | -----------
|
||||
email | `string` | 【必填】邮箱,用于确定请求者身份
|
||||
password | `string` | 【必填】密码,用于确定请求者身份
|
||||
matterUuid | `string` | 【必填】文件uuid,要想下载的文件`uuid`
|
||||
expire | `int` | 【选填】UploadToken过期时间,单位:s。默认 86400s 即24h
|
||||
|
||||
|
||||
#### /api/alien/download/{uuid}/{filename}
|
||||
|
||||
功能:在浏览器中下载文件
|
||||
|
||||
这个接口既可以下载公有文件,又可以下载私有文件。同时对于图片文件还可以做裁剪缩放等操作。
|
||||
|
||||
参数 | 类型 | 描述
|
||||
--------- | ---- | -----------
|
||||
uuid | `string` | 【必填】文件的uuid,该参数放在url的路径中
|
||||
filename | `string` | 【必填】文件的名称,该参数放在url的路径中
|
||||
downloadTokenUuid | `string` | 【选填】download的uuid,如果是私有文件该参数必须,公有文件无需填写。
|
||||
|
||||
该接口同时还可以对图片进行缩放预处理
|
||||
> 图片缩放支持的格式有:".jpg", ".jpeg", ".png", ".tif", ".tiff", ".bmp", ".gif"
|
||||
|
||||
##### 额外参数
|
||||
|
||||
| 参数 | 类型 | 描述 | 取值范围 |
|
||||
| ------------ | ---- | ------------ | ------------ |
|
||||
| imageProcess | `string` | 指定图片处理的方式,对于图片缩放固定为`resize` | 固定为`resize` |
|
||||
| imageResizeM | `string` | 指定图片缩放的策略,有三种策略,`fit` 表示固定一边,另一边按比例缩放;`fill`表示先将图片延伸出指定W与H的矩形框外,然后进行居中裁剪;`fixed`表示直接按照指定的W和H缩放图片,这种方式可能导致图片变形 | [`fit`,`fill`,`fixed`] 不填默认`fit` |
|
||||
| imageResizeW | `int` | 指定的宽度,对于`fit`可以不指定 | 1 ~ 4096 |
|
||||
| imageResizeH | `int` | 指定的高度,对于`fit`可以不指定 | 1 ~ 4096 |
|
||||
|
||||
##### 示例
|
||||
|
||||
原图:
|
||||
|
||||

|
||||
|
||||
1. 将宽度指定为200,高度等比例缩放
|
||||
|
||||

|
||||
|
||||
[http://tank.eyeblue.cn/api/alien/download/3f4b3090-e688-4d63-7705-93a120690505/horse.jpg?imageProcess=resize&imageResizeM=fit&imageResizeW=200](http://tank.eyeblue.cn/api/alien/download/3f4b3090-e688-4d63-7705-93a120690505/horse.jpg?imageProcess=resize&imageResizeM=fit&imageResizeW=200)
|
||||
|
||||
2. 将高度指定为200,宽度等比例缩放
|
||||
|
||||

|
||||
|
||||
[http://tank.eyeblue.cn/api/alien/download/3f4b3090-e688-4d63-7705-93a120690505/horse.jpg?imageProcess=resize&imageResizeM=fit&imageResizeH=200](http://tank.eyeblue.cn/api/alien/download/3f4b3090-e688-4d63-7705-93a120690505/horse.jpg?imageProcess=resize&imageResizeM=fit&imageResizeH=200)
|
||||
|
||||
|
||||
3. 图片自动填充在200*200的大小中 (这种情况用得最多)
|
||||
|
||||

|
||||
|
||||
[http://tank.eyeblue.cn/api/alien/download/3f4b3090-e688-4d63-7705-93a120690505/horse.jpg?imageProcess=resize&imageResizeM=fill&imageResizeW=200&imageResizeH=200](http://tank.eyeblue.cn/api/alien/download/3f4b3090-e688-4d63-7705-93a120690505/horse.jpg?imageProcess=resize&imageResizeM=fill&imageResizeW=200&imageResizeH=200)
|
||||
|
||||
4. 图片固定大小200*200 (一般会导致变形)
|
||||
|
||||

|
||||
|
||||
[http://tank.eyeblue.cn/api/alien/download/3f4b3090-e688-4d63-7705-93a120690505/horse.jpg?imageProcess=resize&imageResizeM=fixed&imageResizeW=200&imageResizeH=200](http://tank.eyeblue.cn/api/alien/download/3f4b3090-e688-4d63-7705-93a120690505/horse.jpg?imageProcess=resize&imageResizeM=fixed&imageResizeW=200&imageResizeH=200)
|
||||
@@ -1,798 +0,0 @@
|
||||
|
||||
# 蓝眼云盘api接口
|
||||
|
||||
|
||||
|
||||
|
||||
## 一、实体
|
||||
|
||||
在详细介绍各controller中的接口前,有必要先介绍蓝眼云盘中的各实体,所有的实体基类均为`Base`
|
||||
|
||||
#### Base
|
||||
|
||||
`Base`定义如下,所有会在数据库中持久化的实体均会继承`Base`,`Controller`在返回实体给前端时,会将字段和值序列化成json字符串,其中键就和每个实体字段后面的`json`标签一致,下文也会有详细例子介绍
|
||||
|
||||
```
|
||||
type Base struct {
|
||||
//唯一标识
|
||||
Uuid string `gorm:"primary_key" json:"uuid"`
|
||||
//排序用的字段,一般是时间戳来表示序号先后
|
||||
Sort int64 `json:"sort"`
|
||||
//修改时间
|
||||
ModifyTime time.Time `json:"modifyTime"`
|
||||
//创建时间
|
||||
CreateTime time.Time `json:"createTime"`
|
||||
}
|
||||
```
|
||||
|
||||
#### Preference
|
||||
|
||||
`Preference`是整个网站的偏好设置,网站的名称,logo,favicon,版权,备案号等信息均由这个实体负责。定义如下:
|
||||
|
||||
```
|
||||
type Preference struct {
|
||||
//继承Base,也就是说Base中的Uuid,Sort,ModifyTime,CreateTime这里也会有
|
||||
Base
|
||||
//网站名称
|
||||
Name string `json:"name"`
|
||||
//网站的logo url
|
||||
LogoUrl string `json:"logoUrl"`
|
||||
//网站的favicon.ico url
|
||||
FaviconUrl string `json:"faviconUrl"`
|
||||
//网站下方第一行信息,一般是版权信息
|
||||
FooterLine1 string `json:"footerLine1"`
|
||||
//网站下方的第二行信息,一般是本案信息
|
||||
FooterLine2 string `json:"footerLine2"`
|
||||
//当前运行的蓝眼博客版本,这个字段不可修改,每次发版时硬编码
|
||||
Version string `json:"version"`
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### Matter
|
||||
|
||||
`Matter`是代表文件(文件夹是一种特殊的文件),为了和系统的`file`重复,这里使用`matter`,这个实体是蓝眼云盘最重要的实体:
|
||||
|
||||
```
|
||||
type Matter struct {
|
||||
//继承Base,也就是说Base中的Uuid,Sort,ModifyTime,CreateTime这里也会有
|
||||
Base
|
||||
//所在的文件夹的uuid,如果在根目录下,这个字段为 root
|
||||
Puuid string `json:"puuid"`
|
||||
//创建这个文件的用户uuid
|
||||
UserUuid string `json:"userUuid"`
|
||||
//该文件是否是文件夹
|
||||
Dir bool `json:"dir"`
|
||||
//该文件是否是应用文件,比如用户上传的头像这个字段就为true. 一般上传的文件就为false
|
||||
Alien bool `json:"alien"`
|
||||
//文件名,带后缀名。例如:avatar.jpg
|
||||
Name string `json:"name"`
|
||||
//文件的md5值,目前该功能尚未实现,作为保留字段
|
||||
Md5 string `json:"md5"`
|
||||
//文件大小,单位 byte。比如某个文件1M大,那么这里就为: 1048576
|
||||
Size int64 `json:"size"`
|
||||
//文件是否为私有,如果true则该文件只能作者或超级管理员可以下载,如果false所有人均可以通过下载链接下载。
|
||||
Privacy bool `json:"privacy"`
|
||||
//文件在磁盘中的路径,前端无需关心这个字段。但是后端在寻找文件时这个字段非常关键。
|
||||
Path string `json:"path"`
|
||||
//该文件的父级matter,该字段不会持久化到数据集,属于获取matter详情时临时组装出来的。
|
||||
Parent *Matter `gorm:"-" json:"parent"`
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### User
|
||||
|
||||
`User`是代表用户:
|
||||
|
||||
```
|
||||
type User struct {
|
||||
//继承Base,也就是说Base中的Uuid,Sort,ModifyTime,CreateTime这里也会有
|
||||
Base
|
||||
//角色,有以下枚举值:GUEST(游客,不会持久化到数据库),USER(普通用户),ADMINISTRATOR(超级管理员)
|
||||
Role string `json:"role"`
|
||||
//用户名,在Matter的path字段中很有用。
|
||||
Username string `json:"username"`
|
||||
//密码,默认不会返回给前端
|
||||
Password string `json:"-"`
|
||||
//邮箱,作为登录时的账户
|
||||
Email string `json:"email"`
|
||||
//手机
|
||||
Phone string `json:"phone"`
|
||||
//性别,有以下枚举值:MALE(男性),FEMALE(女性),UNKNOWN(未知)
|
||||
Gender string `json:"gender"`
|
||||
//城市
|
||||
City string `json:"city"`
|
||||
//头像Url
|
||||
AvatarUrl string `json:"avatarUrl"`
|
||||
//上次登录时的ip
|
||||
LastIp string `json:"lastIp"`
|
||||
//上次登录的时间
|
||||
LastTime time.Time `json:"lastTime"`
|
||||
//该用户允许上传的单文件最大大小
|
||||
SizeLimit int64 `json:"sizeLimit"`
|
||||
//状态,有以下枚举值:OK(正常),DISABLED(被禁用)
|
||||
Status string `json:"status"`
|
||||
}
|
||||
```
|
||||
|
||||
### UploadToken
|
||||
|
||||
用于给陌生人上传的token
|
||||
|
||||
```
|
||||
type UploadToken struct {
|
||||
//继承Base,也就是说Base中的Uuid,Sort,ModifyTime,CreateTime这里也会有
|
||||
Base
|
||||
//颁发该token的用户,系统中任何用户都能颁发token
|
||||
UserUuid string `json:"userUuid"`
|
||||
//使用这个token上传文件就必须上传在这个文件夹下
|
||||
FolderUuid string `json:"folderUuid"`
|
||||
//陌生人上传好了的文件uuid
|
||||
MatterUuid string `json:"matterUuid"`
|
||||
//过期时间
|
||||
ExpireTime time.Time `json:"expireTime"`
|
||||
//使用这个token上传文件就必须是这个文件名
|
||||
Filename string `json:"filename"`
|
||||
//使用这个token上传文件就必须是这个公私有性
|
||||
Privacy bool `json:"privacy"`
|
||||
//使用这个token上传文件就必须这个大小
|
||||
Size int64 `json:"size"`
|
||||
//使用这个token上传文件陌生人的ip
|
||||
Ip string `json:"ip"`
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### DownloadToken
|
||||
|
||||
用于给陌生人下载的token,一个matter如果Privacy=true,那么就意味着只有自己或者超级管理员可以下载,如果让某些自己信任的用户也能下载,那么就需要生成`DownloadToken`给这些用户来下载。
|
||||
|
||||
```
|
||||
type DownloadToken struct {
|
||||
//继承Base,也就是说Base中的Uuid,Sort,ModifyTime,CreateTime这里也会有
|
||||
Base
|
||||
//颁发该token的用户
|
||||
UserUuid string `json:"userUuid"`
|
||||
//该token只能下载这个文件
|
||||
MatterUuid string `json:"matterUuid"`
|
||||
//有效期截止
|
||||
ExpireTime time.Time `json:"expireTime"`
|
||||
//下载者的ip
|
||||
Ip string `json:"ip"`
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Pager
|
||||
|
||||
在前端请求一个列表时,通常返回的都是一个`Pager`,`Pager`中就是装的各个实体的列表。
|
||||
|
||||
```
|
||||
type Pager struct {
|
||||
//当前页数,0基
|
||||
Page int `json:"page"`
|
||||
//每页的大小
|
||||
PageSize int `json:"pageSize"`
|
||||
//总的条目数
|
||||
TotalItems int `json:"totalItems"`
|
||||
//总的页数
|
||||
TotalPages int `json:"totalPages"`
|
||||
//实体的数组
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
```
|
||||
|
||||
### WebResult
|
||||
|
||||
`WebResult`并不是会持久化到数据库中实体,`WebResult`是在`controller`返回数据给前端时包装的一层,有了`WebResult`后每个接口返回的数据会更加统一,方便了前端的统一处理。
|
||||
|
||||
```
|
||||
type WebResult struct {
|
||||
//状态码,具体每个码的意义参考下文
|
||||
Code int `json:"code"`
|
||||
//一句话描述请求结果,通常会是出错时指明出错原因,或者修改权限等小操作时提示的`操作成功`
|
||||
Msg string `json:"msg"`
|
||||
//内容可能是一个实体,也可能是一个 Pager.
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
状态码对应关系如下:
|
||||
|
||||
```
|
||||
const (
|
||||
//正常
|
||||
RESULT_CODE_OK = 200
|
||||
//未登录
|
||||
RESULT_CODE_LOGIN = -400
|
||||
//没有权限
|
||||
RESULT_CODE_UNAUTHORIZED = -401
|
||||
//请求错误
|
||||
RESULT_CODE_BAD_REQUEST = -402
|
||||
//没有找到
|
||||
RESULT_CODE_NOT_FOUND = -404
|
||||
//登录过期
|
||||
RESULT_CODE_LOGIN_EXPIRED = -405
|
||||
//该登录用户不是有效用户
|
||||
RESULT_CODE_LOGIN_INVALID = -406
|
||||
//提交的表单验证不通过
|
||||
RESULT_CODE_FORM_INVALID = -410
|
||||
//请求太频繁
|
||||
RESULT_CODE_FREQUENCY = -420
|
||||
//服务器出错。
|
||||
RESULT_CODE_SERVER_ERROR = -500
|
||||
//远程服务不可用
|
||||
RESULT_CODE_NOT_AVAILABLE = -501
|
||||
//并发异常
|
||||
RESULT_CODE_CONCURRENCY = -511
|
||||
//远程微服务没有找到
|
||||
RESULT_CODE_SERVICE_NOT_FOUND = -600
|
||||
//远程微服务连接超时
|
||||
RESULT_CODE_SERVICE_TIME_OUT = -610
|
||||
//通用的异常
|
||||
RESULT_CODE_UTIL_EXCEPTION = -700
|
||||
)
|
||||
```
|
||||
|
||||
## 二、返回规范
|
||||
|
||||
蓝眼云盘采用前后端分离的模式,前端调用后端接口时,url均以`/api`开头,返回均是json字符串。
|
||||
|
||||
- 返回的json字符串的key均为小写开头的驼峰法,具体参考实体类中`json`标签
|
||||
|
||||
- 返回的时间格式均为 `YYYY-MM-dd HH:mm:ss`(例如:2018-01-06 17:57:00)
|
||||
|
||||
返回内容均是由`WebResult`进行包装,因此具有高度的统一性,在这里我们约定一些说法,后面介绍`Controller`时便不再赘述。
|
||||
|
||||
1. 返回一个`XX`实体
|
||||
|
||||
指的是`WebResult`的`Code=200`, `Data=一个XX实体对象`。
|
||||
|
||||
例:返回一个User,则前端会收到以下json字符串:
|
||||
```
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "",
|
||||
"data": {
|
||||
"uuid": "eed2c66d-1de6-47ff-645e-b67beaa10365",
|
||||
"sort": 1514803034507,
|
||||
"modifyTime": "2018-01-06 18:00:58",
|
||||
"createTime": "2018-01-01 18:37:15",
|
||||
"role": "USER",
|
||||
"username": "demo",
|
||||
"email": "demo@tank.eyeblue.cn",
|
||||
"phone": "",
|
||||
"gender": "UNKNOWN",
|
||||
"city": "",
|
||||
"avatarUrl": "/api/alien/download/ea490cb6-368e-436d-71c0-fcfb08854c80/1180472.png",
|
||||
"lastIp": "124.78.220.82",
|
||||
"lastTime": "2018-01-06 18:00:58",
|
||||
"sizeLimit": 1048576,
|
||||
"status": "OK"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. 返回`XX`的`Pager`
|
||||
|
||||
指的是`WebResult`的`Code=200`, `Data=XX的Pager`。
|
||||
|
||||
例:返回`User`的`Pager`,则前端会收到以下json字符串:
|
||||
```
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "",
|
||||
"data": {
|
||||
"page": 0,
|
||||
"pageSize": 10,
|
||||
"totalItems": 2,
|
||||
"totalPages": 1,
|
||||
"data": [
|
||||
{
|
||||
"uuid": "6a661938-8289-4957-4096-5a1b584bf371",
|
||||
"sort": 1515057859613,
|
||||
"modifyTime": "2018-01-04 17:26:01",
|
||||
"createTime": "2018-01-04 17:24:20",
|
||||
"role": "ADMINISTRATOR",
|
||||
"username": "simba",
|
||||
"email": "y******5@163.com",
|
||||
"phone": "",
|
||||
"gender": "MALE",
|
||||
"city": "",
|
||||
"avatarUrl": "/api/alien/download/d1e453cb-3170-4bdb-73f2-fa0372ee017b/1180480.png",
|
||||
"lastIp": "180.173.103.207",
|
||||
"lastTime": "2018-01-04 17:26:01",
|
||||
"sizeLimit": -1,
|
||||
"status": "OK"
|
||||
},
|
||||
{
|
||||
"uuid": "e59be6a3-f806-463e-553a-4c5892eedf78",
|
||||
"sort": 1514881002975,
|
||||
"modifyTime": "2018-01-02 16:16:43",
|
||||
"createTime": "2018-01-02 16:16:43",
|
||||
"role": "USER",
|
||||
"username": "blog_dev",
|
||||
"email": "b*****@tank.eyeblue.cn",
|
||||
"phone": "",
|
||||
"gender": "MALE",
|
||||
"city": "",
|
||||
"avatarUrl": "/api/alien/download/fdca6eee-d009-4eb3-5ad4-15ba3701cb2e/jump.jpg",
|
||||
"lastIp": "",
|
||||
"lastTime": "2018-01-02 16:16:43",
|
||||
"sizeLimit": 1048576,
|
||||
"status": "OK"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
3. 返回错误信息:yyy
|
||||
|
||||
指的是`WebResult`的`Code=-400`, `Msg=yyy`。(这里的Code具体值参考上文的code表)
|
||||
|
||||
例:返回错误信息:"【新建文件夹】已经存在了,请使用其他名称。",则前端会收到以下json字符串:
|
||||
```
|
||||
{
|
||||
"code": -700,
|
||||
"msg": "【新建文件夹】已经存在了,请使用其他名称。",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
4. 返回成功信息:zzz
|
||||
|
||||
指的是`WebResult`的`Code=200`, `Msg=zzz`。(这里的Code具体值参考上文的code表)
|
||||
|
||||
例:返回成功信息:"删除成功。",则前端会收到以下json字符串:
|
||||
```
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "删除成功。",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 三、接口
|
||||
|
||||
蓝眼云盘所有的接口均定义在`controller`中,总共定义了以下`controller`:
|
||||
|
||||
名称 | 所在文件 | 描述
|
||||
--------- | ---- | -----------
|
||||
PreferenceController | `preference_controller.go` | 网站标题,logo,版权说明等信息的增删改查
|
||||
MatterController | `matter_controller.go` | 站内创建文件夹,上传文件,删除文件,修改权限等
|
||||
UserController | `user_controller.go` | 登录,管理操作站内用户
|
||||
AlienController | `alien_controller.go` | 第三方授权上传,下载,预处理
|
||||
|
||||
每个接口都有不同的访问级别,系统中定义了三种访问级别,分别是:
|
||||
|
||||
`游客` < `注册用户` < `管理员`
|
||||
|
||||
### PreferenceController
|
||||
|
||||
该Controller负责网站中的偏好设置,主要操作`Preference`实体
|
||||
|
||||
----------
|
||||
|
||||
#### /api/preference/fetch
|
||||
|
||||
**功能**:读取网站偏好设置,网站名称,logo,版权,备案信息均从此接口读取。
|
||||
|
||||
**访问级别**:`游客`,`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:无
|
||||
|
||||
**返回**: 一个`Preference`实体
|
||||
|
||||
|
||||
----------
|
||||
|
||||
|
||||
#### /api/preference/edit
|
||||
|
||||
**功能**:编辑网站偏好设置,修改网站名称,logo,版权,备案信息。
|
||||
|
||||
**访问级别**:`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
name | `string` | 必填 | 网站名称
|
||||
logoUrl | `string` | 选填 | 网站logoUrl,如果不填默认使用蓝眼云盘logo
|
||||
faviconUrl | `string` | 选填 | 网站faviconUrl,如果不填默认使用蓝眼云盘favicon.ico
|
||||
footerLine1 | `string` | 选填 | 网站版权所有信息
|
||||
footerLine2 | `string` | 选填 | 网站备案信息
|
||||
|
||||
**返回**: 一个`Preference`实体
|
||||
|
||||
----------
|
||||
|
||||
### MatterController
|
||||
|
||||
该Controller负责站内创建文件夹,上传文件,删除文件,修改权限等,主要操作`Matter`实体
|
||||
|
||||
----------
|
||||
|
||||
#### /api/matter/create/directory
|
||||
|
||||
**功能**:创建文件夹
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
puuid | `string` | 必填 | 准备创建的目录所在的目录,如果在根目录下创建传`root`
|
||||
name | `string` | 必填 | 文件夹名称, 不能包含以下特殊符号:`< > \| * ? / \`
|
||||
|
||||
**返回**: 新建的这个文件夹的`Matter`实体
|
||||
|
||||
----------
|
||||
|
||||
|
||||
#### /api/matter/upload
|
||||
|
||||
**功能**:上传文件
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
userUuid | `string` | 选填 | 该文件的归属人,如果不填则使用当前登录的用户uuid;如果是管理员要给用户A上传文件,那么这里应该填A的uuid.
|
||||
alien | `bool` | 选填 | 是否是应用数据,true表示应用数据,这时会自动放置在`应用数据`这个文件夹下,比如上传头像。false表示非应用数据,这时`puuid`字段为必填
|
||||
puuid | `bool` | 选填 | 文件上传到哪个目录下。 如果`alien`=false,这个字段必填。
|
||||
privacy | `bool` | 选填 | 文件的私有性,默认`false`
|
||||
file | `file` | 必填 | 文件,在浏览器中是通过`<input type="file" name="file"/>`来选择的
|
||||
|
||||
|
||||
**返回**: 刚上传的这个文件的`Matter`实体
|
||||
|
||||
----------
|
||||
|
||||
|
||||
#### /api/matter/delete
|
||||
|
||||
**功能**:删除文件或者文件夹
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
uuid | `string` | 必填 | 待删除的文件或文件夹的uuid
|
||||
|
||||
|
||||
**返回**: 成功信息“删除成功”
|
||||
|
||||
----------
|
||||
|
||||
|
||||
#### /api/matter/delete/batch
|
||||
|
||||
**功能**:批量删除文件或文件夹
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
uuids | `string` | 必填 | 待删除的文件或文件夹的uuids,用逗号(,)分隔。
|
||||
|
||||
**返回**: 成功信息“删除成功”
|
||||
|
||||
----------
|
||||
|
||||
#### /api/matter/rename
|
||||
|
||||
**功能**:重命名文件或文件夹
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
uuid | `string` | 必填 | 文件的uuid
|
||||
name | `string` | 必填 | 新名字,不能包含以下特殊符号:`< > \| * ? / \`
|
||||
|
||||
**返回**: 刚重命名的这个文件的`Matter`实体
|
||||
|
||||
----------
|
||||
#### /api/matter/change/privacy
|
||||
|
||||
**功能**:改变文件的公私有属性
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
uuid | `string` | 必填 | 文件的uuid
|
||||
privacy | `bool` | 选填 | 文件的私有性,默认`false`
|
||||
|
||||
**返回**: 成功信息“设置成功”
|
||||
|
||||
----------
|
||||
|
||||
#### /api/matter/move
|
||||
|
||||
**功能**:将一个文件夹或者文件移入到另一个文件夹下。
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
srcUuids | `string` | 必填 | 待移动的文件或文件夹的uuids,用逗号(,)分隔。
|
||||
destUuid | `string` | 必填 | 目标文件夹,根目录用`root`
|
||||
|
||||
**返回**: 成功信息“设置成功”
|
||||
|
||||
----------
|
||||
|
||||
|
||||
#### /api/matter/detail
|
||||
|
||||
**功能**:产看文件详情
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
uuid | `string` | 必填 | 该文件的uuid。
|
||||
destUuid | `string` | 必填 | 目标文件夹,根目录用`root`
|
||||
|
||||
**返回**: 这个文件的`Matter`实体
|
||||
|
||||
----------
|
||||
|
||||
#### /api/matter/page
|
||||
|
||||
**功能**:按照分页的方式获取某个文件夹下文件和子文件夹的列表
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
puuid | `string` | 选填 | 文件夹uuid,如果根目录填`root`
|
||||
page | `int` | 选填 | 当前页数,0基,默认0
|
||||
pageSize | `int` | 选填 | 每页条目数,默认200
|
||||
userUuid | `string` | 选填 | 筛选文件拥有者,对于普通用户使用当前登录的用户uuid.
|
||||
name | `string` | 选填 | 模糊筛选文件名
|
||||
dir | `bool` | 选填 | 筛选是否为文件夹
|
||||
orderDir | `DESC`或`ASC` | 选填 | 按文件夹排序,`DESC`降序排,`ASC`升序排
|
||||
orderCreateTime | `DESC`或`ASC` | 选填 | 按创建时间排序,`DESC`降序排,`ASC`升序排
|
||||
orderSize | `DESC`或`ASC` | 选填 | 按文件大小排序,`DESC`降序排,`ASC`升序排
|
||||
orderName | `DESC`或`ASC` | 选填 | 按名称排序,`DESC`降序排,`ASC`升序排
|
||||
extensions | `string` | 选填 | 按文件后缀名筛选,逗号(,)分隔。例:`jpg,png,pdf`
|
||||
|
||||
|
||||
**返回**: `Matter`的`Pager`
|
||||
|
||||
----------
|
||||
|
||||
#### /api/alien/download/{uuid}/{filename}
|
||||
|
||||
这个接口的定义在在`AlienController`中的,具体使用请参考[蓝眼云盘编程接口](https://github.com/eyebluecn/tank/blob/master/build/doc/alien_zh.md) 这里只做简单的下载使用。
|
||||
|
||||
**功能**:下载文件。
|
||||
|
||||
**访问级别**:`游客`,`注册用户`,`管理员`
|
||||
|
||||
**请求参数**: 均是放置在url中
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
uuid | `string` | 必填 | 要下载的文件uuid
|
||||
filename | `string` | 必填 | 要下载的文件名
|
||||
|
||||
**返回**: 二进制的文件
|
||||
|
||||
----------
|
||||
|
||||
### UserController
|
||||
|
||||
该Controller负责站内创建文件夹,上传文件,删除文件,修改权限等,主要操作`Matter`实体
|
||||
|
||||
----------
|
||||
|
||||
#### /api/user/create
|
||||
|
||||
**功能**:创建用户
|
||||
|
||||
**访问级别**:`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
username | `string` | 必填 | 用户名,且只能包含字母,数字和'_'
|
||||
password | `string` | 必填 | 密码,密码长度至少为6位
|
||||
email | `string` | 必填 | 邮箱,作为用户登录的凭证
|
||||
avatarUrl | `string` | 选填 | 头像
|
||||
phone | `string` | 选填 | 电话
|
||||
gender | `string` | 选填 | 性别
|
||||
role | `string` | 选填 | 角色
|
||||
city | `string` | 选填 | 城市
|
||||
sizeLimit | `string` | 选填 | 用户上传单文件限制,单位byte. 如果负数表示无限制。
|
||||
|
||||
|
||||
**返回**: 新建的`User`实体
|
||||
|
||||
----------
|
||||
|
||||
#### /api/user/edit
|
||||
|
||||
**功能**:编辑用户
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
uuid | `string` | 必填 | 待编辑的用户uuid
|
||||
avatarUrl | `string` | 选填 | 头像
|
||||
phone | `string` | 选填 | 电话
|
||||
gender | `string` | 选填 | 性别
|
||||
role | `string` | 选填 | 角色
|
||||
city | `string` | 选填 | 城市
|
||||
sizeLimit | `string` | 选填 | 用户上传单文件限制,单位byte. 如果负数表示无限制。
|
||||
|
||||
|
||||
**返回**: 编辑的`User`实体
|
||||
|
||||
----------
|
||||
|
||||
#### /api/user/change/password
|
||||
|
||||
**功能**:用户修改密码
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
oldPassword | `string` | 必填 | 旧密码
|
||||
newPassword | `string` | 必填 | 新密码
|
||||
|
||||
**返回**: 修改密码的`User`实体
|
||||
|
||||
----------
|
||||
|
||||
|
||||
#### /api/user/change/password
|
||||
|
||||
**功能**:管理员重置用户密码
|
||||
|
||||
**访问级别**:`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
userUuid | `string` | 必填 | 待重置密码的用户uuid
|
||||
password | `string` | 必填 | 密码
|
||||
|
||||
**返回**: 修改密码的`User`实体
|
||||
|
||||
----------
|
||||
|
||||
#### /api/user/login
|
||||
|
||||
**功能**:登录
|
||||
|
||||
**访问级别**:`游客`,`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
email | `string` | 必填 | 邮箱
|
||||
password | `string` | 必填 | 密码
|
||||
|
||||
**返回**: 当前登录的`User`实体
|
||||
|
||||
----------
|
||||
|
||||
#### /api/user/logout
|
||||
|
||||
**功能**:登录
|
||||
|
||||
**访问级别**:`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:无
|
||||
|
||||
**返回**: 成功信息"退出成功!"
|
||||
|
||||
----------
|
||||
|
||||
#### /api/user/detail
|
||||
|
||||
**功能**:查看用户详情
|
||||
|
||||
**访问级别**:`游客`,`注册用户`,`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
uuid | `string` | 必填 | 待查看的用户uuid
|
||||
|
||||
**返回**: `User`实体
|
||||
|
||||
----------
|
||||
|
||||
#### /api/user/page
|
||||
|
||||
**功能**:查看用户列表
|
||||
|
||||
**访问级别**:`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
page | `int` | 选填 | 当前页数,0基,默认0
|
||||
pageSize | `int` | 选填 | 每页条目数,默认200
|
||||
username | `string` | 选填 | 模糊筛选用户名
|
||||
email | `string` | 选填 | 模糊筛选邮箱
|
||||
phone | `string` | 选填 | 模糊筛选电话
|
||||
orderLastTime | `DESC`或`ASC` | 选填 | 按上次登录时间排序,`DESC`降序排,`ASC`升序排
|
||||
orderCreateTime | `DESC`或`ASC` | 选填 | 按创建时间排序,`DESC`降序排,`ASC`升序排
|
||||
|
||||
**返回**: `User`实体的`Pager`
|
||||
|
||||
----------
|
||||
|
||||
#### /api/user/disable
|
||||
|
||||
**功能**:禁用用户
|
||||
|
||||
**访问级别**:`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
uuid | `string` | 必填 | 待操作的用户
|
||||
|
||||
**返回**: 被操作的用户`User`实体
|
||||
|
||||
----------
|
||||
|
||||
#### /api/user/enable
|
||||
|
||||
**功能**:启用用户
|
||||
|
||||
**访问级别**:`管理员`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
名称 | 类型 | 必填性 | 描述
|
||||
--------- | ---- | ---- | -----------
|
||||
uuid | `string` | 必填 | 待操作的用户
|
||||
|
||||
**返回**: 被操作的用户`User`实体
|
||||
|
||||
----------
|
||||
|
||||
### AlienController
|
||||
|
||||
这个Controller主要暴露给第三方使用,详情请参考:[蓝眼云盘编程接口](https://github.com/eyebluecn/tank/blob/master/build/doc/alien_zh.md)
|
||||
|
||||
|
After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 49 KiB |
@@ -0,0 +1,193 @@
|
||||
CREATE TABLE `tank31_bridge` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`share_uuid` char(36) DEFAULT NULL,
|
||||
`matter_uuid` char(36) DEFAULT NULL,
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `uuid` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `tank31_dashboard` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`invoke_num` bigint(20) NOT NULL,
|
||||
`total_invoke_num` bigint(20) NOT NULL DEFAULT '0',
|
||||
`uv` bigint(20) NOT NULL DEFAULT '0',
|
||||
`total_uv` bigint(20) NOT NULL DEFAULT '0',
|
||||
`matter_num` bigint(20) NOT NULL DEFAULT '0',
|
||||
`total_matter_num` bigint(20) NOT NULL DEFAULT '0',
|
||||
`file_size` bigint(20) NOT NULL DEFAULT '0',
|
||||
`total_file_size` bigint(20) NOT NULL DEFAULT '0',
|
||||
`avg_cost` bigint(20) NOT NULL DEFAULT '0',
|
||||
`dt` varchar(45) NOT NULL,
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `uuid` (`uuid`),
|
||||
KEY `idx_dt` (`dt`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `tank31_download_token` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`user_uuid` char(36) NOT NULL,
|
||||
`matter_uuid` char(36) NOT NULL,
|
||||
`expire_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`ip` varchar(128) NOT NULL,
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `uuid` (`uuid`),
|
||||
KEY `idx_mu` (`matter_uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `tank31_footprint` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`user_uuid` char(36) DEFAULT NULL,
|
||||
`ip` varchar(128) NOT NULL,
|
||||
`host` varchar(45) NOT NULL,
|
||||
`uri` varchar(255) NOT NULL,
|
||||
`params` text,
|
||||
`cost` bigint(20) NOT NULL DEFAULT '0',
|
||||
`success` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `uuid` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `tank31_image_cache` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`name` varchar(255) NOT NULL,
|
||||
`user_uuid` char(36) DEFAULT NULL,
|
||||
`username` varchar(45) NOT NULL,
|
||||
`matter_uuid` char(36) DEFAULT NULL,
|
||||
`matter_name` varchar(255) NOT NULL,
|
||||
`mode` varchar(512) DEFAULT NULL,
|
||||
`md5` varchar(45) DEFAULT NULL,
|
||||
`size` bigint(20) NOT NULL DEFAULT '0',
|
||||
`path` varchar(512) DEFAULT NULL,
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `uuid` (`uuid`),
|
||||
KEY `idx_mu` (`matter_uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `tank31_matter` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`puuid` char(36) DEFAULT NULL,
|
||||
`user_uuid` char(36) DEFAULT NULL,
|
||||
`username` varchar(45) NOT NULL,
|
||||
`dir` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`name` varchar(255) NOT NULL,
|
||||
`md5` varchar(45) DEFAULT NULL,
|
||||
`size` bigint(20) NOT NULL DEFAULT '0',
|
||||
`privacy` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`path` varchar(1024) DEFAULT NULL,
|
||||
`times` bigint(20) NOT NULL DEFAULT '0',
|
||||
`prop` varchar(1024) NOT NULL DEFAULT '{}',
|
||||
`visit_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`delete_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `uuid` (`uuid`),
|
||||
KEY `idx_puuid` (`puuid`),
|
||||
KEY `idx_uu` (`user_uuid`),
|
||||
KEY `idx_del` (`deleted`),
|
||||
KEY `idx_delt` (`delete_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `tank31_preference` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`name` varchar(45) DEFAULT NULL,
|
||||
`logo_url` varchar(255) DEFAULT NULL,
|
||||
`favicon_url` varchar(255) DEFAULT NULL,
|
||||
`copyright` varchar(1024) DEFAULT NULL,
|
||||
`record` varchar(1024) DEFAULT NULL,
|
||||
`download_dir_max_size` bigint(20) NOT NULL DEFAULT '-1',
|
||||
`download_dir_max_num` bigint(20) NOT NULL DEFAULT '-1',
|
||||
`default_total_size_limit` bigint(20) NOT NULL DEFAULT '-1',
|
||||
`allow_register` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`preview_config` text,
|
||||
`scan_config` text,
|
||||
`deleted_keep_days` bigint(20) NOT NULL DEFAULT '7',
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `uuid` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `tank31_session` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`user_uuid` char(36) DEFAULT NULL,
|
||||
`ip` varchar(128) NOT NULL,
|
||||
`expire_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `uuid` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `tank31_share` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`name` varchar(255) DEFAULT NULL,
|
||||
`share_type` varchar(45) DEFAULT NULL,
|
||||
`username` varchar(45) DEFAULT NULL,
|
||||
`user_uuid` char(36) DEFAULT NULL,
|
||||
`download_times` bigint(20) NOT NULL DEFAULT '0',
|
||||
`code` varchar(45) NOT NULL,
|
||||
`expire_infinity` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`expire_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `uuid` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `tank31_upload_token` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`user_uuid` char(36) NOT NULL,
|
||||
`folder_uuid` char(36) NOT NULL,
|
||||
`matter_uuid` char(36) NOT NULL,
|
||||
`expire_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`filename` varchar(255) NOT NULL,
|
||||
`privacy` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`size` bigint(20) NOT NULL DEFAULT '0',
|
||||
`ip` varchar(128) NOT NULL,
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `uuid` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE `tank31_user` (
|
||||
`uuid` char(36) NOT NULL DEFAULT '',
|
||||
`sort` bigint(20) NOT NULL,
|
||||
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`create_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`role` varchar(45) DEFAULT NULL,
|
||||
`username` varchar(45) NOT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`avatar_url` varchar(255) DEFAULT NULL,
|
||||
`last_ip` varchar(128) DEFAULT NULL,
|
||||
`last_time` timestamp NOT NULL DEFAULT '2018-01-01 00:00:00',
|
||||
`size_limit` bigint(20) NOT NULL DEFAULT '-1',
|
||||
`total_size_limit` bigint(20) NOT NULL DEFAULT '-1',
|
||||
`total_size` bigint(20) NOT NULL DEFAULT '0',
|
||||
`status` varchar(45) DEFAULT NULL,
|
||||
PRIMARY KEY (`uuid`),
|
||||
UNIQUE KEY `username` (`username`),
|
||||
UNIQUE KEY `uuid` (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.3e2e293d.css",
|
||||
"main.js": "/static/js/main.1a935cc6.js",
|
||||
"static/js/833.2731ecbb.chunk.js": "/static/js/833.2731ecbb.chunk.js",
|
||||
"static/media/logo.png": "/static/media/logo.847e54ef7fb4b744fad4.png",
|
||||
"static/media/empty.svg": "/static/media/empty.1ac6f6fb3e1d8c985f32df632ded4fe1.svg",
|
||||
"static/media/psd.svg": "/static/media/psd.f2767f53369b5e75d7708a857d8381f4.svg",
|
||||
"static/media/xls.svg": "/static/media/xls.9f55e13113424a3cc3316acbf072f072.svg",
|
||||
"static/media/ppt.svg": "/static/media/ppt.8696321d8f3893a15681473769c8283c.svg",
|
||||
"static/media/doc.svg": "/static/media/doc.017d14ee10ef3d2427494d1b0e52b03e.svg",
|
||||
"static/media/pdf.svg": "/static/media/pdf.67d0061b2cef7912ed36b895cb8a328a.svg",
|
||||
"static/media/video.svg": "/static/media/video.09bf3324c0e699b3611bf6bb0fc1b50e.svg",
|
||||
"static/media/file.svg": "/static/media/file.b6be968e09dc04a45ec49a0dbcef53da.svg",
|
||||
"static/media/text.svg": "/static/media/text.fa66aadee4b7dd9d51f4d1c863e5f75e.svg",
|
||||
"static/media/audio.svg": "/static/media/audio.59dab6a9512494e5a34c8a424ab68f39.svg",
|
||||
"static/media/image.svg": "/static/media/image.ee35022875b37a7962afa08bce8bc1fd.svg",
|
||||
"static/media/folder.svg": "/static/media/folder.b4ce8a2960e8da846081c692d3065dff.svg",
|
||||
"static/media/archive.svg": "/static/media/archive.f58837716d1fc6f2e61dc1618dad27a6.svg",
|
||||
"index.html": "/index.html",
|
||||
"main.3e2e293d.css.map": "/static/css/main.3e2e293d.css.map",
|
||||
"main.1a935cc6.js.map": "/static/js/main.1a935cc6.js.map",
|
||||
"833.2731ecbb.chunk.js.map": "/static/js/833.2731ecbb.chunk.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.3e2e293d.css",
|
||||
"static/js/main.1a935cc6.js"
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html><head><title>蓝眼云盘</title><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="user-scalable=no,width=device-width,initial-scale=1,maximum-scale=1"><meta name=msapplication-tap-highlight content=no><meta name=apple-mobile-web-app-capable content=yes><link rel="shortcut icon" href=/favicon.ico><link href=/static/css/app.8dad0c121390f7cc4db58bee31527c91.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.58f5ada3fb59ca99ef92.js></script><script type=text/javascript src=/static/js/vendor.fd6fd2c2da583dfd7fae.js></script><script type=text/javascript src=/static/js/app.ea4ca89d736fc05aca99.js></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="eyeblue tank"/><title>EyeblueTank</title><script defer="defer" src="/static/js/main.1a935cc6.js"></script><link href="/static/css/main.3e2e293d.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run EyeblueTank.</noscript><div id="root"></div></body></html>
|
||||
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189477205" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5356" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M625.664 132.608V199.68h309.76v43.008h-309.76V312.32h309.76v43.008h-309.76v68.608h309.76v43.008h-309.76v68.608h309.76v43.008h-309.76v68.608h309.76v43.008h-309.76v68.096h309.76v43.008h-309.76v89.088H1024v-757.76h-398.336z" fill="#333333" p-id="5357"></path><path d="M0 914.944L577.024 1024V0L0 109.056m417.792 401.92c-21.504 17.92-52.224 27.136-92.16 27.136h-76.8V670.72h-76.8V302.08h158.208c36.352 0 65.536 9.728 87.04 28.672 21.504 18.944 32.768 48.64 32.768 88.064 0 43.52-10.752 74.24-32.256 92.16zM358.912 378.368c-9.728-8.192-23.552-12.288-40.96-12.288H248.832v108.544h69.632c17.408 0 31.232-4.608 40.96-13.312 9.728-8.704 14.848-23.04 14.848-41.984-0.512-18.944-5.632-32.768-15.36-40.96z" fill="#C35132" p-id="5358"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189634329" class="icon" style="" viewBox="0 0 1219 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10648" xmlns:xlink="http://www.w3.org/1999/xlink" width="238.0859375" height="200"><defs><style type="text/css"></style></defs><path d="M1197.787429 327.192381a19.504762 19.504762 0 0 1 19.553523 19.407238v614.156191c0 34.913524-28.574476 63.24419-63.878095 63.24419H63.878095C28.623238 1024 0 995.718095 0 960.75581V346.599619a19.504762 19.504762 0 0 1 19.602286-19.358476h1178.185143z m-66.80381-213.089524C1179.550476 114.102857 1219.047619 153.209905 1219.047619 201.386667v80.213333H1.657905V88.259048C1.657905 39.497143 41.593905 0 90.794667 0h290.864762c17.408 0 33.987048 7.655619 45.104761 20.967619l78.214096 93.135238h626.005333z" fill="#1ab394" p-id="10649"></path></svg>
|
||||
|
Before Width: | Height: | Size: 943 B |
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189353878" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1197" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M9.367 0h992.97v341.333H9.366z" fill="#55C7F7" p-id="1198"></path><path d="M9.367 341.333h992.97v341.334H9.366z" fill="#F95F5D" p-id="1199"></path><path d="M9.367 682.667h992.97V1024H9.366z" fill="#7ECF3B" p-id="1200"></path><path d="M350.7 0h310.303v1024H350.7z" fill="#FDAF42" p-id="1201"></path><path d="M304.154 386.638V646.05h403.394V386.638H304.154z m356.849 215.97H350.7V429.46h310.303v173.15z" fill="#FFFFFF" p-id="1202"></path></svg>
|
||||
|
Before Width: | Height: | Size: 828 B |
|
Before Width: | Height: | Size: 4.5 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189404825" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3026" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M146.386345 0a81.949268 81.949268 0 0 0-81.583423 81.583423v860.711206a81.949268 81.949268 0 0 0 81.583423 81.583423h731.120797a81.949268 81.949268 0 0 0 81.583422-81.583423v-617.546266l-302.350522-324.748363z" fill="#9B45E6" p-id="3027"></path><path d="M959.090564 326.37434v16.015879h-204.79187s-100.769958-20.812512-97.558652-108.777897a94.631892 94.631892 0 0 0 95.973324 92.802667z" fill="#2987C8" p-id="3028"></path><path d="M656.740042 0v233.571672a92.965265 92.965265 0 0 0 97.558652 92.802668H959.090564z" fill="#FFFFFF" p-id="3029"></path><path d="M539.913557 543.930134l-227.189711 30.40578v214.385137a82.843555 82.843555 0 0 0-39.999047-1.585328c-31.991108 6.381962-52.84427 27.194474-46.381009 46.381009 6.381962 20.812512 36.787742 30.40578 68.778849 23.983169 28.779802-4.796634 48.006987-22.39784 48.006987-39.999048v-171.174784l166.378151-20.812513v132.801715a84.266286 84.266286 0 0 0-39.999047 0c-33.576436 6.381962-54.388948 27.194474-48.006987 46.381009s36.787742 30.40578 70.404827 23.983169c28.779802-6.381962 49.592315-23.983169 48.006987-41.584375z" fill="#FFFFFF" p-id="3030"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189459054" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4644" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M625.390933 132.437333v66.8672h309.930667v43.1104h-309.930667v69.973334h309.930667v43.1104h-309.930667v68.130133h309.930667v43.076267h-309.930667v68.130133h309.930667v43.076267h-309.930667v68.130133h309.930667v43.1104h-309.930667v68.096h309.930667v43.1104h-309.930667v89.361067H1024V132.437333H625.390933zM0 108.714667V914.773333l576.682667 108.680534V0L0 108.714667zM417.962667 686.08h-84.309334L279.893333 447.3856 212.411733 686.08H154.350933L70.587733 334.916267h83.114667l33.109333 218.692266 54.9888-241.220266h86.8352L375.466667 576.1024l49.9712-263.68H508.586667L417.962667 686.08v-0.034133z" fill="#00B6FF" p-id="4645"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189511483" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6709" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M676.297143 0H145.609143C130.834286 0 118.857143 11.977143 118.857143 35.218286V1005.714286c0 6.308571 11.977143 18.285714 26.752 18.285714h732.781714c14.774857 0 26.752-11.977143 26.752-18.285714V237.312c0-12.726857-1.700571-16.822857-4.699428-19.84L687.670857 4.699429A16.164571 16.164571 0 0 0 676.297143 0z" fill="#E9E9E0" p-id="6710"></path><path d="M685.714286 2.761143V219.428571h216.667428z" fill="#D9D7CA" p-id="6711"></path><path d="M878.390857 1024H145.609143A26.752 26.752 0 0 1 118.857143 997.248V713.142857h786.285714v284.105143c0 14.774857-11.977143 26.752-26.752 26.752z" fill="#C8BDB8" p-id="6712"></path><path d="M338.285714 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z" fill="#FFFFFF" p-id="6713"></path><path d="M521.142857 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z" fill="#FFFFFF" p-id="6714"></path><path d="M704 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z" fill="#FFFFFF" p-id="6715"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189634329" class="icon" style="" viewBox="0 0 1219 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10648" xmlns:xlink="http://www.w3.org/1999/xlink" width="238.0859375" height="200"><defs><style type="text/css"></style></defs><path d="M1197.787429 327.192381a19.504762 19.504762 0 0 1 19.553523 19.407238v614.156191c0 34.913524-28.574476 63.24419-63.878095 63.24419H63.878095C28.623238 1024 0 995.718095 0 960.75581V346.599619a19.504762 19.504762 0 0 1 19.602286-19.358476h1178.185143z m-66.80381-213.089524C1179.550476 114.102857 1219.047619 153.209905 1219.047619 201.386667v80.213333H1.657905V88.259048C1.657905 39.497143 41.593905 0 90.794667 0h290.864762c17.408 0 33.987048 7.655619 45.104761 20.967619l78.214096 93.135238h626.005333z" fill="#23B7E5" p-id="10649"></path></svg>
|
||||
|
Before Width: | Height: | Size: 943 B |
|
Before Width: | Height: | Size: 3.8 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514190539077" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14917" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M128 0h597.3l227.6 227.9v739.2c0 31.4-25.5 56.9-56.9 56.9H128c-31.4 0-56.9-25.5-56.9-56.9V56.9C71.1 25.5 96.6 0 128 0z" fill="#13BE93" p-id="14918"></path><path d="M630.5 1024H128c-25.7 0-47.4-17-54.4-40.4l218.1-218.1c22.2-22.2 58.2-22.2 80.5 0L630.5 1024z" fill="#6BD8BD" p-id="14919"></path><path d="M952.9 858v109.1c0 31.4-25.5 56.9-56.9 56.9H322.4l-4.7-4.7 358-358c22.2-22.2 58.2-22.2 80.5 0L952.9 858z" fill="#9CF9E2" p-id="14920"></path><path d="M725.3 0l227.6 227.6H782.2c-31.4 0-56.9-25.5-56.9-56.9V0z" fill="#69DCC0" p-id="14921"></path><path d="M327.1 483.6m-85.3 0a85.3 85.3 0 1 0 170.6 0 85.3 85.3 0 1 0-170.6 0Z" fill="#E9FFFA" p-id="14922"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514284130163" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1551" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M915.114667 1024H108.885333V0h587.776v218.112H914.773333V1024z m-785.066667-20.821333h763.904V238.933333H675.84V20.821333H129.706667v982.357334z" fill="#F90E09" p-id="1552"></path><path d="M708.266667 10.581333L904.533333 206.848h-196.266666z" fill="#F90E09" p-id="1553"></path><path d="M282.965333 792.576c33.450667-23.210667 55.637333-57.344 76.8-91.136-30.378667 25.941333-59.050667 54.954667-76.8 91.136z m396.629334-169.642667c31.402667 15.018667 65.877333 31.061333 101.376 21.504-24.576-29.696-67.584-21.504-101.376-21.504z m-246.101334 23.210667c45.397333-16.725333 91.818667-29.696 138.922667-39.594667-30.378667-26.965333-55.978667-58.368-76.458667-93.525333-16.725333 46.08-38.912 90.112-62.464 133.12z m67.925334-243.370667c14.677333-37.546667 19.114667-83.285333-5.802667-117.418666-7.168 38.912-4.096 79.189333 5.802667 117.418666z m-45.397334-105.130666c4.096-24.917333 35.84-29.696 55.637334-22.186667 12.288 7.850667 18.432 22.869333 18.773333 37.205333 1.365333 44.032-6.485333 87.381333-12.629333 130.730667-3.413333 20.138667 8.874667 38.229333 17.749333 55.296 21.845333 40.277333 52.224 76.458667 92.16 99.669333 48.128-5.802667 98.645333-12.970667 145.749333 2.389334 35.157333 11.946667 26.965333 77.141333-11.264 77.824-53.589333 2.730667-102.058667-23.893333-150.186666-43.349334-66.218667 4.778667-130.730667 24.917333-194.218667 44.032-28.672 46.762667-54.613333 98.986667-101.034667 130.730667-23.210667 18.090667-76.458667 3.072-64.512-32.085333 20.138667-49.152 70.314667-76.117333 114.346667-100.693334 12.629333-6.485333 19.797333-18.773333 26.282667-31.061333 30.037333-57.685333 60.074667-115.370667 84.309333-175.786667-12.629333-56.661333-31.061333-114.688-21.162667-172.714666z" fill="#F90E09" p-id="1554"></path></svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189544355" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8186" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M176 1024l672 0c26.464 0 48-21.536 48-48l0-672c0-0.544-0.256-0.992-0.288-1.504-0.064-0.736-0.256-1.376-0.416-2.08-0.544-2.272-1.472-4.32-2.88-6.112-0.224-0.288-0.192-0.64-0.416-0.928l-256-288c-0.096-0.096-0.224-0.096-0.32-0.192-1.92-2.048-4.352-3.456-7.136-4.288-0.608-0.192-1.152-0.256-1.792-0.352-0.928-0.16-1.792-0.544-2.752-0.544l-448 0c-26.464 0-48 21.536-48 48l0 928c0 26.464 21.536 48 48 48zM640 58.08l204.384 229.92-188.384 0c-7.04 0-16-13.44-16-24l0-205.92zM160 48c0-8.832 7.2-16 16-16l432 0 0 232c0 25.888 20.96 56 48 56l208 0 0 656c0 8.832-7.2 16-16 16l-672 0c-8.96 0-16-7.04-16-16l0-928zM304 448l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 576l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 320l192 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-192 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 704l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 832l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16z" p-id="8187"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189554639" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8871" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M80 34.4h864v960H80z" fill="#8095FF" p-id="8872"></path><path d="M176 112m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8873"></path><path d="M176 272m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8874"></path><path d="M176 432m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8875"></path><path d="M176 592m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8876"></path><path d="M176 752m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8877"></path><path d="M176 912m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8878"></path><path d="M864 112m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8879"></path><path d="M864 272m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8880"></path><path d="M864 432m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8881"></path><path d="M864 592m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8882"></path><path d="M864 752m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8883"></path><path d="M864 912m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8884"></path><path d="M648 508L436 362.4c-4.8-3.2-11.2-4-16.8-0.8-5.6 3.2-8.8 8.8-8.8 14.4v290.4c0 5.6 3.2 11.2 8.8 14.4 5.6 3.2 12 2.4 16.8-0.8L648 533.6c4.8-2.4 7.2-8 7.2-12.8 0-4.8-3.2-9.6-7.2-12.8z" fill="#FFFFFF" p-id="8885"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189485601" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6045" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M577.536 892.672V157.44H1024v735.232z m157.696-656.384h-131.328v104.96h131.328z m0 157.44h-131.328v104.96h131.328z m0 157.44h-131.328v104.96h131.328z m0 157.44h-131.328v104.96h131.328zM919.04 236.288h-131.328v104.96h131.328z m0 157.44h-131.328v104.96h131.328z m0 157.44h-131.328v104.96h131.328z m0 157.44h-131.328v104.96h131.328zM0 157.44L551.424 0v1024L0 866.56z m104.96 551.424h78.848l104.96-133.888 104.96 133.888h78.848l-144.384-183.808 144.384-183.808h-78.848l-104.96 133.888-104.96-133.888H104.96l144.384 183.808-144.384 183.808z" fill="#01723E" p-id="6046"></path></svg>
|
||||
|
Before Width: | Height: | Size: 963 B |
|
Before Width: | Height: | Size: 434 KiB |
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
object-assign
|
||||
(c) Sindre Sorhus
|
||||
@license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
|
||||
/*! VelocityJS.org (1.5.2). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License */
|
||||
|
||||
/*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */
|
||||
|
||||
/** @license React v0.20.2
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v16.13.1
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
//! moment.js
|
||||
@@ -1,2 +0,0 @@
|
||||
!function(e){function __webpack_require__(r){if(_[r])return _[r].exports;var t=_[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,__webpack_require__),t.l=!0,t.exports}var r=window.webpackJsonp;window.webpackJsonp=function(_,n,o){for(var c,a,i,u=0,p=[];u<_.length;u++)a=_[u],t[a]&&p.push(t[a][0]),t[a]=0;for(c in n)Object.prototype.hasOwnProperty.call(n,c)&&(e[c]=n[c]);for(r&&r(_,n,o);p.length;)p.shift()();if(o)for(u=0;u<o.length;u++)i=__webpack_require__(__webpack_require__.s=o[u]);return i};var _={},t={2:0};__webpack_require__.e=function(e){function onScriptComplete(){o.onerror=o.onload=null,clearTimeout(c);var r=t[e];0!==r&&(r&&r[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}var r=t[e];if(0===r)return new Promise(function(e){e()});if(r)return r[2];var _=new Promise(function(_,n){r=t[e]=[_,n]});r[2]=_;var n=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.timeout=12e4,__webpack_require__.nc&&o.setAttribute("nonce",__webpack_require__.nc),o.src=__webpack_require__.p+"static/js/"+e+"."+{0:"fd6fd2c2da583dfd7fae",1:"ea4ca89d736fc05aca99"}[e]+".js";var c=setTimeout(onScriptComplete,12e4);return o.onerror=o.onload=onScriptComplete,n.appendChild(o),_},__webpack_require__.m=e,__webpack_require__.c=_,__webpack_require__.d=function(exports,e,r){__webpack_require__.o(exports,e)||Object.defineProperty(exports,e,{configurable:!1,enumerable:!0,get:r})},__webpack_require__.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return __webpack_require__.d(r,"a",r),r},__webpack_require__.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},__webpack_require__.p="/",__webpack_require__.oe=function(e){throw console.error(e),e}}([]);
|
||||
//# sourceMappingURL=manifest.58f5ada3fb59ca99ef92.js.map
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514189353878" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="1197" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M9.367 0h992.97v341.333H9.366z" fill="#55C7F7" p-id="1198"></path>
|
||||
<path d="M9.367 341.333h992.97v341.334H9.366z" fill="#F95F5D" p-id="1199"></path>
|
||||
<path d="M9.367 682.667h992.97V1024H9.366z" fill="#7ECF3B" p-id="1200"></path>
|
||||
<path d="M350.7 0h310.303v1024H350.7z" fill="#FDAF42" p-id="1201"></path>
|
||||
<path d="M304.154 386.638V646.05h403.394V386.638H304.154z m356.849 215.97H350.7V429.46h310.303v173.15z"
|
||||
fill="#FFFFFF" p-id="1202"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 855 B |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1543321997742" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="3887" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M160 32c-12 0-24.8 4.8-33.6 14.4S112 68 112 80v864c0 12 4.8 24.8 14.4 33.6C136 987.2 148 992 160 992h704c12 0 24.8-4.8 33.6-14.4C907.2 968 912 956 912 944V304L640 32H160z"
|
||||
fill="#FF5562" p-id="3888"></path>
|
||||
<path d="M912 304H688c-12 0-24.8-4.8-33.6-14.4-9.6-8.8-14.4-21.6-14.4-33.6V32l272 272z" fill="#FFBBC0"
|
||||
p-id="3889"></path>
|
||||
<path d="M669.6 491.2c0-1.6 0.8-4 0-6.4V369.6c0-4.8-2.4-8.8-5.6-12-4-3.2-8-4-12.8-3.2l-250.4 70.4c-7.2 1.6-12 7.2-12 14.4v275.2c-9.6-4-20.8-6.4-32.8-6.4-8.8 0-17.6 0.8-26.4 3.2-40.8 11.2-66.4 43.2-58.4 72.8 6.4 23.2 30.4 37.6 60.8 37.6 8.8 0 17.6-1.6 26.4-3.2 36.8-10.4 60.8-36.8 60-63.2 0.8-1.6 0.8-3.2 0.8-5.6V570.4l220-61.6v136c-9.6-4-20.8-6.4-32.8-6.4-8.8 0-17.6 0.8-26.4 3.2-40.8 11.2-66.4 43.2-58.4 72.8C528 737.6 552 752 582.4 752c8.8 0 17.6-0.8 26.4-3.2 36-9.6 60-36 60-62.4 0.8-1.6 0.8-3.2 0.8-5.6V491.2z m-250.4 48v-53.6l220-61.6v53.6l-220 61.6z"
|
||||
fill="#FFFFFF" p-id="3890"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1543300132402" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2107" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M533.947184 38.36489h65.880106v88.119185c117.859409 0.660894 235.60867-1.211639 353.35793 0.660894 25.102953-2.533427 44.81962 16.962943 42.506492 42.07691 1.872533 216.993492-0.440596 434.097133 1.112505 651.090626-1.112505 22.250094 2.191965 46.923466-10.695466 66.640133-16.081751 11.455494-36.899909 10.023557-55.625236 10.904749-110.25913-0.550745-220.408111-0.330447-330.656225-0.330447v88.119185h-68.843113c-167.657764-30.621417-335.745108-58.709407-503.722304-88.119185-0.110149-256.977572 0-513.955144 0-770.822567 168.858388-29.519927 337.826924-58.268811 506.685311-88.339483z"
|
||||
fill="#2A5699" p-id="2108"></path>
|
||||
<path d="M599.816275 159.528769h363.491637v704.953477h-363.491637v-88.119185h286.38735v-44.059592h-286.38735v-55.07449h286.38735v-44.059593h-286.38735v-55.07449h286.38735v-44.059592h-286.38735v-55.074491h286.38735v-44.059592h-286.38735v-55.074491h286.38735v-44.059592h-286.38735v-55.07449h286.38735v-44.059593h-286.38735v-77.104286zM254.829667 354.162018c20.928306-1.211639 41.856613-2.092831 62.784919-3.19432 14.649814 74.350562 29.619061 148.590975 45.491529 222.61109 12.446835-76.443393 26.215457-152.666487 39.543484-228.999731 22.029796-0.771043 44.059592-1.982682 65.97924-3.30447-24.89367 106.734362-46.703168 214.349917-73.909966 320.423385-18.39488 9.582961-45.932125-0.440596-67.741623 1.10149-14.649814-72.90761-31.722906-145.38564-44.819621-218.645727-12.898446 71.156242-29.641091 141.651589-44.390039 212.367235a4187.754101 4187.754101 0 0 1-63.666111-3.866229c-18.284731-96.931103-39.763782-193.190297-56.836874-290.341698 18.835476-0.881192 37.792115-1.652235 56.627591-2.313129 11.33433 70.164901 24.221761 139.999355 34.146184 210.274404 15.508976-72.037433 31.37043-144.074867 46.791287-216.1123z"
|
||||
fill="#FFFFFF" p-id="2109"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1582644951614" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3842"
|
||||
width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M692.906667 385.024c-11.605333-2.730667-23.210667-6.144-34.816-11.605333l-63.488 25.258666-5.461334 2.048h-5.461333c-8.874667 0-17.749333-4.096-23.210667-11.605333-5.461333-7.509333-6.826667-17.066667-4.778666-25.258667l8.874666-30.72-97.621333-19.797333v400.725333L901.12 402.090667l-105.130667-21.162667c-18.432 5.461333-38.229333 8.874667-59.392 8.874667-13.653333 0-28.672-1.365333-43.690666-4.778667z"
|
||||
fill="#A6DAFC" p-id="3843"></path>
|
||||
<path d="M512 502.442667v467.626666l389.802667-100.352V402.090667zM111.274667 413.696l356.352-100.352V580.266667z"
|
||||
fill="#568EC8" p-id="3844"></path>
|
||||
<path d="M111.274667 413.696v456.021333L512 970.069333V502.442667z" fill="#A6DAFC" p-id="3845"></path>
|
||||
<path d="M512 502.442667l389.802667-100.352L1024 546.816 645.802667 658.090667z" fill="#78C5FD" p-id="3846"></path>
|
||||
<path d="M111.274667 413.696l400.725333 88.746667-122.197333 167.253333L0 569.344z" fill="#CFF0FF"
|
||||
p-id="3847"></path>
|
||||
<path d="M886.784 160.426667c-2.730667-6.826667-6.144-13.653333-9.557333-20.48-1.365333-2.048-2.730667-4.096-4.096-6.826667-4.096-6.144-8.192-12.970667-13.653334-18.432s-10.24-11.605333-16.384-16.384c-2.048-2.048-4.096-3.413333-6.144-4.778667-8.192-6.826667-17.066667-12.288-25.941333-17.749333-2.048-1.365333-4.778667-2.730667-6.826667-3.413333-4.778667-2.048-9.557333-4.778667-15.018666-6.144-7.509333-2.730667-15.701333-5.461333-23.893334-6.826667-2.730667-0.682667-6.144-1.365333-8.874666-2.048-0.682667 0-2.048 0-2.730667-0.682667-2.048 0-4.096-0.682667-6.144-0.682666-1.365333 0-2.048 0-3.413333-0.682667-2.048 0-3.413333 0-5.461334-0.682667H727.04c-4.096 0-8.192 0-11.605333 0.682667h-2.048c-4.096 0.682667-8.192 0.682667-12.288 1.365333h-0.682667c-4.096 0.682667-7.509333 1.365333-11.605333 2.048-0.682667 0-1.365333 0-1.365334 0.682667-4.096 0.682667-7.509333 2.048-10.922666 3.413333-0.682667 0-1.365333 0.682667-2.048 0.682667-3.413333 1.365333-7.509333 2.730667-10.922667 4.096-0.682667 0-0.682667 0.682667-1.365333 0.682667-3.413333 1.365333-6.826667 3.413333-10.24 4.778666 0 0-0.682667 0-0.682667 0.682667-3.413333 2.048-6.826667 3.413333-10.24 5.461333-0.682667 0.682667-1.365333 0.682667-2.048 1.365334-3.413333 2.048-6.144 4.096-9.557333 6.144-0.682667 0.682667-1.365333 0.682667-1.365334 1.365333-3.413333 2.048-6.144 4.778667-8.874666 7.509333l-8.192 8.192-1.365334 1.365334c-2.730667 2.730667-4.778667 5.461333-7.509333 8.192-0.682667 0.682667-0.682667 1.365333-1.365333 1.365333-2.048 2.730667-4.778667 6.144-6.826667 8.874667 0 0.682667-0.682667 0.682667-0.682667 1.365333-2.048 3.413333-4.096 6.144-5.461333 9.557333 0 0.682667-0.682667 0.682667-0.682667 1.365334-2.048 3.413333-3.413333 6.826667-4.778666 10.24 0 0.682667-0.682667 1.365333-0.682667 2.048-1.365333 3.413333-2.730667 6.826667-4.096 10.922666 0 0.682667-0.682667 1.365333-0.682667 2.048-1.365333 4.096-2.048 7.509333-3.413333 11.605334-10.24 46.421333 2.730667 92.16 32.085333 127.658666L593.92 339.968l-9.557333 32.768v0.682667h0.682666l58.709334-23.210667 16.384-6.826667c6.144 3.413333 12.970667 6.144 19.797333 8.192s13.653333 4.778667 21.162667 6.144c2.730667 0.682667 6.144 1.365333 8.874666 2.048 0.682667 0 2.048 0 2.730667 0.682667 2.048 0 4.096 0.682667 6.144 0.682667 1.365333 0 2.048 0 3.413333 0.682666 2.048 0 3.413333 0 5.461334 0.682667H739.328c4.096 0 8.192 0 11.605333-0.682667h2.048c4.096-0.682667 8.192-0.682667 12.288-1.365333h0.682667c4.096-0.682667 7.509333-1.365333 11.605333-2.048 0.682667 0 1.365333 0 2.048-0.682667 4.096-0.682667 7.509333-2.048 10.922667-3.413333 0.682667 0 1.365333-0.682667 2.048-0.682667 3.413333-1.365333 7.509333-2.730667 10.922667-4.096 0.682667 0 0.682667-0.682667 1.365333-0.682666 3.413333-1.365333 6.826667-3.413333 10.24-4.778667 0 0 0.682667 0 0.682667-0.682667 3.413333-2.048 6.826667-3.413333 10.24-5.461333 0.682667-0.682667 1.365333-0.682667 2.048-1.365333 3.413333-2.048 6.144-4.096 9.557333-6.144 0.682667-0.682667 1.365333-0.682667 1.365333-1.365334 3.413333-2.048 6.144-4.778667 8.874667-7.509333l8.192-8.192 1.365333-1.365333c2.730667-2.730667 4.778667-5.461333 7.509334-8.192 0.682667-0.682667 0.682667-1.365333 1.365333-2.048 2.048-2.730667 4.778667-6.144 6.826667-8.874667 0-0.682667 0.682667-0.682667 0.682666-1.365333 2.048-3.413333 4.096-6.144 5.461334-9.557334 0-0.682667 0.682667-0.682667 0.682666-1.365333 2.048-3.413333 3.413333-6.826667 4.778667-10.24 0-0.682667 0.682667-1.365333 0.682667-2.048 1.365333-3.413333 2.730667-6.826667 4.096-10.922667 0-0.682667 0.682667-1.365333 0.682666-2.048 1.365333-4.096 2.048-7.509333 3.413334-11.605333 5.461333-28.672 2.730667-57.344-6.826667-83.285333z"
|
||||
fill="#F9DA3E" p-id="3848"></path>
|
||||
<path d="M739.328 167.936h48.469333v27.989333h-13.653333v-15.701333h-83.968v15.701333h-13.653333v-27.989333h48.469333c-1.365333-3.413333-3.413333-6.826667-4.778667-10.24l14.336-2.048c2.048 3.413333 3.413333 7.509333 4.778667 12.288z m37.546667 52.565333v12.288h-37.546667v25.258667h48.469333v12.970667H677.205333v-12.970667h48.469334v-25.258667h-37.546667v-12.288h88.746667z m-51.882667-24.576c-10.24 8.874667-22.528 16.384-37.546667 22.528l-5.461333-12.288c14.336-5.461333 25.941333-11.605333 34.816-19.797333l8.192 9.557333z m56.661333 10.922667l-7.509333 11.605333c-11.605333-9.557333-23.210667-17.066667-35.498667-22.528l6.826667-10.24c13.653333 6.144 25.258667 12.970667 36.181333 21.162667z"
|
||||
fill="#FFFFFF" p-id="3849"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514189511483" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="6709" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M676.297143 0H145.609143C130.834286 0 118.857143 11.977143 118.857143 35.218286V1005.714286c0 6.308571 11.977143 18.285714 26.752 18.285714h732.781714c14.774857 0 26.752-11.977143 26.752-18.285714V237.312c0-12.726857-1.700571-16.822857-4.699428-19.84L687.670857 4.699429A16.164571 16.164571 0 0 0 676.297143 0z"
|
||||
fill="#E9E9E0" p-id="6710"></path>
|
||||
<path d="M685.714286 2.761143V219.428571h216.667428z" fill="#D9D7CA" p-id="6711"></path>
|
||||
<path d="M878.390857 1024H145.609143A26.752 26.752 0 0 1 118.857143 997.248V713.142857h786.285714v284.105143c0 14.774857-11.977143 26.752-26.752 26.752z"
|
||||
fill="#C8BDB8" p-id="6712"></path>
|
||||
<path d="M338.285714 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z"
|
||||
fill="#FFFFFF" p-id="6713"></path>
|
||||
<path d="M521.142857 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z"
|
||||
fill="#FFFFFF" p-id="6714"></path>
|
||||
<path d="M704 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z"
|
||||
fill="#FFFFFF" p-id="6715"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514189634329" class="icon" style="" viewBox="0 0 1219 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="10648" width="238.0859375" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M1197.787429 327.192381a19.504762 19.504762 0 0 1 19.553523 19.407238v614.156191c0 34.913524-28.574476 63.24419-63.878095 63.24419H63.878095C28.623238 1024 0 995.718095 0 960.75581V346.599619a19.504762 19.504762 0 0 1 19.602286-19.358476h1178.185143z m-66.80381-213.089524C1179.550476 114.102857 1219.047619 153.209905 1219.047619 201.386667v80.213333H1.657905V88.259048C1.657905 39.497143 41.593905 0 90.794667 0h290.864762c17.408 0 33.987048 7.655619 45.104761 20.967619l78.214096 93.135238h626.005333z"
|
||||
fill="#23B7E5" p-id="10649"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 949 B |
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514190539077" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="14917" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M128 0h597.3l227.6 227.9v739.2c0 31.4-25.5 56.9-56.9 56.9H128c-31.4 0-56.9-25.5-56.9-56.9V56.9C71.1 25.5 96.6 0 128 0z"
|
||||
fill="#13BE93" p-id="14918"></path>
|
||||
<path d="M630.5 1024H128c-25.7 0-47.4-17-54.4-40.4l218.1-218.1c22.2-22.2 58.2-22.2 80.5 0L630.5 1024z"
|
||||
fill="#6BD8BD" p-id="14919"></path>
|
||||
<path d="M952.9 858v109.1c0 31.4-25.5 56.9-56.9 56.9H322.4l-4.7-4.7 358-358c22.2-22.2 58.2-22.2 80.5 0L952.9 858z"
|
||||
fill="#9CF9E2" p-id="14920"></path>
|
||||
<path d="M725.3 0l227.6 227.6H782.2c-31.4 0-56.9-25.5-56.9-56.9V0z" fill="#69DCC0" p-id="14921"></path>
|
||||
<path d="M327.1 483.6m-85.3 0a85.3 85.3 0 1 0 170.6 0 85.3 85.3 0 1 0-170.6 0Z" fill="#E9FFFA" p-id="14922"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514284130163" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="1551" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M915.114667 1024H108.885333V0h587.776v218.112H914.773333V1024z m-785.066667-20.821333h763.904V238.933333H675.84V20.821333H129.706667v982.357334z"
|
||||
fill="#F90E09" p-id="1552"></path>
|
||||
<path d="M708.266667 10.581333L904.533333 206.848h-196.266666z" fill="#F90E09" p-id="1553"></path>
|
||||
<path d="M282.965333 792.576c33.450667-23.210667 55.637333-57.344 76.8-91.136-30.378667 25.941333-59.050667 54.954667-76.8 91.136z m396.629334-169.642667c31.402667 15.018667 65.877333 31.061333 101.376 21.504-24.576-29.696-67.584-21.504-101.376-21.504z m-246.101334 23.210667c45.397333-16.725333 91.818667-29.696 138.922667-39.594667-30.378667-26.965333-55.978667-58.368-76.458667-93.525333-16.725333 46.08-38.912 90.112-62.464 133.12z m67.925334-243.370667c14.677333-37.546667 19.114667-83.285333-5.802667-117.418666-7.168 38.912-4.096 79.189333 5.802667 117.418666z m-45.397334-105.130666c4.096-24.917333 35.84-29.696 55.637334-22.186667 12.288 7.850667 18.432 22.869333 18.773333 37.205333 1.365333 44.032-6.485333 87.381333-12.629333 130.730667-3.413333 20.138667 8.874667 38.229333 17.749333 55.296 21.845333 40.277333 52.224 76.458667 92.16 99.669333 48.128-5.802667 98.645333-12.970667 145.749333 2.389334 35.157333 11.946667 26.965333 77.141333-11.264 77.824-53.589333 2.730667-102.058667-23.893333-150.186666-43.349334-66.218667 4.778667-130.730667 24.917333-194.218667 44.032-28.672 46.762667-54.613333 98.986667-101.034667 130.730667-23.210667 18.090667-76.458667 3.072-64.512-32.085333 20.138667-49.152 70.314667-76.117333 114.346667-100.693334 12.629333-6.485333 19.797333-18.773333 26.282667-31.061333 30.037333-57.685333 60.074667-115.370667 84.309333-175.786667-12.629333-56.661333-31.061333-114.688-21.162667-172.714666z"
|
||||
fill="#F90E09" p-id="1554"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1543300178225" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="5733" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M537.372818 38.36489h62.454472v99.134083c117.738246 0.660894 235.60867-1.211639 353.236766 0.550745 25.334266-2.423278 45.172097 17.29339 42.627656 42.627655 1.872533 205.758296-0.440596 411.626741 1.10149 617.506201-1.10149 22.250094 2.20298 46.923466-10.574302 66.640134-16.081751 11.664777-36.999043 10.133706-55.834519 11.014898-110.148981-0.550745-220.297962-0.330447-330.557091-0.330447v110.148981h-68.523681c-167.856032-30.621417-336.06454-58.599258-504.041736-88.119185-0.110149-256.977572 0-513.955144 0-770.822567 169.970892-29.420793 339.93077-59.381316 510.110945-88.350498z"
|
||||
fill="#D24625" p-id="5734"></path>
|
||||
<path d="M599.82729 170.543667h363.491636v671.908783h-363.491636v-88.119185h264.357554v-44.059592h-264.357554v-55.074491h264.357554v-44.059592h-264.247405c-0.110149-21.5892-0.110149-43.1784-0.231313-64.767601 43.630011 13.53731 93.307202 13.217878 132.299941-13.008594 42.18706-25.003819 64.216856-72.698327 67.851772-120.271672-48.366417-0.330447-96.710805-0.220298-144.956059-0.220298-0.121164-47.914807 0.550745-95.829613-0.991341-143.634271-18.075448 3.524767-36.128866 7.269833-54.083149 11.125047v-109.818534z"
|
||||
fill="#FFFFFF" p-id="5735"></path>
|
||||
<path d="M677.041725 246.216017c76.553542 3.524767 140.880546 67.961921 144.956059 144.295165-48.366417 0.550745-96.710805 0.330447-145.066208 0.330447 0-48.245254-0.121164-96.490507 0.110149-144.625612z"
|
||||
fill="#D24625" p-id="5736"></path>
|
||||
<path d="M203.940838 329.378497c59.810897 2.863874 132.288926-23.682031 181.855967 21.148605 47.485226 57.607917 34.917227 163.571236-35.467972 198.047867-25.003819 12.777282-53.642554 11.014898-80.849351 10.133706-0.110149 43.068251-0.220298 86.136503-0.110149 129.19374-21.820513-1.872533-43.74016-3.745065-65.538644-5.507449-0.980326-117.628097-1.211639-235.377357 0.110149-353.016469z"
|
||||
fill="#FFFFFF" p-id="5737"></path>
|
||||
<path d="M269.380347 388.969096c21.699349-0.991341 48.575701-4.956704 63.214501 15.420857 12.567999 21.5892 11.89609 50.007637 1.442951 72.257732-12.567999 22.69069-40.986436 20.48771-62.895068 23.131286-2.313129-36.899909-2.092831-73.799817-1.762384-110.809875z"
|
||||
fill="#D24625" p-id="5738"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1545064197737" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="14227" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M759.725253 0H134.464646v1024h817.131314V191.870707z" fill="#02007A" p-id="14228"></path>
|
||||
<path d="M72.40404 708.525253h687.838384v258.585858H72.40404z" fill="#230091" p-id="14229"></path>
|
||||
<path d="M82.747475 718.868687h667.151515v237.89899H82.747475zM755.070707 5.171717l191.353535 191.353536h-191.353535z"
|
||||
fill="#FFFFFF" p-id="14230"></path>
|
||||
<path d="M506.828283 791.272727v93.090909h25.858586c28.444444 0 41.373737-12.929293 41.373737-45.511111s-12.929293-47.579798-41.373737-47.579798h-25.858586z m-25.858586-25.858586h51.717172c42.408081 0 67.232323 29.99596 67.232323 74.989899S575.612121 910.222222 532.686869 910.222222H480.969697v-144.808081z m-132.39596 104.468687c1.034343 26.375758 22.755556 42.408081 55.337374 42.408081 34.650505 0 55.854545-17.066667 55.854546-43.959596 0-21.20404-12.412121-33.09899-40.856566-39.822222l-16.549495-3.620202c-17.583838-4.137374-24.824242-9.826263-24.824242-19.135354 0-11.894949 10.860606-19.652525 26.892929-19.652525s27.410101 7.757576 28.444444 21.204041h24.307071c-0.517172-24.824242-21.20404-41.890909-52.751515-41.89091S351.676768 782.480808 351.676768 807.822222c0 20.169697 12.412121 33.09899 38.787878 38.787879l18.618182 4.137374c18.10101 4.137374 25.341414 10.343434 25.341414 20.169697 0 11.894949-11.894949 20.169697-28.961616 20.169697s-30.513131-8.791919-32.064646-21.721212l-24.824243 0.517171zM258.585859 788.686869v53.785858h20.686868c18.10101 0 31.030303-9.826263 31.030303-26.892929s-12.412121-26.892929-31.030303-26.892929h-20.686868z m-25.858586-23.272728h56.888889c28.444444 0 46.545455 20.686869 46.545454 49.131314s-17.583838 49.131313-46.545454 49.131313h-31.030303v46.545454h-25.858586v-144.808081z"
|
||||
fill="#230091" p-id="14231"></path>
|
||||
<path d="M415.806061 443.216162h-31.030303v137.567676H321.163636V196.525253h93.090909c91.022222 0 140.670707 35.684848 140.670708 122.052525 0.517172 103.434343-92.573737 124.638384-139.119192 124.638384z m-5.688889-192.905051c-6.206061 0-14.99798 0.517172-26.89293 1.551515V387.878788h36.202021C461.834343 387.878788 491.313131 366.157576 491.313131 312.888889c0-40.856566-32.064646-62.577778-81.195959-62.577778z m258.068687 337.19596c70.852525 0 96.711111-50.165657 96.711111-84.816162 0-54.820202-35.684848-67.749495-66.19798-87.40202-25.858586-17.066667-49.648485-23.272727-49.648485-40.856566 0-22.755556 15.515152-27.410101 36.20202-27.410101 25.858586 0 54.820202 2.068687 67.232323 16.032323V306.682828c-12.929293-10.343434-37.236364-13.446465-68.783838-13.446464-67.749495 0-93.608081 44.993939-93.608081 84.29899 0 50.682828 33.616162 65.680808 66.19798 83.781818 21.20404 11.894949 46.545455 20.686869 46.545455 44.476767 0 13.963636-8.791919 27.927273-37.753536 27.927273-26.892929 0-59.991919-10.343434-74.989899-23.789899v59.991919c13.446465 10.343434 40.339394 17.583838 78.09293 17.583839z"
|
||||
fill="#7AB7FF" p-id="14232"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514189544355" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="8186" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M176 1024l672 0c26.464 0 48-21.536 48-48l0-672c0-0.544-0.256-0.992-0.288-1.504-0.064-0.736-0.256-1.376-0.416-2.08-0.544-2.272-1.472-4.32-2.88-6.112-0.224-0.288-0.192-0.64-0.416-0.928l-256-288c-0.096-0.096-0.224-0.096-0.32-0.192-1.92-2.048-4.352-3.456-7.136-4.288-0.608-0.192-1.152-0.256-1.792-0.352-0.928-0.16-1.792-0.544-2.752-0.544l-448 0c-26.464 0-48 21.536-48 48l0 928c0 26.464 21.536 48 48 48zM640 58.08l204.384 229.92-188.384 0c-7.04 0-16-13.44-16-24l0-205.92zM160 48c0-8.832 7.2-16 16-16l432 0 0 232c0 25.888 20.96 56 48 56l208 0 0 656c0 8.832-7.2 16-16 16l-672 0c-8.96 0-16-7.04-16-16l0-928zM304 448l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 576l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 320l192 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-192 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 704l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 832l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16z"
|
||||
p-id="8187"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514189554639" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="8871" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M80 34.4h864v960H80z" fill="#8095FF" p-id="8872"></path>
|
||||
<path d="M176 112m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8873"></path>
|
||||
<path d="M176 272m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8874"></path>
|
||||
<path d="M176 432m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8875"></path>
|
||||
<path d="M176 592m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8876"></path>
|
||||
<path d="M176 752m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8877"></path>
|
||||
<path d="M176 912m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8878"></path>
|
||||
<path d="M864 112m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8879"></path>
|
||||
<path d="M864 272m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8880"></path>
|
||||
<path d="M864 432m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8881"></path>
|
||||
<path d="M864 592m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8882"></path>
|
||||
<path d="M864 752m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8883"></path>
|
||||
<path d="M864 912m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8884"></path>
|
||||
<path d="M648 508L436 362.4c-4.8-3.2-11.2-4-16.8-0.8-5.6 3.2-8.8 8.8-8.8 14.4v290.4c0 5.6 3.2 11.2 8.8 14.4 5.6 3.2 12 2.4 16.8-0.8L648 533.6c4.8-2.4 7.2-8 7.2-12.8 0-4.8-3.2-9.6-7.2-12.8z"
|
||||
fill="#FFFFFF" p-id="8885"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1543300142282" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2233" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M534.310676 38.36489h65.428495v88.119185c110.25913 0 220.507245 0.220298 330.766374-0.330447 18.615178 0.771043 39.113903-0.550745 55.305803 10.574302 11.345345 16.302049 10.023557 37.010058 10.783586 55.746399-0.550745 191.218631-0.319432 382.327112-0.220298 573.435594-0.550745 32.053353 2.974022 64.767601-3.745066 96.380358-4.405959 22.910988-31.943204 23.461733-50.338084 24.232776-114.114344 0.330447-228.338837-0.220298-342.56333 0v99.134083h-68.402517c-167.867047-30.511268-336.075555-58.709407-504.151885-88.119185v-770.932716c169.0897-29.420793 338.168386-58.389975 507.136922-88.240349z"
|
||||
fill="#207245" p-id="2234"></path>
|
||||
<path d="M599.739171 159.528769h363.491636v693.938579h-363.491636v-66.089389h88.119184v-77.104286h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-66.089388z"
|
||||
fill="#FFFFFF" p-id="2235"></path>
|
||||
<path d="M731.917948 225.618157h154.208573v77.104287h-154.208573v-77.104287z" fill="#207245" p-id="2236"></path>
|
||||
<path d="M353.44605 328.827752c24.89367-1.762384 49.897488-3.304469 74.901307-4.516108-29.409778 60.251492-58.929705 120.502985-88.879213 180.53418 30.29097 61.683429 61.242833 122.926263 91.632937 184.609692-26.545904-1.553101-52.98166-3.19432-79.527564-5.066854-18.725327-45.932125-41.526166-90.322164-54.964342-138.358134-14.969246 44.731501-36.349164 86.918561-53.521389 130.74684-24.122627-0.330447-48.256268-1.321788-72.367881-2.313129 28.308288-55.404937 55.625235-111.250471 84.814716-166.324961-24.783521-56.726725-52.001334-112.35196-77.544883-168.748238 24.232776-1.431937 48.454537-2.863874 72.698327-4.185662 16.412198 43.068251 34.366482 85.585758 47.925822 129.7555 14.506621-46.802302 36.216985-90.861894 54.832163-136.133126z"
|
||||
fill="#FFFFFF" p-id="2237"></path>
|
||||
<path d="M731.917948 346.782036h154.208573v77.104287h-154.208573v-77.104287zM731.917948 467.945915h154.208573v77.104287h-154.208573v-77.104287zM731.917948 589.109794h154.208573v77.104287h-154.208573v-77.104287zM731.917948 710.273673h154.208573v77.104286h-154.208573v-77.104286z"
|
||||
fill="#207245" p-id="2238"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -1,83 +1,78 @@
|
||||
@if "%DEBUG%" == "" echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Tank build script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
@if "%DEBUG%" == "" ECHO off
|
||||
@REM ##########################################################################
|
||||
@REM
|
||||
@REM Tank build script for Windows
|
||||
@REM manual https://ss64.com/nt/
|
||||
@REM
|
||||
@REM ##########################################################################
|
||||
|
||||
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if "%GOPATH%"=="" (
|
||||
echo The GOPATH environment variable is not defined correctly
|
||||
goto end
|
||||
@REM prepare the variables.
|
||||
|
||||
@REM version name
|
||||
SET VERSION_NAME=tank-4.2.0
|
||||
ECHO VERSION_NAME: %VERSION_NAME%
|
||||
@REM golang proxy
|
||||
SET GOPROXY=https://goproxy.cn
|
||||
ECHO GOPROXY: %GOPROXY%
|
||||
@REM assign variable like Linux GOARCH=$(go env GOARCH) eg. amd64
|
||||
FOR /f %%i IN ('go env GOARCH') DO SET GOARCH=%%i
|
||||
ECHO GOARCH: %GOARCH%
|
||||
@REM eg. D:\Group\Golang
|
||||
FOR /f %%i IN ('go env GOPATH') DO SET GOPATH=%%i
|
||||
ECHO GOPATH: %GOPATH%
|
||||
@REM eg. windows
|
||||
FOR /f %%i IN ('go env GOOS') DO SET GOOS=%%i
|
||||
ECHO GOOS: %GOOS%
|
||||
@REM service dir eg. D:\Group\eyeblue\tank\build\pack
|
||||
SET PACK_DIR=%CD%
|
||||
ECHO PACK_DIR: %PACK_DIR%
|
||||
@REM build dir eg. D:\Group\eyeblue\tank\build
|
||||
FOR %%F IN (%CD%) DO SET BUILD_DIR_SLASH=%%~dpF
|
||||
SET BUILD_DIR=%BUILD_DIR_SLASH:~0,-1%
|
||||
ECHO BUILD_DIR: %BUILD_DIR%
|
||||
@REM project dir eg. D:\Group\eyeblue\tank
|
||||
FOR %%F IN (%BUILD_DIR%) DO SET PROJECT_DIR_SLASH=%%~dpF
|
||||
SET PROJECT_DIR=%PROJECT_DIR_SLASH:~0,-1%
|
||||
ECHO PROJECT_DIR: %PROJECT_DIR%
|
||||
|
||||
@REM final zip file name. eg. tank-x.x.x.windows-amd64.zip
|
||||
SET FILE_NAME=%VERSION_NAME%.%GOOS%-%GOARCH%.zip
|
||||
ECHO FILE_NAME: %FILE_NAME%
|
||||
@REM zip dist dir eg. D:\Group\eyeblue\tank\tmp\dist
|
||||
SET DIST_DIR=%PROJECT_DIR%\tmp\dist
|
||||
ECHO DIST_DIR: %DIST_DIR%
|
||||
@REM component dir eg. D:\Group\eyeblue\tank\tmp\dist\tank-x.x.x
|
||||
SET COMPONENT_DIR=%DIST_DIR%\%VERSION_NAME%
|
||||
ECHO COMPONENT_DIR: %COMPONENT_DIR%
|
||||
@REM final dist path eg. D:\Group\eyeblue\tank\tmp\dist\tank-x.x.x.windows-amd64.zip
|
||||
SET DIST_PATH=%DIST_DIR%\%FILE_NAME%
|
||||
ECHO DIST_PATH: %DIST_PATH%
|
||||
|
||||
cd %PROJECT_DIR%
|
||||
|
||||
ECHO go build -mod=readonly
|
||||
go build -mod=readonly
|
||||
|
||||
|
||||
IF EXIST %COMPONENT_DIR% (
|
||||
rmdir /s/q %COMPONENT_DIR%
|
||||
md %COMPONENT_DIR%
|
||||
) ELSE (
|
||||
md %COMPONENT_DIR%
|
||||
)
|
||||
|
||||
set PRE_DIR=%cd%
|
||||
|
||||
@rem version name
|
||||
set VERSION_NAME=tank-1.0.2
|
||||
ECHO copy .\tank.exe %COMPONENT_DIR%
|
||||
copy .\tank.exe %COMPONENT_DIR%
|
||||
|
||||
cd %GOPATH%
|
||||
ECHO %BUILD_DIR%\conf %COMPONENT_DIR%\conf /E/H/I
|
||||
xcopy %BUILD_DIR%\conf %COMPONENT_DIR%\conf /E/H/I
|
||||
|
||||
echo golang.org . Please download from: https://github.com/eyebluecn/golang.org and put in the directory with same level of github.com
|
||||
@rem echo go get golang.org/x
|
||||
@rem go get golang.org/x
|
||||
ECHO %BUILD_DIR%\html %COMPONENT_DIR%\html /E/H/I
|
||||
xcopy %BUILD_DIR%\html %COMPONENT_DIR%\html /E/H/I
|
||||
|
||||
@rem resize image
|
||||
echo go get github.com/disintegration/imaging
|
||||
go get github.com/disintegration/imaging
|
||||
ECHO please zip to %DIST_PATH%
|
||||
|
||||
@rem json parser
|
||||
echo go get github.com/json-iterator/go
|
||||
go get github.com/json-iterator/go
|
||||
|
||||
|
||||
@rem mysql
|
||||
echo go get github.com/go-sql-driver/mysql
|
||||
go get github.com/go-sql-driver/mysql
|
||||
|
||||
@rem dao database
|
||||
echo go get github.com/jinzhu/gorm
|
||||
go get github.com/jinzhu/gorm
|
||||
|
||||
|
||||
@rem uuid
|
||||
echo go get github.com/nu7hatch/gouuid
|
||||
go get github.com/nu7hatch/gouuid
|
||||
|
||||
echo build tank ...
|
||||
go install tank
|
||||
|
||||
echo packaging
|
||||
|
||||
set distFolder=%GOPATH%\src\tank\dist
|
||||
if not exist %distFolder% (
|
||||
md %distFolder%
|
||||
)
|
||||
|
||||
set distPath=%distFolder%\%VERSION_NAME%
|
||||
if exist %distPath% (
|
||||
echo clear %distPath%
|
||||
rmdir /s/q %distPath%
|
||||
)
|
||||
|
||||
echo create directory %distPath%
|
||||
md %distPath%
|
||||
|
||||
echo copying tank.exe
|
||||
copy %GOPATH%\bin\tank.exe %distPath%
|
||||
|
||||
echo copying build
|
||||
xcopy %GOPATH%\src\tank\build %distPath% /e/h
|
||||
|
||||
echo "remove pack"
|
||||
rmdir /s/q %distPath%\pack
|
||||
|
||||
echo "remove service"
|
||||
rmdir /s/q %distPath%\service
|
||||
|
||||
cd %PRE_DIR%
|
||||
|
||||
echo check the dist file in %distPath%
|
||||
echo finish!
|
||||
ECHO finish packaging!
|
||||
@@ -1,80 +1,80 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# if GOPATH not set
|
||||
if [ -z "$GOPATH" ] ; then
|
||||
echo "GOPATH not defined"
|
||||
exit 1
|
||||
fi
|
||||
###########################################################################
|
||||
#
|
||||
# Tank build script for Linux or MacOS
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
PRE_DIR=$(pwd)
|
||||
#prepare the variables.
|
||||
|
||||
VERSION_NAME=tank-1.0.2
|
||||
FINAL_NAME=$VERSION_NAME.linux-amd64.tar.gz
|
||||
# version name
|
||||
VERSION_NAME=tank-4.2.0
|
||||
echo "VERSION_NAME: ${VERSION_NAME}"
|
||||
# golang proxy
|
||||
GOPROXY=https://goproxy.cn
|
||||
echo "GOPROXY: ${GOPROXY}"
|
||||
# eg. amd64
|
||||
GOARCH=$(go env GOARCH)
|
||||
echo "GOARCH: ${GOARCH}"
|
||||
# eg. /data/golang
|
||||
GOPATH=$(go env GOPATH)
|
||||
echo "GOPATH: ${GOPATH}"
|
||||
# eg. darwin
|
||||
GOOS=$(go env GOOS)
|
||||
echo "GOOS: ${GOOS}"
|
||||
# service dir eg. /data/tank/build/pack
|
||||
PACK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
echo "PACK_DIR: ${PACK_DIR}"
|
||||
# build dir eg. /data/tank/build
|
||||
BUILD_DIR=$(dirname ${PACK_DIR})
|
||||
echo "BUILD_DIR: ${BUILD_DIR}"
|
||||
# project dir eg. /data/tank
|
||||
PROJECT_DIR=$(dirname ${BUILD_DIR})
|
||||
echo "PROJECT_DIR: ${PROJECT_DIR}"
|
||||
# final zip file name.
|
||||
FILE_NAME=${VERSION_NAME}.${GOOS}-${GOARCH}.tar.gz
|
||||
echo "FILE_NAME: ${FILE_NAME}"
|
||||
# zip dist dir eg. /data/tank/tmp/dist
|
||||
DIST_DIR=${PROJECT_DIR}/tmp/dist
|
||||
echo "DIST_DIR: ${DIST_DIR}"
|
||||
# component dir eg. /data/tank/tmp/dist/tank-x.x.x
|
||||
COMPONENT_DIR=${DIST_DIR}/${VERSION_NAME}
|
||||
echo "COMPONENT_DIR: ${COMPONENT_DIR}"
|
||||
# final dist path eg. /data/tank/tmp/dist/tank-x.x.x.darwin-amd64.tar.gz
|
||||
DIST_PATH=${DIST_DIR}/${FILE_NAME}
|
||||
echo "DIST_PATH: ${DIST_PATH}"
|
||||
|
||||
cd $GOPATH
|
||||
cd ${PROJECT_DIR}
|
||||
|
||||
echo "golang.org . Please download from: https://github.com/eyebluecn/golang.org and put in the directory with same level of github.com"
|
||||
# echo "go get golang.org/x"
|
||||
# go get golang.org/x
|
||||
|
||||
# resize image
|
||||
echo "go get github.com/disintegration/imaging"
|
||||
go get github.com/disintegration/imaging
|
||||
|
||||
# json parser
|
||||
echo "go get github.com/json-iterator/go"
|
||||
go get github.com/json-iterator/go
|
||||
|
||||
# mysql
|
||||
echo "go get github.com/go-sql-driver/mysql"
|
||||
go get github.com/go-sql-driver/mysql
|
||||
|
||||
# dao database
|
||||
echo "go get github.com/jinzhu/gorm"
|
||||
go get github.com/jinzhu/gorm
|
||||
|
||||
# uuid
|
||||
echo "go get github.com/nu7hatch/gouuid"
|
||||
go get github.com/nu7hatch/gouuid
|
||||
|
||||
echo "build tank ..."
|
||||
go install tank
|
||||
|
||||
echo "packaging..."
|
||||
distFolder="$GOPATH/src/tank/dist"
|
||||
echo "go build"
|
||||
go build
|
||||
|
||||
# if a directory
|
||||
if [ ! -d distFolder ] ; then
|
||||
mkdir $distFolder
|
||||
if [[ -d COMPONENT_DIR ]] ; then
|
||||
rm -rf ${COMPONENT_DIR}
|
||||
mkdir ${COMPONENT_DIR}
|
||||
else
|
||||
mkdir -p ${COMPONENT_DIR}
|
||||
fi
|
||||
|
||||
distPath=$distFolder/$VERSION_NAME
|
||||
|
||||
# if a directory
|
||||
if [ -d $distPath ] ; then
|
||||
echo "clear $distPath"
|
||||
rm -rf $distPath
|
||||
fi
|
||||
|
||||
echo "create directory $distPath"
|
||||
mkdir $distPath
|
||||
|
||||
echo "copying cmd tank"
|
||||
cp "$GOPATH/bin/tank" $distPath
|
||||
cp ./tank ${COMPONENT_DIR}
|
||||
|
||||
echo "copying build"
|
||||
cp -r "$GOPATH/src/tank/build/." $distPath
|
||||
cp -r ${BUILD_DIR}/* ${COMPONENT_DIR}
|
||||
|
||||
echo "remove pack"
|
||||
rm -rf $distPath/pack
|
||||
rm -rf ${COMPONENT_DIR}/pack
|
||||
|
||||
echo "remove doc"
|
||||
rm -rf ${COMPONENT_DIR}/doc
|
||||
|
||||
echo "compress to tar.gz"
|
||||
echo "tar -zcvf $distFolder/$FINAL_NAME ./$VERSION_NAME"
|
||||
cd $distPath
|
||||
cd ..
|
||||
tar -zcvf $distFolder/$FINAL_NAME ./$VERSION_NAME
|
||||
echo "tar -zcvf $DIST_PATH $COMPONENT_DIR"
|
||||
|
||||
cd $PRE_DIR
|
||||
cd ${DIST_DIR}
|
||||
tar -zcvf ${DIST_PATH} ./${VERSION_NAME}
|
||||
|
||||
echo "check the dist file in $distPath"
|
||||
echo "finish!"
|
||||
echo "finish packaging!"
|
||||
@@ -0,0 +1,379 @@
|
||||
#!/bin/bash
|
||||
#set -e
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Tank cross-compilation build script
|
||||
# Supports building for multiple platforms and architectures
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Print usage information
|
||||
usage() {
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -v, --version VERSION Version name (default: tank-4.2.0)"
|
||||
echo " -o, --os OS Target OS: linux, windows, darwin, or 'all'"
|
||||
echo " -a, --arch ARCH Target architecture: amd64, arm64, 386, or 'all'"
|
||||
echo " -p, --platform PLATFORM Specific platform (OS/ARCH format, e.g. linux/amd64)"
|
||||
echo " --list-platforms List all supported platforms"
|
||||
echo " --clean Clean dist directory before building"
|
||||
echo " -h, --help Show this help message"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 # Build for current platform"
|
||||
echo " $0 -o linux -a amd64 # Build for Linux AMD64"
|
||||
echo " $0 -p linux/arm64 # Build for Linux ARM64"
|
||||
echo " $0 -o all -a amd64 # Build for all OS with AMD64"
|
||||
echo " $0 -o all -a all # Build for all supported platforms"
|
||||
echo " $0 --clean -o all -a all # Clean and build all platforms"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# List supported platforms
|
||||
list_platforms() {
|
||||
echo "Supported platforms:"
|
||||
echo " linux/amd64 - Linux 64-bit"
|
||||
echo " linux/arm64 - Linux ARM64"
|
||||
echo " linux/386 - Linux 32-bit"
|
||||
echo " windows/amd64 - Windows 64-bit"
|
||||
echo " windows/arm64 - Windows ARM64"
|
||||
echo " windows/386 - Windows 32-bit"
|
||||
echo " darwin/amd64 - macOS Intel"
|
||||
echo " darwin/arm64 - macOS Apple Silicon"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Log functions
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Default values
|
||||
VERSION_NAME="tank-4.2.0"
|
||||
TARGET_OS=""
|
||||
TARGET_ARCH=""
|
||||
SPECIFIC_PLATFORM=""
|
||||
BUILD_ALL_OS=false
|
||||
BUILD_ALL_ARCH=false
|
||||
CLEAN_DIST=false
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-v|--version)
|
||||
VERSION_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
-o|--os)
|
||||
if [[ "$2" == "all" ]]; then
|
||||
BUILD_ALL_OS=true
|
||||
else
|
||||
TARGET_OS="$2"
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
-a|--arch)
|
||||
if [[ "$2" == "all" ]]; then
|
||||
BUILD_ALL_ARCH=true
|
||||
else
|
||||
TARGET_ARCH="$2"
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
-p|--platform)
|
||||
SPECIFIC_PLATFORM="$2"
|
||||
shift 2
|
||||
;;
|
||||
--list-platforms)
|
||||
list_platforms
|
||||
;;
|
||||
--clean)
|
||||
CLEAN_DIST=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown option: $1"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Parse specific platform
|
||||
if [[ -n "$SPECIFIC_PLATFORM" ]]; then
|
||||
if [[ "$SPECIFIC_PLATFORM" =~ ^([^/]+)/([^/]+)$ ]]; then
|
||||
TARGET_OS="${BASH_REMATCH[1]}"
|
||||
TARGET_ARCH="${BASH_REMATCH[2]}"
|
||||
else
|
||||
log_error "Invalid platform format. Use OS/ARCH format (e.g., linux/amd64)"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Set defaults if nothing specified
|
||||
if [[ -z "$TARGET_OS" && "$BUILD_ALL_OS" == false ]]; then
|
||||
TARGET_OS=$(go env GOOS)
|
||||
fi
|
||||
|
||||
if [[ -z "$TARGET_ARCH" && "$BUILD_ALL_ARCH" == false ]]; then
|
||||
TARGET_ARCH=$(go env GOARCH)
|
||||
fi
|
||||
|
||||
# Define supported platforms as a simple list
|
||||
SUPPORTED_PLATFORMS="linux/amd64 linux/arm64 linux/386 windows/amd64 windows/arm64 windows/386 darwin/amd64 darwin/arm64"
|
||||
|
||||
# Check if platform is supported
|
||||
is_platform_supported() {
|
||||
local platform="$1"
|
||||
echo "$SUPPORTED_PLATFORMS" | grep -q "\b$platform\b"
|
||||
}
|
||||
|
||||
# Validate platform
|
||||
validate_platform() {
|
||||
local os=$1
|
||||
local arch=$2
|
||||
local platform="${os}/${arch}"
|
||||
|
||||
if ! is_platform_supported "$platform"; then
|
||||
log_warn "Platform ${platform} may not be fully tested"
|
||||
return 1
|
||||
fi
|
||||
log_info "Platform ${platform} supported"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Setup directories
|
||||
GOPROXY=https://goproxy.cn
|
||||
PACK_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
BUILD_DIR=$(dirname ${PACK_DIR})
|
||||
PROJECT_DIR=$(dirname ${BUILD_DIR})
|
||||
DIST_DIR=${PROJECT_DIR}/tmp/dist
|
||||
|
||||
log_info "=== Tank Cross-Compilation Build ==="
|
||||
log_info "Version: ${VERSION_NAME}"
|
||||
log_info "GOPROXY: ${GOPROXY}"
|
||||
log_info "Project: ${PROJECT_DIR}"
|
||||
log_info "Dist: ${DIST_DIR}"
|
||||
|
||||
# Clean dist directory if requested
|
||||
if [[ "$CLEAN_DIST" == true ]]; then
|
||||
log_info "Cleaning dist directory..."
|
||||
rm -rf ${DIST_DIR}
|
||||
fi
|
||||
|
||||
# Create dist directory
|
||||
mkdir -p ${DIST_DIR}
|
||||
|
||||
# Build function for specific platform
|
||||
build_platform() {
|
||||
local os=$1
|
||||
local arch=$2
|
||||
local platform="${os}/${arch}"
|
||||
|
||||
log_info "Building ${platform}..."
|
||||
|
||||
# Validate platform
|
||||
validate_platform "$os" "$arch"
|
||||
|
||||
# Determine binary name and archive format
|
||||
local binary_name="tank"
|
||||
local archive_ext="tar.gz"
|
||||
if [[ "$os" == "windows" ]]; then
|
||||
binary_name="tank.exe"
|
||||
archive_ext="zip"
|
||||
fi
|
||||
|
||||
# Setup paths
|
||||
local file_name="${VERSION_NAME}.${os}-${arch}.${archive_ext}"
|
||||
local component_dir="${DIST_DIR}/${VERSION_NAME}-${os}-${arch}"
|
||||
local dist_path="${DIST_DIR}/${file_name}"
|
||||
|
||||
log_info " Target: ${platform}"
|
||||
log_info " Binary: ${binary_name}"
|
||||
log_info " Output: ${file_name}"
|
||||
|
||||
# Clean previous build
|
||||
if [[ -d "$component_dir" ]]; then
|
||||
rm -rf "$component_dir"
|
||||
fi
|
||||
mkdir -p "$component_dir"
|
||||
|
||||
# Change to project directory
|
||||
cd ${PROJECT_DIR}
|
||||
|
||||
# Cross-compile
|
||||
log_info " Cross-compiling..."
|
||||
export GOOS="$os"
|
||||
export GOARCH="$arch"
|
||||
export GOPROXY="$GOPROXY"
|
||||
export CGO_ENABLED=0 # Disable CGO for cross-compilation
|
||||
|
||||
log_info " Starting go build..." # 添加此行
|
||||
if ! go build -mod=readonly -ldflags="-s -w" -o "${binary_name}"; then
|
||||
log_error "Failed to build for ${platform}"
|
||||
return 1
|
||||
fi
|
||||
log_info " go build completed" # 添加此行
|
||||
|
||||
# Copy binary
|
||||
log_info " Copying binary..."
|
||||
cp "./${binary_name}" "${component_dir}/"
|
||||
|
||||
# Copy configuration and static files
|
||||
log_info " Copying build files..."
|
||||
if [[ -d "${BUILD_DIR}/conf" ]]; then
|
||||
cp -r "${BUILD_DIR}/conf" "${component_dir}/"
|
||||
fi
|
||||
if [[ -d "${BUILD_DIR}/html" ]]; then
|
||||
cp -r "${BUILD_DIR}/html" "${component_dir}/"
|
||||
fi
|
||||
if [[ -d "${BUILD_DIR}/service" ]]; then
|
||||
cp -r "${BUILD_DIR}/service" "${component_dir}/"
|
||||
fi
|
||||
|
||||
# Create archive
|
||||
log_info " Creating archive..."
|
||||
cd ${DIST_DIR}
|
||||
|
||||
if [[ "$archive_ext" == "zip" ]]; then
|
||||
# Use zip for Windows
|
||||
if command -v zip >/dev/null 2>&1; then
|
||||
zip -r "${file_name}" "$(basename "$component_dir")" >/dev/null 2>&1
|
||||
else
|
||||
log_warn "zip command not found, using tar.gz instead"
|
||||
tar -zcf "${VERSION_NAME}.${os}-${arch}.tar.gz" "$(basename "$component_dir")" >/dev/null 2>&1
|
||||
fi
|
||||
else
|
||||
# Use tar.gz for Unix-like systems
|
||||
tar -zcf "${file_name}" "$(basename "$component_dir")" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
log_error "Failed to create archive for ${platform}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
cd ${PROJECT_DIR}
|
||||
rm -f "./${binary_name}"
|
||||
rm -rf "$component_dir"
|
||||
|
||||
# Get file size
|
||||
local file_size=$(ls -lh "${DIST_DIR}/${file_name}" | awk '{print $5}')
|
||||
log_success "Built ${file_name} (${file_size})"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Build execution
|
||||
build_count=0
|
||||
success_count=0
|
||||
failed_builds=()
|
||||
|
||||
if [[ "$BUILD_ALL_OS" == true && "$BUILD_ALL_ARCH" == true ]]; then
|
||||
log_info "Building for all supported platforms..."
|
||||
# Build all supported platforms explicitly
|
||||
for os in linux windows darwin; do
|
||||
for arch in amd64 arm64 386; do
|
||||
platform="${os}/${arch}"
|
||||
if is_platform_supported "$platform"; then
|
||||
((build_count++))
|
||||
if build_platform "$os" "$arch"; then
|
||||
((success_count++))
|
||||
else
|
||||
failed_builds+=("$platform")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
elif [[ "$BUILD_ALL_OS" == true ]]; then
|
||||
log_info "Building for all OS with architecture: ${TARGET_ARCH}"
|
||||
for os in linux windows darwin; do
|
||||
platform="${os}/${TARGET_ARCH}"
|
||||
if is_platform_supported "$platform"; then
|
||||
((build_count++))
|
||||
if build_platform "$os" "$TARGET_ARCH"; then
|
||||
((success_count++))
|
||||
else
|
||||
failed_builds+=("$platform")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
elif [[ "$BUILD_ALL_ARCH" == true ]]; then
|
||||
log_info "Building for OS ${TARGET_OS} with all architectures"
|
||||
for arch in amd64 arm64 386; do
|
||||
platform="${TARGET_OS}/${arch}"
|
||||
if is_platform_supported "$platform"; then
|
||||
((build_count++))
|
||||
if build_platform "$TARGET_OS" "$arch"; then
|
||||
((success_count++))
|
||||
else
|
||||
failed_builds+=("$platform")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
log_info "Building for ${TARGET_OS}/${TARGET_ARCH}"
|
||||
((build_count++))
|
||||
if build_platform "$TARGET_OS" "$TARGET_ARCH"; then
|
||||
((success_count++))
|
||||
else
|
||||
failed_builds+=("${TARGET_OS}/${TARGET_ARCH}")
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build summary
|
||||
echo ""
|
||||
log_info "=== Build Summary ==="
|
||||
echo "Total builds: ${build_count}"
|
||||
echo "Successful: ${success_count}"
|
||||
echo "Failed: $((build_count - success_count))"
|
||||
|
||||
if [[ ${#failed_builds[@]} -gt 0 ]]; then
|
||||
echo ""
|
||||
log_warn "Failed builds:"
|
||||
for platform in "${failed_builds[@]}"; do
|
||||
echo " - $platform"
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ $success_count -gt 0 ]]; then
|
||||
echo ""
|
||||
log_success "Generated files:"
|
||||
ls -lh ${DIST_DIR}/*.{tar.gz,zip} 2>/dev/null | awk '{print " " $9 " (" $5 ")"}'
|
||||
|
||||
echo ""
|
||||
log_info "Files located in: ${DIST_DIR}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [[ $((build_count - success_count)) -eq 0 ]]; then
|
||||
log_success "All builds completed successfully!"
|
||||
exit 0
|
||||
else
|
||||
log_error "Some builds failed!"
|
||||
exit 1
|
||||
fi
|
||||
@@ -8,7 +8,7 @@ EXE_PATH=$TANK_DIR/tank
|
||||
|
||||
if [ -f "$EXE_PATH" ]; then
|
||||
nohup $EXE_PATH >/dev/null 2>&1 &
|
||||
echo 'Start tank successfully!'
|
||||
echo 'Start tank successfully! Default value http://127.0.0.1:6010'
|
||||
else
|
||||
echo 'Cannot find $EXE_PATH.'
|
||||
exit 1
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=EyeblueTank
|
||||
Documentation=https://tank-doc.eyeblue.cn
|
||||
Wants=network.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
#DynamicUser=yes
|
||||
ExecStart=/data/program/tank/tank
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,6 @@
|
||||
package core
|
||||
|
||||
type Application interface {
|
||||
//start the application
|
||||
Start()
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package core
|
||||
|
||||
/**
|
||||
* bean interface means singleton in application
|
||||
*/
|
||||
type Bean interface {
|
||||
//init the bean when constructing
|
||||
Init()
|
||||
//cleanup the bean when system's cleanup
|
||||
Cleanup()
|
||||
//when everything(including db's connection) loaded, this method will be invoked.
|
||||
Bootstrap()
|
||||
//shortcut for panic check.
|
||||
PanicError(err error)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package core
|
||||
|
||||
import "gorm.io/gorm/schema"
|
||||
|
||||
const (
|
||||
//authentication key of cookie
|
||||
COOKIE_AUTH_KEY = "_ak"
|
||||
|
||||
USERNAME_KEY = "_username"
|
||||
PASSWORD_KEY = "_password"
|
||||
|
||||
DEFAULT_SERVER_PORT = 6010
|
||||
|
||||
//db table's prefix. tank42_ means current version is tank:4.2.x
|
||||
TABLE_PREFIX = "tank42_"
|
||||
|
||||
VERSION = "4.2.0"
|
||||
)
|
||||
|
||||
type Config interface {
|
||||
Installed() bool
|
||||
ServerPort() int
|
||||
//get the db type
|
||||
DbType() string
|
||||
//get the mysql url. eg. tank:tank123@tcp(127.0.0.1:3306)/tank?charset=utf8&parseTime=True&loc=Local
|
||||
MysqlUrl() string
|
||||
//get the sqlite path
|
||||
SqliteFolder() string
|
||||
//files storage location.
|
||||
MatterPath() string
|
||||
//table name strategy
|
||||
NamingStrategy() schema.NamingStrategy
|
||||
//when installed by user. Write configs to tank.json
|
||||
FinishInstall(dbType string, mysqlPort int, mysqlHost string, mysqlSchema string, mysqlUsername string, mysqlPassword string, mysqlCharset string)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/tool/cache"
|
||||
"gorm.io/gorm"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Context interface {
|
||||
http.Handler
|
||||
|
||||
//get the gorm.DB. all the db connection will use this
|
||||
GetDB() *gorm.DB
|
||||
|
||||
GetBean(bean Bean) Bean
|
||||
|
||||
//get the global session cache
|
||||
GetSessionCache() *cache.Table
|
||||
|
||||
GetControllerMap() map[string]Controller
|
||||
|
||||
//when application installed. this method will invoke every bean's Bootstrap method
|
||||
InstallOk()
|
||||
|
||||
//this method will invoke every bean's Cleanup method
|
||||
Cleanup()
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package core
|
||||
|
||||
import "net/http"
|
||||
|
||||
type Controller interface {
|
||||
Bean
|
||||
//register self's fixed routes
|
||||
RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request)
|
||||
//handle some special routes, eg. params in the url.
|
||||
HandleRoutes(writer http.ResponseWriter, request *http.Request) (func(writer http.ResponseWriter, request *http.Request), bool)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package core
|
||||
|
||||
//the global variables in the application.
|
||||
|
||||
//application
|
||||
var APPLICATION Application
|
||||
|
||||
//logger
|
||||
var LOGGER Logger
|
||||
|
||||
//config
|
||||
var CONFIG Config
|
||||
|
||||
//context
|
||||
var CONTEXT Context
|
||||
@@ -0,0 +1,20 @@
|
||||
package core
|
||||
|
||||
//run a method with panic recovery.
|
||||
func RunWithRecovery(f func()) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
LOGGER.Error("error in async method: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
//execute the method
|
||||
f()
|
||||
}
|
||||
|
||||
//shortcut for panic check
|
||||
func PanicError(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package core
|
||||
|
||||
type Logger interface {
|
||||
|
||||
//basic log method
|
||||
Log(prefix string, format string, v ...interface{})
|
||||
|
||||
//log with different level.
|
||||
Debug(format string, v ...interface{})
|
||||
Info(format string, v ...interface{})
|
||||
Warn(format string, v ...interface{})
|
||||
Error(format string, v ...interface{})
|
||||
Panic(format string, v ...interface{})
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AlienController struct {
|
||||
BaseController
|
||||
uploadTokenDao *UploadTokenDao
|
||||
downloadTokenDao *DownloadTokenDao
|
||||
matterDao *MatterDao
|
||||
spaceDao *SpaceDao
|
||||
matterService *MatterService
|
||||
imageCacheDao *ImageCacheDao
|
||||
imageCacheService *ImageCacheService
|
||||
alienService *AlienService
|
||||
shareService *ShareService
|
||||
spaceMemberService *SpaceMemberService
|
||||
}
|
||||
|
||||
func (this *AlienController) Init() {
|
||||
this.BaseController.Init()
|
||||
|
||||
b := core.CONTEXT.GetBean(this.uploadTokenDao)
|
||||
if c, ok := b.(*UploadTokenDao); ok {
|
||||
this.uploadTokenDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.downloadTokenDao)
|
||||
if c, ok := b.(*DownloadTokenDao); ok {
|
||||
this.downloadTokenDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterDao)
|
||||
if c, ok := b.(*MatterDao); ok {
|
||||
this.matterDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceDao)
|
||||
if c, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterService)
|
||||
if c, ok := b.(*MatterService); ok {
|
||||
this.matterService = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.imageCacheDao)
|
||||
if c, ok := b.(*ImageCacheDao); ok {
|
||||
this.imageCacheDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.imageCacheService)
|
||||
if c, ok := b.(*ImageCacheService); ok {
|
||||
this.imageCacheService = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.alienService)
|
||||
if c, ok := b.(*AlienService); ok {
|
||||
this.alienService = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.shareService)
|
||||
if c, ok := b.(*ShareService); ok {
|
||||
this.shareService = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceMemberService)
|
||||
if b, ok := b.(*SpaceMemberService); ok {
|
||||
this.spaceMemberService = b
|
||||
}
|
||||
}
|
||||
|
||||
func (this *AlienController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request))
|
||||
|
||||
routeMap["/api/alien/fetch/upload/token"] = this.Wrap(this.FetchUploadToken, USER_ROLE_USER)
|
||||
routeMap["/api/alien/fetch/download/token"] = this.Wrap(this.FetchDownloadToken, USER_ROLE_USER)
|
||||
routeMap["/api/alien/confirm"] = this.Wrap(this.Confirm, USER_ROLE_USER)
|
||||
routeMap["/api/alien/upload"] = this.Wrap(this.Upload, USER_ROLE_GUEST)
|
||||
routeMap["/api/alien/crawl/token"] = this.Wrap(this.CrawlToken, USER_ROLE_GUEST)
|
||||
routeMap["/api/alien/crawl/direct"] = this.Wrap(this.CrawlDirect, USER_ROLE_USER)
|
||||
|
||||
return routeMap
|
||||
}
|
||||
|
||||
// handle some special routes, eg. params in the url.
|
||||
func (this *AlienController) HandleRoutes(writer http.ResponseWriter, request *http.Request) (func(writer http.ResponseWriter, request *http.Request), bool) {
|
||||
|
||||
path := request.URL.Path
|
||||
|
||||
//match /api/alien/preview/{uuid}/{filename} (response header not contain content-disposition)
|
||||
reg := regexp.MustCompile(`^/api/alien/preview/([^/]+)/([^/]+)$`)
|
||||
strs := reg.FindStringSubmatch(path)
|
||||
if len(strs) == 3 {
|
||||
var f = func(writer http.ResponseWriter, request *http.Request) {
|
||||
this.Preview(writer, request, strs[1], strs[2])
|
||||
}
|
||||
return f, true
|
||||
}
|
||||
|
||||
//match /api/alien/download/{uuid}/{filename} (response header contain content-disposition)
|
||||
reg = regexp.MustCompile(`^/api/alien/download/([^/]+)/([^/]+)$`)
|
||||
strs = reg.FindStringSubmatch(path)
|
||||
if len(strs) == 3 {
|
||||
var f = func(writer http.ResponseWriter, request *http.Request) {
|
||||
this.Download(writer, request, strs[1], strs[2])
|
||||
}
|
||||
return f, true
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// fetch a upload token for guest. Guest can upload file with this token.
|
||||
func (this *AlienController) FetchUploadToken(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
filename := request.FormValue("filename")
|
||||
expireTimeStr := request.FormValue("expireTime")
|
||||
privacyStr := request.FormValue("privacy")
|
||||
sizeStr := request.FormValue("size")
|
||||
//store dir path
|
||||
dirPath := request.FormValue("dirPath")
|
||||
|
||||
filename = CheckMatterName(request, filename)
|
||||
|
||||
var expireTime time.Time
|
||||
if expireTimeStr == "" {
|
||||
panic(result.BadRequest("time format error"))
|
||||
} else {
|
||||
expireTime = util.ConvertDateTimeStringToTime(expireTimeStr)
|
||||
}
|
||||
if expireTime.Before(time.Now()) {
|
||||
panic(result.BadRequest("expire time cannot before now"))
|
||||
}
|
||||
|
||||
var privacy = false
|
||||
if privacyStr == TRUE {
|
||||
privacy = true
|
||||
}
|
||||
|
||||
var size int64
|
||||
if sizeStr == "" {
|
||||
panic(result.BadRequest("file size cannot be null"))
|
||||
} else {
|
||||
|
||||
var err error
|
||||
size, err = strconv.ParseInt(sizeStr, 10, 64)
|
||||
if err != nil {
|
||||
panic(result.BadRequest("file size error"))
|
||||
}
|
||||
if size < 1 {
|
||||
panic(result.BadRequest("file size error"))
|
||||
}
|
||||
}
|
||||
|
||||
user := this.checkUser(request)
|
||||
space := this.spaceDao.CheckByUuid(user.SpaceUuid)
|
||||
dirMatter := this.matterService.CreateDirectories(request, user, space, dirPath)
|
||||
|
||||
uploadToken := &UploadToken{
|
||||
UserUuid: user.Uuid,
|
||||
FolderUuid: dirMatter.Uuid,
|
||||
MatterUuid: "",
|
||||
ExpireTime: expireTime,
|
||||
Filename: filename,
|
||||
Privacy: privacy,
|
||||
Size: size,
|
||||
Ip: util.GetIpAddress(request),
|
||||
}
|
||||
|
||||
uploadToken = this.uploadTokenDao.Create(uploadToken)
|
||||
|
||||
return this.Success(uploadToken)
|
||||
|
||||
}
|
||||
|
||||
// user confirm a file whether uploaded successfully.
|
||||
func (this *AlienController) Confirm(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
matterUuid := request.FormValue("matterUuid")
|
||||
if matterUuid == "" {
|
||||
panic(result.BadRequest("matterUuid cannot be null"))
|
||||
}
|
||||
|
||||
user := this.checkUser(request)
|
||||
|
||||
matter := this.matterDao.CheckByUuid(matterUuid)
|
||||
if matter.UserUuid != user.Uuid {
|
||||
panic(result.BadRequest("matter not belong to you"))
|
||||
}
|
||||
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
// a guest upload a file with a upload token.
|
||||
func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
//allow cors.
|
||||
this.allowCORS(writer)
|
||||
if request.Method == "OPTIONS" {
|
||||
//nil means empty response body.
|
||||
return nil
|
||||
}
|
||||
|
||||
uploadTokenUuid := request.FormValue("uploadTokenUuid")
|
||||
file, handler, err := request.FormFile("file")
|
||||
this.PanicError(err)
|
||||
defer func() {
|
||||
e := file.Close()
|
||||
this.PanicError(e)
|
||||
}()
|
||||
|
||||
if uploadTokenUuid == "" {
|
||||
panic(result.BadRequest("uploadTokenUuid cannot be null"))
|
||||
}
|
||||
|
||||
uploadToken := this.uploadTokenDao.CheckByUuid(uploadTokenUuid)
|
||||
|
||||
if uploadToken.ExpireTime.Before(time.Now()) {
|
||||
panic(result.BadRequest("uploadToken has expired"))
|
||||
}
|
||||
|
||||
user := this.userDao.CheckByUuid(uploadToken.UserUuid)
|
||||
space := this.spaceDao.CheckByUuid(user.SpaceUuid)
|
||||
|
||||
err = request.ParseMultipartForm(32 << 20)
|
||||
this.PanicError(err)
|
||||
|
||||
if handler.Filename != uploadToken.Filename {
|
||||
panic(result.BadRequest("filename doesn't the one in uploadToken"))
|
||||
}
|
||||
|
||||
if handler.Size != uploadToken.Size {
|
||||
panic(result.BadRequest("file size doesn't the one in uploadToken"))
|
||||
}
|
||||
|
||||
dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, space)
|
||||
|
||||
matter := this.matterService.Upload(request, file, handler, user, space, dirMatter, uploadToken.Filename, uploadToken.Privacy)
|
||||
|
||||
//expire the upload token.
|
||||
uploadToken.ExpireTime = time.Now()
|
||||
this.uploadTokenDao.Save(uploadToken)
|
||||
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
// crawl a url with uploadToken. guest can visit this method.
|
||||
func (this *AlienController) CrawlToken(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
//allow cors.
|
||||
this.allowCORS(writer)
|
||||
if request.Method == "OPTIONS" {
|
||||
//nil means empty response body.
|
||||
return nil
|
||||
}
|
||||
|
||||
uploadTokenUuid := request.FormValue("uploadTokenUuid")
|
||||
url := request.FormValue("url")
|
||||
|
||||
if uploadTokenUuid == "" {
|
||||
panic(result.BadRequest("uploadTokenUuid cannot be null"))
|
||||
}
|
||||
|
||||
uploadToken := this.uploadTokenDao.CheckByUuid(uploadTokenUuid)
|
||||
|
||||
if uploadToken.ExpireTime.Before(time.Now()) {
|
||||
panic(result.BadRequest("uploadToken has expired"))
|
||||
}
|
||||
|
||||
user := this.userDao.CheckByUuid(uploadToken.UserUuid)
|
||||
space := this.spaceDao.CheckByUuid(user.SpaceUuid)
|
||||
|
||||
dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, space)
|
||||
|
||||
matter := this.matterService.AtomicCrawl(request, url, uploadToken.Filename, user, space, dirMatter, uploadToken.Privacy)
|
||||
|
||||
//expire the upload token.
|
||||
uploadToken.ExpireTime = time.Now()
|
||||
this.uploadTokenDao.Save(uploadToken)
|
||||
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
// crawl a url directly. only user can visit this method.
|
||||
func (this *AlienController) CrawlDirect(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
filename := request.FormValue("filename")
|
||||
privacyStr := request.FormValue("privacy")
|
||||
dirPath := request.FormValue("dirPath")
|
||||
url := request.FormValue("url")
|
||||
|
||||
filename = CheckMatterName(request, filename)
|
||||
|
||||
var privacy bool
|
||||
if privacyStr == TRUE {
|
||||
privacy = true
|
||||
}
|
||||
|
||||
user := this.checkUser(request)
|
||||
space := this.spaceDao.CheckByUuid(user.SpaceUuid)
|
||||
dirMatter := this.matterService.CreateDirectories(request, user, space, dirPath)
|
||||
|
||||
matter := this.matterService.AtomicCrawl(request, url, filename, user, space, dirMatter, privacy)
|
||||
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
// fetch a download token for guest. Guest can download file with this token.
|
||||
func (this *AlienController) FetchDownloadToken(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
matterUuid := request.FormValue("matterUuid")
|
||||
expireTimeStr := request.FormValue("expireTime")
|
||||
|
||||
if matterUuid == "" {
|
||||
panic(result.BadRequest("matterUuid cannot be null."))
|
||||
}
|
||||
|
||||
user := this.checkUser(request)
|
||||
|
||||
matter := this.matterDao.CheckByUuid(matterUuid)
|
||||
canRead := this.spaceMemberService.canRead(user, matter.SpaceUuid)
|
||||
if !canRead {
|
||||
panic(result.BadRequest("no auth to visit this file."))
|
||||
}
|
||||
|
||||
var expireTime time.Time
|
||||
if expireTimeStr == "" {
|
||||
panic(result.BadRequest("time format error"))
|
||||
} else {
|
||||
expireTime = util.ConvertDateTimeStringToTime(expireTimeStr)
|
||||
}
|
||||
if expireTime.Before(time.Now()) {
|
||||
panic(result.BadRequest("expire time cannot before now"))
|
||||
}
|
||||
|
||||
downloadToken := &DownloadToken{
|
||||
UserUuid: user.Uuid,
|
||||
MatterUuid: matterUuid,
|
||||
ExpireTime: expireTime,
|
||||
Ip: util.GetIpAddress(request),
|
||||
}
|
||||
|
||||
downloadToken = this.downloadTokenDao.Create(downloadToken)
|
||||
|
||||
return this.Success(downloadToken)
|
||||
|
||||
}
|
||||
|
||||
// preview a file.
|
||||
func (this *AlienController) Preview(writer http.ResponseWriter, request *http.Request, uuid string, filename string) {
|
||||
matter := this.alienService.ValidMatter(writer, request, uuid, filename)
|
||||
this.alienService.PreviewOrDownload(writer, request, matter, false)
|
||||
}
|
||||
|
||||
// download a file.
|
||||
func (this *AlienController) Download(writer http.ResponseWriter, request *http.Request, uuid string, filename string) {
|
||||
matter := this.alienService.ValidMatter(writer, request, uuid, filename)
|
||||
this.alienService.PreviewOrDownload(writer, request, matter, true)
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// @Service
|
||||
type AlienService struct {
|
||||
BaseBean
|
||||
matterDao *MatterDao
|
||||
matterService *MatterService
|
||||
userDao *UserDao
|
||||
uploadTokenDao *UploadTokenDao
|
||||
downloadTokenDao *DownloadTokenDao
|
||||
shareService *ShareService
|
||||
imageCacheDao *ImageCacheDao
|
||||
imageCacheService *ImageCacheService
|
||||
spaceService *SpaceService
|
||||
}
|
||||
|
||||
func (this *AlienService) Init() {
|
||||
this.BaseBean.Init()
|
||||
|
||||
b := core.CONTEXT.GetBean(this.matterDao)
|
||||
if b, ok := b.(*MatterDao); ok {
|
||||
this.matterDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterService)
|
||||
if b, ok := b.(*MatterService); ok {
|
||||
this.matterService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.userDao)
|
||||
if b, ok := b.(*UserDao); ok {
|
||||
this.userDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.uploadTokenDao)
|
||||
if c, ok := b.(*UploadTokenDao); ok {
|
||||
this.uploadTokenDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.downloadTokenDao)
|
||||
if c, ok := b.(*DownloadTokenDao); ok {
|
||||
this.downloadTokenDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.shareService)
|
||||
if c, ok := b.(*ShareService); ok {
|
||||
this.shareService = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.imageCacheDao)
|
||||
if c, ok := b.(*ImageCacheDao); ok {
|
||||
this.imageCacheDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.imageCacheService)
|
||||
if c, ok := b.(*ImageCacheService); ok {
|
||||
this.imageCacheService = c
|
||||
}
|
||||
b = core.CONTEXT.GetBean(this.spaceService)
|
||||
if c, ok := b.(*SpaceService); ok {
|
||||
this.spaceService = c
|
||||
}
|
||||
}
|
||||
|
||||
// check whether the request params ok.
|
||||
func (this *AlienService) ValidMatter(
|
||||
writer http.ResponseWriter,
|
||||
request *http.Request,
|
||||
uuid string,
|
||||
filename string) *Matter {
|
||||
|
||||
matter := this.matterDao.CheckByUuid(uuid)
|
||||
|
||||
if matter.Name != filename {
|
||||
panic(result.BadRequest("filename in url incorrect"))
|
||||
}
|
||||
|
||||
//only private file need auth.
|
||||
if matter.Privacy {
|
||||
|
||||
//1.use downloadToken to auth.
|
||||
downloadTokenUuid := request.FormValue("downloadTokenUuid")
|
||||
if downloadTokenUuid != "" {
|
||||
downloadToken := this.downloadTokenDao.CheckByUuid(downloadTokenUuid)
|
||||
if downloadToken.ExpireTime.Before(time.Now()) {
|
||||
panic(result.BadRequest("downloadToken has expired"))
|
||||
}
|
||||
|
||||
if downloadToken.MatterUuid != uuid {
|
||||
panic(result.BadRequest("token and file info not match"))
|
||||
}
|
||||
|
||||
tokenUser := this.userDao.CheckByUuid(downloadToken.UserUuid)
|
||||
|
||||
if matter.SpaceUuid != tokenUser.SpaceUuid {
|
||||
//whether user has the space's read auth.
|
||||
this.spaceService.CheckReadableByUuid(request, tokenUser, matter.SpaceUuid)
|
||||
}
|
||||
|
||||
//TODO: expire the download token. If download by chunk, do this later.
|
||||
downloadToken.ExpireTime = time.Now()
|
||||
this.downloadTokenDao.Save(downloadToken)
|
||||
|
||||
} else {
|
||||
|
||||
//whether this is myself's matter.
|
||||
operator := this.findUser(request)
|
||||
if operator == nil {
|
||||
panic(result.BadRequest("no auth"))
|
||||
}
|
||||
|
||||
if matter.SpaceUuid != operator.SpaceUuid {
|
||||
//whether user has the space's read auth.
|
||||
this.spaceService.CheckReadableByUuid(request, operator, matter.SpaceUuid)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return matter
|
||||
}
|
||||
|
||||
func (this *AlienService) PreviewOrDownload(
|
||||
writer http.ResponseWriter,
|
||||
request *http.Request,
|
||||
matter *Matter,
|
||||
withContentDisposition bool,
|
||||
) {
|
||||
//download directory
|
||||
if matter.Dir {
|
||||
|
||||
this.matterService.DownloadZip(writer, request, []*Matter{matter})
|
||||
|
||||
} else {
|
||||
|
||||
//handle the image operation.
|
||||
needProcess, imageResizeM, imageResizeW, imageResizeH := this.imageCacheService.ResizeParams(request)
|
||||
if needProcess {
|
||||
|
||||
//if image, try to use cache.
|
||||
mode := fmt.Sprintf("%s_%d_%d", imageResizeM, imageResizeW, imageResizeH)
|
||||
imageCache := this.imageCacheDao.FindByMatterUuidAndMode(matter.Uuid, mode)
|
||||
if imageCache == nil {
|
||||
imageCache = this.imageCacheService.cacheImage(writer, request, matter)
|
||||
}
|
||||
|
||||
//download the cache image file.
|
||||
this.matterService.DownloadFile(writer, request, GetSpaceCacheRootDir(imageCache.Username)+imageCache.Path, imageCache.Name, withContentDisposition)
|
||||
|
||||
} else {
|
||||
this.matterService.DownloadFile(writer, request, matter.AbsolutePath(), matter.Name, withContentDisposition)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//async increase the download times.
|
||||
go core.RunWithRecovery(func() {
|
||||
this.matterDao.TimesIncrement(matter.Uuid)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type BaseBean struct {
|
||||
logger core.Logger
|
||||
}
|
||||
|
||||
func (this *BaseBean) Init() {
|
||||
this.logger = core.LOGGER
|
||||
}
|
||||
|
||||
func (this *BaseBean) Bootstrap() {
|
||||
|
||||
}
|
||||
|
||||
//clean up the application.
|
||||
func (this *BaseBean) Cleanup() {
|
||||
|
||||
}
|
||||
|
||||
//shortcut for panic check.
|
||||
func (this *BaseBean) PanicError(err error) {
|
||||
core.PanicError(err)
|
||||
}
|
||||
|
||||
//find the current user from request.
|
||||
func (this *BaseBean) findUser(request *http.Request) *User {
|
||||
|
||||
//try to find from SessionCache.
|
||||
sessionId := util.GetSessionUuidFromRequest(request, core.COOKIE_AUTH_KEY)
|
||||
if sessionId == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
cacheItem, err := core.CONTEXT.GetSessionCache().Value(sessionId)
|
||||
if err != nil {
|
||||
this.logger.Warn("error while get from session cache. sessionId = %s, error = %v", sessionId, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if cacheItem == nil || cacheItem.Data() == nil {
|
||||
|
||||
this.logger.Warn("cache item doesn't exist with sessionId = %s", sessionId)
|
||||
return nil
|
||||
}
|
||||
|
||||
if value, ok := cacheItem.Data().(*User); ok {
|
||||
return value
|
||||
} else {
|
||||
this.logger.Error("cache item not store the *User")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
//find current error. If not found, panic the LOGIN error.
|
||||
func (this *BaseBean) checkUser(request *http.Request) *User {
|
||||
if this.findUser(request) == nil {
|
||||
panic(result.LOGIN)
|
||||
} else {
|
||||
return this.findUser(request)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/i18n"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"github.com/json-iterator/go"
|
||||
"go/types"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type BaseController struct {
|
||||
BaseBean
|
||||
userDao *UserDao
|
||||
spaceDao *SpaceDao
|
||||
spaceService *SpaceService
|
||||
sessionDao *SessionDao
|
||||
}
|
||||
|
||||
func (this *BaseController) Init() {
|
||||
|
||||
this.BaseBean.Init()
|
||||
|
||||
b := core.CONTEXT.GetBean(this.userDao)
|
||||
if b, ok := b.(*UserDao); ok {
|
||||
this.userDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceDao)
|
||||
if b, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceService)
|
||||
if b, ok := b.(*SpaceService); ok {
|
||||
this.spaceService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.sessionDao)
|
||||
if b, ok := b.(*SessionDao); ok {
|
||||
this.sessionDao = b
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this *BaseController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
return make(map[string]func(writer http.ResponseWriter, request *http.Request))
|
||||
}
|
||||
|
||||
// handle some special routes, eg. params in the url.
|
||||
func (this *BaseController) HandleRoutes(writer http.ResponseWriter, request *http.Request) (func(writer http.ResponseWriter, request *http.Request), bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// wrap the handle method.
|
||||
func (this *BaseController) Wrap(f func(writer http.ResponseWriter, request *http.Request) *result.WebResult, qualifiedRole string) func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
var webResult *result.WebResult = nil
|
||||
|
||||
//if the api not annotated with GUEST. login is required.
|
||||
if qualifiedRole != USER_ROLE_GUEST {
|
||||
user := this.checkUser(request)
|
||||
|
||||
if user.Status == USER_STATUS_DISABLED {
|
||||
//check user's status
|
||||
webResult = result.CustomWebResultI18n(request, result.USER_DISABLED, i18n.UserDisabled)
|
||||
} else {
|
||||
if qualifiedRole == USER_ROLE_ADMINISTRATOR && user.Role != USER_ROLE_ADMINISTRATOR {
|
||||
webResult = result.ConstWebResult(result.UNAUTHORIZED)
|
||||
} else {
|
||||
webResult = f(writer, request)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
webResult = f(writer, request)
|
||||
}
|
||||
|
||||
//if webResult not nil. response a json. if webResult is nil, return empty body or binary content.
|
||||
if webResult != nil {
|
||||
|
||||
writer.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
b, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(webResult)
|
||||
|
||||
this.PanicError(err)
|
||||
|
||||
writer.WriteHeader(result.FetchHttpStatus(webResult.Code))
|
||||
|
||||
_, err = fmt.Fprintf(writer, string(b))
|
||||
this.PanicError(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// wrap the handle method without result.
|
||||
func (this *BaseController) WrapPure(f func(writer http.ResponseWriter, request *http.Request), qualifiedRole string) func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
var webResult *result.WebResult = nil
|
||||
|
||||
//if the api not annotated with GUEST. login is required.
|
||||
if qualifiedRole != USER_ROLE_GUEST {
|
||||
user := this.checkUser(request)
|
||||
|
||||
if user.Status == USER_STATUS_DISABLED {
|
||||
//check user's status
|
||||
webResult = result.CustomWebResultI18n(request, result.USER_DISABLED, i18n.UserDisabled)
|
||||
} else {
|
||||
if qualifiedRole == USER_ROLE_ADMINISTRATOR && user.Role != USER_ROLE_ADMINISTRATOR {
|
||||
webResult = result.ConstWebResult(result.UNAUTHORIZED)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//if webResult not nil. response a json. if webResult is nil, return empty body or binary content.
|
||||
if webResult != nil {
|
||||
|
||||
writer.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
b, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(webResult)
|
||||
|
||||
this.PanicError(err)
|
||||
|
||||
writer.WriteHeader(result.FetchHttpStatus(webResult.Code))
|
||||
|
||||
_, err = fmt.Fprintf(writer, string(b))
|
||||
this.PanicError(err)
|
||||
}
|
||||
|
||||
//no error.
|
||||
f(writer, request)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// response a success result. 1.string 2. WebResult 3.nil pointer 4.any type
|
||||
func (this *BaseController) Success(data interface{}) *result.WebResult {
|
||||
var webResult *result.WebResult = nil
|
||||
if value, ok := data.(string); ok {
|
||||
//a simple message
|
||||
webResult = &result.WebResult{Code: result.OK.Code, Msg: value}
|
||||
} else if value, ok := data.(*result.WebResult); ok {
|
||||
//a webResult
|
||||
webResult = value
|
||||
} else if _, ok := data.(types.Nil); ok {
|
||||
//nil pointer means OK.
|
||||
webResult = result.ConstWebResult(result.OK)
|
||||
} else {
|
||||
//other type.
|
||||
webResult = &result.WebResult{Code: result.OK.Code, Data: data}
|
||||
}
|
||||
return webResult
|
||||
}
|
||||
|
||||
// allow cors.
|
||||
func (this *BaseController) allowCORS(writer http.ResponseWriter) {
|
||||
util.AllowCORS(writer)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
)
|
||||
|
||||
type BaseDao struct {
|
||||
BaseBean
|
||||
}
|
||||
|
||||
//get an order string by sortMap
|
||||
func (this *BaseDao) GetSortString(sortArray []builder.OrderPair) string {
|
||||
|
||||
if sortArray == nil || len(sortArray) == 0 {
|
||||
return ""
|
||||
}
|
||||
str := ""
|
||||
for _, pair := range sortArray {
|
||||
if pair.Value == DIRECTION_DESC || pair.Value == DIRECTION_ASC {
|
||||
if str != "" {
|
||||
str = str + ","
|
||||
}
|
||||
str = str + " " + pair.Key + " " + pair.Value
|
||||
}
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
const (
|
||||
TRUE = "true"
|
||||
FALSE = "false"
|
||||
|
||||
DIRECTION_ASC = "ASC"
|
||||
DIRECTION_DESC = "DESC"
|
||||
|
||||
EMPTY_JSON_MAP = "{}"
|
||||
EMPTY_JSON_ARRAY = "[]"
|
||||
)
|
||||
|
||||
//pager
|
||||
type Pager struct {
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
TotalItems int `json:"totalItems"`
|
||||
TotalPages int `json:"totalPages"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
func NewPager(page int, pageSize int, totalItems int, data interface{}) *Pager {
|
||||
|
||||
return &Pager{
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
TotalItems: totalItems,
|
||||
TotalPages: int(math.Ceil(float64(totalItems) / float64(pageSize))),
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/uuid"
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
type BridgeDao struct {
|
||||
BaseDao
|
||||
}
|
||||
|
||||
//find by uuid. if not found return nil.
|
||||
func (this *BridgeDao) FindByUuid(uuid string) *Bridge {
|
||||
|
||||
var bridge = &Bridge{}
|
||||
db := core.CONTEXT.GetDB().Where("uuid = ?", uuid).First(bridge)
|
||||
if db.Error != nil {
|
||||
if db.Error.Error() == result.DB_ERROR_NOT_FOUND {
|
||||
return nil
|
||||
} else {
|
||||
panic(db.Error)
|
||||
}
|
||||
}
|
||||
return bridge
|
||||
|
||||
}
|
||||
|
||||
//find by uuid. if not found panic NotFound error
|
||||
func (this *BridgeDao) CheckByUuid(uuid string) *Bridge {
|
||||
|
||||
entity := this.FindByUuid(uuid)
|
||||
if entity == nil {
|
||||
panic(result.NotFound("not found record with uuid = %s", uuid))
|
||||
}
|
||||
|
||||
return entity
|
||||
|
||||
}
|
||||
|
||||
//find by shareUuid and matterUuid. if not found panic NotFound error.
|
||||
func (this *BridgeDao) CheckByShareUuidAndMatterUuid(shareUuid string, matterUuid string) *Bridge {
|
||||
|
||||
var bridge = &Bridge{}
|
||||
db := core.CONTEXT.GetDB().Where("share_uuid = ? AND matter_uuid = ?", shareUuid, matterUuid).First(bridge)
|
||||
if db.Error != nil {
|
||||
if db.Error.Error() == result.DB_ERROR_NOT_FOUND {
|
||||
panic(result.NotFound("not found record with shareUuid = %s and matterUuid = %s", shareUuid, matterUuid))
|
||||
} else {
|
||||
panic(db.Error)
|
||||
}
|
||||
}
|
||||
|
||||
return bridge
|
||||
}
|
||||
|
||||
//get pager
|
||||
func (this *BridgeDao) PlainPage(page int, pageSize int, shareUuid string, sortArray []builder.OrderPair) (int, []*Bridge) {
|
||||
|
||||
var wp = &builder.WherePair{}
|
||||
|
||||
if shareUuid != "" {
|
||||
wp = wp.And(&builder.WherePair{Query: "share_uuid = ?", Args: []interface{}{shareUuid}})
|
||||
}
|
||||
|
||||
var conditionDB *gorm.DB
|
||||
conditionDB = core.CONTEXT.GetDB().Model(&Bridge{}).Where(wp.Query, wp.Args...)
|
||||
|
||||
var count int64 = 0
|
||||
db := conditionDB.Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
var bridges []*Bridge
|
||||
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&bridges)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return int(count), bridges
|
||||
}
|
||||
|
||||
//get pager
|
||||
func (this *BridgeDao) Page(page int, pageSize int, shareUuid string, sortArray []builder.OrderPair) *Pager {
|
||||
|
||||
count, bridges := this.PlainPage(page, pageSize, shareUuid, sortArray)
|
||||
pager := NewPager(page, pageSize, count, bridges)
|
||||
|
||||
return pager
|
||||
}
|
||||
|
||||
func (this *BridgeDao) Create(bridge *Bridge) *Bridge {
|
||||
|
||||
timeUUID, _ := uuid.NewV4()
|
||||
bridge.Uuid = string(timeUUID.String())
|
||||
bridge.CreateTime = time.Now()
|
||||
bridge.UpdateTime = time.Now()
|
||||
bridge.Sort = time.Now().UnixNano() / 1e6
|
||||
db := core.CONTEXT.GetDB().Create(bridge)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return bridge
|
||||
}
|
||||
|
||||
func (this *BridgeDao) Save(bridge *Bridge) *Bridge {
|
||||
|
||||
bridge.UpdateTime = time.Now()
|
||||
db := core.CONTEXT.GetDB().Save(bridge)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return bridge
|
||||
}
|
||||
|
||||
func (this *BridgeDao) Delete(bridge *Bridge) {
|
||||
|
||||
db := core.CONTEXT.GetDB().Delete(&bridge)
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
|
||||
func (this *BridgeDao) DeleteByMatterUuid(matterUuid string) {
|
||||
|
||||
var wp = &builder.WherePair{}
|
||||
|
||||
wp = wp.And(&builder.WherePair{Query: "matter_uuid = ?", Args: []interface{}{matterUuid}})
|
||||
|
||||
db := core.CONTEXT.GetDB().Where(wp.Query, wp.Args).Delete(Bridge{})
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
|
||||
func (this *BridgeDao) DeleteByShareUuid(shareUuid string) {
|
||||
|
||||
var wp = &builder.WherePair{}
|
||||
|
||||
wp = wp.And(&builder.WherePair{Query: "share_uuid = ?", Args: []interface{}{shareUuid}})
|
||||
|
||||
db := core.CONTEXT.GetDB().Where(wp.Query, wp.Args).Delete(Bridge{})
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
|
||||
func (this *BridgeDao) FindByShareUuid(shareUuid string) []*Bridge {
|
||||
|
||||
if shareUuid == "" {
|
||||
panic(result.BadRequest("shareUuid cannot be nil"))
|
||||
}
|
||||
|
||||
var bridges []*Bridge
|
||||
|
||||
db := core.CONTEXT.GetDB().
|
||||
Where("share_uuid = ?", shareUuid).
|
||||
Find(&bridges)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return bridges
|
||||
}
|
||||
|
||||
func (this *BridgeDao) Cleanup() {
|
||||
this.logger.Info("[BridgeDao] cleanup: delete all bridge records.")
|
||||
db := core.CONTEXT.GetDB().Where("uuid is not null").Delete(Bridge{})
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||