Commit 07e3db1c3b51f6e6374b887e00fc4140081aba16

Authored by wdn127929
1 parent 7aa0e4bb

相机、相册单图 七牛传

@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 additional functionality it is fine to subclass or reimplement 7 additional functionality it is fine to subclass or reimplement
8 FlutterApplication and put your custom class here. --> 8 FlutterApplication and put your custom class here. -->
9 9
  10 +
10 <uses-permission android:name="android.permission.READ_CONTACTS" /> 11 <uses-permission android:name="android.permission.READ_CONTACTS" />
11 <uses-permission android:name="android.permission.WRITE_CONTACTS" /> 12 <uses-permission android:name="android.permission.WRITE_CONTACTS" />
12 <uses-permission android:name="android.permission.READ_CONTACTS"/> 13 <uses-permission android:name="android.permission.READ_CONTACTS"/>
@@ -50,6 +50,8 @@ @@ -50,6 +50,8 @@
50 <key>NSAllowsArbitraryLoads</key> 50 <key>NSAllowsArbitraryLoads</key>
51 <true/> 51 <true/>
52 </dict> 52 </dict>
  53 + <key>NSPhotoLibraryUsageDescription</key>
  54 + <string>需要您的同意,APP才能访问您的相册来上传图片</string>
53 <key>NSAppleMusicUsageDescription</key> 55 <key>NSAppleMusicUsageDescription</key>
54 <string>需要您的同意,APP才能访问媒体资料库</string> 56 <string>需要您的同意,APP才能访问媒体资料库</string>
55 <key>NSCalendarsUsageDescription</key> 57 <key>NSCalendarsUsageDescription</key>
  1 +import 'package:json_annotation/json_annotation.dart';
  2 +
  3 +part 'qiniu_info_model.g.dart';
  4 +
  5 +@JsonSerializable()
  6 +class QiniuInfoModel extends Object {
  7 + @JsonKey(name: 'ret')
  8 + int ret;
  9 +
  10 + @JsonKey(name: 'data')
  11 + QiniuInfoSunModel data;
  12 +
  13 + @JsonKey(name: 'msg')
  14 + String msg;
  15 +
  16 + QiniuInfoModel(
  17 + this.ret,
  18 + this.data,
  19 + this.msg,
  20 + );
  21 +
  22 + factory QiniuInfoModel.fromJson(Map<String, dynamic> srcJson) =>
  23 + _$QiniuInfoModelFromJson(srcJson);
  24 +
  25 + Map<String, dynamic> toJson() => _$QiniuInfoModelToJson(this);
  26 +}
  27 +
  28 +@JsonSerializable()
  29 +class QiniuInfoSunModel extends Object {
  30 + @JsonKey(name: 'token')
  31 + String token;
  32 +
  33 + @JsonKey(name: 'domain')
  34 + String domain;
  35 +
  36 + QiniuInfoSunModel(
  37 + this.token,
  38 + this.domain,
  39 + );
  40 +
  41 + factory QiniuInfoSunModel.fromJson(Map<String, dynamic> srcJson) =>
  42 + _$QiniuInfoSunModelFromJson(srcJson);
  43 +
  44 + Map<String, dynamic> toJson() => _$QiniuInfoSunModelToJson(this);
  45 +}
  1 +// GENERATED CODE - DO NOT MODIFY BY HAND
  2 +
  3 +part of 'qiniu_info_model.dart';
  4 +
  5 +// **************************************************************************
  6 +// JsonSerializableGenerator
  7 +// **************************************************************************
  8 +
  9 +QiniuInfoModel _$QiniuInfoModelFromJson(Map<String, dynamic> json) {
  10 + return QiniuInfoModel(
  11 + json['ret'] as int,
  12 + json['data'] == null
  13 + ? null
  14 + : QiniuInfoSunModel.fromJson(json['data'] as Map<String, dynamic>),
  15 + json['msg'] as String);
  16 +}
  17 +
  18 +Map<String, dynamic> _$QiniuInfoModelToJson(QiniuInfoModel instance) =>
  19 + <String, dynamic>{
  20 + 'ret': instance.ret,
  21 + 'data': instance.data,
  22 + 'msg': instance.msg
  23 + };
  24 +
  25 +QiniuInfoSunModel _$QiniuInfoSunModelFromJson(Map<String, dynamic> json) {
  26 + return QiniuInfoSunModel(json['token'] as String, json['domain'] as String);
  27 +}
  28 +
  29 +Map<String, dynamic> _$QiniuInfoSunModelToJson(QiniuInfoSunModel instance) =>
  30 + <String, dynamic>{'token': instance.token, 'domain': instance.domain};
@@ -63,4 +63,7 @@ class HttpUrl { @@ -63,4 +63,7 @@ class HttpUrl {
63 "?service=App.Advance.CreateOrder"; //顾客扫桌码点餐-扫码创建订单 63 "?service=App.Advance.CreateOrder"; //顾客扫桌码点餐-扫码创建订单
64 static const String get_reserve_detail = 64 static const String get_reserve_detail =
65 "?service=App.Reserve.Detail"; //订座详情页面 65 "?service=App.Reserve.Detail"; //订座详情页面
  66 + static const String get_qiniu_info =
  67 + "?service=App.Qiniu.GetUploadToken"; //获取七牛上传token信息
  68 +
66 } 69 }
@@ -126,6 +126,11 @@ class HomePageState extends State<HomePage> with WidgetsBindingObserver { @@ -126,6 +126,11 @@ class HomePageState extends State<HomePage> with WidgetsBindingObserver {
126 NavigatorUtil.goNotebookDetailPage(context, notifyParam['rid'], 126 NavigatorUtil.goNotebookDetailPage(context, notifyParam['rid'],
127 mid: notifyParam['mid'], fromNotify: true); 127 mid: notifyParam['mid'], fromNotify: true);
128 break; 128 break;
  129 + case "12":
  130 + //在线买单消息 去处理 跳转在线买单处理页面
  131 + NavigatorUtil.goOnlineCheckEditPage(context,
  132 + rid: notifyParam["rid"], fromNotify: true);
  133 + break;
129 case "1": 134 case "1":
130 NavigatorUtil.goHasOrderFoodPage(context, 135 NavigatorUtil.goHasOrderFoodPage(context,
131 rid: notifyParam["rid"], fromNotify: true); 136 rid: notifyParam["rid"], fromNotify: true);
1 -import 'dart:io';  
2 -  
3 -import 'package:flutter/material.dart';  
4 -import 'package:flutter_screenutil/flutter_screenutil.dart';  
5 -import 'package:one_key/pages/online_check/photo_view_wiget.dart';  
6 -  
7 -import 'package:one_key/provider/online_check_edit_provider.dart';  
8 -import 'package:one_key/res/colors.dart';  
9 -import 'package:one_key/utils/utils.dart';  
10 -import 'package:one_key/widgets/MyDivider.dart';  
11 -import 'package:one_key/widgets/v_empty_view.dart';  
12 -import 'package:provider/provider.dart';  
13 -  
14 -import 'package:image_picker/image_picker.dart';  
15 -import 'package:video_player/video_player.dart';  
16 -import 'package:qiniu_flutter_sdk/qiniu_flutter_sdk.dart';  
17 -  
18 -final int MAX_IMAGE_NUMBER = 9;  
19 -typedef void OnPickImageCallback(  
20 - double maxWidth, double maxHeight, int quality);  
21 -  
22 -class ImgPickerWidget extends StatefulWidget {  
23 - final ScrollController scrollController;  
24 - final Color borderColor;  
25 - final ValueChanged onChange;  
26 - ImgPickerWidget(  
27 - {Key key,  
28 - this.scrollController,  
29 - this.borderColor = Colors.blue,  
30 - this.onChange})  
31 - : super(key: key);  
32 -  
33 - @override  
34 - _ImgPickerWidgetState createState() => _ImgPickerWidgetState();  
35 -}  
36 -  
37 -class _ImgPickerWidgetState extends State<ImgPickerWidget> {  
38 - File _image;  
39 - final picker = ImagePicker();  
40 - OnlineCheckEditProvider _onlineCheckEditProvider;  
41 -  
42 - //相册 相机  
43 - // Future _getFromPictureOrCamera(context, imageSource) async {  
44 - // File image = await picker.getImage(  
45 - // source: imageSource,  
46 - // );  
47 - // if (image != null) {  
48 - // _provider.imageList.add(image);  
49 - // _provider.notifyListeners();  
50 - // }  
51 - // // _provider.uploadTravelReleaseImg(image);  
52 - // }  
53 -  
54 - Future _getFromPictureOrCamera(imageSource) async {  
55 - final pickedFile = await picker.getImage(source: imageSource);  
56 -  
57 - setState(() {  
58 - if (pickedFile != null) {  
59 - _image = File(pickedFile.path);  
60 - _onlineCheckEditProvider.imageList.add(_image);  
61 - _onlineCheckEditProvider.notifyListeners();  
62 - } else {  
63 - print('No image selected.');  
64 - }  
65 - });  
66 - }  
67 -  
68 - @override  
69 - void dispose() {  
70 - super.dispose();  
71 - }  
72 -  
73 - Future _openModalBottomSheet(context) async {  
74 - final option = await showModalBottomSheet(  
75 - context: context,  
76 - backgroundColor: Colors.transparent,  
77 - builder: (BuildContext context) {  
78 - return Container(  
79 - // height: ScreenUtil().setWidth(180 * 2),  
80 - decoration: BoxDecoration(  
81 - color: MyColours.color_ffffff,  
82 - borderRadius: BorderRadius.only(  
83 - topLeft: Radius.circular(ScreenUtil().setWidth(24)),  
84 - topRight: Radius.circular(ScreenUtil().setWidth(24)))),  
85 - child: Column(  
86 - mainAxisSize: MainAxisSize.min,  
87 - children: <Widget>[  
88 - InkWell(  
89 - onTap: () {  
90 - _getFromPictureOrCamera(ImageSource.camera);  
91 - Navigator.pop(context);  
92 - },  
93 - child: Padding(  
94 - padding: EdgeInsets.symmetric(  
95 - vertical: ScreenUtil().setWidth(18 * 2)),  
96 - child: Text(  
97 - '拍摄',  
98 - style: TextStyle(  
99 - fontSize: ScreenUtil().setSp(32),  
100 - color: MyColours.color_353535,  
101 - fontWeight: FontWeight.bold),  
102 - ),  
103 - ),  
104 - ),  
105 - MyDivider(  
106 - double.infinity,  
107 - ScreenUtil().setWidth(2),  
108 - color: MyColours.color_EEEEEE,  
109 - ),  
110 - InkWell(  
111 - onTap: () {  
112 - _getFromPictureOrCamera(ImageSource.gallery);  
113 - Navigator.pop(context);  
114 - },  
115 - child: Padding(  
116 - padding: EdgeInsets.symmetric(  
117 - vertical: ScreenUtil().setWidth(18 * 2)),  
118 - child: Text(  
119 - '从相册选择',  
120 - style: TextStyle(  
121 - fontSize: ScreenUtil().setSp(32),  
122 - color: MyColours.color_353535,  
123 - fontWeight: FontWeight.bold),  
124 - ),  
125 - ),  
126 - ),  
127 - MyDivider(  
128 - double.infinity,  
129 - ScreenUtil().setWidth(10),  
130 - color: MyColours.color_EEEEEE,  
131 - ),  
132 - InkWell(  
133 - onTap: () {  
134 - Navigator.pop(context, '取消');  
135 - },  
136 - child: Padding(  
137 - padding: EdgeInsets.symmetric(  
138 - vertical: ScreenUtil().setWidth(18 * 2)),  
139 - child: Text(  
140 - '取消',  
141 - style: TextStyle(  
142 - fontSize: ScreenUtil().setSp(32),  
143 - color: MyColours.color_353535,  
144 - fontWeight: FontWeight.bold),  
145 - ),  
146 - ),  
147 - )  
148 - ],  
149 - ),  
150 - );  
151 - });  
152 - }  
153 -  
154 - _getGridImg(count, context, isLinjie) {  
155 - OnlineCheckEditProvider _provider =  
156 - Provider.of<OnlineCheckEditProvider>(context, listen: false);  
157 - return GridView.builder(  
158 - controller: widget.scrollController,  
159 - // padding: EdgeInsets.only(top: ScreenUtil().getAdapterSize(10)),  
160 - shrinkWrap: true,  
161 - itemCount: count,  
162 - //SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget  
163 - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(  
164 - //横轴元素个数  
165 - crossAxisCount: 3,  
166 - //纵轴间距  
167 - mainAxisSpacing: 20.0,  
168 - //横轴间距  
169 - crossAxisSpacing: 10.0,  
170 - //子组件宽高长度比例  
171 - childAspectRatio: 1.0),  
172 - itemBuilder: (BuildContext context, int index) {  
173 - //Widget Function(BuildContext context, int index)  
174 - var linjie = MAX_IMAGE_NUMBER;  
175 - if (isLinjie) {  
176 - linjie = MAX_IMAGE_NUMBER - 1;  
177 - }  
178 - if (index == count - 1 && index < linjie) {  
179 - return InkWell(  
180 - onTap: () {  
181 - _openModalBottomSheet(context);  
182 - },  
183 - child: Container(  
184 - width: ScreenUtil().setWidth(90 * 2),  
185 - height: ScreenUtil().setWidth(90 * 2),  
186 - decoration: BoxDecoration(  
187 - border: Border.all(  
188 - color: MyColours.color_E0E0E0,  
189 - width: ScreenUtil().setWidth(2)),  
190 - ),  
191 - child: Column(  
192 - children: [  
193 - VEmptyView(74),  
194 - Image.asset(  
195 - Utils.getImgPath('add_image'),  
196 - width: ScreenUtil().setWidth(32),  
197 - height: ScreenUtil().setWidth(32),  
198 - ),  
199 - VEmptyView(10),  
200 - Text(  
201 - '添加照片',  
202 - style: TextStyle(  
203 - fontSize: ScreenUtil().setSp(24),  
204 - color: MyColours.color_999999),  
205 - )  
206 - ],  
207 - )),  
208 - );  
209 - }  
210 - return _provider.imageList.length < 1  
211 - ? Text('')  
212 - : InkWell(  
213 - onTap: () {  
214 - _showPhotoView(context, index, _provider.imageList[index]);  
215 - },  
216 - child:  
217 - Image.file(_provider.imageList[index], fit: BoxFit.cover),  
218 - );  
219 - });  
220 - }  
221 -  
222 - //查看大图  
223 - _showPhotoView(BuildContext context, int index, List imgs,  
224 - {isShow = false, List dashName}) async {  
225 - // if (imgs.length == 1 &&  
226 - // imgs[0] ==  
227 - // 'http://nosqn.colorcun.com/custom/lite-online/image/def-banner.png') {  
228 - // imgs[0] = 'http://nosqn.colorcun.com/app/seller-hj-empty.png';  
229 - // }  
230 - Utils.setBarStatus(false, color: Colors.black);  
231 - dynamic result = await showGeneralDialog(  
232 - context: context,  
233 - barrierDismissible: false,  
234 - // barrierColor: Colors.red,  
235 - barrierLabel:  
236 - MaterialLocalizations.of(context).modalBarrierDismissLabel,  
237 - transitionDuration: const Duration(milliseconds: 150),  
238 - pageBuilder: (BuildContext context, Animation animation,  
239 - Animation secondaryAnimation) {  
240 - Widget child = Stack(  
241 - children: <Widget>[  
242 - PhotoPreview(  
243 - initialIndex: index,  
244 - photoList: imgs,  
245 - isShow: isShow,  
246 - dashName: dashName)  
247 - ],  
248 - );  
249 - return child;  
250 - });  
251 - Utils.setBarStatus(true, color: Colors.white);  
252 - }  
253 -  
254 - @override  
255 - Widget build(BuildContext context) {  
256 - _onlineCheckEditProvider =  
257 - Provider.of<OnlineCheckEditProvider>(context, listen: true);  
258 - return Container(  
259 - width: double.infinity,  
260 - decoration: BoxDecoration(  
261 - color: Colors.white, borderRadius: BorderRadius.circular(10)),  
262 - child: Column(  
263 - crossAxisAlignment: CrossAxisAlignment.start,  
264 - children: <Widget>[  
265 - Container(  
266 - height: ScreenUtil().setWidth(53 * 2),  
267 - width: double.infinity,  
268 - decoration: BoxDecoration(  
269 - color: MyColours.color_FAFAFA,  
270 - borderRadius: BorderRadius.only(  
271 - topLeft: Radius.circular(10),  
272 - topRight: Radius.circular(10)),  
273 - ),  
274 - child: Padding(  
275 - padding: EdgeInsets.fromLTRB(  
276 - ScreenUtil().setWidth(20),  
277 - ScreenUtil().setWidth(36),  
278 - ScreenUtil().setWidth(20),  
279 - ScreenUtil().setWidth(26)),  
280 - child: Text(  
281 - '消费清单(选填)',  
282 - style: TextStyle(  
283 - fontSize: ScreenUtil().setSp(32),  
284 - color: MyColours.color_353535,  
285 - fontWeight: FontWeight.bold),  
286 - ),  
287 - )),  
288 - Padding(  
289 - padding: EdgeInsets.all(ScreenUtil().setWidth(40)),  
290 - child: _getGridImg(  
291 - _onlineCheckEditProvider.imageList.length < MAX_IMAGE_NUMBER  
292 - ? _onlineCheckEditProvider.imageList.length + 1  
293 - : _onlineCheckEditProvider.imageList.length,  
294 - context,  
295 - _onlineCheckEditProvider.imageList.length == MAX_IMAGE_NUMBER  
296 - ? true  
297 - : false),  
298 - )  
299 - // _getGridImg(1, context)  
300 - ],  
301 - ),  
302 - );  
303 - }  
304 -}  
  1 +import 'package:flutter/widgets.dart';
  2 +
  3 +abstract class DisposableState<T extends StatefulWidget> extends State<T> {
  4 + List<Function> disposerList = [];
  5 +
  6 + void addDisposer(Function disposer) {
  7 + disposerList.add(disposer);
  8 + }
  9 +
  10 + @override
  11 + @mustCallSuper
  12 + void dispose() {
  13 + for (var disposer in disposerList) {
  14 + try {
  15 + disposer?.call();
  16 + } catch (error) {
  17 + rethrow;
  18 + }
  19 + }
  20 + super.dispose();
  21 + }
  22 +}
  1 +import 'dart:convert';
  2 +import 'dart:io';
  3 +import 'dart:async';
  4 +
  5 +import 'package:cached_network_image/cached_network_image.dart';
  6 +import 'package:flutter/material.dart';
  7 +import 'package:flutter/services.dart';
  8 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  9 +import 'package:one_key/pages/online_check/photo_view_wiget.dart';
  10 +import 'package:one_key/pages/online_check/progress.dart';
  11 +
  12 +import 'package:one_key/provider/online_check_edit_provider.dart';
  13 +import 'package:one_key/res/colors.dart';
  14 +import 'package:one_key/utils/utils.dart';
  15 +import 'package:one_key/widgets/MyDivider.dart';
  16 +import 'package:one_key/widgets/v_empty_view.dart';
  17 +import 'package:path_provider/path_provider.dart';
  18 +import 'package:photo/photo.dart';
  19 +import 'package:provider/provider.dart';
  20 +
  21 +import 'package:image_picker/image_picker.dart';
  22 +import 'package:qiniu_flutter_sdk/qiniu_flutter_sdk.dart';
  23 +import './dispose.dart';
  24 +import 'package:photo_manager/photo_manager.dart';
  25 +
  26 +final int MAX_IMAGE_NUMBER = 5;
  27 +typedef void OnPickImageCallback(
  28 + double maxWidth, double maxHeight, int quality);
  29 +
  30 +class ImgPickerWidget extends StatefulWidget {
  31 + final ScrollController scrollController;
  32 + final Color borderColor;
  33 + final ValueChanged onChange;
  34 + ImgPickerWidget(
  35 + {Key key,
  36 + this.scrollController,
  37 + this.borderColor = Colors.blue,
  38 + this.onChange})
  39 + : super(key: key);
  40 +
  41 + @override
  42 + _ImgPickerWidgetState createState() => _ImgPickerWidgetState();
  43 +}
  44 +
  45 +class _ImgPickerWidgetState extends DisposableState<ImgPickerWidget> {
  46 + final picker = ImagePicker();
  47 + OnlineCheckEditProvider _onlineCheckEditProvider;
  48 + // 控制器,可以用于取消任务、获取上述的状态,进度等信息
  49 + PutController putController;
  50 + // 用户输入的文件名
  51 + String key;
  52 + // 用户输入的 partSize
  53 + int partSize = 4;
  54 + // 用户输入的 token
  55 + String token;
  56 +
  57 + /// storage 实例
  58 + Storage storage;
  59 + // 当前的进度
  60 + double progressValue = 0.01;
  61 + // 当前的任务状态
  62 + StorageStatus statusValue;
  63 +
  64 + @override
  65 + void initState() {
  66 + storage = Storage();
  67 + super.initState();
  68 + }
  69 +
  70 + @override
  71 + void dispose() {
  72 + super.dispose();
  73 + }
  74 +
  75 + ///#相机拍照,单图选择
  76 + Future _getFromPictureOrCamera(imageSource) async {
  77 + final pickedFile = await picker.getImage(source: imageSource);
  78 +
  79 + setState(() {
  80 + if (pickedFile != null) {
  81 + _onlineCheckEditProvider.imageListFile.add(File(pickedFile.path));
  82 + _onlineCheckEditProvider.statusMap[pickedFile.path] = false;
  83 + } else {
  84 + print('No image selected.');
  85 + }
  86 + });
  87 + if (pickedFile != null) {
  88 + startUpload(File(pickedFile.path));
  89 + }
  90 + }
  91 +
  92 + ///多图片选择
  93 + void pickAsset(PickType type, {List<AssetPathEntity> pathList}) async {
  94 + /// context is required, other params is optional.
  95 + List<AssetEntity> imgList = await PhotoPicker.pickAsset(
  96 + // BuildContext required
  97 + context: context,
  98 +
  99 + /// The following are optional parameters.
  100 + themeColor: MyColours.color_199095,
  101 + // the title color and bottom color
  102 + textColor: Colors.white,
  103 + // text color
  104 + padding: 1.0,
  105 + // item padding
  106 + dividerColor: Colors.grey,
  107 + // divider color
  108 + disableColor: Colors.grey.shade300,
  109 + // the check box disable color
  110 + itemRadio: 0.88,
  111 + // the content item radio
  112 + maxSelected:
  113 + MAX_IMAGE_NUMBER - _onlineCheckEditProvider.imageListFile.length,
  114 + // max picker image count
  115 + // provider: I18nProvider.english,
  116 + provider: I18nProvider.chinese,
  117 + // i18n provider ,default is chinese. , you can custom I18nProvider or use ENProvider()
  118 + rowCount: 3,
  119 + // item row count
  120 + thumbSize: 150,
  121 + // preview thumb size , default is 64
  122 + sortDelegate: SortDelegate.common,
  123 + // default is common ,or you make custom delegate to sort your gallery
  124 + checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(
  125 + activeColor: MyColours.color_353535,
  126 + unselectedColor: Colors.white,
  127 + checkColor: MyColours.color_199095,
  128 + ),
  129 + // default is DefaultCheckBoxBuilderDelegate ,or you make custom delegate to create checkbox
  130 + // loadingDelegate: this,
  131 + // if you want to build custom loading widget,extends LoadingDelegate, [see example/lib/main.dart]
  132 + badgeDelegate: const DurationBadgeDelegate(),
  133 + // badgeDelegate to show badge widget
  134 + pickType: type,
  135 + photoPathList: pathList,
  136 + );
  137 + if (imgList == null || imgList.isEmpty) {
  138 + print("No pick item.");
  139 + return;
  140 + } else {
  141 + List<String> r = [];
  142 + for (var e in imgList) {
  143 + var file = await e.file;
  144 + r.add(file.absolute.path);
  145 + setState(() {
  146 + _onlineCheckEditProvider.imageListFile.add(File(file.absolute.path));
  147 + _onlineCheckEditProvider.statusMap[file.absolute.path] = false;
  148 + });
  149 + startUpload(File(file.absolute.path));
  150 + }
  151 + }
  152 + }
  153 +
  154 + ///七牛云sdk
  155 +
  156 + void onStatus(StorageStatus status) {
  157 + print('状态变化: 当前任务状态:${status.toString()}');
  158 + setState(() => statusValue = status);
  159 + }
  160 +
  161 + ///任务进度变化:进度
  162 + void onProgress(double percent) {
  163 + setState(() => progressValue = percent);
  164 + print('任务进度变化:进度:${percent.toStringAsFixed(4)}');
  165 + }
  166 +
  167 + ///实际发送变化:进度
  168 + void onSendProgress(double percent) {
  169 + setState(() => progressValue = percent);
  170 + print('实际发送变化:进度:${percent.toStringAsFixed(4)}');
  171 + }
  172 +
  173 + ///上传到七牛云
  174 + void startUpload(File selectedFile) async {
  175 + print('创建 PutController');
  176 + putController = PutController();
  177 + // _onlineCheckEditProvider.statusMapProgress[selectedFile.path] =
  178 + // putController;
  179 + print('添加实际发送进度订阅');
  180 + addDisposer(putController.addSendProgressListener(onSendProgress));
  181 +
  182 + print('添加任务进度订阅');
  183 + addDisposer(putController.addProgressListener(onProgress));
  184 +
  185 + print('添加状态订阅');
  186 + addDisposer(putController.addStatusListener(onStatus));
  187 + if (token == null || token == '') {
  188 + await _onlineCheckEditProvider.getQiniuInfo(context, {});
  189 + }
  190 + var usedToken = _onlineCheckEditProvider.qiniuInfoSunModel.token;
  191 +
  192 + if (usedToken == null || usedToken == '') {
  193 + print('token 不能为空');
  194 + return;
  195 + }
  196 + print('开始上传文件');
  197 + storage.putFile(
  198 + selectedFile,
  199 + usedToken,
  200 + options: PutOptions(
  201 + key: key,
  202 + partSize: partSize,
  203 + controller: putController,
  204 + ),
  205 + )
  206 + ..then((PutResponse response) {
  207 + print('上传已完成: 原始响应数据: ${jsonEncode(response.rawData)}');
  208 + print('------------------------');
  209 + String imgUrl = _onlineCheckEditProvider.qiniuInfoSunModel.domain +
  210 + '/' +
  211 + response.rawData['key'];
  212 + _onlineCheckEditProvider.imageListUrl.add(imgUrl);
  213 + // _image
  214 + _onlineCheckEditProvider.statusMap[selectedFile.path] = true;
  215 + _onlineCheckEditProvider.notifyListeners();
  216 + })
  217 + ..catchError((dynamic error) {
  218 + if (error is StorageError) {
  219 + switch (error.type) {
  220 + case StorageErrorType.CONNECT_TIMEOUT:
  221 + print('发生错误: 连接超时');
  222 + break;
  223 + case StorageErrorType.SEND_TIMEOUT:
  224 + print('发生错误: 发送数据超时');
  225 + break;
  226 + case StorageErrorType.RECEIVE_TIMEOUT:
  227 + print('发生错误: 响应数据超时');
  228 + break;
  229 + case StorageErrorType.RESPONSE:
  230 + print('发生错误: ${error.message}');
  231 + break;
  232 + case StorageErrorType.CANCEL:
  233 + print('发生错误: 请求取消');
  234 + break;
  235 + case StorageErrorType.UNKNOWN:
  236 + print('发生错误: 未知错误');
  237 + break;
  238 + case StorageErrorType.NO_AVAILABLE_HOST:
  239 + print('发生错误: 无可用 Host');
  240 + break;
  241 + case StorageErrorType.IN_PROGRESS:
  242 + print('发生错误: 已在队列中');
  243 + break;
  244 + }
  245 + } else {
  246 + print('发生错误: ${error.toString()}');
  247 + }
  248 +
  249 + print('------------------------');
  250 + });
  251 + }
  252 +
  253 + ///添加图片UI弹出
  254 + Future _openModalBottomSheet(context) async {
  255 + final option = await showModalBottomSheet(
  256 + context: context,
  257 + backgroundColor: Colors.transparent,
  258 + isDismissible: false,
  259 + builder: (BuildContext context) {
  260 + return Container(
  261 + // height: ScreenUtil().setWidth(180 * 2),
  262 + decoration: BoxDecoration(
  263 + color: MyColours.color_ffffff,
  264 + borderRadius: BorderRadius.only(
  265 + topLeft: Radius.circular(ScreenUtil().setWidth(24)),
  266 + topRight: Radius.circular(ScreenUtil().setWidth(24)))),
  267 + child: Column(
  268 + mainAxisSize: MainAxisSize.min,
  269 + children: <Widget>[
  270 + InkWell(
  271 + onTap: () {
  272 + _getFromPictureOrCamera(ImageSource.camera);
  273 + Navigator.pop(context);
  274 + },
  275 + child: Container(
  276 + width: double.infinity,
  277 + height: ScreenUtil().setWidth(58 * 2),
  278 + child: Center(
  279 + child: Text(
  280 + '拍摄',
  281 + style: TextStyle(
  282 + fontSize: ScreenUtil().setSp(32),
  283 + color: MyColours.color_353535,
  284 + fontWeight: FontWeight.bold),
  285 + ),
  286 + )),
  287 + ),
  288 + MyDivider(
  289 + double.infinity,
  290 + ScreenUtil().setWidth(2),
  291 + color: MyColours.color_EEEEEE,
  292 + ),
  293 + InkWell(
  294 + onTap: () {
  295 + // pickAsset(PickType.onlyImage);
  296 + _getFromPictureOrCamera(ImageSource.gallery);
  297 + Navigator.pop(context);
  298 + },
  299 + child: Container(
  300 + width: double.infinity,
  301 + height: ScreenUtil().setWidth(58 * 2),
  302 + child: Center(
  303 + child: Text(
  304 + '从相册选择',
  305 + style: TextStyle(
  306 + fontSize: ScreenUtil().setSp(32),
  307 + color: MyColours.color_353535,
  308 + fontWeight: FontWeight.bold),
  309 + ),
  310 + )),
  311 + ),
  312 + MyDivider(
  313 + double.infinity,
  314 + ScreenUtil().setWidth(10),
  315 + color: MyColours.color_EEEEEE,
  316 + ),
  317 + InkWell(
  318 + onTap: () {
  319 + Navigator.pop(context, '取消');
  320 + },
  321 + child: Container(
  322 + width: double.infinity,
  323 + height: ScreenUtil().setWidth(58 * 2),
  324 + child: Center(
  325 + child: Text(
  326 + '取消',
  327 + style: TextStyle(
  328 + fontSize: ScreenUtil().setSp(32),
  329 + color: MyColours.color_353535,
  330 + fontWeight: FontWeight.bold),
  331 + ),
  332 + )))
  333 + ],
  334 + ),
  335 + );
  336 + });
  337 + }
  338 +
  339 + //查看大图
  340 + _showPhotoView(BuildContext context, int index, List imgs,
  341 + {isShow = false, List dashName}) async {
  342 + // if (imgs.length == 1 &&
  343 + // imgs[0] ==
  344 + // 'http://nosqn.colorcun.com/custom/lite-online/image/def-banner.png') {
  345 + // imgs[0] = 'http://nosqn.colorcun.com/app/seller-hj-empty.png';
  346 + // }
  347 + Utils.setBarStatus(false, color: Colors.black);
  348 + dynamic result = await showGeneralDialog(
  349 + context: context,
  350 + barrierDismissible: false,
  351 + // barrierColor: Colors.red,
  352 + barrierLabel:
  353 + MaterialLocalizations.of(context).modalBarrierDismissLabel,
  354 + transitionDuration: const Duration(milliseconds: 150),
  355 + pageBuilder: (BuildContext context, Animation animation,
  356 + Animation secondaryAnimation) {
  357 + Widget child = Stack(
  358 + children: <Widget>[
  359 + PhotoPreview(
  360 + initialIndex: index,
  361 + photoList: imgs,
  362 + isShow: isShow,
  363 + dashName: dashName)
  364 + ],
  365 + );
  366 + return child;
  367 + });
  368 + Utils.setBarStatus(true, color: Colors.white);
  369 + }
  370 +
  371 + @override
  372 + Widget build(BuildContext context) {
  373 + _onlineCheckEditProvider =
  374 + Provider.of<OnlineCheckEditProvider>(context, listen: true);
  375 + return Container(
  376 + width: double.infinity,
  377 + decoration: BoxDecoration(
  378 + color: Colors.white, borderRadius: BorderRadius.circular(10)),
  379 + child: Column(
  380 + crossAxisAlignment: CrossAxisAlignment.start,
  381 + children: <Widget>[
  382 + Container(
  383 + height: ScreenUtil().setWidth(53 * 2),
  384 + width: double.infinity,
  385 + decoration: BoxDecoration(
  386 + color: MyColours.color_FAFAFA,
  387 + borderRadius: BorderRadius.only(
  388 + topLeft: Radius.circular(10),
  389 + topRight: Radius.circular(10)),
  390 + ),
  391 + child: Padding(
  392 + padding: EdgeInsets.fromLTRB(
  393 + ScreenUtil().setWidth(20),
  394 + ScreenUtil().setWidth(36),
  395 + ScreenUtil().setWidth(20),
  396 + ScreenUtil().setWidth(26)),
  397 + child: Text(
  398 + '消费清单(选填)',
  399 + style: TextStyle(
  400 + fontSize: ScreenUtil().setSp(32),
  401 + color: MyColours.color_353535,
  402 + fontWeight: FontWeight.bold),
  403 + ),
  404 + )),
  405 + Padding(
  406 + padding: EdgeInsets.all(ScreenUtil().setWidth(40)),
  407 + child: _getGridImg(
  408 + _onlineCheckEditProvider.imageListFile.length < MAX_IMAGE_NUMBER
  409 + ? _onlineCheckEditProvider.imageListFile.length + 1
  410 + : _onlineCheckEditProvider.imageListFile.length,
  411 + context,
  412 + _onlineCheckEditProvider.imageListFile.length ==
  413 + MAX_IMAGE_NUMBER
  414 + ? true
  415 + : false),
  416 + )
  417 + // _getGridImg(1, context)
  418 + ],
  419 + ),
  420 + );
  421 + }
  422 +
  423 + /// 九宫格
  424 + Widget _getGridImg(count, context, isLinjie) {
  425 + OnlineCheckEditProvider _provider =
  426 + Provider.of<OnlineCheckEditProvider>(context, listen: false);
  427 + return GridView.builder(
  428 + controller: widget.scrollController,
  429 + // padding: EdgeInsets.only(top: ScreenUtil().getAdapterSize(10)),
  430 + shrinkWrap: true,
  431 + itemCount: count,
  432 + //SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
  433 + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  434 + //横轴元素个数
  435 + crossAxisCount: 3,
  436 + //纵轴间距
  437 + mainAxisSpacing: ScreenUtil().setWidth(30),
  438 + //横轴间距
  439 + crossAxisSpacing: ScreenUtil().setWidth(30),
  440 + //子组件宽高长度比例
  441 + childAspectRatio: 1.0),
  442 + itemBuilder: (BuildContext context, int index) {
  443 + //Widget Function(BuildContext context, int index)
  444 + var linjie = MAX_IMAGE_NUMBER;
  445 + if (isLinjie) {
  446 + linjie = MAX_IMAGE_NUMBER - 1;
  447 + }
  448 + if (index == count - 1 && index < linjie) {
  449 + return InkWell(
  450 + onTap: () {
  451 + _openModalBottomSheet(context);
  452 + },
  453 + child: Container(
  454 + width: ScreenUtil().setWidth(90 * 2),
  455 + height: ScreenUtil().setWidth(90 * 2),
  456 + decoration: BoxDecoration(
  457 + border: Border.all(
  458 + color: MyColours.color_E0E0E0,
  459 + width: ScreenUtil().setWidth(2)),
  460 + ),
  461 + child: Column(
  462 + children: [
  463 + VEmptyView(74),
  464 + Image.asset(
  465 + Utils.getImgPath('add_image'),
  466 + width: ScreenUtil().setWidth(32),
  467 + height: ScreenUtil().setWidth(32),
  468 + ),
  469 + VEmptyView(10),
  470 + Text(
  471 + '添加照片',
  472 + style: TextStyle(
  473 + fontSize: ScreenUtil().setSp(24),
  474 + color: MyColours.color_999999),
  475 + )
  476 + ],
  477 + )),
  478 + );
  479 + }
  480 + return _provider.imageListFile.length < 1
  481 + ? Text('')
  482 + : InkWell(
  483 + onTap: () {
  484 + ///没有上传完成的不可以点击
  485 + _showPhotoView(
  486 + context, index, _provider.imageListUrl[index]);
  487 + },
  488 + child: Stack(
  489 + children: [
  490 + Stack(
  491 + alignment: Alignment.topRight,
  492 + children: [
  493 + Image.file(
  494 + _provider.imageListFile[index],
  495 + fit: BoxFit.cover,
  496 + width: ScreenUtil().setWidth(100 * 2),
  497 + height: ScreenUtil().setWidth(100 * 2),
  498 + ),
  499 + Offstage(
  500 + offstage: !_provider
  501 + .statusMap[_provider.imageListFile[index].path],
  502 + child: GestureDetector(
  503 + child: Image.asset(
  504 + Utils.getImgPath("delete"),
  505 + width: ScreenUtil().setWidth(40),
  506 + height: ScreenUtil().setWidth(40),
  507 + ),
  508 + onTap: () {
  509 + //点击删除按钮
  510 + setState(() {
  511 + _provider.imageListFile.removeWhere(
  512 + (element) =>
  513 + element ==
  514 + _provider.imageListFile[index]);
  515 + });
  516 + },
  517 + ),
  518 + ),
  519 + ],
  520 + ),
  521 + Offstage(
  522 + offstage: _provider
  523 + .statusMap[_provider.imageListFile[index].path],
  524 + child: Progress(progressValue),
  525 + )
  526 + ],
  527 + ));
  528 + });
  529 + }
  530 +}
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:flutter_screenutil/screenutil.dart'; 2 import 'package:flutter_screenutil/screenutil.dart';
3 -import 'package:one_key/pages/online_check/ImgPickerWidget.dart'; 3 +import 'package:one_key/pages/online_check/img_picker_widget.dart';
  4 +import 'package:one_key/provider/online_check_edit_provider.dart';
4 import 'package:one_key/res/colors.dart'; 5 import 'package:one_key/res/colors.dart';
5 import 'package:one_key/utils/navigator_util.dart'; 6 import 'package:one_key/utils/navigator_util.dart';
6 import 'package:one_key/utils/utils.dart'; 7 import 'package:one_key/utils/utils.dart';
7 import 'package:one_key/widgets/MyDivider.dart'; 8 import 'package:one_key/widgets/MyDivider.dart';
8 import 'package:one_key/widgets/h_empty_view.dart'; 9 import 'package:one_key/widgets/h_empty_view.dart';
  10 +import 'package:one_key/widgets/my_item.dart';
9 import 'package:one_key/widgets/system_app_bar.dart'; 11 import 'package:one_key/widgets/system_app_bar.dart';
10 import 'package:one_key/widgets/v_empty_view.dart'; 12 import 'package:one_key/widgets/v_empty_view.dart';
  13 +import 'package:provider/provider.dart';
11 14
12 class OnlineCheckEditPage extends StatefulWidget { 15 class OnlineCheckEditPage extends StatefulWidget {
13 final bool fromNotify; 16 final bool fromNotify;
@@ -21,10 +24,14 @@ class _OnlineCheckEditPageState extends State<OnlineCheckEditPage> { @@ -21,10 +24,14 @@ class _OnlineCheckEditPageState extends State<OnlineCheckEditPage> {
21 ScrollController _scrollController = ScrollController(); 24 ScrollController _scrollController = ScrollController();
22 TextEditingController _editingController = TextEditingController(); 25 TextEditingController _editingController = TextEditingController();
23 FocusNode _focusNode = FocusNode(); 26 FocusNode _focusNode = FocusNode();
  27 + OnlineCheckEditProvider _onlineCheckEditProvider;
24 28
25 @override 29 @override
26 void initState() { 30 void initState() {
27 super.initState(); 31 super.initState();
  32 + WidgetsBinding.instance.addPostFrameCallback((_) {
  33 + _getQiniuInfo();
  34 + });
28 _focusNode.addListener(() { 35 _focusNode.addListener(() {
29 if (_focusNode.hasFocus) { 36 if (_focusNode.hasFocus) {
30 //有焦点 37 //有焦点
@@ -36,6 +43,18 @@ class _OnlineCheckEditPageState extends State<OnlineCheckEditPage> { @@ -36,6 +43,18 @@ class _OnlineCheckEditPageState extends State<OnlineCheckEditPage> {
36 }); 43 });
37 } 44 }
38 45
  46 + @override
  47 + void dispose() {
  48 + super.dispose();
  49 + // _onlineCheckEditProvider
  50 + }
  51 +
  52 + ///获取七牛云token
  53 + ///
  54 + _getQiniuInfo() async {
  55 + await _onlineCheckEditProvider.getQiniuInfo(context, {});
  56 + }
  57 +
39 ///顶部logo 58 ///顶部logo
40 Widget _getLogoWidget() { 59 Widget _getLogoWidget() {
41 return Column( 60 return Column(
@@ -156,9 +175,87 @@ class _OnlineCheckEditPageState extends State<OnlineCheckEditPage> { @@ -156,9 +175,87 @@ class _OnlineCheckEditPageState extends State<OnlineCheckEditPage> {
156 ); 175 );
157 } 176 }
158 177
159 - ///消费清单 178 + ///顾客信息
  179 + Widget _customInfoItemWidget(String title, String subTitle) {
  180 + return Row(
  181 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  182 + children: [
  183 + Text(
  184 + title,
  185 + style: TextStyle(
  186 + fontSize: ScreenUtil().setSp(28), color: MyColours.color_707070),
  187 + ),
  188 + Text(
  189 + subTitle,
  190 + style: TextStyle(
  191 + fontSize: ScreenUtil().setSp(28),
  192 + color: MyColours.color_707070,
  193 + fontWeight: FontWeight.bold),
  194 + )
  195 + ],
  196 + );
  197 + }
  198 +
  199 + Widget _customInfoWidget() {
  200 + return Container(
  201 + width: double.infinity,
  202 + decoration: BoxDecoration(
  203 + color: Colors.white, borderRadius: BorderRadius.circular(10)),
  204 + child: Column(
  205 + crossAxisAlignment: CrossAxisAlignment.start,
  206 + children: <Widget>[
  207 + Container(
  208 + height: ScreenUtil().setWidth(53 * 2),
  209 + width: double.infinity,
  210 + decoration: BoxDecoration(
  211 + color: MyColours.color_FAFAFA,
  212 + borderRadius: BorderRadius.only(
  213 + topLeft: Radius.circular(10),
  214 + topRight: Radius.circular(10)),
  215 + ),
  216 + child: Padding(
  217 + padding: EdgeInsets.fromLTRB(
  218 + ScreenUtil().setWidth(20),
  219 + ScreenUtil().setWidth(36),
  220 + ScreenUtil().setWidth(20),
  221 + ScreenUtil().setWidth(26)),
  222 + child: Text(
  223 + '顾客信息',
  224 + style: TextStyle(
  225 + fontSize: ScreenUtil().setSp(32),
  226 + color: MyColours.color_353535,
  227 + fontWeight: FontWeight.bold),
  228 + ),
  229 + )),
  230 + Container(
  231 + color: Colors.white,
  232 + padding: EdgeInsets.fromLTRB(
  233 + ScreenUtil().setWidth(40),
  234 + ScreenUtil().setWidth(24),
  235 + ScreenUtil().setWidth(40),
  236 + ScreenUtil().setWidth(36)),
  237 + child: Column(
  238 + children: [
  239 + _customInfoItemWidget('买单顾客', 'ffff'),
  240 + VEmptyView(24),
  241 + _customInfoItemWidget('顾客电话', 'ffff'),
  242 + VEmptyView(24),
  243 + _customInfoItemWidget('到店时间', 'ffff'),
  244 + VEmptyView(24),
  245 + _customInfoItemWidget('申请时间', 'ffff')
  246 + ],
  247 + ),
  248 + )
  249 + // _getGridImg(1, context)
  250 + ],
  251 + ),
  252 + );
  253 + }
  254 +
160 @override 255 @override
161 Widget build(BuildContext context) { 256 Widget build(BuildContext context) {
  257 + _onlineCheckEditProvider =
  258 + Provider.of<OnlineCheckEditProvider>(context, listen: true);
162 return Scaffold( 259 return Scaffold(
163 backgroundColor: MyColours.color_f5f5f5, 260 backgroundColor: MyColours.color_f5f5f5,
164 appBar: SystemAppBar( 261 appBar: SystemAppBar(
@@ -197,7 +294,9 @@ class _OnlineCheckEditPageState extends State<OnlineCheckEditPage> { @@ -197,7 +294,9 @@ class _OnlineCheckEditPageState extends State<OnlineCheckEditPage> {
197 ), 294 ),
198 ), 295 ),
199 VEmptyView(20), 296 VEmptyView(20),
200 - ImgPickerWidget() 297 + ImgPickerWidget(scrollController: _scrollController),
  298 + VEmptyView(20),
  299 + _customInfoWidget()
201 ], 300 ],
202 )), 301 )),
203 ), 302 ),
  1 +import 'package:flutter/material.dart';
  2 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  3 +import 'package:one_key/res/colors.dart';
  4 +
  5 +class Progress extends StatelessWidget {
  6 + final double value;
  7 + Progress(this.value);
  8 +
  9 + Widget get progress {
  10 + return Container(
  11 + width: ScreenUtil().setWidth(30),
  12 + height: ScreenUtil().setWidth(30),
  13 + padding: EdgeInsets.all(10),
  14 + color: Colors.red,
  15 + child: CircularProgressIndicator(
  16 + value: value,
  17 + // strokeWidth: 14,
  18 + backgroundColor: Colors.grey[200],
  19 + ),
  20 + );
  21 + }
  22 +
  23 + Widget get progressText {
  24 + final integer = (value * 100).toInt(); //当前上传进度
  25 + final decimal = (((value * 100) - integer) * 100).toInt(); //剩余进度
  26 + final unit = '%';
  27 +
  28 + return DefaultTextStyle(
  29 + style: TextStyle(
  30 + color: Colors.black87,
  31 + // fontWeight: FontWeight.bold,
  32 + ),
  33 + child:
  34 + // Row(
  35 + // mainAxisSize: MainAxisSize.min,
  36 + // children: [
  37 + // Text(
  38 + // integer.toString(),
  39 + // style: TextStyle(fontSize: ScreenUtil().setSp(13)),
  40 + // ),
  41 + // Column(
  42 + // children: [
  43 + Container(
  44 + width: ScreenUtil().setWidth(100 * 2),
  45 + height: ScreenUtil().setWidth(100 * 2),
  46 + color: Color.fromRGBO(0, 0, 0, 0.5),
  47 + child: Center(
  48 + child: Text('${integer}${unit}',
  49 + style: TextStyle(
  50 + fontSize: ScreenUtil().setSp(24),
  51 + color: MyColours.color_fefefe)),
  52 + ))
  53 +
  54 + // Text('.$decimal',
  55 + // style: TextStyle(fontSize: ScreenUtil().setSp(13))),
  56 + // ],
  57 + // )
  58 + // ],
  59 + );
  60 + }
  61 +
  62 + @override
  63 + Widget build(BuildContext context) {
  64 + // return Stack(
  65 + // alignment: AlignmentDirectional.center,
  66 + // children: [progress, progressText],
  67 + // );
  68 + return progressText;
  69 + }
  70 +}
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
  2 +import 'package:one_key/constant/constant.dart';
  3 +import 'package:one_key/models/qiniu_info_model.dart';
  4 +import 'package:one_key/net/base_resp.dart';
  5 +import 'package:one_key/net/dio_util.dart';
  6 +import 'package:one_key/net/http_url.dart';
  7 +import 'package:one_key/utils/utils.dart';
2 8
3 class OnlineCheckEditProvider extends ChangeNotifier { 9 class OnlineCheckEditProvider extends ChangeNotifier {
4 - List imageList = []; //图片数组 10 + List imageListFile = []; //本地图片显示
  11 + List imageListUrl = []; //七牛云地址
  12 + Map statusMap = {}; //图片上传状态 <bool> true显示图片 ******* false显示进度
  13 + QiniuInfoSunModel qiniuInfoSunModel;
  14 + // Map statusMapProgress = {}; //图片上传状态 <bool> true显示图片 ******* false显示进度
  15 +
  16 + /// 获取七牛上传token信息
  17 + Future<QiniuInfoSunModel> getQiniuInfo(
  18 + BuildContext context, Map<String, String> params,
  19 + {isShowLoading = true}) async {
  20 + BaseResp<Map<String, dynamic>> baseResp = await DioUtil()
  21 + .request<Map<String, dynamic>>(
  22 + context, Method.get, HttpUrl.get_qiniu_info,
  23 + data: params, showLoading: false)
  24 + .catchError((error) {});
  25 + if (baseResp.code == Constant.status_success) {
  26 + if (baseResp.data.isEmpty) {
  27 + } else {
  28 + //解析解析
  29 + qiniuInfoSunModel = QiniuInfoModel.fromJson(baseResp.responseData).data;
  30 + return qiniuInfoSunModel;
  31 + }
  32 + } else {
  33 + if (baseResp != null) {
  34 + Utils.showToast(baseResp.msg ?? "");
  35 + }
  36 + }
  37 + }
5 } 38 }
@@ -57,4 +57,5 @@ class MyColours { @@ -57,4 +57,5 @@ class MyColours {
57 static const Color color_9C9C9C = Color(0xff9C9C9C); 57 static const Color color_9C9C9C = Color(0xff9C9C9C);
58 static const Color color_FD5656 = Color(0xffFD5656); 58 static const Color color_FD5656 = Color(0xffFD5656);
59 static const Color color_FAFAFA = Color(0xffFAFAFA); 59 static const Color color_FAFAFA = Color(0xffFAFAFA);
  60 + static const Color color_0D0D0D = Color(0xff0D0D0D);
60 } 61 }
@@ -667,6 +667,20 @@ packages: @@ -667,6 +667,20 @@ packages:
667 url: "https://pub.flutter-io.cn" 667 url: "https://pub.flutter-io.cn"
668 source: hosted 668 source: hosted
669 version: "3.1.0" 669 version: "3.1.0"
  670 + photo:
  671 + dependency: "direct main"
  672 + description:
  673 + name: photo
  674 + url: "https://pub.flutter-io.cn"
  675 + source: hosted
  676 + version: "0.4.8"
  677 + photo_manager:
  678 + dependency: transitive
  679 + description:
  680 + name: photo_manager
  681 + url: "https://pub.flutter-io.cn"
  682 + source: hosted
  683 + version: "0.4.8"
670 photo_view: 684 photo_view:
671 dependency: "direct main" 685 dependency: "direct main"
672 description: 686 description:
@@ -996,27 +1010,6 @@ packages: @@ -996,27 +1010,6 @@ packages:
996 url: "https://pub.flutter-io.cn" 1010 url: "https://pub.flutter-io.cn"
997 source: hosted 1011 source: hosted
998 version: "2.1.0-nullsafety.3" 1012 version: "2.1.0-nullsafety.3"
999 - video_player:  
1000 - dependency: "direct main"  
1001 - description:  
1002 - name: video_player  
1003 - url: "https://pub.flutter-io.cn"  
1004 - source: hosted  
1005 - version: "0.10.12+5"  
1006 - video_player_platform_interface:  
1007 - dependency: transitive  
1008 - description:  
1009 - name: video_player_platform_interface  
1010 - url: "https://pub.flutter-io.cn"  
1011 - source: hosted  
1012 - version: "2.2.0"  
1013 - video_player_web:  
1014 - dependency: transitive  
1015 - description:  
1016 - name: video_player_web  
1017 - url: "https://pub.flutter-io.cn"  
1018 - source: hosted  
1019 - version: "0.1.4+1"  
1020 watcher: 1013 watcher:
1021 dependency: transitive 1014 dependency: transitive
1022 description: 1015 description:
@@ -90,11 +90,14 @@ dependencies: @@ -90,11 +90,14 @@ dependencies:
90 easy_contact_picker: ^0.0.2 90 easy_contact_picker: ^0.0.2
91 flutter_app_badger: ^1.1.2 91 flutter_app_badger: ^1.1.2
92 scrollable_positioned_list: ^0.1.8 92 scrollable_positioned_list: ^0.1.8
93 - image_picker: ^0.6.7+21  
94 - video_player: ^0.10.3 93 +#查看大图
95 photo_view: ^0.9.2 94 photo_view: ^0.9.2
96 #七牛云sdk 95 #七牛云sdk
97 qiniu_flutter_sdk: ^0.2.0 96 qiniu_flutter_sdk: ^0.2.0
  97 + #相机拍照,单图选择
  98 + image_picker: ^0.6.7+21
  99 + #多图选择
  100 + photo: ^0.4.8
98 101
99 102
100 103