Skip to content

Commit c1721ef

Browse files
committed
Merge branch 'dev'
2 parents 1193b9a + 4cc6206 commit c1721ef

File tree

15 files changed

+262
-12
lines changed

15 files changed

+262
-12
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Flutter-PicGo: 一个用于快速上传图片并获取图片URL链接的**手机
2121
- 七牛云 [v1.3+]
2222
- 阿里云OSS [v1.4+]
2323
- 腾讯云COS [v1.5+]
24+
- 牛图网 [v1.6+]
2425

2526
> 开发进度可以查看 [Projects](https://github.com/PicGo/flutter-picgo/projects),会同步更新开发进度
2627
@@ -65,7 +66,7 @@ Flutter-PicGo: 一个用于快速上传图片并获取图片URL链接的**手机
6566

6667
- [Flutter-Go](https://github.com/alibaba/flutter-go)
6768

68-
# [License](https://github.com/hackycy/flutter-picgo/blob/master/LICENSE)
69+
# License
6970

7071
``` txt
7172
MIT License

docs/static/location.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>Flutter-Picgo Release</title>
8+
<script>
9+
// var u = navigator.userAgent;
10+
// var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //判断是否是 android终端
11+
// var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //判断是否是 iOS终端
12+
if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
13+
window.location.href = 'https://apps.apple.com/cn/app/flutter-picgo/id1519714305'
14+
} else if (/(Android)/i.test(navigator.userAgent)) {
15+
window.location.href = 'https://www.pgyer.com/flutter-picgo'
16+
}
17+
</script>
18+
</head>
19+
20+
<body>
21+
</body>
22+
23+
</html>

docs/version.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"iOS": {
3-
"versionName": "1.6.0",
4-
"versionCode": "14"
3+
"versionName": "1.7.0",
4+
"versionCode": "15"
55
},
66
"Android": {
7-
"versionName": "1.6.0",
8-
"versionCode": "14"
7+
"versionName": "1.7.0",
8+
"versionCode": "15"
99
}
1010
}

docs/设计文档.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@
2424

2525
| 版本 | 描述 |
2626
| ---- | ------------------------------------------------ |
27-
| 1 | pb_setting,uploaded表初始化,增加Github图床记录 |
27+
| 1 | pb_setting,uploaded表初始化,增加Github图床记录 |
2828
| 2 | uploaded新增info列,新增SM.MS图床记录 |
29-
| 3 | 新增Gitee图床记录 |
30-
| 4 | 新增Qiniu图床记录 |
29+
| 3 | 新增Gitee图床记录 |
30+
| 4 | 新增Qiniu图床记录 |
3131
| 5 | 新增阿里云OSS图床记录 |
3232
| 6 | 新增腾讯云COS图床记录 |
33-
| 7 | 新增牛图网图床记录 |
33+
| 7 | 新增牛图网图床记录 |
34+
| 8 | 新增兰空图床记录 |
3435

lib/api/lsky_api.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import 'package:dio/dio.dart';
2+
import 'package:flutter_picgo/utils/net.dart';
3+
import 'package:path/path.dart' as path;
4+
5+
class LskyApi {
6+
static Future token(String email, String pwd, String host) async {
7+
String url = path.joinAll([host, 'api/token']);
8+
Response res = await NetUtils.getInstance().post(url, data: {
9+
'email': email,
10+
'password': pwd,
11+
});
12+
return res.data;
13+
}
14+
15+
static Future upload(String token, String host, FormData data) async {
16+
String url = path.joinAll([host, 'api/upload']);
17+
Response res = await NetUtils.getInstance()
18+
.post(url, data: data, options: buildCommonOptions(token));
19+
return res.data;
20+
}
21+
22+
static Options buildCommonOptions(String token) {
23+
return Options(headers: {
24+
'token': token,
25+
});
26+
}
27+
}

lib/model/lsky_config.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class LskyConfig {
2+
String host;
3+
String email;
4+
String password;
5+
String token;
6+
7+
LskyConfig({this.host, this.email, this.password, this.token});
8+
9+
LskyConfig.fromJson(Map<String, dynamic> json) {
10+
host = json['host'];
11+
email = json['email'];
12+
password = json['password'];
13+
token = json['token'];
14+
}
15+
16+
Map<String, dynamic> toJson() {
17+
final Map<String, dynamic> data = new Map<String, dynamic>();
18+
data['host'] = this.host;
19+
data['email'] = this.email;
20+
data['password'] = this.password;
21+
data['token'] = this.token;
22+
return data;
23+
}
24+
}

lib/resources/pb_type_keys.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ class PBTypeKeys {
1212
static const tcyun = 'tcyun';
1313

1414
static const niupic = 'niupic';
15+
16+
static const lsky = 'lsky';
1517
}

lib/routers/router_handler.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:flutter_picgo/views/pb_setting_page/aliyun_page/aliyun_page.dart
77
import 'package:flutter_picgo/views/pb_setting_page/gitee_page/gitee_page.dart';
88
import 'package:flutter_picgo/views/pb_setting_page/gitee_page/gitee_repo_page.dart';
99
import 'package:flutter_picgo/views/pb_setting_page/github_page/github_repo_page.dart';
10+
import 'package:flutter_picgo/views/pb_setting_page/lsky_page/lsky_page.dart';
1011
import 'package:flutter_picgo/views/pb_setting_page/niupic_page/niupic_page.dart';
1112
import 'package:flutter_picgo/views/pb_setting_page/pb_setting_page.dart';
1213
import 'package:flutter_picgo/views/pb_setting_page/qiniu_page/qiniu_page.dart';
@@ -126,6 +127,11 @@ var pbsettingNiupicHandler = new Handler(
126127
handlerFunc: (context, parameters) => NiupicPage(),
127128
);
128129

130+
// 兰空图床设置页面
131+
var pbsettingLskyHandler = new Handler(
132+
handlerFunc: (context, parameters) => LskyPage(),
133+
);
134+
129135
// picgo设置页面
130136
var picgosettingHandler = new Handler(
131137
handlerFunc: (BuildContext context, Map<String, List<String>> params) =>

lib/routers/routers.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ class Routes {
3434
// --------- niupic -------------------
3535
static const String settingPbNiupic = '/setting/pb/niupic';
3636
// -----------------------------------
37+
// --------- lsky -------------------
38+
static const String settingPbLsky = '/setting/pb/lsky';
39+
// -----------------------------------
3740

3841
static void configureRoutes(Router router) {
3942
router.notFoundHandler = notfoundHandler;
@@ -54,5 +57,6 @@ class Routes {
5457
router.define(settingPbAliyun, handler: pbsettingAliyunHandler);
5558
router.define(settingPbTcyun, handler: pbsettingTcyunHandler);
5659
router.define(settingPbNiupic, handler: pbsettingNiupicHandler);
60+
router.define(settingPbLsky, handler: pbsettingLskyHandler);
5761
}
5862
}

lib/utils/db_provider.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class DbProvider {
3434
try {
3535
db = await openDatabase(
3636
path,
37-
version: 7,
37+
version: 8,
3838
onCreate: (db, version) async {
3939
// 创建pb_setting表
4040
_initPb(db);
@@ -108,6 +108,9 @@ class DbProvider {
108108
// 牛图网
109109
await db.rawInsert(
110110
'INSERT INTO $TABLE_NAME_PBSETTING(type, path, name, config, visible) VALUES("${PBTypeKeys.niupic}", "/setting/pb/niupic", "牛图网图床", NULL, 1)');
111+
// 兰空图床
112+
await db.rawInsert(
113+
'INSERT INTO $TABLE_NAME_PBSETTING(type, path, name, config, visible) VALUES("${PBTypeKeys.lsky}", "/setting/pb/lsky", "兰空图床", NULL, 1)');
111114
// copy data
112115
// update authors set dynasty_index=(select id from dynasties where dynasties .name=authors.dynasty) where dynasty in (select name from dynasties )
113116
if (isExists) {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import 'dart:convert';
2+
3+
import 'package:dio/dio.dart';
4+
import 'package:flutter_picgo/api/lsky_api.dart';
5+
import 'package:flutter_picgo/model/lsky_config.dart';
6+
import 'package:flutter_picgo/model/uploaded.dart';
7+
import 'package:flutter_picgo/resources/pb_type_keys.dart';
8+
import 'package:flutter_picgo/utils/image_upload.dart';
9+
import 'dart:io';
10+
11+
import 'package:flutter_picgo/utils/strategy/image_upload_strategy.dart';
12+
import 'package:flutter_picgo/utils/strings.dart';
13+
14+
class LskyImageUpload implements ImageUploadStrategy {
15+
@override
16+
Future<Uploaded> delete(Uploaded uploaded) async {
17+
return uploaded;
18+
}
19+
20+
@override
21+
Future<Uploaded> upload(File file, String renameImage) async {
22+
String configStr = await ImageUploadUtils.getPBConfig(PBTypeKeys.lsky);
23+
if (isBlank(configStr)) {
24+
throw LskyError(error: '读取配置文件错误!请重试');
25+
}
26+
LskyConfig config = LskyConfig.fromJson(json.decode(configStr));
27+
FormData formData = FormData.fromMap({
28+
"image": await MultipartFile.fromFile(file.path, filename: renameImage),
29+
});
30+
var result = await LskyApi.upload(config.token, config.host, formData);
31+
if (result['code'] == 200) {
32+
var uploadedItem =
33+
Uploaded(-1, '${result['data']['url']}', PBTypeKeys.lsky, info: '');
34+
await ImageUploadUtils.saveUploadedItem(uploadedItem);
35+
return uploadedItem;
36+
} else {
37+
throw new LskyError(error: '${result['msg']}');
38+
}
39+
}
40+
}
41+
42+
class LskyError implements Exception {
43+
LskyError({
44+
this.error,
45+
});
46+
47+
dynamic error;
48+
49+
String get message => (error?.toString() ?? '');
50+
51+
@override
52+
String toString() {
53+
var msg = 'LskyError $message';
54+
if (error is Error) {
55+
msg += '\n${error.stackTrace}';
56+
}
57+
return msg;
58+
}
59+
}

lib/utils/strategy/upload_strategy_factory.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'package:flutter_picgo/utils/strategy/impl/aliyun_image_upload.dart';
33
import 'package:flutter_picgo/utils/strategy/impl/gitee_image_upload.dart';
44
import 'package:flutter_picgo/utils/strategy/impl/github_image_upload.dart';
55
import 'package:flutter_picgo/utils/strategy/image_upload_strategy.dart';
6+
import 'package:flutter_picgo/utils/strategy/impl/lsky_image_upload.dart';
67
import 'package:flutter_picgo/utils/strategy/impl/niupic_image_upload.dart';
78
import 'package:flutter_picgo/utils/strategy/impl/qiniu_image_upload.dart';
89
import 'package:flutter_picgo/utils/strategy/impl/smms_image_upload.dart';
@@ -39,6 +40,9 @@ class UploadStrategyFactory {
3940
} else if (type == PBTypeKeys.niupic) {
4041
/// 牛图网
4142
cache[type] = new NiupicImageUpload();
43+
} else if (type == PBTypeKeys.lsky) {
44+
/// 兰空
45+
cache[type] = new LskyImageUpload();
4246
}
4347
}
4448
return cache[type];

lib/views/pb_setting_page/base_pb_page_state.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ abstract class BasePBSettingPageState<T extends StatefulWidget>
6666
),
6767
Center(
6868
child: Text(
69-
'请先保存后再进行连接测试',
69+
tip,
7070
textAlign: TextAlign.center,
7171
style: TextStyle(color: Colors.grey[400]),
7272
),
@@ -152,6 +152,9 @@ abstract class BasePBSettingPageState<T extends StatefulWidget>
152152
/// 表单验证
153153
bool get validate => _formKey?.currentState?.validate() ?? true;
154154

155+
/// 子类可重写更改文本
156+
String get tip => '请先保存后再进行连接测试';
157+
155158
/// 保存配置
156159
save() async {
157160
if (isBlank(pbType)) {
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import 'dart:convert';
2+
3+
import 'package:flutter/material.dart';
4+
import 'package:flutter_picgo/api/lsky_api.dart';
5+
import 'package:flutter_picgo/model/config.dart';
6+
import 'package:flutter_picgo/model/lsky_config.dart';
7+
import 'package:flutter_picgo/resources/pb_type_keys.dart';
8+
import 'package:flutter_picgo/utils/strings.dart';
9+
import 'package:flutter_picgo/views/pb_setting_page/base_pb_page_state.dart';
10+
import 'package:toast/toast.dart';
11+
12+
class LskyPage extends StatefulWidget {
13+
_LskyPageState createState() => _LskyPageState();
14+
}
15+
16+
class _LskyPageState extends BasePBSettingPageState<LskyPage> {
17+
@override
18+
AppBar get appbar => AppBar(
19+
title: Text('兰空图床'),
20+
centerTitle: true,
21+
);
22+
23+
@override
24+
onLoadConfig(String config) {
25+
List<Config> configs = [];
26+
Map<String, dynamic> map;
27+
if (isBlank(config)) {
28+
map = LskyConfig().toJson();
29+
} else {
30+
map = LskyConfig.fromJson(json.decode(config)).toJson();
31+
}
32+
map.forEach((key, value) {
33+
Config config;
34+
if (key == 'host') {
35+
config = Config(
36+
label: '设定Host',
37+
placeholder: '例如:https://lsky.si-yee.com',
38+
needValidate: true,
39+
value: value);
40+
} else if (key == 'token') {
41+
config = Config(
42+
label: '设定Token',
43+
placeholder: 'Token',
44+
needValidate: false,
45+
value: value);
46+
} else if (key == 'email') {
47+
config = Config(
48+
label: '设定邮箱',
49+
placeholder: 'Email',
50+
needValidate: true,
51+
value: value);
52+
} else if (key == 'password') {
53+
config = Config(
54+
label: '设定密码',
55+
placeholder: '设定密码',
56+
needValidate: true,
57+
value: value);
58+
}
59+
config.name = key;
60+
configs.add(config);
61+
});
62+
setConfigs(configs);
63+
}
64+
65+
@override
66+
String get tip => '点击保存会自动获取Token,如果已填写字段则不会自动生成';
67+
68+
@override
69+
String get pbType => PBTypeKeys.lsky;
70+
71+
@override
72+
save() async {
73+
if (isBlank(controllers['token'].text.trim())) {
74+
// 如果Token为空,则自动获取
75+
String email = controllers['email'].value.text.trim();
76+
String pwd = controllers['password'].value.text.trim();
77+
String host = controllers['host'].value.text.trim();
78+
var result = await LskyApi.token(email, pwd, host);
79+
if (result["code"] == 200) {
80+
// controllers["token"].text = '${result["data"]["token"]}';
81+
setState(() {
82+
configs[3].value = '${result["data"]["token"]}';
83+
84+
super.save();
85+
});
86+
} else {
87+
Toast.show('Token获取失败,请检查配置', context);
88+
}
89+
} else {
90+
return super.save();
91+
}
92+
}
93+
}

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
1515
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
1616
# Read more about iOS versioning at
1717
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18-
version: 1.6.0+14
18+
version: 1.7.0+15
1919

2020
environment:
2121
sdk: ">=2.7.0 <3.0.0"

0 commit comments

Comments
 (0)