master
jack ning 3 years ago
parent dcd34c17ed
commit 8414606bfa

@ -46,7 +46,7 @@ dependencies:
# 请在ios/Podfile中添加use_frameworks! # 请在ios/Podfile中添加use_frameworks!
vibration: ^1.7.3 vibration: ^1.7.3
# 在线客服 https://pub.dev/packages/bytedesk_kefu # 在线客服 https://pub.dev/packages/bytedesk_kefu
bytedesk_kefu: ^1.2.9 bytedesk_kefu: ^1.3.0
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.

@ -27,8 +27,7 @@ class LeaveMsgBloc extends Bloc<LeaveMsgEvent, LeaveMsgState> {
SubmitLeaveMsgEvent event, Emitter<LeaveMsgState> emit) async { SubmitLeaveMsgEvent event, Emitter<LeaveMsgState> emit) async {
emit(LeaveMsgSubmiting()); emit(LeaveMsgSubmiting());
try { try {
// final JsonResult jsonResult = await leaveMsgRepository.submitLeaveMsg(event.wid, event.aid, event.type, event.mobile, event.email, event.content);
await leaveMsgRepository.submitLeaveMsg(event.content, event.imageUrls);
emit(LeaveMsgSubmitSuccessState()); emit(LeaveMsgSubmitSuccessState());
} catch (error) { } catch (error) {
print(error); print(error);

@ -15,10 +15,15 @@ class GetLeaveMsgCategoryEvent extends LeaveMsgEvent {
} }
class SubmitLeaveMsgEvent extends LeaveMsgEvent { class SubmitLeaveMsgEvent extends LeaveMsgEvent {
final List<String>? imageUrls; // final List<String>? imageUrls;
final String? wid;
final String? aid;
final String? type;
final String? mobile;
final String? email;
final String? content; final String? content;
// @required this.imageUrls
SubmitLeaveMsgEvent({@required this.content, @required this.imageUrls}) SubmitLeaveMsgEvent({@required this.wid, @required this.aid, @required this.type, @required this.mobile, @required this.email, @required this.content})
: super(); : super();
} }

@ -33,14 +33,12 @@ class BytedeskLeaveMsgHttpApi extends BytedeskBaseHttpApi {
return categories; return categories;
} }
// TODO: // TODO: , List<String>? imageUrls
Future<JsonResult> submitLeaveMsg( Future<JsonResult> submitLeaveMsg(String? wid, String? aid, String? type,
String? content, List<String>? imageUrls) async { String? mobile, String? email, String? content) async {
// //
var body = json.encode({"content": content, "client": client}); var body = json.encode({"wid": wid, "aid": aid, "type": type, "mobile": mobile, "email": email,"content": content, "client": client});
// final initUrl = Uri.http(BytedeskConstants.host, '/api/leavemsg/save');
// final initUrl = '$baseUrl/api/feedback/create';
final initUrl = Uri.http(BytedeskConstants.host, '/api/leavemsg/create');
final initResponse = final initResponse =
await this.httpClient.post(initUrl, headers: getHeaders(), body: body); await this.httpClient.post(initUrl, headers: getHeaders(), body: body);
//json //json
@ -48,12 +46,12 @@ class BytedeskLeaveMsgHttpApi extends BytedeskBaseHttpApi {
//string json //string json
final responseJson = final responseJson =
json.decode(utf8decoder.convert(initResponse.bodyBytes)); json.decode(utf8decoder.convert(initResponse.bodyBytes));
print("responseJson $responseJson"); print("submitLeaveMsg:");
print(responseJson);
// token // token
if (responseJson.toString().contains('invalid_token')) { if (responseJson.toString().contains('invalid_token')) {
bytedeskEventBus.fire(InvalidTokenEventBus()); bytedeskEventBus.fire(InvalidTokenEventBus());
} }
// return User.fromJson(responseJson); // return User.fromJson(responseJson);
return JsonResult(); return JsonResult();
} }

@ -11,9 +11,9 @@ class LeaveMsgRepository {
return await bytedeskHttpApi.getHelpLeaveMsgCategories(uid); return await bytedeskHttpApi.getHelpLeaveMsgCategories(uid);
} }
Future<JsonResult> submitLeaveMsg( // , List<String>? imageUrls
String? content, List<String>? imageUrls) async { Future<JsonResult> submitLeaveMsg(String? wid, String? aid, String? type, String? mobile, String? email, String? content) async {
return await bytedeskHttpApi.submitLeaveMsg(content, imageUrls); return await bytedeskHttpApi.submitLeaveMsg(wid, aid, type, mobile, email, content);
} }
Future<String> upload(String? filePath) async { Future<String> upload(String? filePath) async {

@ -1,12 +1,12 @@
import 'dart:io'; // import 'dart:io';
import 'package:bytedesk_kefu/blocs/leavemsg_bloc/bloc.dart'; import 'package:bytedesk_kefu/blocs/leavemsg_bloc/bloc.dart';
import 'package:bytedesk_kefu/ui/widget/image_choose_widget.dart'; // import 'package:bytedesk_kefu/ui/widget/image_choose_widget.dart';
import 'package:bytedesk_kefu/ui/widget/my_button.dart'; import 'package:bytedesk_kefu/ui/widget/my_button.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_picker/image_picker.dart'; // import 'package:image_picker/image_picker.dart';
class LeaveMsgPage extends StatefulWidget { class LeaveMsgPage extends StatefulWidget {
// //
@ -15,6 +15,10 @@ class LeaveMsgPage extends StatefulWidget {
final String? type; final String? type;
final String? tip; final String? tip;
// //
// String? mobile;
// String? email;
// String? content;
//
LeaveMsgPage( LeaveMsgPage(
{Key? key, {Key? key,
@required this.wid, @required this.wid,
@ -30,11 +34,13 @@ class LeaveMsgPage extends StatefulWidget {
class _LeaveMsgPageState extends State<LeaveMsgPage> { class _LeaveMsgPageState extends State<LeaveMsgPage> {
// //
ScrollController _scrollController = new ScrollController(); // ScrollController _scrollController = new ScrollController(); //
TextEditingController _textEditController = new TextEditingController(); // TextEditingController _nameEditController = new TextEditingController();
ImagePicker picker = ImagePicker(); TextEditingController _mobileEditController = new TextEditingController();
List<String> _imageUrls = []; TextEditingController _contentEditController = new TextEditingController();
List<File> _fileList = []; // ImagePicker picker = ImagePicker();
File? _selectedImageFile; // List<String> _imageUrls = [];
// List<File> _fileList = [];
// File? _selectedImageFile;
// List<MultipartFile> mSubmitFileList = []; // List<MultipartFile> mSubmitFileList = [];
@override @override
@ -55,11 +61,11 @@ class _LeaveMsgPageState extends State<LeaveMsgPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// //
print('fileList的内容: $_fileList'); // print('fileList的内容: $_fileList');
if (_selectedImageFile != null) { // if (_selectedImageFile != null) {
_fileList.add(_selectedImageFile!); // _fileList.add(_selectedImageFile!);
} // }
_selectedImageFile = null; // _selectedImageFile = null;
// //
// TODO: // TODO:
return Scaffold( return Scaffold(
@ -74,10 +80,10 @@ class _LeaveMsgPageState extends State<LeaveMsgPage> {
child: InkWell( child: InkWell(
onTap: () { onTap: () {
// //
BlocProvider.of<LeaveMsgBloc>(context) // BlocProvider.of<LeaveMsgBloc>(context)
..add(SubmitLeaveMsgEvent( // ..add(SubmitLeaveMsgEvent(
imageUrls: _imageUrls, // imageUrls: _imageUrls,
content: _textEditController.text)); // content: _contentEditController.text));
}, },
child: Text( child: Text(
'提交', '提交',
@ -95,9 +101,9 @@ class _LeaveMsgPageState extends State<LeaveMsgPage> {
Fluttertoast.showToast(msg: '上传图片中'); Fluttertoast.showToast(msg: '上传图片中');
} else if (state is UploadImageSuccess) { } else if (state is UploadImageSuccess) {
// url // url
if (!_imageUrls.contains(state.url)) { // if (!_imageUrls.contains(state.url)) {
_imageUrls.add(state.url); // _imageUrls.add(state.url);
} // }
} else if (state is LeaveMsgSubmiting) { } else if (state is LeaveMsgSubmiting) {
Fluttertoast.showToast(msg: '提交留言中'); Fluttertoast.showToast(msg: '提交留言中');
} else if (state is LeaveMsgSubmitSuccessState) { } else if (state is LeaveMsgSubmitSuccessState) {
@ -113,6 +119,44 @@ class _LeaveMsgPageState extends State<LeaveMsgPage> {
padding: EdgeInsets.only(top: 5.0, left: 10, right: 10), padding: EdgeInsets.only(top: 5.0, left: 10, right: 10),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
// Container(
// // constraints: BoxConstraints(
// // minHeight: 150,
// // ),
// // color: Color(0xffffffff),
// margin: EdgeInsets.only(top: 15),
// child: TextField(
// controller: _nameEditController,
// // maxLines: 5,
// // maxLength: 500,
// decoration: InputDecoration(
// hintText: "称呼",
// hintStyle:
// TextStyle(color: Color(0xff999999), fontSize: 16),
// contentPadding: EdgeInsets.only(left: 15, right: 15),
// border: InputBorder.none,
// ),
// ),
// ),
Container(
// constraints: BoxConstraints(
// minHeight: 150,
// ),
// color: Color(0xffffffff),
margin: EdgeInsets.only(top: 15),
child: TextField(
controller: _mobileEditController,
// maxLines: 5,
// maxLength: 500,
decoration: InputDecoration(
hintText: "手机号",
hintStyle:
TextStyle(color: Color(0xff999999), fontSize: 16),
contentPadding: EdgeInsets.only(left: 15, right: 15),
border: InputBorder.none,
),
),
),
Container( Container(
constraints: BoxConstraints( constraints: BoxConstraints(
minHeight: 150, minHeight: 150,
@ -120,11 +164,11 @@ class _LeaveMsgPageState extends State<LeaveMsgPage> {
// color: Color(0xffffffff), // color: Color(0xffffffff),
margin: EdgeInsets.only(top: 15), margin: EdgeInsets.only(top: 15),
child: TextField( child: TextField(
controller: _textEditController, controller: _contentEditController,
maxLines: 5, maxLines: 5,
maxLength: 500, maxLength: 500,
decoration: InputDecoration( decoration: InputDecoration(
hintText: "快说点儿什么吧......", hintText: "留言内容",
hintStyle: hintStyle:
TextStyle(color: Color(0xff999999), fontSize: 16), TextStyle(color: Color(0xff999999), fontSize: 16),
contentPadding: EdgeInsets.only(left: 15, right: 15), contentPadding: EdgeInsets.only(left: 15, right: 15),
@ -132,86 +176,94 @@ class _LeaveMsgPageState extends State<LeaveMsgPage> {
), ),
), ),
), ),
GridView.count( // GridView.count(
shrinkWrap: true, // shrinkWrap: true,
primary: false, // primary: false,
crossAxisCount: 3, // crossAxisCount: 3,
children: List.generate(_fileList.length + 1, (index) { // children: List.generate(_fileList.length + 1, (index) {
// GridViewitem // // GridViewitem
var content; // var content;
if (index == _fileList.length) { // if (index == _fileList.length) {
// // //
var addCell = Center( // var addCell = Center(
child: Image.asset( // child: Image.asset(
'assets/images/feedback/mine_feedback_add_image.png', // 'assets/images/feedback/mine_feedback_add_image.png',
width: double.infinity, // width: double.infinity,
height: double.infinity, // height: double.infinity,
)); // ));
content = GestureDetector( // content = GestureDetector(
onTap: () { // onTap: () {
// // //
// pickImage(context); // // pickImage(context);
showModalBottomSheet( // showModalBottomSheet(
context: context, // context: context,
builder: (context) { // builder: (context) {
return ImageChooseWidget( // return ImageChooseWidget(
pickImageCallBack: () { // pickImageCallBack: () {
_pickImage(); // _pickImage();
}, // },
takeImageCallBack: () { // takeImageCallBack: () {
_takeImage(); // _takeImage();
}, // },
); // );
}); // });
}, // },
child: addCell, // child: addCell,
); // );
} else { // } else {
// // //
content = Stack( // content = Stack(
children: <Widget>[ // children: <Widget>[
Center( // Center(
child: Image.file( // child: Image.file(
_fileList[index], // _fileList[index],
width: double.infinity, // width: double.infinity,
height: double.infinity, // height: double.infinity,
fit: BoxFit.cover, // fit: BoxFit.cover,
), // ),
), // ),
Align( // Align(
alignment: Alignment.topRight, // alignment: Alignment.topRight,
child: InkWell( // child: InkWell(
onTap: () { // onTap: () {
_fileList.removeAt(index); // _fileList.removeAt(index);
_selectedImageFile = null; // _selectedImageFile = null;
setState(() {}); // setState(() {});
}, // },
child: Image.asset( // child: Image.asset(
'assets/images/feedback/mine_feedback_ic_del.png', // 'assets/images/feedback/mine_feedback_ic_del.png',
width: 20.0, // width: 20.0,
height: 20.0, // height: 20.0,
), // ),
), // ),
) // )
], // ],
); // );
} // }
return Container( // return Container(
margin: const EdgeInsets.all(10.0), // margin: const EdgeInsets.all(10.0),
width: 80.0, // width: 80.0,
height: 80.0, // height: 80.0,
color: const Color(0xFFffffff), // color: const Color(0xFFffffff),
child: content, // child: content,
); // );
}), // }),
), // ),
MyButton( MyButton(
onPressed: () { onPressed: () {
// //
// BlocProvider.of<LeaveMsgBloc>(context)
// ..add(SubmitLeaveMsgEvent(
// imageUrls: _imageUrls,
// content: _contentEditController.text));
BlocProvider.of<LeaveMsgBloc>(context) BlocProvider.of<LeaveMsgBloc>(context)
..add(SubmitLeaveMsgEvent( ..add(SubmitLeaveMsgEvent(
imageUrls: _imageUrls, wid: widget.wid,
content: _textEditController.text)); aid: widget.aid,
type: widget.type,
mobile: _mobileEditController.text,
email: "",
content: _contentEditController.text));
}, },
text: '提交', text: '提交',
) )
@ -222,46 +274,46 @@ class _LeaveMsgPageState extends State<LeaveMsgPage> {
} }
// //
Future<void> _pickImage() async { // Future<void> _pickImage() async {
if (_fileList.length >= 9) { // if (_fileList.length >= 9) {
Fluttertoast.showToast(msg: "最多选取9张图片"); // Fluttertoast.showToast(msg: "最多选取9张图片");
return; // return;
} // }
try { // try {
XFile? pickedFile = await picker.pickImage( // XFile? pickedFile = await picker.pickImage(
source: ImageSource.gallery, maxWidth: 800, imageQuality: 95); // source: ImageSource.gallery, maxWidth: 800, imageQuality: 95);
print('pick image path: ${pickedFile!.path}'); // print('pick image path: ${pickedFile!.path}');
setState(() { // setState(() {
_selectedImageFile = File(pickedFile.path); // _selectedImageFile = File(pickedFile.path);
}); // });
// // //
BlocProvider.of<LeaveMsgBloc>(context) // BlocProvider.of<LeaveMsgBloc>(context)
..add(UploadImageEvent(filePath: pickedFile.path)); // ..add(UploadImageEvent(filePath: pickedFile.path));
} catch (e) { // } catch (e) {
print('pick image error ${e.toString()}'); // print('pick image error ${e.toString()}');
Fluttertoast.showToast(msg: "未选取图片"); // Fluttertoast.showToast(msg: "未选取图片");
} // }
} // }
// //
Future<void> _takeImage() async { // Future<void> _takeImage() async {
if (_fileList.length >= 9) { // if (_fileList.length >= 9) {
Fluttertoast.showToast(msg: "最多选取9张图片"); // Fluttertoast.showToast(msg: "最多选取9张图片");
return; // return;
} // }
try { // try {
XFile? pickedFile = await picker.pickImage( // XFile? pickedFile = await picker.pickImage(
source: ImageSource.camera, maxWidth: 800, imageQuality: 95); // source: ImageSource.camera, maxWidth: 800, imageQuality: 95);
print('take image path: ${pickedFile!.path}'); // print('take image path: ${pickedFile!.path}');
setState(() { // setState(() {
_selectedImageFile = File(pickedFile.path); // _selectedImageFile = File(pickedFile.path);
}); // });
// // //
BlocProvider.of<LeaveMsgBloc>(context) // BlocProvider.of<LeaveMsgBloc>(context)
..add(UploadImageEvent(filePath: pickedFile.path)); // ..add(UploadImageEvent(filePath: pickedFile.path));
} catch (e) { // } catch (e) {
print('take image error ${e.toString()}'); // print('take image error ${e.toString()}');
Fluttertoast.showToast(msg: "未选取图片"); // Fluttertoast.showToast(msg: "未选取图片");
} // }
} // }
} }

@ -45,7 +45,7 @@ class BytedeskConstants {
// static const String httpBaseUrliOS = 'http://' + mqttHost + ':8000'; // static const String httpBaseUrliOS = 'http://' + mqttHost + ':8000';
// static const String httpUploadUrl = 'http://' + mqttHost + ':8000'; // static const String httpUploadUrl = 'http://' + mqttHost + ':8000';
// static const String host = mqttHost + ':8000'; // static const String host = mqttHost + ':8000';
// static const String mqttHost = '192.168.0.104'; // static const String mqttHost = '192.168.0.102';
// 线 // 线
static const bool isDebug = false; // false; static const bool isDebug = false; // false;

Loading…
Cancel
Save