Skip to content

Commit 58accda

Browse files
committed
feature:complete lsky repo manage
1 parent 2492cdf commit 58accda

File tree

7 files changed

+368
-1
lines changed

7 files changed

+368
-1
lines changed

lib/api/lsky_api.dart

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,33 @@ class LskyApi {
1919
return res.data;
2020
}
2121

22+
static Future images(String token, String host, int page,
23+
{int rows = 10}) async {
24+
String url = path.joinAll([host, 'api/images']);
25+
Response res = await NetUtils.getInstance().post(
26+
url,
27+
data: {
28+
'page': page,
29+
'rows': rows,
30+
},
31+
options: buildCommonOptions(token),
32+
);
33+
return res.data;
34+
}
35+
36+
static Future delete(String token, String host, String id) async {
37+
String url = path.joinAll([host, 'api/delete']);
38+
Response res = await NetUtils.getInstance().post(url,
39+
data: {
40+
'id': id,
41+
},
42+
options: buildCommonOptions(token));
43+
return res.data;
44+
}
45+
2246
static Options buildCommonOptions(String token) {
2347
return Options(headers: {
2448
'token': token,
25-
});
49+
}, contentType: Headers.formUrlEncodedContentType);
2650
}
2751
}

lib/model/lsky_content.dart

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
class LskyContent {
2+
int id;
3+
String strategy;
4+
String path;
5+
String name;
6+
Null aliasName;
7+
String pathname;
8+
String size;
9+
String mime;
10+
String sha1;
11+
String md5;
12+
String ip;
13+
int suspicious;
14+
int uploadTime;
15+
String uploadDate;
16+
String url;
17+
18+
LskyContent(
19+
{this.id,
20+
this.strategy,
21+
this.path,
22+
this.name,
23+
this.aliasName,
24+
this.pathname,
25+
this.size,
26+
this.mime,
27+
this.sha1,
28+
this.md5,
29+
this.ip,
30+
this.suspicious,
31+
this.uploadTime,
32+
this.uploadDate,
33+
this.url});
34+
35+
LskyContent.fromJson(Map<String, dynamic> json) {
36+
id = json['id'];
37+
strategy = json['strategy'];
38+
path = json['path'];
39+
name = json['name'];
40+
aliasName = json['alias_name'];
41+
pathname = json['pathname'];
42+
size = json['size'];
43+
mime = json['mime'];
44+
sha1 = json['sha1'];
45+
md5 = json['md5'];
46+
ip = json['ip'];
47+
suspicious = json['suspicious'];
48+
uploadTime = json['upload_time'];
49+
uploadDate = json['upload_date'];
50+
url = json['url'];
51+
}
52+
53+
Map<String, dynamic> toJson() {
54+
final Map<String, dynamic> data = new Map<String, dynamic>();
55+
data['id'] = this.id;
56+
data['strategy'] = this.strategy;
57+
data['path'] = this.path;
58+
data['name'] = this.name;
59+
data['alias_name'] = this.aliasName;
60+
data['pathname'] = this.pathname;
61+
data['size'] = this.size;
62+
data['mime'] = this.mime;
63+
data['sha1'] = this.sha1;
64+
data['md5'] = this.md5;
65+
data['ip'] = this.ip;
66+
data['suspicious'] = this.suspicious;
67+
data['upload_time'] = this.uploadTime;
68+
data['upload_date'] = this.uploadDate;
69+
data['url'] = this.url;
70+
return data;
71+
}
72+
}

lib/routers/router_handler.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
33

44
import 'package:flutter_picgo/views/home.dart';
55
import 'package:flutter_picgo/views/album_page/album_page.dart';
6+
import 'package:flutter_picgo/views/manage_page/lsky_page/lsky_repo_page.dart';
67
import 'package:flutter_picgo/views/manage_page/smms_page/smms_repo_page.dart';
78
import 'package:flutter_picgo/views/pb_setting_page/aliyun_page/aliyun_page.dart';
89
import 'package:flutter_picgo/views/pb_setting_page/gitee_page/gitee_page.dart';
@@ -139,6 +140,11 @@ var pbsettingLskyHandler = new Handler(
139140
handlerFunc: (context, parameters) => LskyPage(),
140141
);
141142

143+
// 兰空管理页面
144+
var pbsettingLskyRepoHandler = new Handler(
145+
handlerFunc: (context, parameters) => LskyRepoPage(),
146+
);
147+
142148
// 又拍云图床设置页面
143149
var pbsettingUpyunHandler = new Handler(
144150
handlerFunc: (context, parameters) => UpyunPage(),

lib/routers/routers.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Routes {
3737
// -----------------------------------
3838
// --------- lsky -------------------
3939
static const String settingPbLsky = '/setting/pb/lsky';
40+
static const String settingPbLskyRepo = '/setting/pb/lsky/repo';
4041
// -----------------------------------
4142
// --------- upyun -------------------
4243
static const String settingPbUpyun = '/setting/pb/upyun';
@@ -64,5 +65,6 @@ class Routes {
6465
router.define(settingPbLsky, handler: pbsettingLskyHandler);
6566
router.define(settingPbUpyun, handler: pbsettingUpyunHandler);
6667
router.define(settingPbSMMSRepo, handler: pbsettingSMMSRepoHandler);
68+
router.define(settingPbLskyRepo, handler: pbsettingLskyRepoHandler);
6769
}
6870
}
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_picgo/components/manage_item.dart';
3+
import 'package:flutter_picgo/model/lsky_content.dart';
4+
import 'package:flutter_picgo/views/manage_page/base_loading_page_state.dart';
5+
import 'package:flutter_picgo/views/manage_page/lsky_page/lsky_repo_page_presenter.dart';
6+
import 'package:pull_to_refresh/pull_to_refresh.dart';
7+
import 'package:url_launcher/url_launcher.dart';
8+
9+
class LskyRepoPage extends StatefulWidget {
10+
_LskyRepoPageState createState() => _LskyRepoPageState();
11+
}
12+
13+
class _LskyRepoPageState extends BaseLoadingPageState<LskyRepoPage>
14+
implements LskyRepoPageContract {
15+
String errorMsg;
16+
int currentPage = 1;
17+
RefreshController _refreshController =
18+
RefreshController(initialRefresh: false);
19+
List<LskyContent> contents = [];
20+
LskyRepoPagePresenter _presenter;
21+
22+
_LskyRepoPageState() {
23+
_presenter = LskyRepoPagePresenter(this);
24+
}
25+
26+
@override
27+
void initState() {
28+
super.initState();
29+
_presenter.doLoadContents(currentPage);
30+
}
31+
32+
@override
33+
AppBar get appBar => AppBar(
34+
title: Text('图床仓库'),
35+
centerTitle: true,
36+
);
37+
38+
Widget buildEmtpy() {
39+
return Center(
40+
child: Text('数据空空如也噢'),
41+
);
42+
}
43+
44+
@override
45+
Widget buildError() {
46+
return Center(
47+
child: Column(
48+
mainAxisAlignment: MainAxisAlignment.center,
49+
children: <Widget>[
50+
RaisedButton(
51+
color: Theme.of(context).accentColor,
52+
textColor: Colors.white,
53+
child: Text('刷新'),
54+
onPressed: () {
55+
setState(() {
56+
this.state = LoadState.LOADING;
57+
// _presenter.doLoadContents(_path, _prePath);
58+
});
59+
},
60+
),
61+
SizedBox(height: 5),
62+
Text(this.errorMsg ?? '未知错误',
63+
style: TextStyle(color: Colors.grey[400])),
64+
],
65+
),
66+
);
67+
}
68+
69+
@override
70+
Widget buildLoading() {
71+
return Center(
72+
child: SizedBox(
73+
width: 20,
74+
height: 20,
75+
child: CircularProgressIndicator(
76+
backgroundColor: Colors.transparent,
77+
valueColor: AlwaysStoppedAnimation(Colors.blue),
78+
),
79+
),
80+
);
81+
}
82+
83+
@override
84+
Widget buildSuccess() {
85+
return SmartRefresher(
86+
enablePullDown: false,
87+
enablePullUp: true,
88+
footer: CustomFooter(
89+
builder: (BuildContext context, LoadStatus mode) {
90+
Widget body;
91+
if (mode == LoadStatus.idle) {
92+
body = Text("上拉加载");
93+
} else if (mode == LoadStatus.loading) {
94+
body = SizedBox(
95+
width: 15,
96+
height: 15,
97+
child: CircularProgressIndicator(),
98+
);
99+
} else if (mode == LoadStatus.failed) {
100+
body = Text("加载失败!点击重试!");
101+
} else if (mode == LoadStatus.canLoading) {
102+
body = Text("松手,加载更多!");
103+
} else {
104+
body = Text("没有更多数据了!");
105+
}
106+
return Container(
107+
height: 55.0,
108+
child: Center(child: body),
109+
);
110+
},
111+
),
112+
onLoading: _onLoading,
113+
controller: _refreshController,
114+
child: ListView.builder(
115+
itemCount: contents.length,
116+
itemBuilder: (context, index) {
117+
return ManageItem(
118+
Key('$index'),
119+
contents[index].url,
120+
contents[index].name,
121+
'${contents[index].size}k',
122+
FileContentType.FILE,
123+
onTap: () {
124+
launch(contents[index].url);
125+
},
126+
confirmDismiss: (direction) async {
127+
bool result = await showDialog(
128+
context: context,
129+
builder: (BuildContext context) {
130+
return AlertDialog(
131+
title: Text('确定删除吗'),
132+
content: Text('删除后无法恢复'),
133+
actions: <Widget>[
134+
FlatButton(
135+
child: Text('确定'),
136+
onPressed: () {
137+
Navigator.pop(context, true);
138+
}),
139+
],
140+
);
141+
});
142+
if (!(result ?? false)) {
143+
return false;
144+
}
145+
146+
var del = await _presenter
147+
.doDeleteContents('${contents[index].id}');
148+
return del;
149+
},
150+
);
151+
}));
152+
}
153+
154+
_onLoading() async {
155+
_presenter.doLoadContents(currentPage);
156+
}
157+
158+
@override
159+
void loadError(String msg) {
160+
setState(() {
161+
this.state = LoadState.ERROR;
162+
this.errorMsg = msg;
163+
});
164+
}
165+
166+
@override
167+
void loadSuccess(List<LskyContent> data, bool isEnd) {
168+
if (data != null && data.length > 0) {
169+
setState(() {
170+
if (this.state != LoadState.SUCCESS) {
171+
this.state = LoadState.SUCCESS;
172+
}
173+
this.contents.addAll(data);
174+
175+
if (isEnd) {
176+
_refreshController.loadNoData();
177+
}
178+
179+
currentPage += 1;
180+
});
181+
} else {
182+
if (currentPage == 1) {
183+
setState(() {
184+
this.state = LoadState.EMTPY;
185+
});
186+
}
187+
}
188+
}
189+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import 'dart:convert';
2+
3+
import 'package:flutter_picgo/api/lsky_api.dart';
4+
import 'package:flutter_picgo/model/lsky_config.dart';
5+
import 'package:flutter_picgo/model/lsky_content.dart';
6+
import 'package:flutter_picgo/resources/pb_type_keys.dart';
7+
import 'package:flutter_picgo/utils/image_upload.dart';
8+
import 'package:flutter_picgo/utils/strings.dart';
9+
10+
abstract class LskyRepoPageContract {
11+
void loadSuccess(List<LskyContent> data, bool isEnd);
12+
13+
void loadError(String msg);
14+
}
15+
16+
class LskyRepoPagePresenter {
17+
LskyRepoPageContract _view;
18+
19+
LskyRepoPagePresenter(this._view);
20+
21+
doLoadContents(int page) async {
22+
try {
23+
String configStr = await ImageUploadUtils.getPBConfig(PBTypeKeys.lsky);
24+
if (isBlank(configStr)) {
25+
_view.loadError('读取配置错误!');
26+
return;
27+
}
28+
LskyConfig config = LskyConfig.fromJson(json.decode(configStr));
29+
var result = await LskyApi.images(config.token, config.host, page);
30+
if (result['code'] == 200) {
31+
bool isEnd =
32+
result['data']['current_page'] == result['data']['last_page'];
33+
_view.loadSuccess(
34+
(result['data']['data'] as List<dynamic>)
35+
.map((e) => LskyContent.fromJson(e))
36+
.toList(),
37+
isEnd);
38+
} else {
39+
_view.loadError(result['msg']);
40+
}
41+
} catch (e) {
42+
_view.loadError('$e');
43+
}
44+
}
45+
46+
Future<bool> doDeleteContents(String id) async {
47+
try {
48+
String configStr = await ImageUploadUtils.getPBConfig(PBTypeKeys.lsky);
49+
if (isBlank(configStr)) {
50+
return false;
51+
}
52+
LskyConfig config = LskyConfig.fromJson(json.decode(configStr));
53+
var result = await LskyApi.delete(config.token, config.host, id);
54+
if (result['code'] == 200) {
55+
return true;
56+
}
57+
return false;
58+
} catch (e) {
59+
return false;
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)