reason

修改上传视频逻辑

...@@ -114,6 +114,36 @@ class DioUtils { ...@@ -114,6 +114,36 @@ class DioUtils {
114 } 114 }
115 } 115 }
116 116
117 + // 数据返回格式统一,统一处理异常
118 + Future<BaseEntity<T>> _upload<T>(
119 + String method,
120 + String url, {
121 + Object? data,
122 + Map<String, dynamic>? queryParameters,
123 + CancelToken? cancelToken,
124 + ProgressCallback? progressCallback,
125 + Options? options,
126 + }) async {
127 + final Response<String> response = await _dio.post<String>(
128 + url,
129 + data: data,
130 + queryParameters: queryParameters,
131 + options: _checkOptions(method, options),
132 + cancelToken: cancelToken,
133 + onSendProgress: progressCallback,
134 + );
135 + try {
136 + final String data = response.data.toString();
137 + final bool isCompute = !Constant.isDriverTest && data.length > 10 * 1024;
138 + final Map<String, dynamic> map =
139 + isCompute ? await compute(parseData, data) : parseData(data);
140 + return BaseEntity<T>.fromJson(map);
141 + } catch (e) {
142 + debugPrint(e.toString());
143 + return BaseEntity<T>(ExceptionHandle.parse_error, '数据解析错误!', null);
144 + }
145 + }
146 +
117 Options _checkOptions(String method, Options? options) { 147 Options _checkOptions(String method, Options? options) {
118 options ??= Options(); 148 options ??= Options();
119 options.method = method; 149 options.method = method;
...@@ -178,6 +208,41 @@ class DioUtils { ...@@ -178,6 +208,41 @@ class DioUtils {
178 } 208 }
179 209
180 /// 统一处理(onSuccess返回T对象,onSuccessList返回 List<T>) 210 /// 统一处理(onSuccess返回T对象,onSuccessList返回 List<T>)
211 + void asyncUploadFile<T>(
212 + Method method,
213 + String url, {
214 + NetSuccessCallback<T?>? onSuccess,
215 + NetErrorCallback? onError,
216 + Object? params,
217 + Map<String, dynamic>? queryParameters,
218 + CancelToken? cancelToken,
219 + ProgressCallback? progressCallback,
220 + Options? options,
221 + }) {
222 + Stream.fromFuture(_upload<T>(
223 + method.value,
224 + url,
225 + data: params,
226 + queryParameters: queryParameters,
227 + options: options,
228 + cancelToken: cancelToken,
229 + progressCallback: progressCallback,
230 + )).asBroadcastStream().listen((result) {
231 + if (result.code == 0) {
232 + if (onSuccess != null) {
233 + onSuccess(result.data);
234 + }
235 + } else {
236 + _onError(result.code, result.message, onError);
237 + }
238 + }, onError: (dynamic e) {
239 + _cancelLogPrint(e, url);
240 + final NetError error = ExceptionHandle.handleException(e);
241 + _onError(error.code, error.msg, onError);
242 + });
243 + }
244 +
245 + /// 统一处理(onSuccess返回T对象,onSuccessList返回 List<T>)
181 void asyncRequestNetwork<T>( 246 void asyncRequestNetwork<T>(
182 Method method, 247 Method method,
183 String url, { 248 String url, {
......
...@@ -14,6 +14,7 @@ import 'package:Parlando/routers/routers.dart'; ...@@ -14,6 +14,7 @@ import 'package:Parlando/routers/routers.dart';
14 import 'package:Parlando/widgets/my_app_bar.dart'; 14 import 'package:Parlando/widgets/my_app_bar.dart';
15 15
16 import 'package:Parlando/extension/int_extension.dart'; 16 import 'package:Parlando/extension/int_extension.dart';
17 +import 'package:getwidget/getwidget.dart';
17 import 'package:path_provider/path_provider.dart'; 18 import 'package:path_provider/path_provider.dart';
18 19
19 import '../poem_router.dart'; 20 import '../poem_router.dart';
...@@ -36,13 +37,14 @@ class PoemPublish extends StatefulWidget { ...@@ -36,13 +37,14 @@ class PoemPublish extends StatefulWidget {
36 37
37 class PoemPublishState extends State<PoemPublish> { 38 class PoemPublishState extends State<PoemPublish> {
38 bool isPublishing = false; 39 bool isPublishing = false;
40 + bool isUploading = false;
39 String _langSortName = "普通话"; 41 String _langSortName = "普通话";
40 int _langSortId = 1; //TODO 传入服务器的口音ID 42 int _langSortId = 1; //TODO 传入服务器的口音ID
41 String _address = '我在此地'; 43 String _address = '我在此地';
42 String _longitude = ""; 44 String _longitude = "";
43 String _latitude = ""; 45 String _latitude = "";
44 final LangSortProvider _provider = LangSortProvider(); 46 final LangSortProvider _provider = LangSortProvider();
45 - 47 + final ValueNotifier<double> _counter = ValueNotifier<double>(0.0);
46 final TextEditingController _msgController = TextEditingController(); 48 final TextEditingController _msgController = TextEditingController();
47 49
48 @override 50 @override
...@@ -52,8 +54,9 @@ class PoemPublishState extends State<PoemPublish> { ...@@ -52,8 +54,9 @@ class PoemPublishState extends State<PoemPublish> {
52 54
53 @override 55 @override
54 void dispose() { 56 void dispose() {
55 - super.dispose(); 57 + _counter.dispose();
56 _provider.dispose(); 58 _provider.dispose();
59 + super.dispose();
57 } 60 }
58 61
59 @override 62 @override
...@@ -203,6 +206,16 @@ class PoemPublishState extends State<PoemPublish> { ...@@ -203,6 +206,16 @@ class PoemPublishState extends State<PoemPublish> {
203 color: Colors.black54, fontSize: 15.px), 206 color: Colors.black54, fontSize: 15.px),
204 ), 207 ),
205 ), 208 ),
209 + Gaps.vGap10,
210 + isUploading
211 + ? Padding(
212 + padding: const EdgeInsets.all(20),
213 + child: ValueListenableBuilder<double>(
214 + builder: _buildWithValue,
215 + valueListenable: _counter,
216 + ),
217 + )
218 + : Container(),
206 ], 219 ],
207 ), 220 ),
208 ), 221 ),
...@@ -222,6 +235,21 @@ class PoemPublishState extends State<PoemPublish> { ...@@ -222,6 +235,21 @@ class PoemPublishState extends State<PoemPublish> {
222 ); 235 );
223 } 236 }
224 237
238 + Widget _buildWithValue(BuildContext context, double value, Widget? child) {
239 + return GFProgressBar(
240 + percentage: value,
241 + lineHeight: 10,
242 + alignment: MainAxisAlignment.spaceBetween,
243 + backgroundColor: Colors.black26,
244 + progressBarColor: GFColors.INFO,
245 + child: Text(
246 + "${(value * 100).toStringAsFixed(1)}%",
247 + textAlign: TextAlign.end,
248 + style: const TextStyle(fontSize: 8, color: Colors.white),
249 + ),
250 + );
251 + }
252 +
225 Future<dynamic> _getUploadVideo() async { 253 Future<dynamic> _getUploadVideo() async {
226 final directory = await getApplicationDocumentsDirectory(); 254 final directory = await getApplicationDocumentsDirectory();
227 dynamic video = await MultipartFile.fromFile( 255 dynamic video = await MultipartFile.fromFile(
...@@ -237,6 +265,7 @@ class PoemPublishState extends State<PoemPublish> { ...@@ -237,6 +265,7 @@ class PoemPublishState extends State<PoemPublish> {
237 } 265 }
238 266
239 isPublishing = true; 267 isPublishing = true;
268 + isUploading = true;
240 setState(() {}); 269 setState(() {});
241 270
242 _getUploadVideo().then((value) { 271 _getUploadVideo().then((value) {
...@@ -244,14 +273,17 @@ class PoemPublishState extends State<PoemPublish> { ...@@ -244,14 +273,17 @@ class PoemPublishState extends State<PoemPublish> {
244 "video": value, 273 "video": value,
245 }; 274 };
246 FormData formData = FormData.fromMap(map); 275 FormData formData = FormData.fromMap(map);
247 - DioUtils.instance.asyncRequestNetwork<UploadEntity>( 276 + DioUtils.instance.asyncUploadFile<UploadEntity>(
248 Method.post, 277 Method.post,
249 HttpApi.uploadVideo, 278 HttpApi.uploadVideo,
250 params: formData, 279 params: formData,
280 + progressCallback: (int count, int data) {
281 + _counter.value = count / data;
282 + },
251 onSuccess: (data) { 283 onSuccess: (data) {
252 String path = data!.data!.relativePath!; 284 String path = data!.data!.relativePath!;
253 String videoId = '${widget.id}'; 285 String videoId = '${widget.id}';
254 - 286 + isUploading = false;
255 Map<String, String> params = <String, String>{ 287 Map<String, String> params = <String, String>{
256 "item_id": videoId, 288 "item_id": videoId,
257 "item_url": path, 289 "item_url": path,
......
...@@ -9,10 +9,10 @@ class AddressSelectPage extends StatefulWidget { ...@@ -9,10 +9,10 @@ class AddressSelectPage extends StatefulWidget {
9 const AddressSelectPage({Key? key}) : super(key: key); 9 const AddressSelectPage({Key? key}) : super(key: key);
10 10
11 @override 11 @override
12 - _AddressSelectPageState createState() => _AddressSelectPageState(); 12 + AddressSelectPageState createState() => AddressSelectPageState();
13 } 13 }
14 14
15 -class _AddressSelectPageState extends State<AddressSelectPage> { 15 +class AddressSelectPageState extends State<AddressSelectPage> {
16 List<PoiSearch> _list = []; 16 List<PoiSearch> _list = [];
17 int _index = 0; 17 int _index = 0;
18 final ScrollController _controller = ScrollController(); 18 final ScrollController _controller = ScrollController();
......
...@@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev ...@@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
15 # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 15 # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 # Read more about iOS versioning at 16 # Read more about iOS versioning at
17 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 17 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 -version: 1.0.0+5 18 +version: 1.0.0+6
19 19
20 environment: 20 environment:
21 sdk: ">=2.16.2 <3.0.0" 21 sdk: ">=2.16.2 <3.0.0"
......