Selaa lähdekoodia

1、微信号的绑定

2、微信导师的实现
3、我的人脉头像变圆
tags/0.0.2+8
PH2 4 vuotta sitten
vanhempi
commit
2ec413a335
23 muutettua tiedostoa jossa 1378 lisäystä ja 102 poistoa
  1. BIN
     
  2. +7
    -0
      lib/pages/mine_detail_page/mine_detail_page.dart
  3. +6
    -1
      lib/pages/mine_detail_page/models/mine_detail_model.dart
  4. +52
    -0
      lib/pages/upload_wechat_page/bloc/upload_wechat_bloc.dart
  5. +17
    -0
      lib/pages/upload_wechat_page/bloc/upload_wechat_event.dart
  6. +65
    -0
      lib/pages/upload_wechat_page/bloc/upload_wechat_repository.dart
  7. +24
    -0
      lib/pages/upload_wechat_page/bloc/upload_wechat_state.dart
  8. +18
    -0
      lib/pages/upload_wechat_page/model/upload_wechat_model.dart
  9. +288
    -0
      lib/pages/upload_wechat_page/upload_wechat_page.dart
  10. +62
    -0
      lib/pages/wechat_teacher_page/bloc/wechat_teacher_bloc.dart
  11. +14
    -0
      lib/pages/wechat_teacher_page/bloc/wechat_teacher_event.dart
  12. +89
    -0
      lib/pages/wechat_teacher_page/bloc/wechat_teacher_repository.dart
  13. +25
    -0
      lib/pages/wechat_teacher_page/bloc/wechat_teacher_state.dart
  14. +32
    -0
      lib/pages/wechat_teacher_page/model/wechat_teacher_data_model.dart
  15. +293
    -0
      lib/pages/wechat_teacher_page/model/wechat_teacher_style_model.dart
  16. +272
    -54
      lib/pages/wechat_teacher_page/wechat_teacher_page.dart
  17. +83
    -35
      lib/pages/wechat_teacher_page/widgets/wechat_teacher_item.dart
  18. +6
    -1
      lib/register.dart
  19. +6
    -2
      lib/widgets/mine/mine_data/mine_data_widget.dart
  20. +8
    -2
      lib/widgets/team/fans_list/team_fans_item.dart
  21. +5
    -3
      lib/widgets/team/recommend/team_recommend_widget.dart
  22. +5
    -2
      lib/widgets/team_details/referrer/team_details_referrer_widget.dart
  23. +1
    -2
      pubspec.yaml

+ 7
- 0
lib/pages/mine_detail_page/mine_detail_page.dart Näytä tiedosto

@@ -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
- 1
lib/pages/mine_detail_page/models/mine_detail_model.dart Näytä tiedosto

@@ -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;
}
}


+ 52
- 0
lib/pages/upload_wechat_page/bloc/upload_wechat_bloc.dart Näytä tiedosto

@@ -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();
}
}
}

+ 17
- 0
lib/pages/upload_wechat_page/bloc/upload_wechat_event.dart Näytä tiedosto

@@ -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});
}

+ 65
- 0
lib/pages/upload_wechat_page/bloc/upload_wechat_repository.dart Näytä tiedosto

@@ -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;
}
}

+ 24
- 0
lib/pages/upload_wechat_page/bloc/upload_wechat_state.dart Näytä tiedosto

@@ -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 {}

+ 18
- 0
lib/pages/upload_wechat_page/model/upload_wechat_model.dart Näytä tiedosto

@@ -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;
}
}

+ 288
- 0
lib/pages/upload_wechat_page/upload_wechat_page.dart Näytä tiedosto

@@ -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,
);
}
}

+ 62
- 0
lib/pages/wechat_teacher_page/bloc/wechat_teacher_bloc.dart Näytä tiedosto

@@ -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);
}
}
}

+ 14
- 0
lib/pages/wechat_teacher_page/bloc/wechat_teacher_event.dart Näytä tiedosto

@@ -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});
}

+ 89
- 0
lib/pages/wechat_teacher_page/bloc/wechat_teacher_repository.dart Näytä tiedosto

@@ -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;
}
}

+ 25
- 0
lib/pages/wechat_teacher_page/bloc/wechat_teacher_state.dart Näytä tiedosto

@@ -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 {}

+ 32
- 0
lib/pages/wechat_teacher_page/model/wechat_teacher_data_model.dart Näytä tiedosto

@@ -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;
}
}

+ 293
- 0
lib/pages/wechat_teacher_page/model/wechat_teacher_style_model.dart Näytä tiedosto

@@ -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;
}
}

+ 272
- 54
lib/pages/wechat_teacher_page/wechat_teacher_page.dart Näytä tiedosto

@@ -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,
);
}
}

+ 83
- 35
lib/pages/wechat_teacher_page/widgets/wechat_teacher_item.dart Näytä tiedosto

@@ -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')),
),
],
),
)
],
),


+ 6
- 1
lib/register.dart Näytä tiedosto

@@ -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


+ 6
- 2
lib/widgets/mine/mine_data/mine_data_widget.dart Näytä tiedosto

@@ -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) {


+ 8
- 2
lib/widgets/team/fans_list/team_fans_item.dart Näytä tiedosto

@@ -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),


+ 5
- 3
lib/widgets/team/recommend/team_recommend_widget.dart Näytä tiedosto

@@ -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 ?? '',
),
),
),
);


+ 5
- 2
lib/widgets/team_details/referrer/team_details_referrer_widget.dart Näytä tiedosto

@@ -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),


+ 1
- 2
pubspec.yaml Näytä tiedosto

@@ -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


Ladataan…
Peruuta
Tallenna