@@ -11,6 +11,7 @@ import 'package:permission_handler/permission_handler.dart'; | |||
import 'package:zhiying_base_widget/dialog/loading/loading.dart'; | |||
import 'package:zhiying_base_widget/pages/mine_detail_page/mine_detail_bloc.dart'; | |||
import 'package:zhiying_base_widget/pages/mine_detail_page/models/mine_detail_model.dart'; | |||
import 'package:zhiying_base_widget/pages/upload_wechat_page/upload_wechat_page.dart'; | |||
import 'package:zhiying_base_widget/widgets/others/action_date_alert/action_date_alert.dart'; | |||
import 'package:zhiying_base_widget/widgets/others/action_list_alert/action_list_alert.dart'; | |||
import 'package:zhiying_base_widget/widgets/others/action_selected_alert/action_selected_alert.dart'; | |||
@@ -133,6 +134,12 @@ class _MineDetailContainerState extends State<_MineDetailContainer> { | |||
DateTime.fromMillisecondsSinceEpoch( | |||
registTime * 1000)) | |||
: user?.registerTime ?? ''), | |||
Padding( padding: const EdgeInsets.only(top: 8),child: _createItem('填写微信号', user?.is_upload_wx == '1' ? '已上传' : '未上传微信号与二维码', | |||
onTap: (){ | |||
Navigator.push(context, CupertinoPageRoute(builder: (_) => UploadWeChatPage())); | |||
})) | |||
], | |||
), | |||
); | |||
@@ -6,6 +6,7 @@ class MineDetailModel { | |||
String registerTime; | |||
String fileBucketUrl; | |||
String fileFormat; | |||
String is_upload_wx; | |||
MineDetailModel( | |||
{this.avatar, | |||
@@ -14,7 +15,9 @@ class MineDetailModel { | |||
this.birthday, | |||
this.registerTime, | |||
this.fileBucketUrl, | |||
this.fileFormat}); | |||
this.fileFormat, | |||
this.is_upload_wx, | |||
}); | |||
MineDetailModel.fromJson(Map<String, dynamic> json) { | |||
avatar = json['avatar']; | |||
@@ -24,6 +27,7 @@ class MineDetailModel { | |||
registerTime = json['register_time']; | |||
fileBucketUrl = json['file_bucket_url']; | |||
fileFormat = json['file_format']; | |||
is_upload_wx = json['is_upload_wx']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
@@ -35,6 +39,7 @@ class MineDetailModel { | |||
data['register_time'] = this.registerTime; | |||
data['file_bucket_url'] = this.fileBucketUrl; | |||
data['file_format'] = this.fileFormat; | |||
data['is_upload_wx'] = this.is_upload_wx; | |||
return data; | |||
} | |||
} | |||
@@ -0,0 +1,52 @@ | |||
import 'dart:async'; | |||
import 'package:bloc/bloc.dart'; | |||
import 'package:zhiying_base_widget/pages/upload_wechat_page/bloc/upload_wechat_repository.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'upload_wechat_event.dart'; | |||
import 'upload_wechat_state.dart'; | |||
class UploadWeChatBloc extends Bloc<UploadWeChatEvent, UploadWeChatState> { | |||
@override | |||
UploadWeChatState get initialState => UploadWeChatInitial(); | |||
UploadWeChatRepository repository; | |||
UploadWeChatBloc(this.repository); | |||
@override | |||
Stream<UploadWeChatState> mapEventToState( | |||
UploadWeChatEvent event, | |||
) async* { | |||
/// 初始化 | |||
if (event is UploadWeChatInitEvent) { | |||
yield* _mapInitEventToState(event); | |||
} | |||
/// 更新微信信息 | |||
if (event is UploadWeChatSubmitEvent) { | |||
yield* _mapUpdateEventToState(event); | |||
} | |||
} | |||
/// 初始化 | |||
Stream<UploadWeChatState> _mapInitEventToState(UploadWeChatInitEvent event) async* { | |||
var result = await repository.fetchInitData(); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield UploadWeChatLoadedState(model: result); | |||
} else { | |||
yield UploadWeChatInitErrorState(); | |||
} | |||
} | |||
/// 更新微信信息 | |||
Stream<UploadWeChatState> _mapUpdateEventToState(UploadWeChatSubmitEvent event) async* { | |||
var result = await repository.fetchUpdateWeChatInfo(event?.file, event?.wxAccount); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield UploadWeChatSubmitSuccessState(); | |||
yield UploadWeChatLoadedState(model: result); | |||
} else { | |||
yield UploadWeChatSubmitErrorState(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,17 @@ | |||
import 'dart:io'; | |||
import 'package:meta/meta.dart'; | |||
@immutable | |||
abstract class UploadWeChatEvent {} | |||
/// 获取数据 | |||
class UploadWeChatInitEvent extends UploadWeChatEvent {} | |||
/// 上传或者更新二维码或者图片 | |||
class UploadWeChatSubmitEvent extends UploadWeChatEvent { | |||
File file; | |||
String wxAccount; | |||
UploadWeChatSubmitEvent({this.file, this.wxAccount}); | |||
} |
@@ -0,0 +1,65 @@ | |||
import 'dart:convert'; | |||
import 'dart:io'; | |||
import 'package:path/path.dart'; | |||
import 'package:zhiying_base_widget/pages/upload_wechat_page/model/upload_wechat_model.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class UploadWeChatRepository { | |||
/// 获取数据 | |||
Future<UploadWeChatModel> fetchInitData() async { | |||
try { | |||
var result = await NetUtil.post('/api/v1/user/info/wx', method: NetMethod.GET); | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
return UploadWeChatModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
/// 上传信息 | |||
Future<UploadWeChatModel> fetchUpdateWeChatInfo(final File file, final String wxAccount) async { | |||
try { | |||
if (!EmptyUtil.isEmpty(file) && !EmptyUtil.isEmpty(wxAccount)) { | |||
String uploadUrl = await uploadFile(file); | |||
if (EmptyUtil.isEmpty(uploadUrl)) return null; | |||
var result = await NetUtil.post('/api/v1/user/info/wx', params: {'wx_account': wxAccount, 'wx_qrcode': uploadUrl}, method: NetMethod.POST); | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
return UploadWeChatModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||
} | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
/// 上传图片 | |||
Future<String> uploadFile(final File imageFile) async { | |||
try { | |||
List<int> originBytes = await imageFile.readAsBytes(); | |||
var result1 = await NetUtil.post('/api/v1/img/upload', params: {'dir': 'qrcode', 'file_size': originBytes.length, 'file_name': basename(imageFile.path)}, method: NetMethod.PUT); | |||
if (NetUtil.isSuccess(result1) && !EmptyUtil.isEmpty(result1[GlobalConfig.HTTP_RESPONSE_KEY_DATA]) && !EmptyUtil.isEmpty(result1[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['token'])) { | |||
String token = result1[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['token']; | |||
String host = result1[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['host']; | |||
String key = result1[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['key']; | |||
String method = result1[GlobalConfig.HTTP_RESPONSE_KEY_DATA]['method']; | |||
var result2 = await NetUtil.uploadFile(host, imageFile, params: {'key': key, 'token': token}, method: method); | |||
Map<String, dynamic> json = jsonDecode(result2.toString()); | |||
if (NetUtil.isSuccess(json) && !EmptyUtil.isEmpty(json[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
String filename = json['data']['fname'] ?? ''; | |||
print(filename); | |||
// filename += '?${DateTime.now().millisecondsSinceEpoch.toString()}'; | |||
// print(filename); | |||
// ⚠️ 这里返回key是因为fname是带有域名的,所以直接用key即可 | |||
return !EmptyUtil.isEmpty(filename) ? key : null; | |||
} | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
import 'package:meta/meta.dart'; | |||
import 'package:zhiying_base_widget/pages/upload_wechat_page/model/upload_wechat_model.dart'; | |||
@immutable | |||
abstract class UploadWeChatState {} | |||
/// 初始化 | |||
class UploadWeChatInitial extends UploadWeChatState {} | |||
/// 初始化失败 | |||
class UploadWeChatInitErrorState extends UploadWeChatState{} | |||
/// 数据加载成功 | |||
class UploadWeChatLoadedState extends UploadWeChatState { | |||
UploadWeChatModel model; | |||
UploadWeChatLoadedState({this.model}); | |||
} | |||
/// 上传信息成功 | |||
class UploadWeChatSubmitSuccessState extends UploadWeChatState {} | |||
/// 上传信息失败 | |||
class UploadWeChatSubmitErrorState extends UploadWeChatState {} |
@@ -0,0 +1,18 @@ | |||
class UploadWeChatModel { | |||
String wxAccount; | |||
String wxQrcode; | |||
UploadWeChatModel({this.wxAccount, this.wxQrcode}); | |||
UploadWeChatModel.fromJson(Map<String, dynamic> json) { | |||
wxAccount = json['wx_account']; | |||
wxQrcode = json['wx_qrcode']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['wx_account'] = this.wxAccount; | |||
data['wx_qrcode'] = this.wxQrcode; | |||
return data; | |||
} | |||
} |
@@ -0,0 +1,288 @@ | |||
import 'dart:io'; | |||
import 'package:flutter/cupertino.dart'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:image_picker/image_picker.dart'; | |||
import 'package:permission_handler/permission_handler.dart'; | |||
import 'package:zhiying_base_widget/pages/upload_wechat_page/bloc/upload_wechat_bloc.dart'; | |||
import 'package:zhiying_base_widget/pages/upload_wechat_page/bloc/upload_wechat_event.dart'; | |||
import 'package:zhiying_base_widget/pages/upload_wechat_page/bloc/upload_wechat_repository.dart'; | |||
import 'package:zhiying_base_widget/pages/upload_wechat_page/bloc/upload_wechat_state.dart'; | |||
import 'package:zhiying_base_widget/pages/upload_wechat_page/model/upload_wechat_model.dart'; | |||
import 'package:zhiying_base_widget/widgets/others/action_selected_alert/action_selected_alert.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'package:fluttertoast/fluttertoast.dart'; | |||
import 'package:flutter_bloc/flutter_bloc.dart'; | |||
class UploadWeChatPage extends StatelessWidget { | |||
@override | |||
Widget build(BuildContext context) { | |||
return BlocProvider<UploadWeChatBloc>( | |||
create: (_) => UploadWeChatBloc(UploadWeChatRepository())..add(UploadWeChatInitEvent()), | |||
child: _UploadWeChatPage(), | |||
); | |||
} | |||
} | |||
class _UploadWeChatPage extends StatefulWidget { | |||
@override | |||
__UploadWeChatPageState createState() => __UploadWeChatPageState(); | |||
} | |||
class __UploadWeChatPageState extends State<_UploadWeChatPage> { | |||
/// 是否上传中 | |||
bool _isUploading = false; | |||
bool _canSubmit = true; | |||
TextEditingController _editingController; | |||
File _qrCodeImg; | |||
/// 选择图片 | |||
void _onAddImage() async { | |||
Logger.debug('上传图片'); | |||
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 = await picker.getImage(source: ImageSource.gallery); | |||
if (file == null) return; | |||
setState(() { | |||
_qrCodeImg = File(file.path); | |||
}); | |||
// File resultFile = await EncodeUtil.compressImage(file, 800); | |||
} | |||
/// 点击提交事件 | |||
void _submitOnClick() { | |||
if (!_isUploading) { | |||
String wxAccount = _editingController?.text?.toString(); | |||
if (EmptyUtil.isEmpty(wxAccount)) { | |||
Fluttertoast.cancel(); | |||
Fluttertoast.showToast(msg: '微信号不能为空'); | |||
return; | |||
} | |||
if (EmptyUtil.isEmpty(_qrCodeImg)) { | |||
Fluttertoast.cancel(); | |||
Fluttertoast.showToast(msg: '请上传二维码'); | |||
return; | |||
} | |||
setState(() { | |||
_isUploading = true; | |||
}); | |||
BlocProvider.of<UploadWeChatBloc>(context).add(UploadWeChatSubmitEvent(file: _qrCodeImg, wxAccount: wxAccount)); | |||
} | |||
} | |||
@override | |||
void initState() { | |||
_editingController = TextEditingController(); | |||
super.initState(); | |||
} | |||
@override | |||
void dispose() { | |||
_editingController?.dispose(); | |||
super.dispose(); | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
return Scaffold( | |||
backgroundColor: HexColor.fromHex('#FFF9F9F9'), | |||
appBar: _buildAppBarWidget(), | |||
body: SingleChildScrollView( | |||
child: BlocConsumer<UploadWeChatBloc, UploadWeChatState>( | |||
listener: (context, state) {}, | |||
buildWhen: (prov, current) { | |||
if (current is UploadWeChatInitErrorState) { | |||
return false; | |||
} | |||
if (current is UploadWeChatSubmitErrorState) { | |||
_isUploading = false; | |||
} | |||
if (current is UploadWeChatSubmitSuccessState) { | |||
_isUploading = false; | |||
Fluttertoast.showToast(msg: '上传成功'); | |||
} | |||
return true; | |||
}, | |||
builder: (context, state) { | |||
if (state is UploadWeChatLoadedState) { | |||
if (!EmptyUtil.isEmpty(state?.model?.wxAccount)) { | |||
_editingController.text = state.model.wxAccount; | |||
} | |||
return _buildMainWidget(state?.model); | |||
} | |||
return _buildMainWidget(null); | |||
}, | |||
), | |||
), | |||
); | |||
} | |||
Widget _buildMainWidget(UploadWeChatModel model) { | |||
return Column( | |||
children: <Widget>[ | |||
_buildWeChatImageWidget(model), | |||
_createLine(), | |||
_createInput('微信号', _editingController), | |||
Padding(padding: const EdgeInsets.symmetric(horizontal: 12.5, vertical: 15), child: _buildSubmitButtonWidget()), | |||
], | |||
); | |||
} | |||
/// 二维码图片 | |||
Widget _buildWeChatImageWidget(UploadWeChatModel model) { | |||
return Container( | |||
width: double.infinity, | |||
margin: const EdgeInsets.only(top: 5), | |||
padding: const EdgeInsets.only(top: 15, bottom: 15), | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex('#FFFFFFFF'), | |||
), | |||
child: Column( | |||
children: <Widget>[ | |||
GestureDetector( | |||
onTap: () => _onAddImage(), | |||
behavior: HitTestBehavior.opaque, | |||
child: Container( | |||
height: 90, | |||
width: 90, | |||
// color: Colors.red, | |||
child: !EmptyUtil.isEmpty(_qrCodeImg) | |||
? Image.file( | |||
_qrCodeImg, | |||
fit: BoxFit.cover, | |||
) | |||
: !EmptyUtil.isEmpty(model?.wxQrcode) | |||
? CachedNetworkImage( | |||
imageUrl: model?.wxQrcode ?? '', | |||
fit: BoxFit.cover, | |||
) | |||
: Image.asset( | |||
'assets/images/qrcode/default_qrcode.png', | |||
package: 'zhiying_base_widget', | |||
), | |||
), | |||
), | |||
const SizedBox(height: 6), | |||
GestureDetector( | |||
onTap: () => _onAddImage(), | |||
behavior: HitTestBehavior.opaque, | |||
child: Text( | |||
'点击上传二维码', | |||
style: TextStyle(color: HexColor.fromHex('#FF999999'), fontSize: 13), | |||
), | |||
) | |||
], | |||
), | |||
); | |||
} | |||
/// 阴影 | |||
Widget _createLine() { | |||
return Container( | |||
width: double.infinity, | |||
height: 0.5, | |||
margin: EdgeInsets.only(left: 12.5, right: 12.5), | |||
color: HexColor.fromHex('#FFF7F7F7'), | |||
); | |||
} | |||
Widget _createInput(String title, TextEditingController controller, {VoidCallback onTap}) { | |||
return GestureDetector( | |||
child: Container( | |||
padding: EdgeInsets.only(left: 12.5, right: 12.5), | |||
height: 48, | |||
color: Colors.white, | |||
child: Row( | |||
children: <Widget>[ | |||
Expanded( | |||
child: Text( | |||
title ?? '', | |||
style: TextStyle(fontSize: 13, color: Color(0xff333333), fontWeight: FontWeight.bold), | |||
), | |||
), | |||
Expanded( | |||
child: CupertinoTextField( | |||
decoration: BoxDecoration(color: Colors.transparent), | |||
textInputAction: TextInputAction.done, | |||
controller: controller, | |||
textAlign: TextAlign.right, | |||
placeholder: '请输入微信号', | |||
style: TextStyle( | |||
fontSize: 13, | |||
color: Color(0xff999999), | |||
), | |||
), | |||
), | |||
onTap == null | |||
? Container() | |||
: Icon( | |||
Icons.arrow_forward_ios, | |||
size: 12, | |||
color: Color(0xff999999), | |||
) | |||
], | |||
), | |||
), | |||
onTap: onTap, | |||
); | |||
} | |||
/// 提交按钮 | |||
Widget _buildSubmitButtonWidget() { | |||
return Material( | |||
child: Container( | |||
height: 48, | |||
width: double.infinity, | |||
color: Colors.white, | |||
child: RaisedButton( | |||
child: Text( | |||
_isUploading ? '提交中...' : '提交', | |||
style: TextStyle(fontSize: 15), | |||
), | |||
textColor: HexColor.fromHex('#FFFFFF'), | |||
color: HexColor.fromHex('#FFFF4242'), | |||
disabledColor: HexColor.fromHex('#F5F5F5'), | |||
disabledTextColor: HexColor.fromHex('#999999'), | |||
elevation: 5, | |||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(52 / 2)), | |||
onPressed: _canSubmit ? _submitOnClick : null, | |||
), | |||
), | |||
); | |||
} | |||
/// appbar | |||
Widget _buildAppBarWidget() { | |||
return AppBar( | |||
backgroundColor: HexColor.fromHex('#FFFFFF'), | |||
brightness: Brightness.light, | |||
leading: IconButton( | |||
icon: Icon( | |||
Icons.arrow_back_ios, | |||
size: 22, | |||
color: HexColor.fromHex('#333333'), | |||
), | |||
onPressed: () => Navigator.maybePop(context), | |||
), | |||
title: Text( | |||
'填写微信号', | |||
style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 15, fontWeight: FontWeight.bold), | |||
), | |||
centerTitle: true, | |||
elevation: 0, | |||
); | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
import 'dart:async'; | |||
import 'package:bloc/bloc.dart'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/bloc/wechat_teacher_repository.dart'; | |||
import 'wechat_teacher_event.dart'; | |||
import 'wechat_teacher_state.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class WechatTeacherBloc extends Bloc<WechatTeacherEvent, WechatTeacherState> { | |||
@override | |||
WechatTeacherState get initialState => WechatTeacherInitial(); | |||
WechatTeacherRepository repository; | |||
WechatTeacherBloc(this.repository); | |||
@override | |||
Stream<WechatTeacherState> mapEventToState( | |||
WechatTeacherEvent event, | |||
) async* { | |||
/// 初始化 | |||
if (event is WechatTeacherInitEvent) { | |||
yield* _mapInitEventToState(event); | |||
} | |||
/// 绑定微信导师 | |||
if (event is WechatTeacherBindEvent) { | |||
yield* _mapBindEventToState(event); | |||
} | |||
} | |||
/// 初始化 | |||
Stream<WechatTeacherState> _mapInitEventToState(WechatTeacherInitEvent event) async* { | |||
var cacheStyle = await repository.fetchCachedStyle(); | |||
if (!EmptyUtil.isEmpty(cacheStyle)) { | |||
yield WechatTeacherLoadedState(dataModel: null, styleModel: cacheStyle); | |||
} | |||
var netStyle = await repository.fetchInitStyle(); | |||
if (!EmptyUtil.isEmpty(netStyle)) { | |||
yield WechatTeacherLoadedState(dataModel: null, styleModel: netStyle); | |||
} | |||
var data = await repository.fetchInitData(); | |||
if (!EmptyUtil.isEmpty(data) && (!EmptyUtil.isEmpty(cacheStyle) || !EmptyUtil.isEmpty(netStyle))) { | |||
yield WechatTeacherLoadedState(styleModel: !EmptyUtil.isEmpty(netStyle) ? netStyle : cacheStyle, dataModel: data); | |||
} else { | |||
yield WechatTeacherInitErrorState(); | |||
} | |||
} | |||
/// 绑定微信导师 | |||
Stream<WechatTeacherState> _mapBindEventToState(WechatTeacherBindEvent event) async* { | |||
var style = repository.styleModel; | |||
var result = await repository.bindTeacher(event?.teacherWxChat); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
yield WechatTeacherBindSuccessState(); | |||
yield WechatTeacherLoadedState(styleModel: style, dataModel: result); | |||
} else { | |||
yield WechatTeacherBindErrorState(); | |||
yield WechatTeacherLoadedState(styleModel: style, dataModel: null); | |||
} | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
import 'package:meta/meta.dart'; | |||
@immutable | |||
abstract class WechatTeacherEvent {} | |||
/// 初始化 | |||
class WechatTeacherInitEvent extends WechatTeacherEvent {} | |||
/// 绑定邀请人 | |||
class WechatTeacherBindEvent extends WechatTeacherEvent { | |||
String teacherWxChat; | |||
WechatTeacherBindEvent({this.teacherWxChat}); | |||
} |
@@ -0,0 +1,89 @@ | |||
import 'dart:convert'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/model/wechat_teacher_data_model.dart'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/model/wechat_teacher_style_model.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
class WechatTeacherRepository { | |||
final Map<String, dynamic> data; | |||
WechatTeacherRepository(this.data); | |||
WechatTeacherStyleModel _styleModel; | |||
WechatTeacherDataModel _dataModel; | |||
WechatTeacherStyleModel get styleModel => _styleModel; | |||
WechatTeacherDataModel get dataModel => _dataModel; | |||
/// 初始化 | |||
Future<WechatTeacherStyleModel> fetchInitStyle() async { | |||
try { | |||
String skipIdentifier = | |||
!EmptyUtil.isEmpty(data) && data.containsKey('skip_identifier') && !EmptyUtil.isEmpty(data['skip_identifier']) ? data['skip_identifier'] : 'pub.flutter.wechat_teacher'; | |||
var result = await NetUtil.post('/api/v1/mod/$skipIdentifier', method: NetMethod.GET, cache: true); | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
return handleStyleModel(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
Future<WechatTeacherStyleModel> fetchCachedStyle() async { | |||
try { | |||
String skipIdentifier = | |||
!EmptyUtil.isEmpty(data) && data.containsKey('skip_identifier') && !EmptyUtil.isEmpty(data['skip_identifier']) ? data['skip_identifier'] : 'pub.flutter.wechat_teacher'; | |||
var result = await NetUtil.getRequestCachedData('/api/v1/mod/$skipIdentifier'); | |||
if (!EmptyUtil.isEmpty(result)) { | |||
return handleStyleModel(result); | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
WechatTeacherStyleModel handleStyleModel(final Map<String, dynamic> result) { | |||
var modListData = result['mod_list'][0]['data']; | |||
if (!EmptyUtil.isEmpty(modListData)) { | |||
WechatTeacherStyleModel model = WechatTeacherStyleModel.fromJson(modListData is String ? jsonDecode(modListData) : modListData); | |||
if (!EmptyUtil.isEmpty(model)) { | |||
_styleModel = model; | |||
} | |||
return _styleModel; | |||
} | |||
return null; | |||
} | |||
Future<WechatTeacherDataModel> fetchInitData() async { | |||
try { | |||
var result = await NetUtil.post('/api/v1/user/wx_teacher', method: NetMethod.GET); | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
WechatTeacherDataModel model = WechatTeacherDataModel.fromJson(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA]); | |||
if (!EmptyUtil.isEmpty(model)) { | |||
_dataModel = model; | |||
} | |||
return _dataModel; | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
/// 绑定导师 | |||
Future<WechatTeacherDataModel> bindTeacher(final String wxchatAccount) async { | |||
try { | |||
var result = await NetUtil.post('/api/v1/user/myteam/relate', method: NetMethod.POST, params: {'invite_code': wxchatAccount}); | |||
if (NetUtil.isSuccess(result) && !EmptyUtil.isEmpty(result[GlobalConfig.HTTP_RESPONSE_KEY_DATA])) { | |||
return await fetchInitData(); | |||
} | |||
} catch (e, s) { | |||
Logger.error(e, s); | |||
} | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,25 @@ | |||
import 'package:meta/meta.dart'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/model/wechat_teacher_data_model.dart'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/model/wechat_teacher_style_model.dart'; | |||
@immutable | |||
abstract class WechatTeacherState {} | |||
class WechatTeacherInitial extends WechatTeacherState {} | |||
/// 数据加载成功 | |||
class WechatTeacherLoadedState extends WechatTeacherState { | |||
WechatTeacherDataModel dataModel; | |||
WechatTeacherStyleModel styleModel; | |||
WechatTeacherLoadedState({this.dataModel, this.styleModel}); | |||
} | |||
/// 初始化失败 | |||
class WechatTeacherInitErrorState extends WechatTeacherState {} | |||
/// 绑定导师成功 | |||
class WechatTeacherBindSuccessState extends WechatTeacherState {} | |||
/// 绑定导师失败 | |||
class WechatTeacherBindErrorState extends WechatTeacherState {} |
@@ -0,0 +1,32 @@ | |||
class WechatTeacherDataModel { | |||
String isBindTeacher; | |||
String teacherAvatar; | |||
String teacherUsername; | |||
String teacherWechatAccount; | |||
String teacherWxQrCode; | |||
WechatTeacherDataModel( | |||
{this.isBindTeacher, | |||
this.teacherAvatar, | |||
this.teacherUsername, | |||
this.teacherWechatAccount, | |||
this.teacherWxQrCode}); | |||
WechatTeacherDataModel.fromJson(Map<String, dynamic> json) { | |||
isBindTeacher = json['is_bind_teacher']; | |||
teacherAvatar = json['teacher_avatar']; | |||
teacherUsername = json['teacher_username']; | |||
teacherWechatAccount = json['teacher_wechat_account']; | |||
teacherWxQrCode = json['teacher_wx_qr_code']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['is_bind_teacher'] = this.isBindTeacher; | |||
data['teacher_avatar'] = this.teacherAvatar; | |||
data['teacher_username'] = this.teacherUsername; | |||
data['teacher_wechat_account'] = this.teacherWechatAccount; | |||
data['teacher_wx_qr_code'] = this.teacherWxQrCode; | |||
return data; | |||
} | |||
} |
@@ -0,0 +1,293 @@ | |||
class WechatTeacherStyleModel { | |||
String appBarName; | |||
String appBarNameColor; | |||
String appBarBgColor; | |||
String bgColor; | |||
String bgImg; | |||
String teacherDialogTitle; | |||
String teacherDialogTitleColor; | |||
String teacherDialogBgColor; | |||
CommStyle commStyle; | |||
NobindTeacherDialog nobindTeacherDialog; | |||
MyTeacher myTeacher; | |||
BindTeacherDialog bindTeacherDialog; | |||
String chatDialogImg; | |||
OfficalWxchat officalWxchat; | |||
WechatTeacherStyleModel({ | |||
this.appBarName, | |||
this.appBarNameColor, | |||
this.appBarBgColor, | |||
this.bgColor, | |||
this.bgImg, | |||
this.teacherDialogTitle, | |||
this.teacherDialogTitleColor, | |||
this.teacherDialogBgColor, | |||
this.commStyle, | |||
this.nobindTeacherDialog, | |||
this.myTeacher, | |||
this.bindTeacherDialog, | |||
this.chatDialogImg, | |||
this.officalWxchat, | |||
}); | |||
WechatTeacherStyleModel.fromJson(Map<String, dynamic> json) { | |||
appBarName = json['app_bar_name']; | |||
appBarNameColor = json['app_bar_name_color']; | |||
appBarBgColor = json['app_bar_bg_color']; | |||
bgColor = json['bg_color']; | |||
bgImg = json['bg_img']; | |||
teacherDialogTitle = json['teacher_dialog_title']; | |||
teacherDialogTitleColor = json['teacher_dialog_title_color']; | |||
teacherDialogBgColor = json['teacher_dialog_bg_color']; | |||
commStyle = json['comm_style'] != null ? new CommStyle.fromJson(json['comm_style']) : null; | |||
nobindTeacherDialog = json['nobind_teacher_dialog'] != null ? new NobindTeacherDialog.fromJson(json['nobind_teacher_dialog']) : null; | |||
myTeacher = json['my_teacher'] != null ? new MyTeacher.fromJson(json['my_teacher']) : null; | |||
bindTeacherDialog = json['bind_teacher_dialog'] != null ? new BindTeacherDialog.fromJson(json['bind_teacher_dialog']) : null; | |||
chatDialogImg = json['chat_dialog_img']; | |||
officalWxchat = json['offical_wxchat'] != null ? new OfficalWxchat.fromJson(json['offical_wxchat']) : null; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['app_bar_name'] = this.appBarName; | |||
data['app_bar_name_color'] = this.appBarNameColor; | |||
data['app_bar_bg_color'] = this.appBarBgColor; | |||
data['bg_color'] = this.bgColor; | |||
data['bg_img'] = this.bgImg; | |||
data['teacher_dialog_title'] = this.teacherDialogTitle; | |||
data['teacher_dialog_title_color'] = this.teacherDialogTitleColor; | |||
data['teacher_dialog_bg_color'] = this.teacherDialogBgColor; | |||
if (this.commStyle != null) { | |||
data['comm_style'] = this.commStyle.toJson(); | |||
} | |||
if (this.nobindTeacherDialog != null) { | |||
data['nobind_teacher_dialog'] = this.nobindTeacherDialog.toJson(); | |||
} | |||
if (this.myTeacher != null) { | |||
data['my_teacher'] = this.myTeacher.toJson(); | |||
} | |||
if (this.bindTeacherDialog != null) { | |||
data['bind_teacher_dialog'] = this.bindTeacherDialog.toJson(); | |||
} | |||
data['chat_dialog_img'] = this.chatDialogImg; | |||
if (this.officalWxchat != null) { | |||
data['offical_wxchat'] = this.officalWxchat.toJson(); | |||
} | |||
return data; | |||
} | |||
} | |||
class CommStyle { | |||
String wechatAccountColor; | |||
String btnTextColor; | |||
String btnBgColor; | |||
CommStyle({ | |||
this.wechatAccountColor, | |||
this.btnTextColor, | |||
this.btnBgColor, | |||
}); | |||
CommStyle.fromJson(Map<String, dynamic> json) { | |||
wechatAccountColor = json['wechat_account_color']; | |||
btnTextColor = json['btn_text_color']; | |||
btnBgColor = json['btn_bg_color']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['wechat_account_color'] = this.wechatAccountColor; | |||
data['btn_text_color'] = this.btnTextColor; | |||
data['btn_bg_color'] = this.btnBgColor; | |||
return data; | |||
} | |||
} | |||
class NobindTeacherDialog { | |||
String inputHintText; | |||
String inputHintTextColor; | |||
String inputLineColor; | |||
String btnText; | |||
NobindTeacherDialog({ | |||
this.inputHintText, | |||
this.inputHintTextColor, | |||
this.inputLineColor, | |||
this.btnText, | |||
}); | |||
NobindTeacherDialog.fromJson(Map<String, dynamic> json) { | |||
inputHintText = json['input_hint_text']; | |||
inputHintTextColor = json['input_hint_text_color']; | |||
inputLineColor = json['input_line_color']; | |||
btnText = json['btn_text']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['input_hint_text'] = this.inputHintText; | |||
data['input_hint_text_color'] = this.inputHintTextColor; | |||
data['input_line_color'] = this.inputLineColor; | |||
data['btn_text'] = this.btnText; | |||
return data; | |||
} | |||
} | |||
class MyTeacher { | |||
String teacherType; | |||
DefalutTeacher defalutTeacher; | |||
MyTeacher({this.teacherType, this.defalutTeacher}); | |||
MyTeacher.fromJson(Map<String, dynamic> json) { | |||
teacherType = json['teacher_type']; | |||
defalutTeacher = json['defalut_teacher'] != null ? new DefalutTeacher.fromJson(json['defalut_teacher']) : null; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['teacher_type'] = this.teacherType; | |||
if (this.defalutTeacher != null) { | |||
data['defalut_teacher'] = this.defalutTeacher.toJson(); | |||
} | |||
return data; | |||
} | |||
} | |||
class DefalutTeacher { | |||
String avatar; | |||
String qrcode; | |||
String wxAccount; | |||
DefalutTeacher({this.avatar, this.qrcode, this.wxAccount}); | |||
DefalutTeacher.fromJson(Map<String, dynamic> json) { | |||
avatar = json['avatar']; | |||
qrcode = json['qrcode']; | |||
wxAccount = json['wx_account']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['avatar'] = this.avatar; | |||
data['qrcode'] = this.qrcode; | |||
data['wx_account'] = this.wxAccount; | |||
return data; | |||
} | |||
} | |||
class BindTeacherDialog { | |||
List<String> dataKeys; | |||
String btnText; | |||
String btnTextColor; | |||
String btnBgColor; | |||
String qrcodeText; | |||
String qrcodeTextColor; | |||
BindTeacherDialog({ | |||
this.dataKeys, | |||
this.btnText, | |||
this.btnTextColor, | |||
this.btnBgColor, | |||
this.qrcodeText, | |||
this.qrcodeTextColor, | |||
}); | |||
BindTeacherDialog.fromJson(Map<String, dynamic> json) { | |||
dataKeys = json['data_keys'].cast<String>(); | |||
btnText = json['btn_text']; | |||
btnTextColor = json['btn_text_color']; | |||
btnBgColor = json['btn_bg_color']; | |||
qrcodeText = json['qrcode_text']; | |||
qrcodeTextColor = json['qrcode_text_color']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['data_keys'] = this.dataKeys; | |||
data['btn_text'] = this.btnText; | |||
data['btn_text_color'] = this.btnTextColor; | |||
data['btn_bg_color'] = this.btnBgColor; | |||
data['qrcode_text'] = this.qrcodeText; | |||
data['qrcode_text_color'] = this.qrcodeTextColor; | |||
return data; | |||
} | |||
} | |||
class OfficalWxchat { | |||
String qrcodeText; | |||
String qrcodeTextColor; | |||
String bgColor; | |||
String title; | |||
String titleColor; | |||
String btnText; | |||
List<OfficalWxchatList> list; | |||
OfficalWxchat({ | |||
this.qrcodeText, | |||
this.qrcodeTextColor, | |||
this.bgColor, | |||
this.title, | |||
this.titleColor, | |||
this.btnText, | |||
this.list, | |||
}); | |||
OfficalWxchat.fromJson(Map<String, dynamic> json) { | |||
qrcodeText = json['qrcode_text']; | |||
qrcodeTextColor = json['qrcode_text_color']; | |||
bgColor = json['bg_color']; | |||
title = json['title']; | |||
titleColor = json['title_color']; | |||
btnText = json['btn_text']; | |||
if (json['list'] != null) { | |||
list = new List<OfficalWxchatList>(); | |||
json['list'].forEach((v) { | |||
list.add(new OfficalWxchatList.fromJson(v)); | |||
}); | |||
} | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['qrcode_text'] = this.qrcodeText; | |||
data['qrcode_text_color'] = this.qrcodeTextColor; | |||
data['bg_color'] = this.bgColor; | |||
data['title'] = this.title; | |||
data['title_color'] = this.titleColor; | |||
data['btn_text'] = this.btnText; | |||
if (this.list != null) { | |||
data['list'] = this.list.map((v) => v.toJson()).toList(); | |||
} | |||
return data; | |||
} | |||
} | |||
class OfficalWxchatList { | |||
String type; | |||
String text; | |||
String subText; | |||
String wechatAccount; | |||
String qrcode; | |||
OfficalWxchatList({this.type, this.text, this.subText, this.wechatAccount, this.qrcode}); | |||
OfficalWxchatList.fromJson(Map<String, dynamic> json) { | |||
type = json['type']; | |||
text = json['text']; | |||
subText = json['sub_text']; | |||
wechatAccount = json['wechat_account']; | |||
qrcode = json['qrcode']; | |||
} | |||
Map<String, dynamic> toJson() { | |||
final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
data['type'] = this.type; | |||
data['text'] = this.text; | |||
data['sub_text'] = this.subText; | |||
data['wechat_account'] = this.wechatAccount; | |||
data['qrcode'] = this.qrcode; | |||
return data; | |||
} | |||
} |
@@ -1,24 +1,132 @@ | |||
import 'package:flutter/cupertino.dart'; | |||
import 'package:flutter/material.dart'; | |||
import 'package:flutter/services.dart'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/bloc/wechat_teacher_bloc.dart'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/bloc/wechat_teacher_repository.dart'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/model/wechat_teacher_data_model.dart'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/model/wechat_teacher_style_model.dart'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/widgets/wechat_teacher_item.dart'; | |||
import 'package:zhiying_base_widget/widgets/home/home_quick_entry/cached_network_image_util.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'package:flutter_bloc/flutter_bloc.dart'; | |||
import 'bloc/wechat_teacher_state.dart'; | |||
import 'bloc/wechat_teacher_event.dart'; | |||
import 'package:fluttertoast/fluttertoast.dart'; | |||
// 微信导师 | |||
class WechatTeacherPage extends StatefulWidget { | |||
/// | |||
/// 微信导师 | |||
/// | |||
class WechatTeacherPage extends StatelessWidget { | |||
final Map<String, dynamic> data; | |||
WechatTeacherPage(this.data); | |||
@override | |||
Widget build(BuildContext context) { | |||
return BlocProvider<WechatTeacherBloc>( | |||
create: (_) => WechatTeacherBloc(WechatTeacherRepository(data))..add(WechatTeacherInitEvent()), | |||
child: _WechatTeacherPageContainer(), | |||
); | |||
} | |||
} | |||
class _WechatTeacherPageContainer extends StatefulWidget { | |||
@override | |||
_WechatTeacherPageState createState() => _WechatTeacherPageState(); | |||
_WechatTeacherPageContainerState createState() => _WechatTeacherPageContainerState(); | |||
} | |||
class _WechatTeacherPageState extends State<WechatTeacherPage> { | |||
class _WechatTeacherPageContainerState extends State<_WechatTeacherPageContainer> { | |||
TextEditingController _editingController; | |||
/// 是否绑定中 | |||
bool _isBinding = false; | |||
/// 绑定邀请人 | |||
void _bindTeacher() { | |||
if (!_isBinding) { | |||
String wxAccount = _editingController?.text?.toString(); | |||
if (EmptyUtil.isEmpty(wxAccount)) { | |||
Fluttertoast.showToast(msg: '请输入邀请码或者手机号码'); | |||
return; | |||
} | |||
setState(() { | |||
_isBinding = true; | |||
}); | |||
BlocProvider.of<WechatTeacherBloc>(context).add(WechatTeacherBindEvent(teacherWxChat: wxAccount)); | |||
} | |||
} | |||
/// 拷贝 | |||
void _copyText(String text) { | |||
if (!EmptyUtil.isEmpty(text)) { | |||
Clipboard.setData(ClipboardData(text: text)); | |||
Fluttertoast.showToast(msg: '复制成功~'); | |||
} else { | |||
Fluttertoast.showToast(msg: '内容不能为空~'); | |||
} | |||
} | |||
/// 长按保存图片 | |||
void _longClickSaveImage() { | |||
Logger.log('长按保存图片'); | |||
} | |||
@override | |||
void initState() { | |||
_editingController = TextEditingController(); | |||
super.initState(); | |||
} | |||
@override | |||
void dispose() { | |||
_editingController?.dispose(); | |||
super.dispose(); | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
return BlocConsumer<WechatTeacherBloc, WechatTeacherState>( | |||
listener: (context, state) {}, | |||
buildWhen: (prov, current) { | |||
if (current is WechatTeacherInitErrorState) { | |||
return false; | |||
} | |||
if (current is WechatTeacherBindErrorState) { | |||
_isBinding = false; | |||
return false; | |||
} | |||
if (current is WechatTeacherBindSuccessState) { | |||
_isBinding = false; | |||
Fluttertoast.showToast(msg: '绑定成功'); | |||
return false; | |||
} | |||
return true; | |||
}, | |||
builder: (context, state) { | |||
if (state is WechatTeacherLoadedState) { | |||
return _createMainWidget(state?.styleModel, state?.dataModel); | |||
} | |||
return _createMainWidget(null, null); | |||
}, | |||
); | |||
} | |||
Widget _createMainWidget(WechatTeacherStyleModel styleModel, WechatTeacherDataModel dataModel) { | |||
return Scaffold( | |||
appBar: _createNav(), | |||
appBar: _createNav(styleModel), | |||
backgroundColor: HexColor.fromHex(styleModel?.bgColor ?? '#FFF5F5F5'), | |||
body: SafeArea( | |||
child: SingleChildScrollView( | |||
child: Column( | |||
children: <Widget>[ | |||
_createHeader(), | |||
_createWechat(), | |||
_createHeader(styleModel,dataModel), | |||
Padding( | |||
padding: const EdgeInsets.only(top: 15), | |||
child: CachedNetworkImage( | |||
imageUrl: styleModel?.chatDialogImg ?? '', | |||
width: double.infinity, | |||
)), | |||
_createWechat(styleModel), | |||
], | |||
), | |||
), | |||
@@ -27,7 +135,7 @@ class _WechatTeacherPageState extends State<WechatTeacherPage> { | |||
} | |||
// 导航栏 | |||
Widget _createNav() { | |||
Widget _createNav(WechatTeacherStyleModel styleModel) { | |||
return CupertinoNavigationBar( | |||
border: Border( | |||
bottom: BorderSide( | |||
@@ -35,7 +143,7 @@ class _WechatTeacherPageState extends State<WechatTeacherPage> { | |||
style: BorderStyle.none, | |||
), | |||
), | |||
backgroundColor: Colors.white, | |||
backgroundColor: HexColor.fromHex(styleModel?.appBarBgColor ?? '#FFFFFF'), | |||
leading: Navigator.canPop(context) | |||
? GestureDetector( | |||
child: Container( | |||
@@ -53,26 +161,145 @@ class _WechatTeacherPageState extends State<WechatTeacherPage> { | |||
) | |||
: Container(), | |||
middle: Text( | |||
'微信导师', | |||
styleModel?.appBarName ?? '微信导师', | |||
style: TextStyle( | |||
fontSize: 15, | |||
color: Color(0xff333333), | |||
color: HexColor.fromHex(styleModel?.appBarNameColor ?? '#333333'), | |||
), | |||
), | |||
); | |||
} | |||
Widget _createHeader() { | |||
/// 没绑定的UI | |||
Widget _createNoBindWidget(WechatTeacherStyleModel styleModel) { | |||
return Column( | |||
children: <Widget>[ | |||
Container( | |||
margin: EdgeInsets.only(top: 8, bottom: 2), | |||
child: CupertinoTextField( | |||
onSubmitted: (val) => _bindTeacher(), | |||
controller: _editingController, | |||
placeholder: styleModel?.nobindTeacherDialog?.inputHintText ?? '请填写邀请人邀请码/手机号码', | |||
placeholderStyle: TextStyle(fontSize: 14), | |||
decoration: BoxDecoration(), | |||
), | |||
), | |||
Container( | |||
height: 0.5, | |||
color: Color(0xffd5d5d5), | |||
), | |||
GestureDetector( | |||
onTap: () => _bindTeacher(), | |||
child: Center( | |||
child: Container( | |||
margin: EdgeInsets.only(top: 10), | |||
width: 130, | |||
height: 30, | |||
decoration: BoxDecoration( | |||
color: HexColor.fromHex(styleModel?.commStyle?.btnBgColor ?? '#FF5A5A'), | |||
borderRadius: BorderRadius.circular(15), | |||
), | |||
child: Center( | |||
child: Text( | |||
_isBinding ? '绑定中...' : styleModel?.nobindTeacherDialog?.btnText ?? '绑定邀请人', | |||
style: TextStyle(color: HexColor.fromHex(styleModel?.commStyle?.btnTextColor ?? '#FFFFFFF'), fontSize: 14), | |||
), | |||
), | |||
), | |||
), | |||
) | |||
], | |||
); | |||
} | |||
/// 绑定的UI | |||
Widget _createBindWidget(WechatTeacherStyleModel styleModel, WechatTeacherDataModel dataModel) { | |||
return Container( | |||
width: double.infinity, | |||
height: double.infinity, | |||
margin: const EdgeInsets.only(top: 10), | |||
child: Row( | |||
children: <Widget>[ | |||
Container( | |||
width: 50, | |||
height: 50, | |||
// color: Colors.red, | |||
child: CircleAvatar(child: CachedNetworkImage(imageUrl: dataModel?.teacherAvatar ??'',)), | |||
), | |||
const SizedBox(width: 13), | |||
Column( | |||
crossAxisAlignment: CrossAxisAlignment.start, | |||
mainAxisAlignment: MainAxisAlignment.spaceAround, | |||
children: <Widget>[ | |||
Text(dataModel?.teacherUsername ??'', style: TextStyle(fontSize: 15, color: HexColor.fromHex(styleModel?.teacherDialogTitleColor ?? '#3C3C3C'))), | |||
Text('微信号: ${dataModel?.teacherWechatAccount??''}', style: TextStyle(fontSize: 15, color: HexColor.fromHex(styleModel?.commStyle.wechatAccountColor ?? '#FF5050'))), | |||
GestureDetector( | |||
onTap: () => _copyText(dataModel?.teacherWechatAccount), | |||
child: UnconstrainedBox( | |||
child: Container( | |||
decoration: BoxDecoration( | |||
// color: Color(0xffffdada), | |||
color: HexColor.fromHex(styleModel?.bindTeacherDialog?.btnBgColor ?? '#FFDADA'), | |||
borderRadius: BorderRadius.circular(20), | |||
), | |||
padding: EdgeInsets.only(left: 9, right: 9, top: 4, bottom: 4), | |||
child: Text( | |||
styleModel?.bindTeacherDialog?.btnText ?? '复制去微信添加', | |||
style: TextStyle(fontSize: 13, color: HexColor.fromHex(styleModel?.bindTeacherDialog?.btnTextColor ?? '#FF0000')), | |||
), | |||
), | |||
), | |||
), | |||
], | |||
), | |||
Expanded( | |||
child: Align( | |||
alignment: Alignment.centerRight, | |||
child: GestureDetector( | |||
onLongPress: () => _longClickSaveImage(), | |||
child: Column( | |||
children: <Widget>[ | |||
Container( | |||
width: 56, | |||
height: 56, | |||
// color: Colors.red, | |||
child: CachedNetworkImage( | |||
imageUrl: dataModel?.teacherWxQrCode ?? styleModel?.myTeacher?.defalutTeacher?.qrcode ?? '', | |||
), | |||
), | |||
const SizedBox(height: 9), | |||
Text( | |||
styleModel?.officalWxchat?.qrcodeText ?? '长按保存二维码', | |||
style: TextStyle(fontSize: 13, color: HexColor.fromHex(styleModel?.officalWxchat?.qrcodeTextColor ?? '#999999')), | |||
), | |||
], | |||
), | |||
), | |||
), | |||
) | |||
], | |||
), | |||
); | |||
} | |||
Widget _createHeader(WechatTeacherStyleModel styleModel, WechatTeacherDataModel dataModel) { | |||
return Container( | |||
width: double.infinity, | |||
height: 283, | |||
child: Stack( | |||
children: <Widget>[ | |||
// 背景图 | |||
Container( | |||
width: double.infinity, | |||
height: 185, | |||
color: Colors.redAccent, | |||
// color: Colors.redAccent, | |||
child: CachedNetworkImage( | |||
imageUrl: styleModel?.bgImg ?? '', | |||
fit: BoxFit.contain, | |||
), | |||
), | |||
// 中间弹窗 | |||
Align( | |||
alignment: Alignment.bottomCenter, | |||
child: Container( | |||
@@ -81,7 +308,7 @@ class _WechatTeacherPageState extends State<WechatTeacherPage> { | |||
margin: EdgeInsets.only(left: 10, right: 10), | |||
padding: EdgeInsets.all(12), | |||
decoration: BoxDecoration( | |||
color: Colors.white, | |||
color: HexColor.fromHex(styleModel?.teacherDialogBgColor ?? '#FFFFFF'), | |||
borderRadius: BorderRadius.circular(10), | |||
), | |||
child: Column( | |||
@@ -89,39 +316,18 @@ class _WechatTeacherPageState extends State<WechatTeacherPage> { | |||
crossAxisAlignment: CrossAxisAlignment.start, | |||
children: <Widget>[ | |||
Text( | |||
'我的导师', | |||
styleModel?.teacherDialogTitle ?? '我的导师', | |||
style: TextStyle( | |||
fontWeight: FontWeight.bold, | |||
fontSize: 15, | |||
color: Color(0xff333333), | |||
), | |||
), | |||
Container( | |||
margin: EdgeInsets.only(top: 8, bottom: 2), | |||
child: CupertinoTextField( | |||
placeholder: '请填写邀请人邀请码/手机号码', | |||
placeholderStyle: TextStyle(fontSize: 14), | |||
decoration: BoxDecoration(), | |||
color: HexColor.fromHex(styleModel?.teacherDialogTitleColor ?? '#3C3C3C'), | |||
), | |||
), | |||
Container( | |||
height: 0.5, | |||
color: Color(0xffd5d5d5), | |||
), | |||
Center( | |||
child: Container( | |||
margin: EdgeInsets.only(top: 10), | |||
width: 130, | |||
height: 30, | |||
decoration: BoxDecoration( | |||
color: Colors.redAccent, | |||
borderRadius: BorderRadius.circular(15)), | |||
child: Center( | |||
child: Text( | |||
'绑定邀请人', | |||
style: TextStyle(color: Colors.white, fontSize: 14), | |||
), | |||
), | |||
Expanded( | |||
child: Visibility( | |||
visible: dataModel?.isBindTeacher == '1', | |||
replacement: _createNoBindWidget(styleModel), | |||
child: _createBindWidget(styleModel, dataModel), | |||
), | |||
) | |||
], | |||
@@ -133,13 +339,13 @@ class _WechatTeacherPageState extends State<WechatTeacherPage> { | |||
); | |||
} | |||
Widget _createWechat() { | |||
Widget _createWechat(WechatTeacherStyleModel styleModel) { | |||
return Container( | |||
width: double.infinity, | |||
margin: EdgeInsets.only(left: 10, right: 10, top: 15), | |||
margin: EdgeInsets.only(left: 10, right: 10, top: 0, bottom: 22), | |||
padding: EdgeInsets.all(12), | |||
decoration: BoxDecoration( | |||
color: Colors.white, | |||
color: HexColor.fromHex(styleModel?.officalWxchat?.bgColor ?? '#FFFFFF'), | |||
borderRadius: BorderRadius.circular(10), | |||
), | |||
child: Column( | |||
@@ -147,22 +353,34 @@ class _WechatTeacherPageState extends State<WechatTeacherPage> { | |||
crossAxisAlignment: CrossAxisAlignment.start, | |||
children: <Widget>[ | |||
Text( | |||
'官方微信', | |||
styleModel?.officalWxchat?.title ?? '官方微信', | |||
style: TextStyle( | |||
color: HexColor.fromHex(styleModel?.officalWxchat?.titleColor ?? '#3C3C3C'), | |||
fontSize: 15, | |||
fontWeight: FontWeight.bold, | |||
), | |||
), | |||
WechatTeachetItem(), | |||
Container( | |||
margin: EdgeInsets.only(top: 4, bottom: 4), | |||
width: double.infinity, | |||
height: 0.5, | |||
color: Color(0xffebebeb), | |||
), | |||
WechatTeachetItem(), | |||
_createOfficalWxchatListWidget(styleModel), | |||
], | |||
), | |||
); | |||
} | |||
Widget _createOfficalWxchatListWidget(WechatTeacherStyleModel styleModel) { | |||
List<Widget> widgets = []; | |||
int length = styleModel?.officalWxchat?.list?.length ?? 0; | |||
if (length > 0) { | |||
styleModel.officalWxchat.list.forEach((element) { | |||
widgets.add(WechatTeachetItem(element, styleModel)); | |||
widgets.add(Container(margin: EdgeInsets.only(top: 4, bottom: 4), width: double.infinity, height: 0.5, color: Color(0xffebebeb))); | |||
}); | |||
widgets.removeLast(); | |||
} else { | |||
widgets.add(Container()); | |||
} | |||
return Column( | |||
children: widgets, | |||
); | |||
} | |||
} |
@@ -1,6 +1,31 @@ | |||
import 'package:flutter/material.dart'; | |||
import 'package:flutter/services.dart'; | |||
import 'package:zhiying_base_widget/pages/wechat_teacher_page/model/wechat_teacher_style_model.dart'; | |||
import 'package:zhiying_comm/zhiying_comm.dart'; | |||
import 'package:fluttertoast/fluttertoast.dart'; | |||
class WechatTeachetItem extends StatelessWidget { | |||
OfficalWxchatList itemStyleModel; | |||
WechatTeacherStyleModel styleModel; | |||
WechatTeachetItem(this.itemStyleModel, this.styleModel); | |||
/// 拷贝 | |||
void _copyText(String text) { | |||
if(!EmptyUtil.isEmpty(text)) { | |||
Clipboard.setData(ClipboardData(text: text)); | |||
Fluttertoast.showToast(msg: '复制成功~'); | |||
}else{ | |||
Fluttertoast.showToast(msg: '内容不能为空~'); | |||
} | |||
} | |||
/// 长按保存图片 | |||
void _longClickSaveImage(){ | |||
Logger.log('长按保存图片'); | |||
} | |||
@override | |||
Widget build(BuildContext context) { | |||
return Container( | |||
@@ -11,54 +36,77 @@ class WechatTeachetItem extends StatelessWidget { | |||
child: Column( | |||
crossAxisAlignment: CrossAxisAlignment.start, | |||
children: <Widget>[ | |||
Text( | |||
'微信公众号 智莺生活公众号', | |||
style: TextStyle( | |||
fontSize: 14, | |||
color: Color(0xff3c3c3c), | |||
fontWeight: FontWeight.bold, | |||
), | |||
// Text( | |||
// itemStyleModel?.text ?? '微信公众号 智莺生活公众号', | |||
// style: TextStyle( | |||
// fontSize: 14, | |||
// color: Color(0xff3c3c3c), | |||
// fontWeight: FontWeight.bold, | |||
// ), | |||
// ), | |||
RichText( | |||
text: TextSpan(children: [ | |||
TextSpan( | |||
text: itemStyleModel?.text ?? '', | |||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: HexColor.fromHex(styleModel?.officalWxchat?.titleColor ?? '#FF3C3C3C'))), | |||
TextSpan( | |||
text: ' ${itemStyleModel?.subText ?? ''}', | |||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 11, color: HexColor.fromHex(styleModel?.officalWxchat?.titleColor ?? '#FF3C3C3C'))), | |||
]), | |||
), | |||
Padding( | |||
padding: const EdgeInsets.only(top: 8.0, bottom: 8), | |||
child: Text( | |||
'微信号:5645434', | |||
'微信号:${itemStyleModel?.wechatAccount ?? ''}', | |||
style: TextStyle( | |||
fontSize: 13, | |||
color: Color(0xffff5050), | |||
fontWeight: FontWeight.bold), | |||
fontSize: 13, | |||
// color: Color(0xffff5050), | |||
color: HexColor.fromHex(styleModel?.commStyle?.wechatAccountColor ?? '#FF5050'), | |||
fontWeight: FontWeight.bold, | |||
), | |||
), | |||
), | |||
UnconstrainedBox( | |||
child: Container( | |||
decoration: BoxDecoration( | |||
color: Color(0xffffdada), | |||
borderRadius: BorderRadius.circular(20), | |||
), | |||
padding: | |||
EdgeInsets.only(left: 9, right: 9, top: 4, bottom: 4), | |||
child: Text( | |||
'长按保存二维码', | |||
style: TextStyle(fontSize: 13, color: Color(0xffff0000)), | |||
GestureDetector( | |||
onTap: ()=> _copyText(itemStyleModel?.wechatAccount), | |||
child: UnconstrainedBox( | |||
child: Container( | |||
decoration: BoxDecoration( | |||
// color: Color(0xffffdada), | |||
color: HexColor.fromHex(styleModel?.bindTeacherDialog?.btnBgColor ?? '#FFDADA'), | |||
borderRadius: BorderRadius.circular(20), | |||
), | |||
padding: EdgeInsets.only(left: 9, right: 9, top: 4, bottom: 4), | |||
child: Text( | |||
styleModel?.bindTeacherDialog?.btnText ?? '复制去微信添加', | |||
style: TextStyle(fontSize: 13, color: HexColor.fromHex(styleModel?.bindTeacherDialog?.btnTextColor ?? '#FF0000')), | |||
), | |||
), | |||
), | |||
), | |||
], | |||
), | |||
), | |||
Column( | |||
children: <Widget>[ | |||
Container( | |||
margin: EdgeInsets.only(bottom: 4), | |||
width: 55, | |||
height: 55, | |||
color: Colors.redAccent, | |||
), | |||
Text( | |||
'长按保存二维码', | |||
style: TextStyle(fontSize: 12, color: Color(0xff999999)), | |||
), | |||
], | |||
GestureDetector( | |||
onLongPress: ()=> _longClickSaveImage(), | |||
child: Column( | |||
children: <Widget>[ | |||
Container( | |||
margin: EdgeInsets.only(bottom: 4), | |||
width: 55, | |||
height: 55, | |||
// color: Colors.redAccent, | |||
child: CachedNetworkImage( | |||
imageUrl: itemStyleModel?.qrcode ?? '', | |||
), | |||
), | |||
Text( | |||
styleModel?.officalWxchat?.qrcodeText ?? '长按保存二维码', | |||
style: TextStyle(fontSize: 13, color: HexColor.fromHex(styleModel?.officalWxchat?.qrcodeTextColor ?? '#999999')), | |||
), | |||
], | |||
), | |||
) | |||
], | |||
), | |||
@@ -79,6 +79,8 @@ import 'widgets/search/input/search_input_widget.dart'; | |||
import 'widgets/search/tabbar/search_tab_creater.dart'; | |||
import 'widgets/search_result/goods_list/search_result_goods_list_creater.dart'; | |||
import 'widgets/search_result/search_input/search_result_input.dart'; | |||
import 'package:secverify/secverify.dart'; | |||
import 'package:zhiying_comm/util/second_test/second_test_util.dart'; | |||
class BaseWidgetRegister { | |||
/// 初始化方法 | |||
@@ -126,6 +128,9 @@ class BaseWidgetRegister { | |||
SharesdkPlugin.regist(register); | |||
}); | |||
// MOB 秒验 | |||
SecondTestUtil.getInstance().init(); | |||
Application.addMethod(() async { | |||
return Future.delayed(Duration(seconds: 1)); | |||
}); | |||
@@ -152,7 +157,7 @@ class BaseWidgetRegister { | |||
PageFactory.regist('pub.flutter.feedback', (model) => FeedbackPage(model)); | |||
PageFactory.regist('pub.flutter.feedback_list', (model) => FeedbackRecordPage(model)); | |||
PageFactory.regist( | |||
'pub.flutter.wechat_teacher', (model) => WechatTeacherPage()); | |||
'pub.flutter.wechat_teacher', (model) => WechatTeacherPage(model)); | |||
PageFactory.regist('pub.flutter.cash_out', (model) => WithdrawPage(model)); | |||
// webview | |||
@@ -82,7 +82,7 @@ class MineDataWidget extends StatelessWidget { | |||
), | |||
), | |||
Text( | |||
'${profile.total}', | |||
'${profile?.total?? '0.00'}', | |||
style: TextStyle( | |||
fontSize: 18, | |||
fontWeight: FontWeight.w800, | |||
@@ -136,6 +136,8 @@ class MineDataWidget extends StatelessWidget { | |||
Widget _createCenter() { | |||
List<MineProfileDataModel> datas = profile.gridViews; | |||
int length = datas?.length ?? 0; | |||
if (length > 0) { | |||
int maxColumn = 2; | |||
int row = (datas.length / 2).ceil(); | |||
if (row % 3 == 0) { | |||
@@ -192,13 +194,15 @@ class MineDataWidget extends StatelessWidget { | |||
)); | |||
} | |||
} | |||
return Container( | |||
width: double.infinity, | |||
child: Column( | |||
children: columns, | |||
), | |||
); | |||
}else{ | |||
return Container(); | |||
} | |||
} | |||
Widget _createrCenterItem(String name, String value) { | |||
@@ -73,8 +73,14 @@ class _TeamFansItemState extends State<TeamFansItem> { | |||
onTap: () => _openFansItemDetailsPage(), | |||
child: Container( | |||
width: 50, | |||
child: CachedNetworkImage( | |||
imageUrl: widget?.dataModel?.avatar ?? '', | |||
height: 50, | |||
// decoration: BoxDecoration( | |||
// borderRadius: BorderRadius.circular(50/2) | |||
// ), | |||
child: CircleAvatar( | |||
backgroundImage: CachedNetworkImageProvider( | |||
widget?.dataModel?.avatar ?? '', | |||
), | |||
), | |||
)), | |||
const SizedBox(width: 10), | |||
@@ -255,10 +255,12 @@ class __TeamRecommendWidgetState extends State<_TeamRecommendWidgetContainer> { | |||
borderRadius: BorderRadius.circular(55/2), | |||
child: Container( | |||
width: 55, | |||
// height: 55, | |||
height: 55, | |||
// color: Colors.red, | |||
child: CachedNetworkImage( | |||
imageUrl: dataModel?.referrerAvatar ?? '', | |||
child: CircleAvatar( | |||
backgroundImage: CachedNetworkImageProvider( | |||
dataModel?.referrerAvatar ?? '', | |||
), | |||
), | |||
), | |||
); | |||
@@ -78,8 +78,11 @@ class TeamDetailsReferrerWidget extends StatelessWidget { | |||
Container( | |||
width: 50, | |||
height: 50, | |||
child: CachedNetworkImage( | |||
imageUrl: dataModel?.avatar ?? '', | |||
child: CircleAvatar( | |||
backgroundImage: CachedNetworkImageProvider(dataModel?.avatar ?? ''), | |||
// child: CachedNetworkImage( | |||
// imageUrl: dataModel?.avatar ?? '', | |||
// ), | |||
), | |||
), | |||
const SizedBox(width: 10), | |||
@@ -24,8 +24,6 @@ dependencies: | |||
git: | |||
url: 'http://192.168.0.138:3000/FnuoOS_Flutter_Components/Image_Cropper.git' | |||
ref: '1.2.3+1' | |||
# mob 分享sdk | |||
sharesdk_plugin: ^1.2.8 | |||
# 系统分享 | |||
share_extend: ^1.1.9 | |||
flutter_native_image: ^0.0.5 | |||
@@ -69,6 +67,7 @@ flutter: | |||
assets: | |||
- assets/images/launch_image/launch_image.png | |||
- assets/images/empty/empty.png | |||
- assets/images/qrcode/default_qrcode.png | |||
# | |||
# For details regarding assets in packages, see | |||
# https://flutter.dev/assets-and-images/#from-packages | |||