Browse Source

update api create, update action

master
daivph 5 years ago
parent
commit
6e4230d53f
12 changed files with 241 additions and 102 deletions
  1. +8
    -0
      lib/custom_model/CropPlot.dart
  2. +8
    -8
      lib/data/api/dio_provider.dart
  3. +18
    -12
      lib/data/repository/repository.dart
  4. +1
    -1
      lib/presentation/screens/actions/bloc/action_detail_bloc.dart
  5. +5
    -1
      lib/presentation/screens/actions/bloc/action_detail_event.dart
  6. +15
    -6
      lib/presentation/screens/actions/nursery/sc_edit_action_nursery.dart
  7. +10
    -0
      lib/presentation/screens/plot_detail/bloc/plot_detail_bloc.dart
  8. +11
    -1
      lib/presentation/screens/plot_detail/bloc/plot_detail_event.dart
  9. +1
    -1
      lib/presentation/screens/plot_detail/bloc/plot_detail_state.dart
  10. +156
    -71
      lib/presentation/screens/plot_detail/sc_plot_action.dart
  11. +6
    -0
      lib/utils/const_common.dart
  12. +2
    -1
      lib/utils/formatter.dart

+ 8
- 0
lib/custom_model/CropPlot.dart View File

@@ -189,6 +189,14 @@ class Activities {
this.activityTypeName,
this.activityTypeDescription});

Activities.clone(Activities activities) {
this.id = activities.id;
this.cropId = activities.cropId;
this.activityTypeName = activities.activityTypeName;
this.activityTypeDescription = activities.activityTypeDescription;
this.executeDate = activities.executeDate;
}

Activities.fromJson(Map<String, dynamic> json) {
id = json['id'];
ageDay = json['ageDay'];

+ 8
- 8
lib/data/api/dio_provider.dart View File

@@ -21,24 +21,24 @@ class HttpLogInterceptor extends InterceptorsWrapper {
var token = await pref.getString(DATA_CONST.TOKEN_KEY);
options.headers["Authorization"] = "Bearer $token";
options.receiveTimeout = 20000;
log("onRequest: ${options.uri}\n"
"data=${options.data}\n"
"method=${options.method}\n"
"headers=${options.headers}\n"
"queryParameters=${options.queryParameters}");
// log("onRequest: ${options.uri}\n"
// "data=${options.data}\n"
// "method=${options.method}\n"
// "headers=${options.headers}\n"
// "queryParameters=${options.queryParameters}");
return options;
}

@override
Future onResponse(Response response) {
log("onResponse: $response");
// log("onResponse: $response");
return super.onResponse(response);
}

@override
Future onError(DioError err) {
log("onError: $err\n"
"Response: ${err.response}");
// log("onError: $err\n"
// "Response: ${err.response}");
return super.onError(err);
}
}

+ 18
- 12
lib/data/repository/repository.dart View File

@@ -71,19 +71,22 @@ class Repository {
}

//Action
Future<void> createNursery(Function(dynamic) onSuccess,
Function(String) onError, String activityNursery,
{List<String> filePaths}) async {
Future<void> createAction(
Function(dynamic) onSuccess, Function(String) onError,
{String apiAddAction,
String paramActivity,
String activityAction,
List<String> filePaths}) async {
var formData = FormData();
filePaths.forEach((f) {
formData.files.add(MapEntry("images", MultipartFile.fromFileSync(f)));
});
formData.fields.add(MapEntry("activityNursery", activityNursery));
formData.fields.add(MapEntry(paramActivity, activityAction));
try {
await dio
.post("${ConstCommon.baseUrl}/api/createNursery", data: formData)
.post("${ConstCommon.baseUrl}/$apiAddAction", data: formData)
.then((value) {
onSuccess(value);
onSuccess(value.data);
}).catchError((onError) {
onError(AppException.handleError(onError));
});
@@ -92,19 +95,22 @@ class Repository {
}
}

Future<void> updateNursery(Function(dynamic) onSuccess,
Function(String) onError, String activityNursery,
{List<String> filePaths}) async {
Future<void> updateAction(
Function(dynamic) onSuccess, Function(String) onError,
{String apiUpdateAction,
String paramActivity,
String activityAction,
List<String> filePaths}) async {
var formData = FormData();
filePaths.forEach((f) {
formData.files.add(MapEntry("images", MultipartFile.fromFileSync(f)));
});
formData.fields.add(MapEntry("activityNursery", activityNursery));
formData.fields.add(MapEntry(paramActivity, activityAction));
try {
await dio
.post("${ConstCommon.baseUrl}/api/updateNursery", data: formData)
.post("${ConstCommon.baseUrl}/$apiUpdateAction", data: formData)
.then((value) {
onSuccess(value);
onSuccess(value.data);
}).catchError((onError) {
onError(AppException.handleError(onError));
});

+ 1
- 1
lib/presentation/screens/actions/bloc/action_detail_bloc.dart View File

@@ -31,7 +31,7 @@ class ActionDetailBloc extends Bloc<ActionDetailEvent, ActionDetailState> {
try {
yield ActionDetailLoading();
Response<String> response = await dio.get(
"${ConstCommon.baseUrl}/api/activity-nursery/${event.activityId}");
"${ConstCommon.baseUrl}/${event.apiActivity}/${event.activityId}");
final jsonData = json.decode(response.data);
yield ActionDetailSuccess(item: jsonData);
} catch (error) {

+ 5
- 1
lib/presentation/screens/actions/bloc/action_detail_event.dart View File

@@ -9,6 +9,10 @@ abstract class ActionDetailEvent {

class FetchData extends ActionDetailEvent {
final bool isNeedFetchData;
final String apiActivity;
final int activityId;
FetchData({@required this.isNeedFetchData, @required this.activityId});
FetchData(
{@required this.isNeedFetchData,
@required this.apiActivity,
@required this.activityId});
}

+ 15
- 6
lib/presentation/screens/actions/nursery/sc_edit_action_nursery.dart View File

@@ -98,9 +98,9 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
var activityNursery = jsonEncode(_nursery.toJson()).toString();
//ADD NEW
if (_nursery.activityId == null) {
_repository.createNursery((value) {
_repository.createAction((value) {
LoadingDialog.hideLoadingDialog(context);
Get.back();
Get.back(result: value);
Get.snackbar(label_add_success, "Hoạt động ươm",
snackPosition: SnackPosition.BOTTOM);
}, (error) {
@@ -116,12 +116,16 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
backgroundColor: Colors.red,
duration: Duration(seconds: 3),
));
}, activityNursery, filePaths: filePaths);
},
apiAddAction: ConstCommon.apiAddNursery,
paramActivity: ConstCommon.paramsActionNursery,
activityAction: activityNursery,
filePaths: filePaths);
} else {
//UPDATE
_repository.updateNursery((value) {
_repository.updateAction((value) {
LoadingDialog.hideLoadingDialog(context);
Get.back();
Get.back(result: value);
Get.snackbar(label_update_success, "Hoạt động ươm",
snackPosition: SnackPosition.BOTTOM);
}, (error) {
@@ -137,7 +141,11 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
backgroundColor: Colors.red,
duration: Duration(seconds: 3),
));
}, activityNursery, filePaths: filePaths);
},
apiUpdateAction: ConstCommon.apiUpdateNursery,
paramActivity: ConstCommon.paramsActionNursery,
activityAction: activityNursery,
filePaths: filePaths);
}
} else {
_autoValidate = true;
@@ -524,6 +532,7 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
ActionDetailBloc(repository: Repository())
..add(FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailNursery,
activityId: widget.activityId))),
BlocProvider<MediaHelperBloc>(
create: (context) =>

+ 10
- 0
lib/presentation/screens/plot_detail/bloc/plot_detail_bloc.dart View File

@@ -94,6 +94,16 @@ class PlotDetailBloc extends Bloc<PlotDetailEvent, PlotDetailState> {
} catch (e) {
yield PlotDetailFailure(errorString: AppException.handleError(e));
}
} else if (event is OnUpdate) {
yield PlotDetailLoading();
try {
yield PlotDetailSuccess(
items: event.currentItems,
page: event.currentPage,
hasReachedMax: event.hasReachedMax);
} catch (e) {
yield PlotDetailFailure(errorString: AppException.handleError(e));
}
}
}
}

+ 11
- 1
lib/presentation/screens/plot_detail/bloc/plot_detail_event.dart View File

@@ -1,6 +1,6 @@
part of 'plot_detail_bloc.dart';

abstract class PlotDetailEvent extends Equatable {
abstract class PlotDetailEvent {
const PlotDetailEvent();

@override
@@ -18,3 +18,13 @@ class OnRefresh extends PlotDetailEvent {
final String cropCode;
OnRefresh({this.cropId, this.cropCode});
}

class OnUpdate<T> extends PlotDetailEvent {
final List<T> currentItems;
final int currentPage;
final bool hasReachedMax;
OnUpdate(
{@required this.currentItems,
@required this.currentPage,
@required this.hasReachedMax});
}

+ 1
- 1
lib/presentation/screens/plot_detail/bloc/plot_detail_state.dart View File

@@ -1,6 +1,6 @@
part of 'plot_detail_bloc.dart';

abstract class PlotDetailState extends Equatable {
abstract class PlotDetailState {
const PlotDetailState();

@override

+ 156
- 71
lib/presentation/screens/plot_detail/sc_plot_action.dart View File

@@ -33,10 +33,12 @@ class PlotActionScreen extends StatefulWidget {
class _PlotActionScreenState extends State<PlotActionScreen> {
List<ActionType> actions = new List<ActionType>();
ScrollController _scrollController;
var changeToRefresh = Get.put(ChangeToRefreshLists());

@override
void initState() {
super.initState();
changeToRefresh.initValue();
_scrollController = ScrollController()..addListener(() => setState(() {}));
_initActionButtons();
}
@@ -66,63 +68,76 @@ class _PlotActionScreenState extends State<PlotActionScreen> {
actions.add(ActionType(plot_action_finish, null, EditActionEndScreen()));
}

Widget _createActionButtons(ActionType actionType) {
return GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => actionType.listScreen));
},
child: Container(
height: 75,
margin: EdgeInsets.all(4.0),
padding: EdgeInsets.all(0.0),
decoration: BoxDecoration(
color: COLOR_CONST.WHITE,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.0),
bottomLeft: Radius.circular(8.0),
bottomRight: Radius.circular(8.0),
topRight: Radius.circular(8.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: COLOR_CONST.GRAY1.withOpacity(0.2),
offset: Offset(1.1, 1.1),
blurRadius: 10.0),
],
),
child: Stack(
children: <Widget>[
Positioned(
top: -10,
right: -3,
child: (actionType.addScreen == null)
? Container()
: IconButton(
icon: Icon(
Icons.add_circle,
size: 40,
color: Colors.green,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => actionType.addScreen));
})),
Positioned.fill(
child: Align(
alignment: Alignment.center,
child: Text(
actionType.actionName,
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 13,
color: COLOR_CONST.BLACK2,
),
)),
),
],
),
));
Widget _createActionButtons(ActionType actionType, BuildContext _context) {
return BlocProvider<PlotDetailBloc>(
create: (context) => PlotDetailBloc(repository: Repository()),
child: GestureDetector(
onTap: () {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) => actionType.listScreen))
.then((value) {
if (1 == 1) {
try {
//TODO: refresh list
} catch (e) {
print(e.toString());
}
}
});
},
child: Container(
height: 75,
margin: EdgeInsets.all(4.0),
padding: EdgeInsets.all(0.0),
decoration: BoxDecoration(
color: COLOR_CONST.WHITE,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.0),
bottomLeft: Radius.circular(8.0),
bottomRight: Radius.circular(8.0),
topRight: Radius.circular(8.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: COLOR_CONST.GRAY1.withOpacity(0.2),
offset: Offset(1.1, 1.1),
blurRadius: 10.0),
],
),
child: Stack(
children: <Widget>[
Positioned(
top: -10,
right: -3,
child: (actionType.addScreen == null)
? Container()
: IconButton(
icon: Icon(
Icons.add_circle,
size: 40,
color: Colors.green,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => actionType.addScreen));
})),
Positioned.fill(
child: Align(
alignment: Alignment.center,
child: Text(
actionType.actionName,
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 13,
color: COLOR_CONST.BLACK2,
),
)),
),
],
),
)),
);
}

bool _showTitle(BuildContext context) {
@@ -147,17 +162,23 @@ class _PlotActionScreenState extends State<PlotActionScreen> {
expandedHeight: MediaQuery.of(context).size.width * 1.125 + 32,
flexibleSpace: _showTitle(context)
? null
: FlexibleSpaceBar(
centerTitle: true,
title: GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
childAspectRatio: 16 / 6,
children: actions.map(
(item) {
return _createActionButtons(item);
},
).toList()),
: BlocProvider<PlotDetailBloc>(
create: (context) => PlotDetailBloc(repository: Repository()),
child: BlocBuilder<PlotDetailBloc, PlotDetailState>(
builder: (contextB, state) {
return FlexibleSpaceBar(
centerTitle: true,
title: GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
childAspectRatio: 16 / 6,
children: actions.map(
(item) {
return _createActionButtons(item, contextB);
},
).toList()),
);
}),
),
),
],
@@ -196,6 +217,7 @@ class _InfinityViewState extends State<InfinityView> {
final _scrollController = ScrollController();
final _scrollThreshold = 250.0;
PlotDetailBloc _plotDetailBloc;
var a = Get.put(ChangeToRefreshLists());

@override
void initState() {
@@ -222,6 +244,9 @@ class _InfinityViewState extends State<InfinityView> {
if (state.items.isEmpty) {
return Center(child: Text(label_list_empty));
}
List<Activities> currentItems = List<Activities>.from(state.items);
Get.find<ChangeToRefreshLists>()
.updateValue(currentItems, state.page, state.hasReachedMax);
return RefreshIndicator(
child: Column(
children: [
@@ -247,7 +272,11 @@ class _InfinityViewState extends State<InfinityView> {
itemBuilder: (BuildContext context, int index) {
return index >= state.items.length
? BottomLoader()
: ItemInfinityWidget(item: state.items[index]);
: ItemInfinityWidget(
currentItems: currentItems,
item: state.items[index],
currentPage: state.page,
currentReachedMax: state.hasReachedMax);
},
itemCount: state.hasReachedMax
? state.items.length
@@ -276,9 +305,18 @@ class _InfinityViewState extends State<InfinityView> {
}

class ItemInfinityWidget extends StatelessWidget {
final List<Activities> currentItems;
final Activities item;
final int currentPage;
final bool currentReachedMax;

const ItemInfinityWidget({Key key, @required this.item}) : super(key: key);
const ItemInfinityWidget(
{Key key,
@required this.currentItems,
@required this.item,
@required this.currentPage,
@required this.currentReachedMax})
: super(key: key);

@override
Widget build(BuildContext context) {
@@ -296,7 +334,34 @@ class ItemInfinityWidget extends StatelessWidget {
cropId: item.cropId,
activityId: item.id,
isEdit: true,
));
)).then((value) {
if (value != null) {
try {
//TODO: refresh when edit activity
// BlocProvider.of<PlotDetailBloc>(context)
// .add(OnRefresh(cropId: item.cropId));
// var updatedItem = Activities.fromJson(value);

// List<Activities> updatedItems = new List<Activities>();
// currentItems.forEach((e) {
// if (e.id == updatedItem.id) {
// e.executeDate = updatedItem.executeDate;
// } else {
// //
// }
// updatedItems.add(Activities.clone(e));
// });

// BlocProvider.of<PlotDetailBloc>(context).add(
// OnUpdate<Activities>(
// currentItems: updatedItems,
// currentPage: currentPage,
// hasReachedMax: currentReachedMax));
} catch (e) {
print(e.toString());
}
}
});
}
});
}
@@ -312,3 +377,23 @@ class ActionType {
this.listScreen = listScreen;
}
}

class ChangeToRefreshLists extends GetxController {
List<Activities> currentItems;
int currentPage;
bool currentReachedMax;

void initValue() {
currentItems = List<Activities>();
currentPage = 0;
currentReachedMax = true;
update();
}

void updateValue(List<Activities> updateItems, int page, bool reachedMax) {
currentItems = updateItems;
currentPage = page;
currentReachedMax = reachedMax;
update();
}
}

+ 6
- 0
lib/utils/const_common.dart View File

@@ -4,6 +4,12 @@ class ConstCommon {
static const String baseUrl = "http://tpf.aztrace.vn";
static const String baseImageUrl = "http://s3.tpf.aztrace.vn/upload/";

static const String apiDetailNursery = "api/activity-nursery";

static const String paramsActionNursery = "activityNursery";
static const String apiUpdateNursery = "api/updateNursery";
static const String apiAddNursery = "api/createNursery";

static const String supplyTypeSeed = "GIONG";
static const String supplyTypeDung = "PHANBON";
static const String supplyTypeSubStrate = "GIATHE";

+ 2
- 1
lib/utils/formatter.dart View File

@@ -16,11 +16,12 @@ extension ddMM_HHmm on String {
}
}

//TODO: Check timezone with api update true/false
String format_DDMMYY_HHmm() {
try {
final str = this.toString();
var dateFromString =
DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(str, true).toLocal();
DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(str, false).toLocal();
return DateFormat("dd/MM/yyyy HH:mm").format(dateFromString);
} catch (_) {
return "";

Loading…
Cancel
Save