reason

修改用户信息页面

1 +import 'dart:convert';
2 +import 'package:Parlando/generated/json/base/json_field.dart';
3 +import 'package:Parlando/generated/json/upload_avatar_entity.g.dart';
4 +
5 +@JsonSerializable()
6 +class UploadAvatarEntity {
7 + String? status;
8 + int? code;
9 + String? message;
10 + UploadAvatarData? data;
11 + UploadAvatarError? error;
12 +
13 + UploadAvatarEntity();
14 +
15 + factory UploadAvatarEntity.fromJson(Map<String, dynamic> json) =>
16 + $UploadAvatarEntityFromJson(json);
17 +
18 + Map<String, dynamic> toJson() => $UploadAvatarEntityToJson(this);
19 +
20 + @override
21 + String toString() {
22 + return jsonEncode(this);
23 + }
24 +}
25 +
26 +@JsonSerializable()
27 +class UploadAvatarData {
28 + String? avatar;
29 +
30 + UploadAvatarData();
31 +
32 + factory UploadAvatarData.fromJson(Map<String, dynamic> json) =>
33 + $UploadAvatarDataFromJson(json);
34 +
35 + Map<String, dynamic> toJson() => $UploadAvatarDataToJson(this);
36 +
37 + @override
38 + String toString() {
39 + return jsonEncode(this);
40 + }
41 +}
42 +
43 +@JsonSerializable()
44 +class UploadAvatarError {
45 + UploadAvatarError();
46 +
47 + factory UploadAvatarError.fromJson(Map<String, dynamic> json) =>
48 + $UploadAvatarErrorFromJson(json);
49 +
50 + Map<String, dynamic> toJson() => $UploadAvatarErrorToJson(this);
51 +
52 + @override
53 + String toString() {
54 + return jsonEncode(this);
55 + }
56 +}
1 +import 'package:Parlando/account/models/upload_avatar_entity.dart';
2 +import 'package:Parlando/models/upload_entity.dart';
3 +import 'package:Parlando/net/dio_utils.dart';
4 +import 'package:Parlando/net/http_api.dart';
5 +import 'package:Parlando/util/toast_utils.dart';
6 +import 'package:cached_network_image/cached_network_image.dart';
7 +import 'package:dio/dio.dart';
8 +import 'package:flutter/cupertino.dart';
1 import 'package:flutter/material.dart'; 9 import 'package:flutter/material.dart';
2 import 'package:Parlando/extension/int_extension.dart'; 10 import 'package:Parlando/extension/int_extension.dart';
3 import 'package:Parlando/widgets/my_app_bar.dart'; 11 import 'package:Parlando/widgets/my_app_bar.dart';
...@@ -15,7 +23,10 @@ class AccountEditPage extends StatefulWidget { ...@@ -15,7 +23,10 @@ class AccountEditPage extends StatefulWidget {
15 class MapScreenState extends State<AccountEditPage> 23 class MapScreenState extends State<AccountEditPage>
16 with SingleTickerProviderStateMixin { 24 with SingleTickerProviderStateMixin {
17 bool _status = true; 25 bool _status = true;
26 + bool isUpdateAvatar = false;
18 final FocusNode myFocusNode = FocusNode(); 27 final FocusNode myFocusNode = FocusNode();
28 + String _imageFile =
29 + 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif';
19 30
20 @override 31 @override
21 void initState() { 32 void initState() {
...@@ -52,9 +63,13 @@ class MapScreenState extends State<AccountEditPage> ...@@ -52,9 +63,13 @@ class MapScreenState extends State<AccountEditPage>
52 width: 140.px, 63 width: 140.px,
53 margin: EdgeInsets.only(bottom: 12.px), 64 margin: EdgeInsets.only(bottom: 12.px),
54 child: ClipOval( 65 child: ClipOval(
55 - child: Image.network( 66 + child: CachedNetworkImage(
56 - "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif",
57 fit: BoxFit.cover, 67 fit: BoxFit.cover,
68 + placeholder: (context, url) =>
69 + const CircularProgressIndicator(),
70 + errorWidget: (context, url, error) =>
71 + const Icon(Icons.error),
72 + imageUrl: _imageFile,
58 ), 73 ),
59 ), 74 ),
60 ), 75 ),
...@@ -99,10 +114,8 @@ class MapScreenState extends State<AccountEditPage> ...@@ -99,10 +114,8 @@ class MapScreenState extends State<AccountEditPage>
99 ImageSource.camera, 114 ImageSource.camera,
100 context: context, 115 context: context,
101 capturedImageFile: (s) { 116 capturedImageFile: (s) {
102 - setState(() { 117 + _imageFile = s;
103 - print(s); 118 + updateAvatar(s);
104 - // _imageFile = s;
105 - });
106 }, 119 },
107 ); 120 );
108 }, 121 },
...@@ -122,11 +135,8 @@ class MapScreenState extends State<AccountEditPage> ...@@ -122,11 +135,8 @@ class MapScreenState extends State<AccountEditPage>
122 ImageSource.gallery, 135 ImageSource.gallery,
123 context: context, 136 context: context,
124 capturedImageFile: (s) { 137 capturedImageFile: (s) {
125 - print( 138 + _imageFile = s;
126 - "file path ${s}"); 139 + updateAvatar(s);
127 - setState(() {
128 - // _imageFile = s;
129 - });
130 }, 140 },
131 ); 141 );
132 }, 142 },
...@@ -138,6 +148,13 @@ class MapScreenState extends State<AccountEditPage> ...@@ -138,6 +148,13 @@ class MapScreenState extends State<AccountEditPage>
138 ) 148 )
139 ], 149 ],
140 )), 150 )),
151 + isUpdateAvatar
152 + ? const Center(
153 + child: CupertinoActivityIndicator(
154 + radius: 16.0,
155 + ),
156 + )
157 + : Container(),
141 ]), 158 ]),
142 ) 159 )
143 ], 160 ],
...@@ -158,8 +175,7 @@ class MapScreenState extends State<AccountEditPage> ...@@ -158,8 +175,7 @@ class MapScreenState extends State<AccountEditPage>
158 top: 5.px, 175 top: 5.px,
159 ), 176 ),
160 child: Row( 177 child: Row(
161 - mainAxisAlignment: 178 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
162 - MainAxisAlignment.spaceBetween,
163 mainAxisSize: MainAxisSize.max, 179 mainAxisSize: MainAxisSize.max,
164 children: <Widget>[ 180 children: <Widget>[
165 Column( 181 Column(
...@@ -397,7 +413,8 @@ class MapScreenState extends State<AccountEditPage> ...@@ -397,7 +413,8 @@ class MapScreenState extends State<AccountEditPage>
397 ), 413 ),
398 ], 414 ],
399 ), 415 ),
400 - )); 416 + ),
417 + );
401 } 418 }
402 419
403 @override 420 @override
...@@ -473,6 +490,48 @@ class MapScreenState extends State<AccountEditPage> ...@@ -473,6 +490,48 @@ class MapScreenState extends State<AccountEditPage>
473 }, 490 },
474 ); 491 );
475 } 492 }
493 +
494 + Future<void> updateAvatar(String path) async {
495 + isUpdateAvatar = true;
496 + dynamic avatar = await MultipartFile.fromFile(path, filename: "avatar.png");
497 + Map<String, dynamic> map = <String, dynamic>{
498 + "image": avatar,
499 + };
500 + FormData formData = FormData.fromMap(map);
501 + DioUtils.instance.asyncRequestNetwork<UploadEntity>(
502 + Method.post,
503 + HttpApi.uploadImage,
504 + params: formData,
505 + onSuccess: (data) {
506 + String path = data!.data!.relativePath!;
507 +
508 + Map<String, String> params = <String, String>{
509 + "avatar": path,
510 + };
511 + DioUtils.instance.asyncRequestNetwork<UploadAvatarEntity>(
512 + Method.post,
513 + HttpApi.avatar,
514 + params: params,
515 + onSuccess: (data) {
516 + isUpdateAvatar = false;
517 + setState(() {
518 + _imageFile = data!.data!.avatar!;
519 + });
520 + Toast.show("头像更新成功");
521 + },
522 + onError: (code, msg) {
523 + Toast.show(msg.toString());
524 + isUpdateAvatar = false;
525 + setState(() {});
526 + },
527 + );
528 + },
529 + onError: (code, msg) {
530 + isUpdateAvatar = false;
531 + setState(() {});
532 + },
533 + );
534 + }
476 } 535 }
477 536
478 typedef CapturedImageFile = String Function(String); 537 typedef CapturedImageFile = String Function(String);
......
...@@ -3,6 +3,7 @@ import 'package:Parlando/account/view_models/account_view_model.dart'; ...@@ -3,6 +3,7 @@ import 'package:Parlando/account/view_models/account_view_model.dart';
3 import 'package:Parlando/apis/api_response.dart'; 3 import 'package:Parlando/apis/api_response.dart';
4 import 'package:Parlando/login/login_router.dart'; 4 import 'package:Parlando/login/login_router.dart';
5 import 'package:Parlando/res/constant.dart'; 5 import 'package:Parlando/res/constant.dart';
6 +import 'package:cached_network_image/cached_network_image.dart';
6 import 'package:flustars/flustars.dart'; 7 import 'package:flustars/flustars.dart';
7 import 'package:flutter/material.dart'; 8 import 'package:flutter/material.dart';
8 import 'package:Parlando/membership/membership_router.dart'; 9 import 'package:Parlando/membership/membership_router.dart';
...@@ -98,9 +99,12 @@ class _AccountPageState extends State<AccountPage> { ...@@ -98,9 +99,12 @@ class _AccountPageState extends State<AccountPage> {
98 ), 99 ),
99 ), 100 ),
100 child: ClipOval( 101 child: ClipOval(
101 - child: Image.network( 102 + child: CachedNetworkImage(
102 - "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif",
103 fit: BoxFit.cover, 103 fit: BoxFit.cover,
104 + placeholder: (context, url) =>
105 + const CircularProgressIndicator(),
106 + errorWidget: (context, url, error) => const Icon(Icons.error),
107 + imageUrl: _user.avatar!,
104 ), 108 ),
105 ), 109 ),
106 ), 110 ),
......
...@@ -17,7 +17,7 @@ class AccountViewProvider with ChangeNotifier { ...@@ -17,7 +17,7 @@ class AccountViewProvider with ChangeNotifier {
17 } 17 }
18 18
19 Future<void> fetchAccountData(String value) async { 19 Future<void> fetchAccountData(String value) async {
20 - _apiResponse = ApiResponse.loading('Fetching artist data'); 20 + _apiResponse = ApiResponse.loading('请求数据中...');
21 DioUtils.instance.asyncRequestNetwork<UserEntity>( 21 DioUtils.instance.asyncRequestNetwork<UserEntity>(
22 Method.get, 22 Method.get,
23 HttpApi.user, 23 HttpApi.user,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
4 4
5 // This file is automatically generated. DO NOT EDIT, all your changes would be lost. 5 // This file is automatically generated. DO NOT EDIT, all your changes would be lost.
6 import 'package:flutter/material.dart'; 6 import 'package:flutter/material.dart';
7 +import 'package:Parlando/account/models/upload_avatar_entity.dart';
7 import 'package:Parlando/account/models/user_entity.dart'; 8 import 'package:Parlando/account/models/user_entity.dart';
8 import 'package:Parlando/category/models/category_item_entity.dart'; 9 import 'package:Parlando/category/models/category_item_entity.dart';
9 import 'package:Parlando/home/models/setting_entity.dart'; 10 import 'package:Parlando/home/models/setting_entity.dart';
...@@ -18,6 +19,9 @@ typedef JsonConvertFunction<T> = T Function(Map<String, dynamic> json); ...@@ -18,6 +19,9 @@ typedef JsonConvertFunction<T> = T Function(Map<String, dynamic> json);
18 19
19 class JsonConvert { 20 class JsonConvert {
20 static final Map<String, JsonConvertFunction> _convertFuncMap = { 21 static final Map<String, JsonConvertFunction> _convertFuncMap = {
22 + (UploadAvatarEntity).toString(): UploadAvatarEntity.fromJson,
23 + (UploadAvatarData).toString(): UploadAvatarData.fromJson,
24 + (UploadAvatarError).toString(): UploadAvatarError.fromJson,
21 (UserEntity).toString(): UserEntity.fromJson, 25 (UserEntity).toString(): UserEntity.fromJson,
22 (UserData).toString(): UserData.fromJson, 26 (UserData).toString(): UserData.fromJson,
23 (UserError).toString(): UserError.fromJson, 27 (UserError).toString(): UserError.fromJson,
...@@ -114,16 +118,40 @@ class JsonConvert { ...@@ -114,16 +118,40 @@ class JsonConvert {
114 118
115 //list is returned by type 119 //list is returned by type
116 static M? _getListChildType<M>(List<Map<String, dynamic>> data) { 120 static M? _getListChildType<M>(List<Map<String, dynamic>> data) {
117 - if(<UserEntity>[] is M){ 121 + if (<UploadAvatarEntity>[] is M) {
118 - return data.map<UserEntity>((Map<String, dynamic> e) => UserEntity.fromJson(e)).toList() as M; 122 + return data
119 - } 123 + .map<UploadAvatarEntity>(
120 - if(<UserData>[] is M){ 124 + (Map<String, dynamic> e) => UploadAvatarEntity.fromJson(e))
121 - return data.map<UserData>((Map<String, dynamic> e) => UserData.fromJson(e)).toList() as M; 125 + .toList() as M;
122 - } 126 + }
123 - if(<UserError>[] is M){ 127 + if (<UploadAvatarData>[] is M) {
124 - return data.map<UserError>((Map<String, dynamic> e) => UserError.fromJson(e)).toList() as M; 128 + return data
125 - } 129 + .map<UploadAvatarData>(
126 - if(<CategoryItemEntity>[] is M){ 130 + (Map<String, dynamic> e) => UploadAvatarData.fromJson(e))
131 + .toList() as M;
132 + }
133 + if (<UploadAvatarError>[] is M) {
134 + return data
135 + .map<UploadAvatarError>(
136 + (Map<String, dynamic> e) => UploadAvatarError.fromJson(e))
137 + .toList() as M;
138 + }
139 + if (<UserEntity>[] is M) {
140 + return data
141 + .map<UserEntity>((Map<String, dynamic> e) => UserEntity.fromJson(e))
142 + .toList() as M;
143 + }
144 + if (<UserData>[] is M) {
145 + return data
146 + .map<UserData>((Map<String, dynamic> e) => UserData.fromJson(e))
147 + .toList() as M;
148 + }
149 + if (<UserError>[] is M) {
150 + return data
151 + .map<UserError>((Map<String, dynamic> e) => UserError.fromJson(e))
152 + .toList() as M;
153 + }
154 + if (<CategoryItemEntity>[] is M) {
127 return data.map<CategoryItemEntity>((Map<String, dynamic> e) => CategoryItemEntity.fromJson(e)).toList() as M; 155 return data.map<CategoryItemEntity>((Map<String, dynamic> e) => CategoryItemEntity.fromJson(e)).toList() as M;
128 } 156 }
129 if(<SettingEntity>[] is M){ 157 if(<SettingEntity>[] is M){
......
1 +import 'package:Parlando/generated/json/base/json_convert_content.dart';
2 +import 'package:Parlando/account/models/upload_avatar_entity.dart';
3 +
4 +UploadAvatarEntity $UploadAvatarEntityFromJson(Map<String, dynamic> json) {
5 + final UploadAvatarEntity uploadAvatarEntity = UploadAvatarEntity();
6 + final String? status = jsonConvert.convert<String>(json['status']);
7 + if (status != null) {
8 + uploadAvatarEntity.status = status;
9 + }
10 + final int? code = jsonConvert.convert<int>(json['code']);
11 + if (code != null) {
12 + uploadAvatarEntity.code = code;
13 + }
14 + final String? message = jsonConvert.convert<String>(json['message']);
15 + if (message != null) {
16 + uploadAvatarEntity.message = message;
17 + }
18 + final UploadAvatarData? data =
19 + jsonConvert.convert<UploadAvatarData>(json['data']);
20 + if (data != null) {
21 + uploadAvatarEntity.data = data;
22 + }
23 + final UploadAvatarError? error =
24 + jsonConvert.convert<UploadAvatarError>(json['error']);
25 + if (error != null) {
26 + uploadAvatarEntity.error = error;
27 + }
28 + return uploadAvatarEntity;
29 +}
30 +
31 +Map<String, dynamic> $UploadAvatarEntityToJson(UploadAvatarEntity entity) {
32 + final Map<String, dynamic> data = <String, dynamic>{};
33 + data['status'] = entity.status;
34 + data['code'] = entity.code;
35 + data['message'] = entity.message;
36 + data['data'] = entity.data?.toJson();
37 + data['error'] = entity.error?.toJson();
38 + return data;
39 +}
40 +
41 +UploadAvatarData $UploadAvatarDataFromJson(Map<String, dynamic> json) {
42 + final UploadAvatarData uploadAvatarData = UploadAvatarData();
43 + final String? avatar = jsonConvert.convert<String>(json['avatar']);
44 + if (avatar != null) {
45 + uploadAvatarData.avatar = avatar;
46 + }
47 + return uploadAvatarData;
48 +}
49 +
50 +Map<String, dynamic> $UploadAvatarDataToJson(UploadAvatarData entity) {
51 + final Map<String, dynamic> data = <String, dynamic>{};
52 + data['avatar'] = entity.avatar;
53 + return data;
54 +}
55 +
56 +UploadAvatarError $UploadAvatarErrorFromJson(Map<String, dynamic> json) {
57 + final UploadAvatarError uploadAvatarError = UploadAvatarError();
58 + return uploadAvatarError;
59 +}
60 +
61 +Map<String, dynamic> $UploadAvatarErrorToJson(UploadAvatarError entity) {
62 + final Map<String, dynamic> data = <String, dynamic>{};
63 + return data;
64 +}
...@@ -4,7 +4,9 @@ class HttpApi { ...@@ -4,7 +4,9 @@ class HttpApi {
4 static const String verify = 'verify'; 4 static const String verify = 'verify';
5 static const String login = 'login'; 5 static const String login = 'login';
6 static const String uploadVideo = 'upload/video'; 6 static const String uploadVideo = 'upload/video';
7 + static const String uploadImage = 'upload/image';
7 static const String immersive = 'immersive'; 8 static const String immersive = 'immersive';
9 + static const String avatar = 'avatar';
8 static const String user = 'user'; 10 static const String user = 'user';
9 static const String search = 'search/repositories'; 11 static const String search = 'search/repositories';
10 static const String subscriptions = 'users/simplezhli/subscriptions'; 12 static const String subscriptions = 'users/simplezhli/subscriptions';
......
...@@ -215,7 +215,7 @@ class _PoemPublishState extends State<PoemPublish> { ...@@ -215,7 +215,7 @@ class _PoemPublishState extends State<PoemPublish> {
215 final directory = await getApplicationDocumentsDirectory(); 215 final directory = await getApplicationDocumentsDirectory();
216 dynamic video = await MultipartFile.fromFile( 216 dynamic video = await MultipartFile.fromFile(
217 directory.path + "/" + widget.data, 217 directory.path + "/" + widget.data,
218 - filename: "xxx23.png"); 218 + filename: "video.mp4");
219 return video; 219 return video;
220 } 220 }
221 221
......