|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- import 'dart:io';
- import 'dart:math';
-
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'package:fluttertoast/fluttertoast.dart';
- import 'package:image_picker/image_picker.dart';
- import 'package:permission_handler/permission_handler.dart';
- import 'package:zhiying_base_widget/pages/feedback_page/bloc/feedback_bloc.dart';
- import 'package:zhiying_base_widget/pages/feedback_page/bloc/feedback_repository.dart';
- import 'package:zhiying_base_widget/pages/feedback_page/feedback_record_page.dart';
- import 'package:zhiying_base_widget/pages/feedback_page/model/feedback_model.dart';
- import 'package:zhiying_comm/zhiying_comm.dart';
- import 'package:zhiying_base_widget/pages/feedback_page/widgets/feedback_image.dart';
- import 'package:zhiying_base_widget/pages/feedback_page/widgets/feedback_tab_widget.dart';
- import 'package:zhiying_base_widget/widgets/others/action_selected_alert/action_selected_alert.dart';
- import 'package:zhiying_comm/util/log/let_log.dart';
- import 'package:flutter_bloc/flutter_bloc.dart';
- import 'bloc/feedback_bloc.dart';
- import 'bloc/feedback_repository.dart';
- import 'bloc/feedback_state.dart';
- import 'bloc/feedback_event.dart';
- import 'package:fluttertoast/fluttertoast.dart';
-
- ///
- /// 意见反馈
- ///
- class FeedbackPage extends StatefulWidget {
- final Map<String, dynamic> data;
-
- FeedbackPage(this.data);
-
- @override
- _FeedbackPageState createState() => _FeedbackPageState();
- }
-
- class _FeedbackPageState extends State<FeedbackPage> {
- @override
- Widget build(BuildContext context) {
- return BlocProvider<FeedbackBloc>(
- create: (_) => FeedbackBloc(FeedBackRepository())..add(FeedbackInitEvent()),
- child: _FeedbackPageContainer(),
- );
- }
- }
-
- class _FeedbackPageContainer extends StatefulWidget {
- @override
- __FeedbackPageContainerState createState() => __FeedbackPageContainerState();
- }
-
- class __FeedbackPageContainerState extends State<_FeedbackPageContainer> {
- List<File> _images = List();
- bool _submitable = false;
- TextEditingController _feedback;
-
- TextEditingController _title;
-
- // 是否上传中
- bool isUpLoading = false;
-
- @override
- void initState() {
- _feedback = TextEditingController();
- _title = TextEditingController();
- super.initState();
- }
-
- @override
- void dispose() {
- _feedback?.dispose();
- _title?.dispose();
- super.dispose();
- }
-
- /// 选择图片
- void _onAddImage() async {
- if (_images.length >= 4) {
- Fluttertoast.showToast(msg: '最多上传4张图片');
- return;
- }
-
- var status = await Permission.photos.status;
- if (status != PermissionStatus.granted) {
- status = await Permission.photos.request();
- }
- if (status == PermissionStatus.denied) {
- Fluttertoast.showToast(msg: '暂无权限,图片选择失败');
- return null;
- }
-
- final picker = ImagePicker();
- PickedFile file;
- int index = await showModalBottomSheet(
- context: context,
- builder: (context) {
- return ActionSelectedAlert(
- // title: '拍照/选择图片',
- actions: ['拍照', '从相册选择图片'],
- );
- },
- isScrollControlled: false,
- backgroundColor: Colors.transparent);
- if (index != null) {
- if (index == 0) {
- file = await picker.getImage(source: ImageSource.camera);
- } else {
- file = await picker.getImage(source: ImageSource.gallery);
- }
-
- if (file == null) return;
-
- if (_images.length <= 4) {
- setState(() {
- _images.add(File(file.path));
- });
- } else {
- Fluttertoast.showToast(msg: '最多只能选择4张');
- }
-
- // File resultFile = await EncodeUtil.compressImage(file, 800);
- }
- }
-
- @override
- Widget build(BuildContext context) {
- return BlocConsumer<FeedbackBloc, FeedbackState>(
- listener: (context, state) {},
- buildWhen: (prev, current) {
- /// 保存成功
- if (current is FeedbackSaveSuccessState) {
- Fluttertoast.showToast(msg: '反馈成功~');
- Navigator.pop(context);
- return false;
- }
- if (current is FeedbackSaveErrorState) {
- Fluttertoast.showToast(msg: '反馈失败~');
- setState(() {
- isUpLoading = false;
- });
- return false;
- }
- return true;
- },
- builder: (context, state) {
- if (state is FeedbackLoadedState) {
- return _getMainWidget(state?.model);
- }
- return _getEmptyWidget();
- },
- );
- }
-
- /// 有数据
- Widget _getMainWidget(FeedbackModel model) {
- return Scaffold(
- resizeToAvoidBottomInset: false,
- appBar: _createNav(model),
- body: GestureDetector(
- onTap: () {
- FocusScope.of(context).requestFocus(FocusNode());
- },
- child: SafeArea(
- child: Column(
- children: <Widget>[
- Expanded(
- child: SingleChildScrollView(
- child: Column(
- children: <Widget>[
- Container(
- width: double.infinity,
- margin: EdgeInsets.only(top: 10, bottom: 10, left: 12.5, right: 12.5),
- padding: EdgeInsets.all(12.5),
- decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(7.5)),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisAlignment: MainAxisAlignment.start,
- children: <Widget>[
- _createTitle(model),
- _createUpload(model),
- _createSubmit(model),
- ],
- ),
- )
- ],
- ),
- ),
- ),
- Center(
- child: GestureDetector(
- behavior: HitTestBehavior.opaque,
- onTap: () => RouterUtil.route(model, model.toJson(), context),
- child: Container(
- width: 120,
- height: 30,
- margin: EdgeInsets.all(10),
- decoration: BoxDecoration(
- color: HexColor.fromHex(model?.feedbackListBtnBgColor ?? '#FFFFFF'),
- borderRadius: BorderRadius.circular(15),
- border: Border.all(color: HexColor.fromHex(model?.feedbackListBtnBorderColor ?? '#D1D1D1'), width: 0.5),
- ),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: <Widget>[
- Padding(
- padding: EdgeInsets.only(right: 6),
- child: CachedNetworkImage(
- imageUrl: model?.feedbackListBtnIcon ?? '',
- width: 16.5,
- ),
- ),
- Text(
- model?.feedbackListBtnText ?? '反馈记录',
- style: TextStyle(fontSize: 13, color: HexColor.fromHex(model?.feedbackListBtnTextColor ?? '#333333'), fontWeight: FontWeight.bold),
- )
- ],
- ),
- ),
- ),
- ),
- const SizedBox(height: 25),
- ],
- ),
- ),
- ),
- );
- }
-
- /// 没数据
- Widget _getEmptyWidget() {
- return Scaffold(
- resizeToAvoidBottomInset: false,
- appBar: _createNav(null),
- body: Container(),
- );
- }
-
- /// 导航栏
- Widget _createNav(FeedbackModel mode) {
- return CupertinoNavigationBar(
- border: Border(
- bottom: BorderSide(
- width: 0.0, // One physical pixel.
- style: BorderStyle.none,
- ),
- ),
- backgroundColor: HexColor.fromHex(mode?.appBarBgColor ?? '#FFFFFF'),
- leading: Navigator.canPop(context)
- ? GestureDetector(
- child: Container(
- padding: EdgeInsets.zero,
- child: Icon(
- Icons.arrow_back_ios,
- size: 20,
- ),
- ),
- onTap: () {
- if (Navigator.canPop(context)) {
- Navigator.pop(context);
- }
- },
- )
- : Container(),
- middle: Text(
- mode?.appBarName ?? '意见反馈',
- style: TextStyle(
- fontSize: 15,
- color: HexColor.fromHex(mode?.appBarNameColor ?? '#333333'),
- ),
- ),
- );
- }
-
- Widget _createTitle(FeedbackModel model) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisAlignment: MainAxisAlignment.start,
- children: <Widget>[
- Text(
- model?.feedbackTitle ?? '反馈描述',
- style: TextStyle(
- fontSize: 14,
- color: Color(0xff333333),
- fontWeight: FontWeight.bold,
- ),
- ),
- const SizedBox(height: 2),
-
- /// 异常选项
- Padding(
- padding: EdgeInsets.only(top: 4, bottom: 4),
- child: Visibility(
- visible: !EmptyUtil.isEmpty(model?.feedbackTypes),
- child: Row(
- children: model.feedbackTypes
- .map((e) => Expanded(
- child: GestureDetector(
- behavior: HitTestBehavior.opaque,
- onTap: () {
- setState(() {
- model.feedbackTypes.forEach((element) {
- element.isSelect = false;
- });
- e.isSelect = true;
- });
- },
- child: Container(
- margin: EdgeInsets.only(left: 2, right: 2),
- height: 28,
- child: Container(
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(2.5),
- border: Border.all(
- color: HexColor.fromHex(e.isSelect ? model?.feedbackTypeSelectedBorderColor : model?.feedbackTypeNoSelectedBorderColor),
- //e.isSelect ? Colors.redAccent : Color(0xffe7e7e7),
- width: 1,
- ),
- ),
- child: Stack(
- children: <Widget>[
- Center(
- child: Text(
- e.name ?? '',
- style: TextStyle(
- fontSize: 12,
- color: HexColor.fromHex(
- e.isSelect ? model?.feedbackTypeSelectedTextColor : model?.feedbackTypeNoSelectedTextColor) //e.isSelect ? Colors.redAccent : Color(0xff999999),
- ),
- ),
- ),
- Visibility(
- visible: e.isSelect,
- child: Align(
- alignment: Alignment.bottomRight,
- child: CachedNetworkImage(
- imageUrl: model?.feedbackTypeSelectedBorderIcon,
- width: 10,
- ),
- ),
- )
- ],
- ),
- )),
- )))
- .toList(),
- ),
- ),
- ),
-
- // 标题
- Container(
- height: 32.5,
- margin: EdgeInsets.only(left: 2, right: 2, top: 4, bottom: 4),
- child: CupertinoTextField(
- controller: _title,
- textAlignVertical: TextAlignVertical.center,
- style: TextStyle(fontSize: 12, color: Color(0xff333333)),
- maxLines: 1,
- placeholder: model?.feedbackInputHintText ?? '请输入反馈标题(最多15个字)',
- placeholderStyle: TextStyle(
- fontSize: 12,
- color: HexColor.fromHex(model?.feedbackInputHintTextColor ?? '#999999'),
- ),
- decoration: BoxDecoration(color: Color(0xfff9f9f9), borderRadius: BorderRadius.circular(7.5)),
- onChanged: (value) {
- if (value == null || value == '' || EmptyUtil.isEmpty(_feedback?.text?.toString()?.trim())) {
- _submitable = false;
- } else {
- _submitable = true;
- }
- setState(() {});
- },
- ),
- ),
-
- // 内容
- Container(
- height: 118,
- margin: EdgeInsets.only(left: 2, right: 2, top: 4, bottom: 4),
- child: CupertinoTextField(
- controller: _feedback,
- textAlignVertical: TextAlignVertical.top,
- style: TextStyle(fontSize: 12, color: Color(0xff333333)),
- maxLines: null,
- placeholder: model?.feedbackInputContentHintText ?? '请输入您的意见(最多100个字)',
- placeholderStyle: TextStyle(
- fontSize: 12,
- color: HexColor.fromHex(model?.feedbackInputContentHintTextColor ?? '#999999'),
- ),
- decoration: BoxDecoration(color: Color(0xfff9f9f9), borderRadius: BorderRadius.circular(7.5)),
- onChanged: (value) {
- if (value == null || value == '' || EmptyUtil.isEmpty(_title?.text?.toString()?.trim())) {
- _submitable = false;
- } else {
- _submitable = true;
- }
- setState(() {});
- },
- ),
- ),
- ],
- );
- }
-
- Widget _createUpload(FeedbackModel model) {
- List<Widget> images = List();
- _images.forEach((file) {
- images.add(Container(
- margin: EdgeInsets.only(top: 4, bottom: 4, right: 8),
- width: 80,
- height: 80,
- child: FeedbackImageWidget(
- file: file,
- onDelete: () {
- setState(() {
- _images.remove(file);
- });
- },
- ),
- ));
- });
- if (images.length < 4) {
- images.add(GestureDetector(
- child: Container(
- margin: EdgeInsets.only(top: 4, bottom: 4),
- decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.5), color: Color(0xfff9f9f9)),
- height: 80,
- width: 80,
- child: Icon(
- Icons.add,
- size: 60,
- color: Color(0xffd8d8d8),
- ),
- ),
- onTap: _onAddImage,
- ));
- }
-
- return Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- Row(
- children: <Widget>[
- Padding(
- padding: EdgeInsets.only(right: 10, top: 4, bottom: 4),
- child: Text(
- model?.feedbackUploadImageTitle ?? '上传图片',
- style: TextStyle(
- fontSize: 14,
- color: Color(0xff333333),
- fontWeight: FontWeight.bold,
- ),
- ),
- ),
- Text(
- model?.feedbackUploadImageSubtitle ?? '最多上传4张,大小不超过1M/张',
- style: TextStyle(
- fontSize: 12,
- color: Color(0xff999999),
- ),
- ),
- ],
- ),
- // Row(
- // children: images,
- // )
- Wrap(
- crossAxisAlignment: WrapCrossAlignment.center,
- textDirection: TextDirection.ltr,
- spacing: 0,
- runSpacing: 0,
- runAlignment: WrapAlignment.center,
- alignment: WrapAlignment.start,
- children: images,
- ),
- ],
- );
- }
-
- Widget _createSubmit(FeedbackModel model) {
- return GestureDetector(
- onTap: () {
- if (!_submitable) {
- return;
- }
-
- if(isUpLoading){
- // Fluttertoast.showToast(msg: '提交中...');
- return;
- }
-
- setState(() {
- isUpLoading = true;
- });
-
- Logger.debug('提交:${_feedback.text.toString()}');
- String selectId;
- model.feedbackTypes.forEach((element) {
- if (element.isSelect) {
- selectId = element.typeId;
- }
- });
- BlocProvider.of<FeedbackBloc>(context)
- .add(FeedbackSubmitEvent(model: {'title': _title?.text?.toString(), 'content': _feedback?.text?.toString(), 'type': selectId, 'files': _images}));
- // Fluttertoast.showToast(msg: '提交成功~');
- // Navigator.pop(context);
- },
- child: Container(
- margin: EdgeInsets.only(top: 24, bottom: 4),
- height: 45,
- decoration: BoxDecoration(
- color: HexColor.fromHex(_submitable ? model?.feedbackTypeSelectedBorderColor ?? '' : model?.feedbackPostBtnBgColor ?? ''),
- borderRadius: BorderRadius.circular(7.5),
- ),
- child: Center(
- child: Text(
- isUpLoading ? '提交意见...' : model?.feedbackPostBtnText ?? '提交意见',
- style: TextStyle(
- fontSize: 14,
- color: HexColor.fromHex(model?.feedbackPostBtnTextColor ?? '#FFFFFF'),
- ),
- ),
- ),
- ),
- );
- }
- }
|