import 'package:easy_refresh/easy_refresh.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:lszlgl/base/base_lifecycle_state.dart'; import 'package:lszlgl/base/base_vm.dart'; import 'package:lszlgl/config/colors.dart'; import 'package:lszlgl/model/rsp/sample_task_rsp.dart'; import 'package:lszlgl/network/my_api.dart'; import 'package:lszlgl/page/print/print_page.dart'; import 'package:lszlgl/page/sample_task/sample_list_vm.dart'; import 'package:lszlgl/page/sample_task/sample_task_list_tab_page.dart'; import 'package:lszlgl/service/dict_service.dart'; import 'package:lszlgl/service/print_service.dart'; import 'package:lszlgl/utils/date_time_utils.dart'; import 'package:lszlgl/utils/inject.dart'; import 'package:lszlgl/widget/button.dart'; import 'package:lszlgl/widget/page_widget.dart'; import 'package:lszlgl/widget/print_checkbox_widget.dart'; import '../../main.dart'; import 'reap_sample_detail/reap_sample_task_page.dart'; import 'stock_sample_detail/stock_sample_task_page.dart'; /// 扦样环节列表 class SampleTaskListPage extends StatefulWidget { final StepType type; final int tabIndex; const SampleTaskListPage({ super.key, required this.type, required this.tabIndex, }); @override State createState() => _SampleTaskListPageState(); } class _SampleTaskListPageState extends BaseLifecycleState with AutomaticKeepAliveClientMixin { late SampleListVM vm; List selectList = []; /// 详情 void startTaskDetail(bool detail, SampleTaskItem data, {num? deliveryStatus}) async { bool? success; switch (widget.type) { case StepType.reap: success = await MyRouter.startReapSampleTask( args: ReapSampleTaskPageArgs( detail: detail, id: data.id, deliveryStatus: deliveryStatus)); break; case StepType.stock: success = await MyRouter.startStockSampleTask( args: StockSampleTaskPageArgs(detail: detail, id: data.id)); break; } if (success ?? false) { vm.refreshAll(); } } /// 领取扦样任务 void receiveTask(SampleTaskItem data) async { var delete = await MyNavigator.showDialog( builder: (_) => AlertDialog( title: const Text('系统提示'), content: const Text('任务认领后不可撤销,请确认是否认领任务!'), actions: [ MyButton( '领取', alignment: null, backgroundColor: const Color(0xFFCE615A), onTap: () => MyNavigator.dismiss(status: SmartStatus.dialog, result: true), ), MyButton('取消', alignment: null, onTap: () => MyNavigator.dismiss()), ], ), ); if (!(delete ?? false)) return; MyNavigator.showLoading(); try { var rsp = await MyApi.get().receiveSampleTaskSgjc(data.id ?? 0); MyNavigator.dismissLoading(); if (rsp.data == 1) { MyNavigator.showToast('领取成功'); vm.refreshAll(); } } catch (e) { logger.e(e); MyNavigator.dismissLoading(); } } @override void onInit() { vm = Inject.get()!; } @override void onFirstShow(Duration timeStamp) { vm.refresh(widget.tabIndex); } @override Widget build(BuildContext context) { super.build(context); return Stack( children: [ buildBody(), buildPrintBtn(), ], ); // Container( // margin: const EdgeInsets.symmetric(horizontal: 8), // clipBehavior: Clip.hardEdge, // decoration: const BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.vertical(top: Radius.circular(8)), // ), // alignment: Alignment.center, // child: buildBody(), // ); } // 批量打印前 获取数据 getPrintData() async{ if(selectList.isEmpty){ MyNavigator.showToast('请选择打印数据'); return; } MyNavigator.showLoading(msg: '数据处理中...'); var dataList = await Future.wait(selectList.map((id) => MyApi.get().sampleTaskDetailSgjc(id))); List data = dataList.map((e) => e.data).toList(); if(data.isEmpty){ MyNavigator.dismissLoading(); MyNavigator.showToast('打印数据获取有误'); return; } // List imgList = await Future.wait(data.map((item)=>imageToBytes(item!.ewmfilePictureList!.first.url!))); List printList = []; for(int i = 0; i < data.length; i++){ List textList = PrintService.getPrintTextListWithSampleTaskItem(data[i]); PrintPageArgs arg = PrintPageArgs( urlCode:'${MyApi.globalUrl}/admin-api/zj/code-sampling-task-details-sgjc/getSamplingTaskDetails?id=${data[i]!.id}' , numCode: data[i]!.ewmfilePictureList!.first.name, textList: textList, ); printList.add(arg); } MyNavigator.dismissLoading(); var args = PrintPageArgs(printList: printList); await MyRouter.startPrint(args); } // 通过地址获取图片内容 // Future imageToBytes(String imageUrl) async { // try{ // var response = await Dio().get( // imageUrl, // options: Options(responseType: ResponseType.bytes) // ); // return Uint8List.fromList(response.data); // } catch(e){ // logger.d(e); // return null; // } // } Widget buildPrintBtn() { if (widget.type == StepType.reap && widget.tabIndex == 2) { return ValueListenableBuilder( valueListenable: vm.showPrintBtn, builder: (context, show, child) { if (show) { return child!; } else { return const SizedBox.shrink(); } }, child: Positioned( bottom: 0, left: 8, right: 8, child: MyButton( '打 印', radius: 8, gradient: const LinearGradient(colors: [Color(0xFF3BD2E5), Color(0xFF247AF8)]), onTap: () { getPrintData(); }, )), ); } else { return const SizedBox.shrink(); } } Widget buildBody() { return EasyRefresh.builder( controller: vm.ctrlList[widget.tabIndex], onRefresh: () => vm.getData(widget.tabIndex, refresh: true), onLoad: () => vm.getData(widget.tabIndex, refresh: false), childBuilder: (_, physics) => buildList(physics), ); } Widget buildList(ScrollPhysics physics) { var sliver = vm.pageStateList[widget.tabIndex].builder((v) { var list = v.data; if (v.status == DataStatus.error) { // 加载失败 return SliverToBoxAdapter( child: PageLoadingWidget.error(onTap: () => vm.refresh(widget.tabIndex))); } else if (list == null || list.isEmpty) { // 无数据 return const SliverToBoxAdapter(child: PageLoadingWidget.empty()); } else { return SliverList.builder( itemCount: list.length, itemBuilder: (_, index) => buildItem(index, list[index]), ); } }); return CustomScrollView( physics: physics, slivers: [sliver], ); } Widget buildItem(int index, SampleTaskItem item) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { if (item.deliveryStatus != 2) return; startTaskDetail(true, item); }, child: Container( clipBehavior: Clip.hardEdge, margin: const EdgeInsets.only(left: 8, right: 8, top: 12), decoration: const BoxDecoration( color: Color(0xFFF9FEFE), borderRadius: BorderRadius.all(Radius.circular(8)), ), child: Stack( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 8), buildTop(), buildNumber(item.qyrwdh ?? ''), const Divider(thickness: 0.6, color: Color(0xFFEEEEEE), indent: 8), const SizedBox(height: 8), buildGrid(item), const SizedBox(height: 15), buildBottom(item), ], ), buildState(item.getDeliveryStatusText()), buildSelectBtn(item), ], ), ), ); } buildSelectBtn(SampleTaskItem item){ if(widget.type == StepType.reap && item.deliveryStatus==2){ return ValueListenableBuilder(valueListenable: vm.showPrintBtn, builder: (_,show,__){ if(show){ return Positioned( right: 0, top: 60, child: PrintCheckboxWidget( list: selectList, itemId: item.id!, onChanged: (bool isSelect){ item.isSelect = isSelect; if(isSelect){ selectList.add(item.id!); }else{ selectList.remove(item.id!); } }, ), ); }else{ return const SizedBox.shrink(); } }); }else{ return const SizedBox.shrink(); } } Widget buildTop() { return Row( children: [ Image.asset( imgListTitleIcon, width: 4, height: 20, fit: BoxFit.fill, ), const SizedBox(width: 4), const Text( '样品单号', style: TextStyle(color: MyColor.c_333333, fontSize: 15, fontWeight: FontWeight.w500), ), ], ); } Widget buildState(String state) { String img = imgQYStateOff; Color color = const Color(0xFF149723); if (state != '已扦样') { img = imgQYStateOn; color = const Color(0xFFDEA70A); } return Positioned( top: 0, right: 0, child: Container( padding: const EdgeInsets.fromLTRB(40, 4, 20, 16), decoration: BoxDecoration(image: DecorationImage(image: AssetImage(img), fit: BoxFit.fill)), child: Text( state, style: TextStyle(color: color, fontSize: 15), ), ), ); } Widget buildNumber(String number) { return Padding( padding: const EdgeInsets.only(left: 8, bottom: 6), child: Text( number, style: const TextStyle(color: MyColor.c_333333, fontSize: 16, fontWeight: FontWeight.bold), ), ); } Widget buildGrid(SampleTaskItem item) { List inList = []; if (item.deliveryStatus != 2) { // 未扦样 inList.add(ItemMsgModel(tit: '采样品种', content: item.cypzName, img: imgIconCJPZ)); if (item.jyzb != null) { inList.add(ItemMsgModel(tit: '检验指标', content: item.jyzb, img: imgIconJYZB)); } if (item.ypdj != null) { inList.add(ItemMsgModel( tit: '样品层级', content: DictService.getDict(DictType.ypdj, value: item.ypdj)?.label, img: imgIconYPDJ)); } inList.add(ItemMsgModel(tit: '扦样地区', content: item.qydq, img: imgIconQYDQ)); } else { // 已扦样 inList.add(ItemMsgModel(tit: '采样品种', content: item.cypzName, img: imgIconCJPZ)); if (item.jyzb != null) { inList.add(ItemMsgModel(tit: '检验指标', content: item.jyzb, img: imgIconJYZB)); } if (item.ypdj != null) { inList.add(ItemMsgModel( tit: '样品层级', content: DictService.getDict(DictType.ypdj, value: item.ypdj)?.label, img: imgIconYPDJ)); } inList.add(ItemMsgModel(tit: '扦样地区', content: item.qydq, img: imgIconQYDQ)); inList.add(ItemMsgModel(tit: '扦样人员', content: item.name, img: imgIconQYRY)); inList.add(ItemMsgModel(tit: '扦样时间', content: item.qysj, img: imgIconQYSJ)); } return Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: LayoutBuilder(builder: (context, constraints) { return Wrap( spacing: 4, runSpacing: 12, children: inList.map((item) { return SizedBox( width: constraints.maxWidth / 2 - 2, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(0, 4, 6, 0), child: Image.asset(item.img, width: 36), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(item.tit, style: const TextStyle(color: MyColor.c_666666)), Text( item.content ?? '', style: const TextStyle(color: MyColor.c_666666, fontWeight: FontWeight.bold), ) ], ), ) ], ), ); }).toList(), ); }), ); } Widget buildBottom(SampleTaskItem item) { Widget button = const SizedBox.shrink(); if (widget.type == StepType.reap && item.deliveryStatus == 0) { button = MyButton( '任务领取', onTap: () => receiveTask(item), fountSize: 13, radius: 6, alignment: null, padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), ); } else if (widget.type == StepType.reap && item.deliveryStatus == 1) { button = MyButton( '开始扦样', onTap: () => startTaskDetail(false, item), fountSize: 13, radius: 6, alignment: null, padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), ); } else { button = MyButton( '修改信息', onTap: () => startTaskDetail(false, item, deliveryStatus: item.deliveryStatus), fountSize: 13, radius: 6, alignment: null, padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), ); } return Container( padding: const EdgeInsets.fromLTRB(8, 14, 12, 14), decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Color(0xFFE4F5FC), Color(0xFFF5FDFD)])), child: Row( children: [ Image.asset( imgIconEdit, width: 10, ), const SizedBox(width: 4), Expanded( child: item.deliveryStatus == 2 ? Text( '扦样单据完成于${item.qysj ?? ''}', style: const TextStyle(fontSize: 14, color: MyColor.c_666666), ) : Text( '扦样单据创建于${DateTimeUtils.yyyymmdd(timestamp: item.createTime) ?? ''}', style: const TextStyle(fontSize: 14, color: MyColor.c_666666), )), const SizedBox(width: 4), button, ], ), ); } @override bool get wantKeepAlive => true; } class ItemMsgModel { final String tit; final String? content; final String img; ItemMsgModel({required this.tit, this.content, required this.img}); }