Browse Source

list supply

master
daivph 5 years ago
parent
commit
48b3f631e9
15 changed files with 252 additions and 70 deletions
  1. +9
    -0
      jsons/Supply.json
  2. +5
    -0
      lib/data/api/rest_client.dart
  3. +21
    -0
      lib/data/api/rest_client.g.dart
  4. +7
    -0
      lib/data/repository/repository.dart
  5. +1
    -1
      lib/models/Plot.g.dart
  6. +1
    -1
      lib/models/ResourceHelper.g.dart
  7. +20
    -0
      lib/models/Supply.dart
  8. +29
    -0
      lib/models/Supply.g.dart
  9. +2
    -2
      lib/models/index.dart
  10. +4
    -2
      lib/presentation/screens/home/view/home_page.dart
  11. +49
    -0
      lib/presentation/screens/resources/bloc/supply_bloc.dart
  12. +20
    -0
      lib/presentation/screens/resources/bloc/supply_event.dart
  13. +25
    -0
      lib/presentation/screens/resources/bloc/supply_state.dart
  14. +53
    -63
      lib/presentation/screens/resources/sc_resource_helper.dart
  15. +6
    -1
      lib/utils/const_common.dart

+ 9
- 0
jsons/Supply.json View File

@@ -0,0 +1,9 @@
{
"id": 1,
"name": "Rau muống",
"sku": "SKURAUMUONG",
"manufacturer": "Bộ nông nghiệp",
"unit": "g",
"tbSuppliesTypeId": 1,
"tbCustomerId": 1
}

+ 5
- 0
lib/data/api/rest_client.dart View File

@@ -1,5 +1,7 @@
import 'package:dio/dio.dart';
import 'package:farm_tpf/models/Supply.dart';
import 'package:farm_tpf/models/account.dart';
import 'package:farm_tpf/models/index.dart';
import 'package:farm_tpf/models/password.dart';
import 'package:farm_tpf/models/user.dart';
import 'package:farm_tpf/models/user_request.dart';
@@ -29,4 +31,7 @@ abstract class RestClient {

@PUT("/api/update-my-profile")
Future<Account> updateProfile(@Body() Account account);

@GET("/api/tb-supplies-by-type/{type}")
Future<List<Supply>> getSupplies(@Path() String type);
}

+ 21
- 0
lib/data/api/rest_client.g.dart View File

@@ -126,4 +126,25 @@ class _RestClient implements RestClient {
final value = Account.fromJson(_result.data);
return value;
}

@override
getSupplies(type) async {
ArgumentError.checkNotNull(type, 'type');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
final Response<List<dynamic>> _result = await _dio.request(
'/api/tb-supplies-by-type/$type',
queryParameters: queryParameters,
options: RequestOptions(
method: 'GET',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => Supply.fromJson(i as Map<String, dynamic>))
.toList();
return value;
}
}

+ 7
- 0
lib/data/repository/repository.dart View File

@@ -2,6 +2,8 @@ import 'package:farm_tpf/data/api/dio_provider.dart';
import 'package:farm_tpf/data/api/rest_client.dart';
import 'package:farm_tpf/models/PagedResult.dart';
import 'package:farm_tpf/models/Plot.dart';
import 'package:farm_tpf/models/Supply.dart';
import 'package:farm_tpf/models/index.dart';
import 'package:farm_tpf/models/user.dart';
import 'package:farm_tpf/models/user_request.dart';
import 'package:farm_tpf/utils/const_common.dart';
@@ -25,6 +27,11 @@ class Repository {
return value;
}

Future<List<Supply>> getSupplies(String type) async {
final client = RestClient(dio);
return client.getSupplies(type);
}

Object getInstanceClass() {
var instanceClass;
if (1 == 1) {

+ 1
- 1
lib/models/Plot.g.dart View File

@@ -18,5 +18,5 @@ Map<String, dynamic> _$PlotToJson(Plot instance) => <String, dynamic>{
'id': instance.id,
'times': instance.times,
'activityExecuteDate': instance.activityExecuteDate,
'isExceedLimit': instance.isExceedLimit
'isExceedLimit': instance.isExceedLimit,
};

+ 1
- 1
lib/models/ResourceHelper.g.dart View File

@@ -19,5 +19,5 @@ Map<String, dynamic> _$ResourceHelperToJson(ResourceHelper instance) =>
'id': instance.id,
'name': instance.name,
'description': instance.description,
'isSelected': instance.isSelected
'isSelected': instance.isSelected,
};

+ 20
- 0
lib/models/Supply.dart View File

@@ -0,0 +1,20 @@
import 'package:json_annotation/json_annotation.dart';

part 'Supply.g.dart';

@JsonSerializable()
class Supply {
Supply();

num id;
String name;
String sku;
String manufacturer;
String unit;
num tbSuppliesTypeId;
num tbCustomerId;
bool isSelected = false;

factory Supply.fromJson(Map<String, dynamic> json) => _$SupplyFromJson(json);
Map<String, dynamic> toJson() => _$SupplyToJson(this);
}

+ 29
- 0
lib/models/Supply.g.dart View File

@@ -0,0 +1,29 @@
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'Supply.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Supply _$SupplyFromJson(Map<String, dynamic> json) {
return Supply()
..id = json['id'] as num
..name = json['name'] as String
..sku = json['sku'] as String
..manufacturer = json['manufacturer'] as String
..unit = json['unit'] as String
..tbSuppliesTypeId = json['tbSuppliesTypeId'] as num
..tbCustomerId = json['tbCustomerId'] as num
..isSelected = false;
}

Map<String, dynamic> _$SupplyToJson(Supply instance) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'sku': instance.sku,
'manufacturer': instance.manufacturer,
'unit': instance.unit,
'tbSuppliesTypeId': instance.tbSuppliesTypeId,
'tbCustomerId': instance.tbCustomerId,
};

+ 2
- 2
lib/models/index.dart View File

@@ -1,2 +1,2 @@
export 'Plot.dart' ;
export 'ResourceHelper.dart' ;
export 'Plot.dart';
export 'ResourceHelper.dart';

+ 4
- 2
lib/presentation/screens/home/view/home_page.dart View File

@@ -3,6 +3,7 @@ import 'package:farm_tpf/presentation/screens/actions/plant/sc_plant.dart';
import 'package:farm_tpf/presentation/screens/plot/sc_plot.dart';
import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart';
import 'package:farm_tpf/presentation/screens/resources/sc_resource_helper.dart';
import 'package:farm_tpf/utils/const_common.dart';
import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
@@ -49,8 +50,9 @@ class HomePage extends StatelessWidget {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (_) => ResourceHelperScreen(
resourceName: "test",
selectedPlotId: 1531,
titleName: "phân bón",
type: ConstCommon.supplyTypeDung,
selectedId: 3,
),
fullscreenDialog: false))
.then((value) {

+ 49
- 0
lib/presentation/screens/resources/bloc/supply_bloc.dart View File

@@ -0,0 +1,49 @@
import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:farm_tpf/data/repository/repository.dart';
import 'package:farm_tpf/models/Supply.dart';
import 'package:farm_tpf/utils/bloc/infinity_scroll_bloc.dart';
import 'package:meta/meta.dart';

part 'supply_event.dart';
part 'supply_state.dart';

class SupplyBloc extends Bloc<SupplyEvent, SupplyState> {
final Repository repository;
SupplyBloc({@required this.repository}) : super(SupplyInitial());

@override
Stream<SupplyState> mapEventToState(
SupplyEvent event,
) async* {
if (event is DataFetched) {
try {
final response = await repository.getSupplies(event.type);
List<Supply> supplies = response.map((supply) {
if (supply.id == event.selectedId) {
supply.isSelected = true;
}
return supply;
}).toList();
yield SupplySuccess(items: supplies);
} catch (_) {
yield SupplyFailure();
}
} else if (event is OnRefresh) {
try {
final response = await repository.getSupplies(event.type);
List<Supply> supplies = response.map((supply) {
if (supply.id == event.selectedId) {
supply.isSelected = true;
}
return supply;
}).toList();
yield SupplySuccess(items: supplies);
} catch (_) {
yield SupplyFailure();
}
}
}
}

+ 20
- 0
lib/presentation/screens/resources/bloc/supply_event.dart View File

@@ -0,0 +1,20 @@
part of 'supply_bloc.dart';

abstract class SupplyEvent extends Equatable {
const SupplyEvent();

@override
List<Object> get props => [];
}

class DataFetched extends SupplyEvent {
final int selectedId;
final String type;
DataFetched({this.selectedId, @required this.type});
}

class OnRefresh extends SupplyEvent {
final int selectedId;
final String type;
OnRefresh({this.selectedId, @required this.type});
}

+ 25
- 0
lib/presentation/screens/resources/bloc/supply_state.dart View File

@@ -0,0 +1,25 @@
part of 'supply_bloc.dart';

abstract class SupplyState extends Equatable {
const SupplyState();

@override
List<Object> get props => [];
}

class SupplyInitial extends SupplyState {}

class SupplyFailure extends SupplyState {}

class SupplySuccess<T> extends SupplyState {
final List<T> items;

const SupplySuccess({this.items});

SupplySuccess copyWith({List<T> items}) {
return SupplySuccess(items: items ?? this.items);
}

@override
List<Object> get props => [items];
}

+ 53
- 63
lib/presentation/screens/resources/sc_resource_helper.dart View File

@@ -1,17 +1,21 @@
import 'package:farm_tpf/data/repository/repository.dart';
import 'package:farm_tpf/models/Supply.dart';
import 'package:farm_tpf/models/index.dart';
import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart';
import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
import 'package:farm_tpf/utils/bloc/infinity_scroll_bloc.dart';
import 'package:farm_tpf/presentation/screens/resources/bloc/supply_bloc.dart';
import 'package:farm_tpf/utils/const_string.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class ResourceHelperScreen extends StatefulWidget {
final String resourceName;
final int selectedPlotId;
final String type;
final int selectedId;
final String titleName;
ResourceHelperScreen(
{@required this.resourceName, @required this.selectedPlotId});
{@required this.type,
@required this.selectedId,
@required this.titleName});
@override
_ResourceHelperScreenState createState() => _ResourceHelperScreenState();
}
@@ -20,89 +24,79 @@ class _ResourceHelperScreenState extends State<ResourceHelperScreen> {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) =>
InfinityScrollBloc(repository: Repository())..add(DataFetched()),
create: (context) => SupplyBloc(repository: Repository())
..add(DataFetched(type: widget.type, selectedId: widget.selectedId)),
child: HoldInfinityWidget(
selectedPlotId: widget.selectedPlotId,
selectedId: widget.selectedId,
type: widget.type,
titleName: widget.titleName,
),
);
}
}

class HoldInfinityWidget extends StatelessWidget {
final int selectedPlotId;
HoldInfinityWidget({@required this.selectedPlotId});
final int selectedId;
final String type;
final String titleName;
HoldInfinityWidget(
{@required this.selectedId,
@required this.type,
@required this.titleName});
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(title: Text("Chọn danh sách")),
appBar: AppBar(title: Text("Chọn $titleName")),
body: InfinityView(
selectedPlotId: selectedPlotId,
selectedId: selectedId,
type: type,
));
}
}

class InfinityView extends StatefulWidget {
final int selectedPlotId;
InfinityView({@required this.selectedPlotId});
final int selectedId;
final String type;
InfinityView({@required this.selectedId, @required this.type});
@override
_InfinityViewState createState() => _InfinityViewState();
}

class _InfinityViewState extends State<InfinityView> {
final _scrollController = ScrollController();
final _scrollThreshold = 250.0;
InfinityScrollBloc _infinityScrollBloc;
SupplyBloc _supplyBloc;

@override
void initState() {
_scrollController.addListener(() {
final maxScroll = _scrollController.position.maxScrollExtent;
final currentScroll = _scrollController.position.pixels;
if (maxScroll - currentScroll < _scrollThreshold) {
_infinityScrollBloc.add(DataFetched());
}
});
_infinityScrollBloc = BlocProvider.of<InfinityScrollBloc>(context);
_supplyBloc = BlocProvider.of<SupplyBloc>(context);
_supplyBloc
.add(DataFetched(type: widget.type, selectedId: widget.selectedId));
super.initState();
}

@override
Widget build(BuildContext context) {
return BlocBuilder<InfinityScrollBloc, InfinityScrollState>(
return BlocBuilder<SupplyBloc, SupplyState>(
builder: (context, state) {
if (state is InfinityScrollFailure) {
if (state is SupplyFailure) {
return Center(child: Text(label_error_get_data));
}
if (state is InfinityScrollSuccess) {
if (state is SupplySuccess) {
if (state.items.isEmpty) {
return Center(child: Text(label_list_empty));
}

Plot selectedPlot;
List<Plot> plots = state.items.map((e) => e as Plot).toList();
plots.forEach((plot) {
plot.id == widget.selectedPlotId ? selectedPlot = plot : Plot();
});
return RefreshIndicator(
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return index >= state.items.length
? BottomLoader()
: ItemInfinityWidget(
item: state.items[index],
selectedPlot: selectedPlot,
);
},
itemCount: state.hasReachedMax
? state.items.length
: state.items.length + 1,
controller: _scrollController,
),
itemBuilder: (BuildContext context, int index) {
return index >= state.items.length
? BottomLoader()
: ItemInfinityWidget(item: state.items[index]);
},
itemCount: state.items.length),
onRefresh: () async {
_infinityScrollBloc.add(OnRefresh());
_supplyBloc.add(OnRefresh(
type: widget.type, selectedId: widget.selectedId));
});
}
return Center(
@@ -114,34 +108,30 @@ class _InfinityViewState extends State<InfinityView> {

@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
}

class ItemInfinityWidget extends StatelessWidget {
final Plot item;
final Plot selectedPlot;
final Supply item;

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

@override
Widget build(BuildContext context) {
return GestureDetector(
child: Card(
color: item.id % 3 == 0 ? Colors.white : Colors.greenAccent[100],
child: Material(
child: RadioListTile(
title: Text(item.activityExecuteDate.toString()),
subtitle: Text(item.id.toString()),
value: item,
groupValue: selectedPlot,
onChanged: (Plot value) {
print("selected value: ${value.id}");
Navigator.of(context).pop(value.id);
}),
)),
child: RadioListTile(
title: Text(item.name.toString()),
subtitle: Text(item.manufacturer.toString()),
value: item,
groupValue: item.isSelected ? item : null,
onChanged: (Supply value) {
print("selected value: ${value.id}");
Navigator.of(context).pop(value.id);
}),
)),
onTap: () {});
}
}

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

@@ -1,4 +1,9 @@
class ConstCommon {
static int kExpiredTime = 12 * 60 * 60 * 1000; //24h
static const String baseUrl = "https://aquaman.aztrace.vn";
static const String baseUrl = "https://ironman.aztrace.vn";

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

Loading…
Cancel
Save