import 'package:cs_resources/generated/assets.dart'; import 'package:cs_resources/theme/app_colors_theme.dart'; import 'package:domain/entity/garage_sale_rent_entity.dart'; import 'package:domain/entity/newsfeed_detail_entity.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:plugin_platform/engine/dialog/dialog_engine.dart'; import 'package:plugin_platform/engine/toast/toast_engine.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:router/ext/auto_router_extensions.dart'; import 'package:shared/utils/log_utils.dart'; import 'package:widgets/dialog/app_custom_dialog.dart'; import 'package:widgets/load_state_layout.dart'; import 'package:widgets/my_checkbox_group.dart'; import 'package:widgets/picker/option_pick_util.dart'; import 'package:widgets/widget_export.dart'; import '../../../respository/services_respository.dart'; import '../../../router/page/services_page_router.dart'; import 'home_service_state.dart'; part 'home_service_vm.g.dart'; @riverpod class HomeServiceVm extends _$HomeServiceVm { late ServicesRespository servicesRespositoryInstance; bool _needShowPlaceholder = false; //是否展示LoadingView int _page = 1; // 当前页 int _limit = 10; // 每页数量 int _count = 0; // 总条数 bool _isSingleSelect = true; List> _currentSelectedCategory = []; Map _queryParams = { 'category_id': null, 'keyword': null, 'is_liked': null, }; // Refresh 控制器 final EasyRefreshController refreshController = EasyRefreshController( controlFinishRefresh: true, //允许刷新 controlFinishLoad: true, //允许加载 ); HomeServiceState initState() { return HomeServiceState( list: [] ); } @override HomeServiceState build(){ // 引入数据仓库 // servicesRespositoryInstance = ref.read(commonGarageRespositoryProvider); final state = initState(); Log.d("--------------------------build---------------------"); return state; } //刷新页面状态 void changeLoadingState(LoadState loadState, String? errorMsg) { state = state.copyWith( loadingState: loadState, errorMessage: errorMsg ); } // 初始化页面数据 initPageData() { Log.d("----home_service_vm-----initPageData ${state.loadingState}"); onRefresh(); } // 上拉加载 更多 Future loadMore() async { Log.d("----home_service_vm-----loadMore"); _page++; getListData(); } // 下拉刷新 Future onRefresh() async { // 当前pageView 页面正处于显示状态 Log.d("----forsale_vm-----onRefresh "); // await Future.delayed(const Duration(seconds: 2)); _page = 1; getListData(); } // 手动进行刷新 Future triggerRefresh() async { Log.d("trggerRefresh"); refreshController.callRefresh(); } // 手动进行刷新 Future directRefresh() async { state = state.copyWith(list:[]); // 注意:由于 nestedscrollview 嵌套easyfresh 组件 refreshController.callRefresh() 自动刷新只能滚动顶部但是不会触发下拉刷新,这里调用是 用到了将其滚动到顶部的作用,进而刷新操作主动掉接口 // https://github.com/xuelongqy/flutter_easy_refresh/issues/692 refreshController.callRefresh(); refreshController.resetFooter(); _page = 1; _needShowPlaceholder = true; getListData(); } // 重试请求 Future retryRequest() async { _page = 1; _needShowPlaceholder = true; getListData(); } // 获取list 列表数据 Future getListData({bool? isLoadMore}) async { if (_needShowPlaceholder) { changeLoadingState(LoadState.State_Loading, null); } List> list = [ { 'id':1, 'service_type': 0, // 0 房屋保洁 1 空调保洁 2 维修 'cover_img': 'https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500', 'resources': ['https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500'], 'title': 'House Cleaning Services', 'price': 30, 'unit': '/hr', 'liked': true, 'likes_count': 12, 'company_name': 'HONG YE GROUP PTE LTD', }, { 'id':2, 'service_type': 1, // 0 房屋保洁 1 空调保洁 2 维修 'cover_img': 'https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500', 'resources': ['https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500'], 'title': 'Air Conditioning Cleaning', 'price': 10, 'unit': '/unit', 'liked': false, 'likes_count': 10, 'company_name': 'HONG YE GROUP PTE LTD', }, { 'id':3, 'service_type': 1, // 0 房屋保洁 1 空调保洁 2 维修 'cover_img': 'https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500', 'resources': ['https://img2.baidu.com/it/u=3489233687,2364672159&fm=253&fmt=auto&app=120&f=JPEG?w=507&h=500'], 'title': 'Cleaning Services', 'price': 200, 'unit': '/hr', 'liked': true, 'likes_count': 1212, 'company_name': 'HONG YE GROUP PTE LTD', }, ]; handlerResultData(true, list:list); // try { // //请求网络 // Map params = { // "type": 1, // 类型(1=Sale,2=Rent) // "category_id": _queryParams['category_id'], // "keyword": _queryParams['keyword'], // "page": _page, // "limit": _limit, // }; // Log.d("请求参数------$params"); // final result = await servicesRespositoryInstance.fetchGarageDataList(params); // //校验成功失败 // if (result.isSuccess) { // // handlerResultList((result.data as GarageSaleRentEntity).list as List, isLoadMore ?? false); // } else { // String errorMessage = result.errorMsg!; // changeLoadingState(LoadState.State_Error, errorMessage); // ToastEngine.show(result.errorMsg ?? "Network Load Error"); // } // } catch (e) { // ToastEngine.show("Error: $e"); // } // 最后赋值 _needShowPlaceholder = false; } handlerResultData(bool isList, {List>? list, dynamic? data}){ Future.delayed(const Duration(seconds: 1)).then((value) { if(isList){ // list 数据模式 if(list != null && list.isNotEmpty){ if(_page == 1){ state.list.clear(); state.list!.addAll(list); refreshController.finishRefresh(); changeLoadingState(LoadState.State_Success, null); }else { final allList = state.list; allList!.addAll(list); state = state.copyWith(list: allList); refreshController.finishLoad(); } }else { if(_page == 1){ state.list.clear(); changeLoadingState(LoadState.State_Empty, null); refreshController.finishRefresh(); }else { refreshController.finishLoad(IndicatorResult.noMore); } } }else { // 单个数据模式 if(data!=null){ if(_page == 1){ refreshController.finishRefresh(); }else{ refreshController.finishLoad(); } changeLoadingState(LoadState.State_Success, null); }else { if(_page == 1){ refreshController.finishRefresh(); }else{ refreshController.finishLoad(); } changeLoadingState(LoadState.State_Empty, null); } } }); } void handlerResultList(List? list, bool isLoadMore) { if (list != null && list.isNotEmpty) { //有数据,判断是刷新还是加载更多的数据 if (_page == 1) { //刷新的方式 state.list!.clear(); state.list!.addAll(list.map((item) => item.toJson()).toList()); refreshController.finishRefresh(); //更新展示的状态 changeLoadingState(LoadState.State_Success, null); } else { //加载更多 final allList = state.list; allList!.addAll(list.map((item) => item.toJson()).toList()); state = state.copyWith(list: allList); refreshController.finishLoad(); } } else { if (_page == 1) { //展示无数据的布局 state.list!.clear(); changeLoadingState(LoadState.State_Empty, null); refreshController.finishRefresh(); } else { //展示加载完成,没有更多数据了 if (_page == 1) { //展示无数据的布局 state.list!.clear(); changeLoadingState(LoadState.State_Empty, null); refreshController.finishRefresh(); } else { //展示加载完成,没有更多数据了 if(state.list!.length == 0){ changeLoadingState(LoadState.State_Empty, null); refreshController.finishLoad(); }else { if(_needShowPlaceholder){ changeLoadingState(LoadState.State_Success, null); } } //更新展示的状态 refreshController.finishLoad(IndicatorResult.noMore); } } } } // 获取 homeservice 的分类选项 Future>> getHomeServiceCategoryOptions() async{ await Future.delayed(const Duration(milliseconds: 300)); ToastEngine.dismiss(); List> serviceCategoryList = [ { 'id': 1, 'name': 'House Cleaning Serivces', }, { 'id': 2, 'name': 'Household Appliance Cleaning', }, ]; // 获取分类列表 // try { // // 加入有缓存 就取缓存 // List>? StorageCategoryList = SPUtil.getObjectList( // AppConstant.storageGarageCategoryList)?.cast>(); // // if (StorageCategoryList != null && StorageCategoryList.isNotEmpty) { // Log.d("取StorageCategoryList 缓存: $StorageCategoryList "); // serviceCategoryList = StorageCategoryList; // } else { // Map params = {}; // final result = await commonGarageRespositoryInstance // .fetchGarageCateGoryList(params); // if (result.isSuccess) { // final listJson = result.getListJson(); // // 将 listJson 转换为 List> // serviceCategoryList = (listJson as List?) // ?.map((item) => item as Map) // .toList() ?? []; // // 将 serviceCategoryList 存入缓存 // Log.d("设置StorageCategoryList 缓存"); // SPUtil.putObjectList( // AppConstant.storageGarageCategoryList, serviceCategoryList); // } // } // } catch(error){ // // } return serviceCategoryList; } // 点击了filter icon handlerClickFilterIcon(BuildContext context) async{ List> serviceCategoryList = await getHomeServiceCategoryOptions(); // 显示弹框 handlerShowChooseGarageCategoryDialog(context, serviceCategoryList); } Future handlerShowChooseGarageCategoryDialog(BuildContext context, List> garageCategoryList) async{ await DialogEngine.show( tag: "chooseGarageSaleCategory", position: DialogPosition.center, widget: AppCustomDialog( message: '', title: 'Choose a Category', dialogWidth: MediaQuery.of(context).size.width * 0.8, // contentBoxMaxHeight: 350, // contentBoxMinHeight: 300, isShowConfirmBtn: garageCategoryList!.length > 0 ? true: false, confirmTxt: "Ok", messageBuilder: (BuildContext context){ return Container( color: context.appColors.textWhite, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: garageCategoryList!.length > 0 ? [ MyCheckboxGroup( isSingleSelect: _isSingleSelect, labelStyle: const TextStyle( fontSize: 16, fontWeight: FontWeight.w500, ), items: garageCategoryList!, defaultSelectedItems: [], onChanged: (List> selectedItems){ Log.d("----MyCheckboxGroup onChanged $selectedItems"); _currentSelectedCategory = selectedItems; } ) ]: [ Container( child: CircularProgressIndicator( strokeWidth: 3, valueColor: AlwaysStoppedAnimation(context.appColors.textDarkGray), ), ) ], ), ); }, isShowCancelBtn:false, confirmAction: (){ // 点击了确定 Log.d("----点击了确定按钮"); int? categoryId; if(_isSingleSelect){ if(_currentSelectedCategory.length > 0){ categoryId = _currentSelectedCategory[0]['id']; } } setCurrentQueryParams({ "category_id": _queryParams?['categoryId'], }); directRefresh(); }, ) ); } // 点击 收藏/取消收藏 Future handlerClickCollection(int id, bool? isCollection) async{ try { //请求网络 Map params = { "id": id, }; Log.d("请求参数------$params"); final result = await servicesRespositoryInstance.fetchServiceLiked(params); //校验成功失败 if (result.isSuccess) { // 修改 该id 的 liked 和 likes_count 字段 state.list!.forEach((Map element) { GarageSaleRentList elementEntity = GarageSaleRentList.fromJson(element); if(elementEntity.id == id){ elementEntity.liked = !elementEntity.liked!; elementEntity.likesCount = elementEntity.liked! ? (elementEntity.likesCount! + 1) : (elementEntity.likesCount! - 1); } element = elementEntity.toJson(); }); return true; } else { String errorMessage = result.errorMsg!; changeLoadingState(LoadState.State_Error, errorMessage); ToastEngine.show(result.errorMsg ?? "Network Load Error"); } } catch (e) { Log.e("Error: $e"); ToastEngine.show("Error: $e"); } } // 设置当前的 _queryParams setCurrentQueryParams(Map params){ _queryParams.addAll(params); } // 获取当前的 _queryParams Map getCurrentQueryParams(String? key){ if(key!=null && key!.isNotEmpty){ return _queryParams[key]; } return _queryParams; } // 点击 sort icon handlerClickSortIcon(BuildContext context) async{ // await SmartDialog.showAttach( // targetContext: context, // alignment: Alignment.bottomCenter, // highlightBuilder: (Offset targetOffset, Size targetSize) { // Log.d("666 ${targetOffset} ${targetSize}"); // return Positioned( // right: 0, // top: 0, // child: Container(height: targetOffset.dy + 50, width: targetSize.width, color: Colors.white), // ); // }, // builder: (_) => _listDialog(), // ); // DialogEngine.showAttach( // targetContext: context, // position: DialogPosition.top, // clickMaskDismiss:false, // usePenetrate: true, // widget: _listDialog() // ); OptionPickerUtil.showCupertinoOptionPicker( items: state.sortByOptionsList, initialSelectIndex: 0, onPickerChanged: (_, index) { state = state.copyWith(sortBySelectedOption: state.sortByOptionsList?[index]); // 调用list 接口 }, ); } Widget _listDialog() { return Container( width: 200, height: 200, color: Colors.white, child: Column( children: [ Text("排序方式"), Text("价格从低到高"), Text("价格从高到低"), Text("距离最近"), Text("距离最远"), ], ), ); } // 去详情页面 void handlerGotoDetail({BuildContext? context, required int id, int serviceTypeCode= 0 }){ Log.d("去详情页面 $id $serviceTypeCode"); if(serviceTypeCode == 0 || serviceTypeCode == 1){ // clean service 跳转到 clean 详情页 appRouter.push(ServiceCleanDetailPageRoute(id: id, serviceTypeCode: serviceTypeCode)); }else if(serviceTypeCode == 2){ // repair service 跳转到 repair 详情页 appRouter.push(ServiceRepairDetailPageRoute(id: id, serviceTypeCode: serviceTypeCode)); } } }