diff --git a/README.md b/README.md
index 563e89e..1cf226f 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@ Flutter-PicGo: 一个用于快速上传图片并获取图片URL链接的**手机
- 七牛云 [v1.3+]
- 阿里云OSS [v1.4+]
- 腾讯云COS [v1.5+]
+- 牛图网 [v1.6+]
> 开发进度可以查看 [Projects](https://github.com/PicGo/flutter-picgo/projects),会同步更新开发进度
@@ -65,7 +66,7 @@ Flutter-PicGo: 一个用于快速上传图片并获取图片URL链接的**手机
- [Flutter-Go](https://github.com/alibaba/flutter-go)
-# [License](https://github.com/hackycy/flutter-picgo/blob/master/LICENSE)
+# License
``` txt
MIT License
diff --git a/docs/static/location.html b/docs/static/location.html
new file mode 100644
index 0000000..97263e3
--- /dev/null
+++ b/docs/static/location.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ Flutter-Picgo Release
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/version.json b/docs/version.json
index cd58e8d..74b8f5f 100644
--- a/docs/version.json
+++ b/docs/version.json
@@ -1,10 +1,10 @@
{
"iOS": {
- "versionName": "1.6.0",
- "versionCode": "14"
+ "versionName": "1.7.0",
+ "versionCode": "15"
},
"Android": {
- "versionName": "1.6.0",
- "versionCode": "14"
+ "versionName": "1.7.0",
+ "versionCode": "15"
}
}
\ No newline at end of file
diff --git "a/docs/\350\256\276\350\256\241\346\226\207\346\241\243.md" "b/docs/\350\256\276\350\256\241\346\226\207\346\241\243.md"
index a2a4629..a3d9ead 100644
--- "a/docs/\350\256\276\350\256\241\346\226\207\346\241\243.md"
+++ "b/docs/\350\256\276\350\256\241\346\226\207\346\241\243.md"
@@ -24,11 +24,12 @@
| 版本 | 描述 |
| ---- | ------------------------------------------------ |
-| 1 | pb_setting,uploaded表初始化,增加Github图床记录 |
+| 1 | pb_setting,uploaded表初始化,增加Github图床记录 |
| 2 | uploaded新增info列,新增SM.MS图床记录 |
-| 3 | 新增Gitee图床记录 |
-| 4 | 新增Qiniu图床记录 |
+| 3 | 新增Gitee图床记录 |
+| 4 | 新增Qiniu图床记录 |
| 5 | 新增阿里云OSS图床记录 |
| 6 | 新增腾讯云COS图床记录 |
-| 7 | 新增牛图网图床记录 |
+| 7 | 新增牛图网图床记录 |
+| 8 | 新增兰空图床记录 |
diff --git a/lib/api/lsky_api.dart b/lib/api/lsky_api.dart
new file mode 100644
index 0000000..c327e93
--- /dev/null
+++ b/lib/api/lsky_api.dart
@@ -0,0 +1,27 @@
+import 'package:dio/dio.dart';
+import 'package:flutter_picgo/utils/net.dart';
+import 'package:path/path.dart' as path;
+
+class LskyApi {
+ static Future token(String email, String pwd, String host) async {
+ String url = path.joinAll([host, 'api/token']);
+ Response res = await NetUtils.getInstance().post(url, data: {
+ 'email': email,
+ 'password': pwd,
+ });
+ return res.data;
+ }
+
+ static Future upload(String token, String host, FormData data) async {
+ String url = path.joinAll([host, 'api/upload']);
+ Response res = await NetUtils.getInstance()
+ .post(url, data: data, options: buildCommonOptions(token));
+ return res.data;
+ }
+
+ static Options buildCommonOptions(String token) {
+ return Options(headers: {
+ 'token': token,
+ });
+ }
+}
diff --git a/lib/model/lsky_config.dart b/lib/model/lsky_config.dart
new file mode 100644
index 0000000..ab2a7a2
--- /dev/null
+++ b/lib/model/lsky_config.dart
@@ -0,0 +1,24 @@
+class LskyConfig {
+ String host;
+ String email;
+ String password;
+ String token;
+
+ LskyConfig({this.host, this.email, this.password, this.token});
+
+ LskyConfig.fromJson(Map json) {
+ host = json['host'];
+ email = json['email'];
+ password = json['password'];
+ token = json['token'];
+ }
+
+ Map toJson() {
+ final Map data = new Map();
+ data['host'] = this.host;
+ data['email'] = this.email;
+ data['password'] = this.password;
+ data['token'] = this.token;
+ return data;
+ }
+}
diff --git a/lib/resources/pb_type_keys.dart b/lib/resources/pb_type_keys.dart
index b0ee8f3..f003a53 100644
--- a/lib/resources/pb_type_keys.dart
+++ b/lib/resources/pb_type_keys.dart
@@ -12,4 +12,6 @@ class PBTypeKeys {
static const tcyun = 'tcyun';
static const niupic = 'niupic';
+
+ static const lsky = 'lsky';
}
diff --git a/lib/routers/router_handler.dart b/lib/routers/router_handler.dart
index 7007fb8..f80bbf7 100644
--- a/lib/routers/router_handler.dart
+++ b/lib/routers/router_handler.dart
@@ -7,6 +7,7 @@ import 'package:flutter_picgo/views/pb_setting_page/aliyun_page/aliyun_page.dart
import 'package:flutter_picgo/views/pb_setting_page/gitee_page/gitee_page.dart';
import 'package:flutter_picgo/views/pb_setting_page/gitee_page/gitee_repo_page.dart';
import 'package:flutter_picgo/views/pb_setting_page/github_page/github_repo_page.dart';
+import 'package:flutter_picgo/views/pb_setting_page/lsky_page/lsky_page.dart';
import 'package:flutter_picgo/views/pb_setting_page/niupic_page/niupic_page.dart';
import 'package:flutter_picgo/views/pb_setting_page/pb_setting_page.dart';
import 'package:flutter_picgo/views/pb_setting_page/qiniu_page/qiniu_page.dart';
@@ -126,6 +127,11 @@ var pbsettingNiupicHandler = new Handler(
handlerFunc: (context, parameters) => NiupicPage(),
);
+// 兰空图床设置页面
+var pbsettingLskyHandler = new Handler(
+ handlerFunc: (context, parameters) => LskyPage(),
+);
+
// picgo设置页面
var picgosettingHandler = new Handler(
handlerFunc: (BuildContext context, Map> params) =>
diff --git a/lib/routers/routers.dart b/lib/routers/routers.dart
index f63e8f1..7a39a3d 100644
--- a/lib/routers/routers.dart
+++ b/lib/routers/routers.dart
@@ -34,6 +34,9 @@ class Routes {
// --------- niupic -------------------
static const String settingPbNiupic = '/setting/pb/niupic';
// -----------------------------------
+ // --------- lsky -------------------
+ static const String settingPbLsky = '/setting/pb/lsky';
+ // -----------------------------------
static void configureRoutes(Router router) {
router.notFoundHandler = notfoundHandler;
@@ -54,5 +57,6 @@ class Routes {
router.define(settingPbAliyun, handler: pbsettingAliyunHandler);
router.define(settingPbTcyun, handler: pbsettingTcyunHandler);
router.define(settingPbNiupic, handler: pbsettingNiupicHandler);
+ router.define(settingPbLsky, handler: pbsettingLskyHandler);
}
}
diff --git a/lib/utils/db_provider.dart b/lib/utils/db_provider.dart
index 9979988..5f8ee74 100644
--- a/lib/utils/db_provider.dart
+++ b/lib/utils/db_provider.dart
@@ -34,7 +34,7 @@ class DbProvider {
try {
db = await openDatabase(
path,
- version: 7,
+ version: 8,
onCreate: (db, version) async {
// 创建pb_setting表
_initPb(db);
@@ -108,6 +108,9 @@ class DbProvider {
// 牛图网
await db.rawInsert(
'INSERT INTO $TABLE_NAME_PBSETTING(type, path, name, config, visible) VALUES("${PBTypeKeys.niupic}", "/setting/pb/niupic", "牛图网图床", NULL, 1)');
+ // 兰空图床
+ await db.rawInsert(
+ 'INSERT INTO $TABLE_NAME_PBSETTING(type, path, name, config, visible) VALUES("${PBTypeKeys.lsky}", "/setting/pb/lsky", "兰空图床", NULL, 1)');
// copy data
// update authors set dynasty_index=(select id from dynasties where dynasties .name=authors.dynasty) where dynasty in (select name from dynasties )
if (isExists) {
diff --git a/lib/utils/strategy/impl/lsky_image_upload.dart b/lib/utils/strategy/impl/lsky_image_upload.dart
new file mode 100644
index 0000000..66f7fcb
--- /dev/null
+++ b/lib/utils/strategy/impl/lsky_image_upload.dart
@@ -0,0 +1,59 @@
+import 'dart:convert';
+
+import 'package:dio/dio.dart';
+import 'package:flutter_picgo/api/lsky_api.dart';
+import 'package:flutter_picgo/model/lsky_config.dart';
+import 'package:flutter_picgo/model/uploaded.dart';
+import 'package:flutter_picgo/resources/pb_type_keys.dart';
+import 'package:flutter_picgo/utils/image_upload.dart';
+import 'dart:io';
+
+import 'package:flutter_picgo/utils/strategy/image_upload_strategy.dart';
+import 'package:flutter_picgo/utils/strings.dart';
+
+class LskyImageUpload implements ImageUploadStrategy {
+ @override
+ Future delete(Uploaded uploaded) async {
+ return uploaded;
+ }
+
+ @override
+ Future upload(File file, String renameImage) async {
+ String configStr = await ImageUploadUtils.getPBConfig(PBTypeKeys.lsky);
+ if (isBlank(configStr)) {
+ throw LskyError(error: '读取配置文件错误!请重试');
+ }
+ LskyConfig config = LskyConfig.fromJson(json.decode(configStr));
+ FormData formData = FormData.fromMap({
+ "image": await MultipartFile.fromFile(file.path, filename: renameImage),
+ });
+ var result = await LskyApi.upload(config.token, config.host, formData);
+ if (result['code'] == 200) {
+ var uploadedItem =
+ Uploaded(-1, '${result['data']['url']}', PBTypeKeys.lsky, info: '');
+ await ImageUploadUtils.saveUploadedItem(uploadedItem);
+ return uploadedItem;
+ } else {
+ throw new LskyError(error: '${result['msg']}');
+ }
+ }
+}
+
+class LskyError implements Exception {
+ LskyError({
+ this.error,
+ });
+
+ dynamic error;
+
+ String get message => (error?.toString() ?? '');
+
+ @override
+ String toString() {
+ var msg = 'LskyError $message';
+ if (error is Error) {
+ msg += '\n${error.stackTrace}';
+ }
+ return msg;
+ }
+}
diff --git a/lib/utils/strategy/upload_strategy_factory.dart b/lib/utils/strategy/upload_strategy_factory.dart
index 7a9fd0b..4368809 100644
--- a/lib/utils/strategy/upload_strategy_factory.dart
+++ b/lib/utils/strategy/upload_strategy_factory.dart
@@ -3,6 +3,7 @@ import 'package:flutter_picgo/utils/strategy/impl/aliyun_image_upload.dart';
import 'package:flutter_picgo/utils/strategy/impl/gitee_image_upload.dart';
import 'package:flutter_picgo/utils/strategy/impl/github_image_upload.dart';
import 'package:flutter_picgo/utils/strategy/image_upload_strategy.dart';
+import 'package:flutter_picgo/utils/strategy/impl/lsky_image_upload.dart';
import 'package:flutter_picgo/utils/strategy/impl/niupic_image_upload.dart';
import 'package:flutter_picgo/utils/strategy/impl/qiniu_image_upload.dart';
import 'package:flutter_picgo/utils/strategy/impl/smms_image_upload.dart';
@@ -39,6 +40,9 @@ class UploadStrategyFactory {
} else if (type == PBTypeKeys.niupic) {
/// 牛图网
cache[type] = new NiupicImageUpload();
+ } else if (type == PBTypeKeys.lsky) {
+ /// 兰空
+ cache[type] = new LskyImageUpload();
}
}
return cache[type];
diff --git a/lib/views/pb_setting_page/base_pb_page_state.dart b/lib/views/pb_setting_page/base_pb_page_state.dart
index 34c65ff..57e2cbc 100644
--- a/lib/views/pb_setting_page/base_pb_page_state.dart
+++ b/lib/views/pb_setting_page/base_pb_page_state.dart
@@ -66,7 +66,7 @@ abstract class BasePBSettingPageState
),
Center(
child: Text(
- '请先保存后再进行连接测试',
+ tip,
textAlign: TextAlign.center,
style: TextStyle(color: Colors.grey[400]),
),
@@ -152,6 +152,9 @@ abstract class BasePBSettingPageState
/// 表单验证
bool get validate => _formKey?.currentState?.validate() ?? true;
+ /// 子类可重写更改文本
+ String get tip => '请先保存后再进行连接测试';
+
/// 保存配置
save() async {
if (isBlank(pbType)) {
diff --git a/lib/views/pb_setting_page/lsky_page/lsky_page.dart b/lib/views/pb_setting_page/lsky_page/lsky_page.dart
new file mode 100644
index 0000000..da941af
--- /dev/null
+++ b/lib/views/pb_setting_page/lsky_page/lsky_page.dart
@@ -0,0 +1,93 @@
+import 'dart:convert';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_picgo/api/lsky_api.dart';
+import 'package:flutter_picgo/model/config.dart';
+import 'package:flutter_picgo/model/lsky_config.dart';
+import 'package:flutter_picgo/resources/pb_type_keys.dart';
+import 'package:flutter_picgo/utils/strings.dart';
+import 'package:flutter_picgo/views/pb_setting_page/base_pb_page_state.dart';
+import 'package:toast/toast.dart';
+
+class LskyPage extends StatefulWidget {
+ _LskyPageState createState() => _LskyPageState();
+}
+
+class _LskyPageState extends BasePBSettingPageState {
+ @override
+ AppBar get appbar => AppBar(
+ title: Text('兰空图床'),
+ centerTitle: true,
+ );
+
+ @override
+ onLoadConfig(String config) {
+ List configs = [];
+ Map map;
+ if (isBlank(config)) {
+ map = LskyConfig().toJson();
+ } else {
+ map = LskyConfig.fromJson(json.decode(config)).toJson();
+ }
+ map.forEach((key, value) {
+ Config config;
+ if (key == 'host') {
+ config = Config(
+ label: '设定Host',
+ placeholder: '例如:https://lsky.si-yee.com',
+ needValidate: true,
+ value: value);
+ } else if (key == 'token') {
+ config = Config(
+ label: '设定Token',
+ placeholder: 'Token',
+ needValidate: false,
+ value: value);
+ } else if (key == 'email') {
+ config = Config(
+ label: '设定邮箱',
+ placeholder: 'Email',
+ needValidate: true,
+ value: value);
+ } else if (key == 'password') {
+ config = Config(
+ label: '设定密码',
+ placeholder: '设定密码',
+ needValidate: true,
+ value: value);
+ }
+ config.name = key;
+ configs.add(config);
+ });
+ setConfigs(configs);
+ }
+
+ @override
+ String get tip => '点击保存会自动获取Token,如果已填写字段则不会自动生成';
+
+ @override
+ String get pbType => PBTypeKeys.lsky;
+
+ @override
+ save() async {
+ if (isBlank(controllers['token'].text.trim())) {
+ // 如果Token为空,则自动获取
+ String email = controllers['email'].value.text.trim();
+ String pwd = controllers['password'].value.text.trim();
+ String host = controllers['host'].value.text.trim();
+ var result = await LskyApi.token(email, pwd, host);
+ if (result["code"] == 200) {
+ // controllers["token"].text = '${result["data"]["token"]}';
+ setState(() {
+ configs[3].value = '${result["data"]["token"]}';
+
+ super.save();
+ });
+ } else {
+ Toast.show('Token获取失败,请检查配置', context);
+ }
+ } else {
+ return super.save();
+ }
+ }
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 033fa80..6987852 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
-version: 1.6.0+14
+version: 1.7.0+15
environment:
sdk: ">=2.7.0 <3.0.0"