diff --git a/lib/constants/api.dart b/lib/constants/api.dart index 0d39e5ba..8ee04810 100644 --- a/lib/constants/api.dart +++ b/lib/constants/api.dart @@ -1,10 +1,20 @@ class API { - static const String host = 'http://192.168.2.201:8804/IntelligentCommunity'; + ///HOST + static const String host = 'http://192.168.2.201:8804'; + + ///接口基础地址 + static const String baseURL = '$host/IntelligentCommunity/app'; + + ///静态资源路径 static String get resource => '$host/static'; + + static String image(String path) => '$resource$path'; + static const int networkTimeOut = 10000; static _Login login = _Login(); static _User user = _User(); static _Manager manager = _Manager(); + static _Upload upload = _Upload(); } class _Login { @@ -48,6 +58,9 @@ class _User { ///修改用户手机号 String get updateTel => '/user/personalData/updateTel'; + + ///修改头像 + String get udpdateAvatar => '/user/personalData/updateHeadPortrait'; } class _Manager { @@ -72,3 +85,11 @@ class _Manager { ///报事报修:批量删除报事报修信息(业主端) String get reportRepairDelete => '/user/reportRepair/falseDelete'; } + +class _Upload { + ///上传咨询建议照片 + String get uploadArticle => '/user/upload/uploadArticle'; + + ///上传头像 + String get uploadAvatar => '/user/upload/appHeadSculpture'; +} diff --git a/lib/main.dart b/lib/main.dart index 17cb9941..501f7bcf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,7 +2,6 @@ import 'package:akuCommunity/pages/splash/splash_page.dart'; import 'package:akuCommunity/provider/sign_up_provider.dart'; import 'package:akuCommunity/provider/user_provider.dart'; import 'package:akuCommunity/utils/developer_util.dart'; -import 'package:akuCommunity/utils/hive_store.dart'; import 'package:bot_toast/bot_toast.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; diff --git a/lib/model/user/user_info_model.dart b/lib/model/user/user_info_model.dart index 58c0131a..869a9a5e 100644 --- a/lib/model/user/user_info_model.dart +++ b/lib/model/user/user_info_model.dart @@ -2,7 +2,7 @@ import 'package:common_utils/common_utils.dart'; class UserInfoModel { int id; - List imgUrls; + String imgUrl; String name; String nickName; String tel; @@ -28,7 +28,7 @@ class UserInfoModel { UserInfoModel( {this.id, - this.imgUrls, + this.imgUrl, this.name, this.nickName, this.tel, @@ -37,23 +37,12 @@ class UserInfoModel { UserInfoModel.fromJson(Map json) { id = json['id']; - imgUrls = json['imgUrls'].cast(); + if (json['imgUrls'] != null) + imgUrl = (json['imgUrls'] as List).first['url']; name = json['name']; nickName = json['nickName']; tel = json['tel']; sex = json['sex']; birthday = json['birthday']; } - - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['imgUrls'] = this.imgUrls; - data['name'] = this.name; - data['nickName'] = this.nickName; - data['tel'] = this.tel; - data['sex'] = this.sex; - data['birthday'] = this.birthday; - return data; - } } diff --git a/lib/pages/personal/personal_page.dart b/lib/pages/personal/personal_page.dart index 2974b991..064bdc9b 100644 --- a/lib/pages/personal/personal_page.dart +++ b/lib/pages/personal/personal_page.dart @@ -1,4 +1,5 @@ import 'package:akuCommunity/const/resource.dart'; +import 'package:akuCommunity/constants/api.dart'; import 'package:akuCommunity/pages/activities_page/activities_page.dart'; import 'package:akuCommunity/pages/address_page/address_page.dart'; import 'package:akuCommunity/pages/life_pay/life_pay_page.dart'; @@ -118,14 +119,16 @@ class _PersonalIndexState extends State margin: EdgeInsets.only(left: 32.w), child: Row( children: [ - Container( + Hero( + tag: 'AVATAR', child: ClipOval( - child: CachedImageWrapper( - url: - 'https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1851283359,3457678391&fm=26&gp=0.jpg', - width: 106.w, + child: FadeInImage.assetNetwork( + //TODO PLACEHOLDER + placeholder: R.ASSETS_ICONS_PROPOSAL_PNG, + image: API + .image(userProvider.userInfoModel.imgUrl), height: 106.w, - isSigned: userProvider.isSigned, + width: 106.w, ), ), ), diff --git a/lib/pages/personal/user_profile_page.dart b/lib/pages/personal/user_profile_page.dart index c168f3e0..1e2d79fa 100644 --- a/lib/pages/personal/user_profile_page.dart +++ b/lib/pages/personal/user_profile_page.dart @@ -1,11 +1,16 @@ import 'dart:io'; import 'package:akuCommunity/base/base_style.dart'; +import 'package:akuCommunity/const/resource.dart'; +import 'package:akuCommunity/constants/api.dart'; import 'package:akuCommunity/pages/personal/change_nick_name_page.dart'; import 'package:akuCommunity/pages/personal/update_tel_page.dart'; import 'package:akuCommunity/provider/user_provider.dart'; +import 'package:akuCommunity/utils/network/base_file_model.dart'; +import 'package:akuCommunity/utils/network/net_util.dart'; import 'package:akuCommunity/widget/bee_scaffold.dart'; import 'package:akuCommunity/utils/headers.dart'; +import 'package:bot_toast/bot_toast.dart'; import 'package:common_utils/common_utils.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -56,6 +61,7 @@ class _UserProfilePageState extends State { } _pickAvatar() async { + final userProvider = Provider.of(context, listen: false); PickedFile file = await Get.bottomSheet(CupertinoActionSheet( title: '选择头像'.text.isIntrinsic.make(), actions: [ @@ -77,8 +83,20 @@ class _UserProfilePageState extends State { child: '取消'.text.isIntrinsic.make(), ), )); - if (file == null) return; - //TODO upload avatar. + if (file == null) + return; + else { + //Upload Avatar + Function cancel = BotToast.showLoading(); + File rawFile = File(file.path); + BaseFileModel model = + await NetUtil().upload(API.upload.uploadAvatar, rawFile); + if (model.status) + userProvider.updateAvatar(model.url); + else + BotToast.showText(text: model.message); + cancel(); + } } @override @@ -88,7 +106,21 @@ class _UserProfilePageState extends State { title: '个人资料', body: ListView( children: [ - _buildTile('头像', CircleAvatar(), onPressed: _pickAvatar), + _buildTile( + '头像', + Hero( + tag: 'AVATAR', + child: ClipOval( + child: FadeInImage.assetNetwork( + placeholder: R.ASSETS_ICONS_PROPOSAL_PNG, + image: API.image(userProvider.userInfoModel.imgUrl), + height: 56.w, + width: 56.w, + ), + ), + ), + onPressed: _pickAvatar, + ), _buildTile( '姓名', userProvider.userInfoModel.name.text.make(), diff --git a/lib/pages/sign/sign_func.dart b/lib/pages/sign/sign_func.dart index 5f246ecc..147daef9 100644 --- a/lib/pages/sign/sign_func.dart +++ b/lib/pages/sign/sign_func.dart @@ -82,6 +82,7 @@ class SignFunc { BaseModel baseModel = await NetUtil().get( API.user.userDetail, ); + if (baseModel.data == null) return null; return UserDetailModel.fromJson(baseModel.data); } } diff --git a/lib/provider/user_provider.dart b/lib/provider/user_provider.dart index 6b34c8f7..60e6eec5 100644 --- a/lib/provider/user_provider.dart +++ b/lib/provider/user_provider.dart @@ -77,11 +77,14 @@ class UserProvider extends ChangeNotifier { Future setBirthday(DateTime date) async { BaseModel baseModel = await NetUtil().post( API.user.setBirthday, - params: {'birthday': DateUtil.formatDate(date,format: "yyyy-MM-dd HH:mm:ss")}, + params: { + 'birthday': DateUtil.formatDate(date, format: "yyyy-MM-dd HH:mm:ss") + }, showMessage: true, ); if (baseModel.status) { - _userInfoModel.birthday = DateUtil.formatDate(date,format: "yyyy-MM-dd HH:mm:ss"); + _userInfoModel.birthday = + DateUtil.formatDate(date, format: "yyyy-MM-dd HH:mm:ss"); notifyListeners(); } } @@ -111,4 +114,18 @@ class UserProvider extends ChangeNotifier { notifyListeners(); } } + + ///修改头像 + Future updateAvatar(String path) async { + BaseModel model = await NetUtil().post( + API.user.udpdateAvatar, + params: { + 'fileUrls': [path] + }, + showMessage: true, + ); + if (model.status) { + await updateProfile(); + } + } } diff --git a/lib/utils/network/base_file_model.dart b/lib/utils/network/base_file_model.dart new file mode 100644 index 00000000..a42550b3 --- /dev/null +++ b/lib/utils/network/base_file_model.dart @@ -0,0 +1,19 @@ +class BaseFileModel { + String message; + String url; + bool status; + BaseFileModel({ + this.message, + this.url, + this.status, + }); + + BaseFileModel.err( + {this.message = '未知错误', this.url = '', this.status = false}); + + BaseFileModel.fromJson(Map json) { + message = json['message'] ?? ''; + url = json['url'] ?? null; + status = json['status'] ?? false; + } +} diff --git a/lib/utils/network/net_util.dart b/lib/utils/network/net_util.dart index 5b4f3de1..d7e95334 100644 --- a/lib/utils/network/net_util.dart +++ b/lib/utils/network/net_util.dart @@ -1,12 +1,15 @@ +import 'dart:io'; + import 'package:akuCommunity/pages/sign/sign_in_page.dart'; import 'package:akuCommunity/provider/user_provider.dart'; +import 'package:akuCommunity/utils/network/base_file_model.dart'; import 'package:akuCommunity/utils/network/base_list_model.dart'; import 'package:akuCommunity/utils/network/base_model.dart'; import 'package:bot_toast/bot_toast.dart'; import 'package:dio/dio.dart'; import 'package:akuCommunity/constants/api.dart'; -import 'package:get/get.dart' hide Response; +import 'package:get/get.dart' hide Response, FormData, MultipartFile; import 'package:logger/logger.dart'; import 'package:power_logger/power_logger.dart'; import 'package:provider/provider.dart'; @@ -27,7 +30,7 @@ class NetUtil { errorMethodCount: 4, )); BaseOptions options = BaseOptions( - baseUrl: '${API.host}/app', + baseUrl: API.baseURL, connectTimeout: API.networkTimeOut, receiveTimeout: API.networkTimeOut, sendTimeout: API.networkTimeOut, @@ -118,6 +121,27 @@ class NetUtil { return BaseListModel.err(); } + Future upload(String path, File file) async { + try { + Response res = await _dio.post(path, + data: FormData.fromMap({ + 'file': await MultipartFile.fromFile(file.path), + })); + _logger.v({ + 'path': res.request.path, + 'header': res.request.headers, + 'params': res.request.queryParameters, + 'data': res.data, + }); + LoggerData.addData(res); + BaseFileModel baseListModel = BaseFileModel.fromJson(res.data); + return baseListModel; + } on DioError catch (e) { + _parseErr(e); + } + return BaseFileModel.err(); + } + _parseErr(DioError err) { _logger.v({ 'type': err.type.toString(), @@ -148,8 +172,8 @@ class NetUtil { _parseRequestError(BaseModel model, {bool showMessage = false}) { final userProvider = Provider.of(Get.context, listen: false); if (!model.status && model.message == '登录失效,请登录') { - Get.offAll(SignInPage()); userProvider.logout(); + Get.offAll(SignInPage()); } if (!model.status || showMessage) { BotToast.showText(text: model.message); diff --git a/pubspec.lock b/pubspec.lock index 853a899a..05d4110e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -43,13 +43,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "0.39.17" - animations: - dependency: transitive - description: - name: animations - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.1.2" animator: dependency: transitive description: @@ -803,7 +796,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: c972545147e812d192795a56b33357aefd60d479 + resolved-ref: "38c7b0431c56f2357b6ef1298009b9b4ff0586c0" url: "http://192.168.2.201:8099/aku_fe/power_logger.git" source: git version: "0.0.1"