x1ongzhu 6 лет назад
Родитель
Сommit
c293819777

BIN
images/2x/icon_shangchuan.png


BIN
images/2x/shili_img_01.png


BIN
images/2x/shili_img_02.png


BIN
images/3x/icon_shangchuan.png


BIN
images/3x/shili_img_01.png


BIN
images/3x/shili_img_02.png


BIN
images/icon_shangchuan.png


BIN
images/shili_img_01.png


BIN
images/shili_img_02.png


+ 27 - 0
lib/model/AppealInfo.dart

@@ -0,0 +1,27 @@
+import 'package:json_annotation/json_annotation.dart';
+part 'AppealInfo.g.dart';
+
+@JsonSerializable()
+class AppealInfo {
+  AppealInfo.empty();
+  AppealInfo(this.id, this.delFlag, this.userId, this.playerInfoId, this.competitionId, this.houseId, this.pic, this.status, this.points, this.createTime);
+
+  int id;
+  String delFlag;
+  int userId;
+  int playerInfoId;
+  int competitionId;
+  int houseId;
+  String pic;
+  int status;
+  int points;
+  int createTime;
+
+  factory AppealInfo.fromJson(Map<String, dynamic> json) => _$AppealInfoFromJson(json);
+
+  Map<String, dynamic> toJson() => _$AppealInfoToJson(this);
+  @override
+  String toString() {
+    return _$AppealInfoToJson(this).toString();
+  }
+}

+ 35 - 0
lib/model/AppealInfo.g.dart

@@ -0,0 +1,35 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'AppealInfo.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+AppealInfo _$AppealInfoFromJson(Map<String, dynamic> json) {
+  return AppealInfo(
+      json['id'] as int,
+      json['delFlag'] as String,
+      json['userId'] as int,
+      json['playerInfoId'] as int,
+      json['competitionId'] as int,
+      json['houseId'] as int,
+      json['pic'] as String,
+      json['status'] as int,
+      json['points'] as int,
+      json['createTime'] as int);
+}
+
+Map<String, dynamic> _$AppealInfoToJson(AppealInfo instance) =>
+    <String, dynamic>{
+      'id': instance.id,
+      'delFlag': instance.delFlag,
+      'userId': instance.userId,
+      'playerInfoId': instance.playerInfoId,
+      'competitionId': instance.competitionId,
+      'houseId': instance.houseId,
+      'pic': instance.pic,
+      'status': instance.status,
+      'points': instance.points,
+      'createTime': instance.createTime
+    };

+ 2 - 1
lib/model/PlayerInfo.dart

@@ -11,7 +11,7 @@ class PlayerInfo {
   PlayerInfo.empty();
 
   PlayerInfo(this.id, this.houseId, this.userId, this.statusFlag, this.userInfo, this.points, this.gameInfo, this.houseInfo, this.liveTime, this.score,
-      this.rank, this.ranking, this.houseRank, this.video, this.played, this.competitionInfo, this.createTime, this.dataError, this.resultError);
+      this.rank, this.ranking, this.houseRank, this.video, this.played, this.competitionInfo, this.createTime, this.dataError, this.resultError,this.competitionId);
 
   factory PlayerInfo.fromJson(Map<String, dynamic> json) => _$PlayerInfoFromJson(json);
 
@@ -34,6 +34,7 @@ class PlayerInfo {
   int createTime;
   bool dataError;
   bool resultError;
+  int competitionId;
 
   Map<String, dynamic> toJson() => _$PlayerInfoToJson(this);
 

+ 4 - 2
lib/model/PlayerInfo.g.dart

@@ -35,7 +35,8 @@ PlayerInfo _$PlayerInfoFromJson(Map<String, dynamic> json) {
               json['competitionInfo'] as Map<String, dynamic>),
       json['createTime'] as int,
       json['dataError'] as bool,
-      json['resultError'] as bool);
+      json['resultError'] as bool,
+      json['competitionId'] as int);
 }
 
 Map<String, dynamic> _$PlayerInfoToJson(PlayerInfo instance) =>
@@ -58,5 +59,6 @@ Map<String, dynamic> _$PlayerInfoToJson(PlayerInfo instance) =>
       'competitionInfo': instance.competitionInfo,
       'createTime': instance.createTime,
       'dataError': instance.dataError,
-      'resultError': instance.resultError
+      'resultError': instance.resultError,
+      'competitionId': instance.competitionId
     };

+ 2 - 2
lib/net/HttpManager.dart

@@ -3,8 +3,8 @@ import 'Result.dart';
 import 'package:intl/intl.dart';
 
 class HttpManager {
-  //  static String baseUrl = 'http://123.58.240.138:8090/';
- static String baseUrl = 'http://192.168.50.132:8080/';
+   static String baseUrl = 'http://123.58.240.138:8090/';
+//  static String baseUrl = 'http://192.168.50.132:8080/';
   static String token;
   static bool debug;
 

+ 2 - 2
lib/pages/AppNotice.dart

@@ -2,14 +2,14 @@ import 'package:cached_network_image/cached_network_image.dart';
 import 'package:flutter/material.dart';
 import 'package:wanna_battle/net/HttpManager.dart';
 
-Future<void> getAppNotice(context) async {
+Future getAppNotice(context) async {
   final res = await HttpManager.get('systemVariable/getOne', data: {
     'variableName': 'appNotice',
   });
   if (res.success) {
     final String imageUrl = (res.data ?? {})['variableValue'] ?? '';
     if (imageUrl.isNotEmpty) {
-      showGeneralDialog(
+      return showGeneralDialog(
         context: context,
         barrierDismissible: true,
         pageBuilder: (BuildContext buildContext, Animation<double> animation, Animation<double> secondaryAnimation) {

+ 202 - 0
lib/pages/Appeal.dart

@@ -0,0 +1,202 @@
+import 'dart:io';
+
+import 'package:cached_network_image/cached_network_image.dart';
+import 'package:dio/dio.dart';
+import 'package:file_picker/file_picker.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_redux/flutter_redux.dart';
+import 'package:image_picker/image_picker.dart';
+import 'package:wanna_battle/model/PlayerInfo.dart';
+import 'package:wanna_battle/net/HttpManager.dart';
+import 'package:wanna_battle/net/Result.dart';
+import 'package:wanna_battle/redux/AppState.dart';
+import 'package:wanna_battle/styles/colors.dart';
+import 'package:wanna_battle/styles/totast.dart';
+
+class Appeal extends StatefulWidget {
+  final PlayerInfo playerInfo;
+  const Appeal(this.playerInfo, {Key key}) : super(key: key);
+  @override
+  State<StatefulWidget> createState() {
+    return AppealState();
+  }
+}
+
+class AppealState extends State<Appeal> {
+  String img1;
+  String img2;
+  @override
+  Widget build(BuildContext context) {
+    return WillPopScope(
+      onWillPop: () {
+        return Future.value(true);
+      },
+      child: Scaffold(
+        appBar: AppBar(
+          title: Text('上传比赛结果'),
+          centerTitle: true,
+        ),
+        body: Column(
+          children: <Widget>[
+            Expanded(
+              child: ListView(
+                padding: EdgeInsets.only(left: 15, top: 18, right: 15, bottom: 18),
+                children: <Widget>[
+                  Container(
+                    padding: EdgeInsets.all(3),
+                    child: Text(
+                      '很遗憾,因为部分手机系统性能问题导致比赛结果上传失败,请你按照下图所示方式上传历史战绩以及本次游戏比赛详情战绩,工作人员审核后会根据实际情况进行名次的排序以及奖励的发放',
+                      style: TextStyle(color: Colors.white, fontSize: 14),
+                    ),
+                  ),
+                  Container(
+                    margin: EdgeInsets.only(top: 20),
+                    child: Row(
+                      children: <Widget>[
+                        Expanded(
+                          child: Container(
+                            padding: EdgeInsets.only(right: 7),
+                            child: imgUpload('点击上传历史战绩截图', img1, (img) {
+                              setState(() {
+                                img1 = img;
+                              });
+                            }),
+                          ),
+                        ),
+                        Expanded(
+                          child: Container(
+                            padding: EdgeInsets.only(left: 7),
+                            child: imgUpload('点击上传战绩详情截图', img2, (img) {
+                              setState(() {
+                                img2 = img;
+                              });
+                            }),
+                          ),
+                        ),
+                      ],
+                    ),
+                  ),
+                  Container(
+                    margin: EdgeInsets.only(top: 30),
+                    child: Text(
+                      '历史战绩-图片示例',
+                      textAlign: TextAlign.center,
+                      style: TextStyle(color: Colors.white, fontSize: 14),
+                    ),
+                  ),
+                  Container(
+                    margin: EdgeInsets.only(top: 10),
+                    child: Image.asset(
+                      'images/shili_img_01.png',
+                      fit: BoxFit.cover,
+                    ),
+                  ),
+                  Container(
+                    margin: EdgeInsets.only(top: 20),
+                    child: Text(
+                      '战绩详情-图片示例',
+                      textAlign: TextAlign.center,
+                      style: TextStyle(color: Colors.white, fontSize: 14),
+                    ),
+                  ),
+                  Container(
+                    margin: EdgeInsets.only(top: 10),
+                    child: Image.asset(
+                      'images/shili_img_02.png',
+                      fit: BoxFit.cover,
+                    ),
+                  ),
+                ],
+              ),
+            ),
+            SafeArea(
+              child: Container(
+                height: 68,
+                width: double.infinity,
+                padding: EdgeInsets.fromLTRB(15, 10, 15, 10),
+                child: FlatButton(
+                  color: PRIMARY_COLOR,
+                  child: Text(
+                    '提交',
+                    style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
+                  ),
+                  onPressed: () async {
+                    if (img1 == null || img1.isEmpty) {
+                      Toast.show(context, '请上传历史战绩截图', 1500, 'info');
+                    } else if (img2 == null || img2.isEmpty) {
+                      Toast.show(context, '请上传战绩详情截图', 1500, 'info');
+                    } else {
+                      Toast.show(context, '加载中', -1, 'loading');
+                      final res = await HttpManager.post('appealInfo/save', data: {
+                        'userId': StoreProvider.of<AppState>(context).state.userInfo.id,
+                        'playerInfoId': widget.playerInfo.id,
+                        'competitionId': widget.playerInfo.competitionId,
+                        'houseId': widget.playerInfo.houseId,
+                        'pic': img1 + ',' + img2,
+                      });
+                      Toast.hide();
+                      if (res.success) {
+                        Navigator.of(context).pop(true);
+                      } else {
+                        Toast.show(context, '提交失败,请稍后再试', 1500, 'info');
+                      }
+                    }
+                  },
+                ),
+              ),
+            )
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget imgUpload(String txt, String img, Function(String img) onUploadSuccess) {
+    return GestureDetector(
+      child: img != null && img.isNotEmpty
+          ? Container(
+              height: 111,
+              decoration: BoxDecoration(border: Border.all(width: 1, color: Color(0x5C1990F8)), color: Color(0xFF293354)),
+              child: CachedNetworkImage(
+                imageUrl: img,
+                height: 111,
+                fit: BoxFit.contain,
+              ),
+            )
+          : Container(
+              height: 111,
+              decoration: BoxDecoration(border: Border.all(width: 1, color: Color(0x5C1990F8)), color: Color(0xFF293354)),
+              child: Column(
+                mainAxisSize: MainAxisSize.max,
+                mainAxisAlignment: MainAxisAlignment.center,
+                children: <Widget>[
+                  Image.asset('images/icon_shangchuan.png', width: 34),
+                  Container(
+                    margin: EdgeInsets.only(top: 10),
+                    child: Text(
+                      txt,
+                      style: TextStyle(color: PRIMARY_COLOR, fontSize: 13),
+                    ),
+                  )
+                ],
+              ),
+            ),
+      onTap: () async {
+        File file = await ImagePicker.pickImage(source: ImageSource.gallery, maxWidth: 1000);
+        if (file == null) {
+          return;
+        }
+        Toast.show(context, '加载中', -1, 'loading');
+        Result res = await HttpManager.post('assets/uploadFile', data: {
+          'file': UploadFileInfo(file, file.path),
+        });
+        Toast.hide();
+        print(res.toJson());
+        if (res.success) {
+          onUploadSuccess(res.data[0]);
+        }
+      },
+    );
+  }
+}

+ 19 - 1
lib/pages/Home.dart

@@ -2,6 +2,8 @@ import 'package:cached_network_image/cached_network_image.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:shared_preferences/shared_preferences.dart';
+import 'package:wanna_battle/model/PlayerInfo.dart';
+import 'package:wanna_battle/net/Result.dart';
 import 'package:wanna_battle/styles/totast.dart';
 import './Competitions.dart';
 import '../widget/HomeDrawer.dart';
@@ -12,6 +14,8 @@ import '../styles/colors.dart';
 import '../net/HttpManager.dart';
 import 'AppNotice.dart';
 import 'UserGuid.dart';
+import '../widget/Dialog.dart';
+import 'Appeal.dart';
 
 class HomePage extends StatefulWidget {
   const HomePage({Key key}) : super(key: key);
@@ -48,6 +52,7 @@ class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin
       }
       getAppNotice(context);
       checkUpgrade(context, _dialogKey);
+      checkErrorPlayerInfo();
     });
   }
 
@@ -143,5 +148,18 @@ class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin
     );
   }
 
+  Future<void> checkErrorPlayerInfo() async {
+    final Result res = await HttpManager.get('playerInfo/getErrorPlayerInfo');
+    if (res.success) {
+      final PlayerInfo playerInfo = PlayerInfo.fromJson(res.data);
+      showCustomDialog(
+        context,
+        '由于系统性能安全策略问题导致本次比赛结果上传失败,你可以上传本次比赛结果照片进行结果申诉',
+        isCancel: true,
+        onsubmit: () {
+          Navigator.push(context, CupertinoPageRoute(builder: (context) => Appeal(playerInfo)));
+        },
+      );
+    }
+  }
 }
-

+ 3 - 3
lib/pages/RoomInfo.dart

@@ -108,14 +108,14 @@ class RoomInfoState extends State<RoomInfo> with SingleTickerProviderStateMixin
       success = await ScreenStreamPlugin.start(playerInfo.id.toString());
       if (success) {
         data['statusFlag'] = 2;
-        data['played'] = 1;
+        data['played'] = true;
       } else {
         data['statusFlag'] = 6;
-        data['played'] = 0;
+        data['played'] = false;
       }
     } else {
       data['statusFlag'] = 6;
-      data['played'] = 0;
+      data['played'] = false;
     }
     Result res = await HttpManager.post('playerInfo/update', data: data);
 

+ 3 - 0
lib/pages/RoomInfoNew.dart

@@ -189,11 +189,14 @@ class _RoomInfoState extends State<RoomInfo> with SingleTickerProviderStateMixin
       success = await ScreenStreamPlugin.start(mPlayerInfo.id.toString());
       if (success) {
         data['statusFlag'] = 2;
+        data['played'] = true;
       } else {
         data['statusFlag'] = 6;
+        data['played'] = false;
       }
     } else {
       data['statusFlag'] = 6;
+      data['played'] = false;
     }
     final Result res = await HttpManager.post('playerInfo/update', data: data);
     if (res.success) {

+ 53 - 10
lib/pages/TipInfo.dart

@@ -1,4 +1,7 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_redux/flutter_redux.dart';
+import 'package:wanna_battle/model/AppealInfo.dart';
+import 'package:wanna_battle/redux/AppState.dart';
 import '../styles/colors.dart';
 import 'package:flutter/cupertino.dart';
 import 'dart:ui';
@@ -10,6 +13,7 @@ import '../model/HouseInfo.dart';
 import '../model/GameInfo.dart';
 import '../pages/RoomInfoNew.dart';
 import '../widget/SuccessfulReception.dart';
+import 'Appeal.dart';
 
 class TipInfo extends StatefulWidget {
   TipInfo({Key key, this.notice}) : super(key: key);
@@ -47,6 +51,25 @@ class TipInfoState extends State<TipInfo> {
         });
       }
     });
+
+    if (notice.playerInfo.resultError) {
+      HttpManager.get('appealInfo/getOne', data: {
+        'userId': StoreProvider.of<AppState>(context).state.userInfo.id,
+        'playerInfoId': notice.playerInfo.id,
+      }).then((res) {
+        if (res.success) {
+          setState(() {
+            canAppeal = true;
+            appealState = 1;
+          });
+        } else {
+          setState(() {
+            canAppeal = true;
+            appealState = 0;
+          });
+        }
+      });
+    }
   }
 
   void showSuccess(money) {
@@ -131,6 +154,7 @@ class TipInfoState extends State<TipInfo> {
                     }
                     return Container(
                       margin: EdgeInsets.only(left: 15, right: 15, bottom: 20),
+                      width: double.infinity,
                       child: Text(
                         content,
                         style: TextStyle(color: Color(0x99FFFFFF), fontSize: 13),
@@ -141,16 +165,35 @@ class TipInfoState extends State<TipInfo> {
                 houseInfo != null && type != 3 ? _houseWidget() : Container(),
                 resultWidget(),
                 Expanded(
-                  child: Container(
-                    child: FlatButton(
-                      child: Text(
-                        '申诉结果',
-                        style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
-                      ),
-                      onPressed: () {},
-                    ),
-                  ),
-                )
+                  child: Container(),
+                ),
+                canAppeal
+                    ? SafeArea(
+                        child: Container(
+                          width: double.infinity,
+                          height: 48,
+                          margin: EdgeInsets.only(left: 15, right: 15, bottom: 10),
+                          child: FlatButton(
+                            color: PRIMARY_COLOR,
+                            child: Text(
+                              appealState == 0 ? '申诉结果' : '已提交申诉',
+                              style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
+                            ),
+                            onPressed: () async {
+                              if (appealState == 0) {
+                                final success = await Navigator.push(context, CupertinoPageRoute(builder: (context) => Appeal(notice.playerInfo)));
+                                if (success != null && success) {
+                                  Toast.show(context, '提交成功', 1500, 'success');
+                                  setState(() {
+                                    appealState = 0;
+                                  });
+                                }
+                              }
+                            },
+                          ),
+                        ),
+                      )
+                    : Container(),
                 // CustomPaint(
                 //   painter: CircleProgressBarPainter(
                 //       Color(0xFFDCA659), Color(0xFFAE4945), 0.0, 270.0, 360.0, 18.0),

+ 8 - 1
pubspec.lock

@@ -175,7 +175,7 @@ packages:
       name: file_picker
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.3.6"
+    version: "1.3.7"
   fixnum:
     dependency: transitive
     description:
@@ -317,6 +317,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "1.0.2"
+  image_picker:
+    dependency: "direct main"
+    description:
+      name: image_picker
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.6.0+10"
   install_plugin:
     dependency: "direct main"
     description:

+ 3 - 2
pubspec.yaml

@@ -1,7 +1,7 @@
 name: wanna_battle
 description: A new Flutter project.
 
-version: 1.0.1+4
+version: 1.0.2+5
 
 environment:
   sdk: ">=2.1.0 <3.0.0"
@@ -23,7 +23,7 @@ dependencies:
   redux_persist_flutter: ^0.8.0
   flutter_picker: ^1.0.9
   intl: "^0.15.6"
-  file_picker: ^1.3.1
+  file_picker: ^1.3.7
   json_serializable: ^2.0.2
   shared_preferences: ^0.5.1
   package_info: ^0.4.0
@@ -45,6 +45,7 @@ dependencies:
   open_file: ^2.0.3
   permission_handler: ^3.1.0
   battery: ^0.3.0+4
+  image_picker: ^0.6.0+4
 
 dev_dependencies:
   build_runner: ^1.1.1