添加key.properties

This commit is contained in:
toly
2021-02-24 20:15:45 +08:00
parent 4197991c3a
commit 742f351b29
14 changed files with 348 additions and 144 deletions

1
android/.gitignore vendored
View File

@@ -4,5 +4,4 @@ gradle-wrapper.jar
/gradlew
/gradlew.bat
/local.properties
/key.properties
GeneratedPluginRegistrant.java

View File

@@ -54,10 +54,10 @@ android {
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
// keyAlias keystoreProperties['keyAlias']
// keyPassword keystoreProperties['keyPassword']
// storeFile file(keystoreProperties['storeFile'])
// storePassword keystoreProperties['storePassword']
}
}
buildTypes {

View File

@@ -7,9 +7,9 @@ import 'package:flutter_unit/app/utils/http_utils/result_bean.dart';
/// 说明:
class CategoryApi {
static Future<ResultBean<bool>> uploadCategoryData(String data) async {
HttpUtil.getInstance().client.get(PathUnit.register);
static Future<ResultBean<bool>> uploadCategoryData(String data) async {
var result = await HttpUtil.getInstance()
.client
.post(PathUnit.categoryDataSync, data: data)
@@ -23,4 +23,20 @@ class CategoryApi {
return ResultBean.error('请求错误');
}
static Future<ResultBean<String>> getCategoryData() async {
var result = await HttpUtil.getInstance()
.client
.get(PathUnit.categoryData)
.catchError((err) {
return ResultBean.error('请求错误: ${err.toString()}');
});
if (result.data != null && result.data['data']!=null) {
var dataStr = result.data['data']['data'];
return ResultBean.ok<String>(dataStr);
}
return ResultBean.error('请求错误');
}
}

View File

@@ -4,12 +4,15 @@
class PathUnit{
static const baseUrl='http://119.45.173.197:8080/api/v1';
// static const baseUrl='http://192.168.0.104:8080/api/v1';
// static const baseUrl='http://119.45.173.197:8080/api/v1';
static const baseUrl='http://192.168.0.104:8080/api/v1';
static const sendEmail = '/sendEmail/';
static const register = '/register';
static const categoryDataSync = '/categoryData/sync';
static const categoryData = '/categoryData';
static const login = '/login';
}

View File

@@ -25,4 +25,12 @@ class ResultBean<T> {
status: false,
);
}
static ResultBean<T> ok<T>(T data) {
return ResultBean(
msg: '请求成功',
data: data,
status: true,
);
}
}

View File

@@ -55,22 +55,12 @@ class CategoryModel extends Equatable {
String toString() {
return 'CategoryModel{id: $id, name: $name, info: $info, createDate: $createDate, imageCover: $imageCover, count: $count, color: $color}';
}
Map toJson() => {
"id": this.id,
"name": this.name,
"info": this.info,
"createDate": this.createDate,
"imageCover": this.imageCover,
"count": this.count,
"color": this.color.value,
};
}
// 收藏集的 To 对象,用与上传/同步 收藏集
class CategoryTo{
final CategoryModel model;
final CategoryPo model;
final List<int> widgetIds;
CategoryTo({this.model, this.widgetIds});

View File

@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter_unit/model/category_model.dart';
import 'package:flutter_unit/model/widget_model.dart';
@@ -69,7 +70,6 @@ class CategoryDbRepository implements CategoryRepository {
return success != -1;
}
@override
Future<List<CategoryTo>> loadCategoryData() async {
List<Map<String, dynamic>> data = await _categoryDao.queryAll();
@@ -82,7 +82,8 @@ class CategoryDbRepository implements CategoryRepository {
for (int i = 0; i < data.length; i++) {
List<int> ids = await _categoryDao.loadCollectWidgetIds(data[i]['id']);
collects.add(CategoryTo(widgetIds: ids, model: CategoryModel.fromPo(CategoryPo.fromJson(data[i]))));
collects
.add(CategoryTo(widgetIds: ids, model: CategoryPo.fromJson(data[i])));
if (i == data.length - 1) {
completer.complete(collects);
@@ -92,4 +93,24 @@ class CategoryDbRepository implements CategoryRepository {
return completer.future;
}
@override
Future<bool> syncCategoryByData(String data) async {
try {
await _categoryDao.clear();
List<dynamic> dataMap = json.decode(data);
for (int i = 0; i < dataMap.length; i++) {
CategoryPo po = CategoryPo.fromNetJson(dataMap[i]["model"]);
List<dynamic> widgetIds = dataMap[i]["widgetIds"];
await addCategory(po);
await _categoryDao.addWidgets(po.id, widgetIds);
// for (int j = 0; j < widgetIds.length; j++) {
// await _categoryDao.addWidget(po.id, widgetIds[j]);
// }
}
return true;
} catch (e) {
print(e);
return false;
}
}
}

View File

@@ -22,6 +22,10 @@ abstract class CategoryRepository {
// 获取 所有收藏集 及 收藏集对应的组件 id 列表
Future<List<CategoryTo>> loadCategoryData();
// 根据 Category 数据 同步 收藏集
Future<bool> syncCategoryByData(String data);
//添加收藏集
Future<bool> addCategory(CategoryPo categoryPo);

View File

@@ -26,21 +26,22 @@ class CategoryDao {
Future<Database> get _db async =>await storage.db;
Future<int> insert(CategoryPo widget) async {
Future<int> insert(CategoryPo category) async {
//插入方法
final db = await _db;
String addSql = //插入数据
"INSERT INTO "
"category(name,color,info,priority,image,created,updated) "
"VALUES (?,?,?,?,?,?,?);";
"category(id,name,color,info,priority,image,created,updated) "
"VALUES (?,?,?,?,?,?,?,?);";
return await db.transaction((tran) async => await tran.rawInsert(addSql, [
widget.name,
widget.color,
widget.info,
widget.priority,
widget.image,
widget.created.toIso8601String(),
widget.updated.toIso8601String(),
category.id,
category.name,
category.color,
category.info,
category.priority,
category.image,
category.created.toIso8601String(),
category.updated.toIso8601String(),
]));
}
@@ -77,6 +78,25 @@ class CategoryDao {
]));
}
Future<int> addWidgets(int categoryId,List<dynamic> widgetIds) async {
final db = await _db;
String addSql = //插入数据
"INSERT INTO "
"category_widget(widgetId,categoryId) VALUES ";
String args = '';
for(int i=0;i< widgetIds.length;i++){
args+= "(${widgetIds[i]},$categoryId)";
if(i==widgetIds.length-1){
args+=";";
}else{
args+=",";
}
}
addSql += args;
return await db.transaction((tran) async => await tran.rawInsert(addSql));
}
Future<bool> existByName(String name) async {
final db = await _db;
@@ -125,6 +145,16 @@ class CategoryDao {
[id]);
}
Future<void> clear() async {
final db = await _db;
await db.execute(
"DELETE FROM category_widget "
"WHERE categoryId >0");
return await db.execute(
"DELETE FROM category "
"WHERE id > 0");
}
Future<int> removeWidget(int categoryId, int widgetId) async {
//插入方法
final db = await _db;

View File

@@ -1,4 +1,5 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_unit/model/category_model.dart';
/// create by 张风捷特烈 on 2020-04-17
/// contact me by email 1981462002@qq.com
@@ -51,6 +52,30 @@ class CategoryPo extends Equatable {
info: map["info"]);
}
factory CategoryPo.fromNetJson(Map<String, dynamic> map) {
return CategoryPo(
id: map['id'],
name: map['name'],
color: map["color"],
created: DateTime.fromMillisecondsSinceEpoch(map["created"]),
image: map["image"],
priority: map["priority"],
count: map["count"],
updated: DateTime.fromMillisecondsSinceEpoch(map["updated"]),
info: map["info"]);
}
Map toJson() => {
"id": this.id,
"name": this.name,
"info": this.info,
"created": this.created.millisecondsSinceEpoch,
"updated": this.updated.millisecondsSinceEpoch,
"image": this.image,
"count": this.count,
"color": this.color,
"priority": this.priority,
};
@override
String toString() {

View File

@@ -16,7 +16,7 @@ class LoginFrom extends StatefulWidget {
class _LoginFromState extends State<LoginFrom> {
final _usernameController = TextEditingController(text: '张风捷特烈');
final _passwordController = TextEditingController(text: '');
final _passwordController = TextEditingController(text: '111111');
bool _showPwd = false;

View File

@@ -9,13 +9,12 @@ import 'package:flutter_unit/app/res/toly_icon.dart';
import 'package:flutter_unit/app/router/unit_router.dart';
import 'package:flutter_unit/app/utils/http_utils/result_bean.dart';
import 'package:flutter_unit/blocs/bloc_exp.dart';
import 'package:flutter_unit/model/category_model.dart';
import 'package:flutter_unit/repositories/itf/category_repository.dart';
import 'package:flutter_unit/user_system/component/authentic_widget.dart';
import 'package:flutter_unit/views/components/permanent/circle_image.dart';
import 'package:flutter_unit/views/components/permanent/feedback_widget.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_unit/views/pages/category/sync/upload_button.dart';
import 'sync/async_button.dart';
import 'category_page.dart';
import 'like_widget_page.dart';
@@ -75,8 +74,13 @@ class _CollectPageState extends State<CollectPage>
)),
backgroundColor: BlocProvider.of<WidgetsBloc>(context).state.color,
actions: <Widget>[
AuthenticWidget.just(SyncCategoryButton()),
AuthenticWidget.just(_buildLoadAction(context)),
SizedBox(
width: 32,
child: AuthenticWidget.just(UploadCategoryButton())),
// SizedBox(width: 5,),
SizedBox(
width: 32,
child: AuthenticWidget.just(SyncCategoryButton())),
_buildAddAction(context)
],
title: Text(
@@ -128,117 +132,11 @@ class _CollectPageState extends State<CollectPage>
),
onPressed: () => Scaffold.of(context).openEndDrawer());
Widget _buildLoadAction(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: FeedbackWidget(
child: Icon(
TolyIcon.download,
size: 28,
),
onPressed: () async {
final dir = await getExternalStorageDirectory();
CategoryRepository rep =
BlocProvider.of<CategoryBloc>(context).repository;
List<CategoryTo> loadCategories = await rep.loadCategoryData();
String json1 = jsonEncode(loadCategories);
loadCategories.forEach((element) {
print("${element.model.name} - ${element.widgetIds} ");
});
print(json1);
File backFile = File(dir.path + "/back.txt");
backFile.writeAsString(json1);
}),
);
}
@override
bool get wantKeepAlive => true;
}
class SyncCategoryButton extends StatefulWidget {
@override
_SyncCategoryButtonState createState() => _SyncCategoryButtonState();
}
enum AsyncType { loading, error, none, success }
class _SyncCategoryButtonState extends State<SyncCategoryButton> {
AsyncType state = AsyncType.none;
@override
Widget build(BuildContext context) {
Widget result;
switch (state) {
case AsyncType.loading:
result = _buildLoading();
break;
case AsyncType.error:
result = _buildError();
break;
case AsyncType.none:
result = _buildDefault();
break;
case AsyncType.success:
result = _buildSuccess();
break;
}
return result;
}
Widget _buildLoading() {
return const CupertinoActivityIndicator();
}
Widget _buildError() {
return const Icon(
TolyIcon.error,
size: 28,
color: Colors.green,
);
}
Widget _buildDefault() {
return FeedbackWidget(
child: const Icon(
TolyIcon.upload,
size: 28,
),
onPressed: () async {
CategoryRepository rep =
BlocProvider.of<CategoryBloc>(context).repository;
List<CategoryTo> loadCategories = await rep.loadCategoryData();
String json = jsonEncode(loadCategories);
setState(() {
state = AsyncType.loading;
});
ResultBean<bool> result = await CategoryApi.uploadCategoryData(json);
if (result.status) {
setState(() {
state = AsyncType.success;
});
_toDefault();
} else {
setState(() {
state = AsyncType.error;
});
}
});
}
Widget _buildSuccess() {
return const Icon(
TolyIcon.upload_success,
size: 25,
color: Colors.green,
);
}
void _toDefault() async {
await Future.delayed(const Duration(milliseconds: 800));
setState(() {
state = AsyncType.none;
});
}
}

View File

@@ -0,0 +1,106 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_unit/app/api/category_api.dart';
import 'package:flutter_unit/app/res/toly_icon.dart';
import 'package:flutter_unit/app/utils/http_utils/result_bean.dart';
import 'package:flutter_unit/blocs/bloc_exp.dart';
import 'package:flutter_unit/blocs/category/category_bloc.dart';
import 'package:flutter_unit/model/category_model.dart';
import 'package:flutter_unit/repositories/itf/category_repository.dart';
import 'package:flutter_unit/views/components/permanent/feedback_widget.dart';
/// create by 张风捷特烈 on 2021/2/24
/// contact me by email 1981462002@qq.com
/// 说明: 同步数据按钮,点击时请求服务器,获取备份数据。
class SyncCategoryButton extends StatefulWidget {
@override
_SyncCategoryButtonState createState() => _SyncCategoryButtonState();
}
enum AsyncType { loading, error, none, success }
class _SyncCategoryButtonState extends State<SyncCategoryButton> {
AsyncType state = AsyncType.none;
@override
Widget build(BuildContext context) {
Widget result;
switch (state) {
case AsyncType.loading:
result = _buildLoading();
break;
case AsyncType.error:
result = _buildError();
break;
case AsyncType.none:
result = _buildDefault();
break;
case AsyncType.success:
result = _buildSuccess();
break;
}
return result;
}
Widget _buildLoading() {
return const CupertinoActivityIndicator();
}
Widget _buildError() {
return const Icon(
TolyIcon.error,
size: 25,
color: Colors.red,
);
}
Widget _buildDefault() {
return FeedbackWidget(
child: const Icon(
TolyIcon.download,
size: 28,
),
onPressed: () async {
setState(() {
state = AsyncType.loading;
});
ResultBean<String> result = await CategoryApi.getCategoryData();
CategoryRepository repository = BlocProvider.of<CategoryBloc>(context).repository;
await repository.syncCategoryByData(result.data);
BlocProvider.of<CategoryBloc>(context).add(EventLoadCategory());
if (result.status) {
setState(() {
state = AsyncType.success;
});
_toDefault();
} else {
setState(() {
state = AsyncType.error;
});
_toDefault();
}
});
}
Widget _buildSuccess() => const Icon(
TolyIcon.upload_success,
size: 25,
color: Colors.green,
);
void _toDefault() async {
await Future.delayed(const Duration(milliseconds: 800));
setState(() {
state = AsyncType.none;
});
}
}

View File

@@ -0,0 +1,104 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_unit/app/api/category_api.dart';
import 'package:flutter_unit/app/res/toly_icon.dart';
import 'package:flutter_unit/app/utils/http_utils/result_bean.dart';
import 'package:flutter_unit/blocs/category/category_bloc.dart';
import 'package:flutter_unit/model/category_model.dart';
import 'package:flutter_unit/repositories/itf/category_repository.dart';
import 'package:flutter_unit/views/components/permanent/feedback_widget.dart';
/// create by 张风捷特烈 on 2021/2/24
/// contact me by email 1981462002@qq.com
/// 说明:
class UploadCategoryButton extends StatefulWidget {
@override
_UploadCategoryButtonState createState() => _UploadCategoryButtonState();
}
enum AsyncType { loading, error, none, success }
class _UploadCategoryButtonState extends State<UploadCategoryButton> {
AsyncType state = AsyncType.none;
@override
Widget build(BuildContext context) {
Widget result;
switch (state) {
case AsyncType.loading:
result = _buildLoading();
break;
case AsyncType.error:
result = _buildError();
break;
case AsyncType.none:
result = _buildDefault();
break;
case AsyncType.success:
result = _buildSuccess();
break;
}
return result;
}
Widget _buildLoading() {
return const CupertinoActivityIndicator();
}
Widget _buildError() {
return const Icon(
TolyIcon.error,
size: 28,
color: Colors.green,
);
}
Widget _buildDefault() {
return FeedbackWidget(
child: const Icon(
TolyIcon.upload,
size: 28,
),
onPressed: () async {
CategoryRepository rep =
BlocProvider.of<CategoryBloc>(context).repository;
List<CategoryTo> loadCategories = await rep.loadCategoryData();
String json = jsonEncode(loadCategories);
setState(() {
state = AsyncType.loading;
});
ResultBean<bool> result = await CategoryApi.uploadCategoryData(json);
if (result.status) {
setState(() {
state = AsyncType.success;
});
_toDefault();
} else {
setState(() {
state = AsyncType.error;
});
}
});
}
Widget _buildSuccess() {
return const Icon(
TolyIcon.upload_success,
size: 25,
color: Colors.green,
);
}
void _toDefault() async {
await Future.delayed(const Duration(milliseconds: 800));
setState(() {
state = AsyncType.none;
});
}
}