Перенес хранение информации о сессии (токен, din, posid) в базу данных
This commit is contained in:
@@ -25,7 +25,7 @@ faq(BuildContext context, bool returnToScanner) {
|
||||
|
||||
// В методе отправляется запрос на удаление токена кассы, очищаются SharedPreferences приложения.
|
||||
logout(BuildContext context) async {
|
||||
String token = await platform.invokeMethod('getToken');
|
||||
String token = await sqliteHelper.getToken();
|
||||
VoidCallback positiveCalback = () {
|
||||
if (token != null) {
|
||||
deleteToken(token).then((response) {
|
||||
@@ -48,7 +48,7 @@ logout(BuildContext context) async {
|
||||
}
|
||||
|
||||
forceLogout(BuildContext context) async {
|
||||
String token = await platform.invokeMethod('getToken');
|
||||
String token = await sqliteHelper.getToken();
|
||||
deleteToken(token).then((response) {
|
||||
print(response.body);
|
||||
platform.invokeMethod('removeKeys').then((result) {
|
||||
@@ -64,9 +64,9 @@ forceLogout(BuildContext context) async {
|
||||
/// Может производиться с нескольких экранов (splash, finish_registration).
|
||||
startScanner(BuildContext context) async {
|
||||
|
||||
String token = await platform.invokeMethod('getToken');
|
||||
String token = await sqliteHelper.getToken();
|
||||
// Канал ловит вызовы методов из "нативной" части приложения.
|
||||
// Могут быть вызваны либо logaut либо faq, либо purchase.
|
||||
// Могут быть вызваны либо logout либо faq, либо purchase.
|
||||
if (token != null) {
|
||||
platform.setMethodCallHandler((MethodCall call) async {
|
||||
|
||||
|
||||
82
lib/db.dart
Normal file
82
lib/db.dart
Normal file
@@ -0,0 +1,82 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path/path.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
const String tableSession = "session";
|
||||
const String columnMerchantID = "merchant_id"; // DIN code, который вводится при авторизации
|
||||
const String columnToken = "token"; // Токен для pos. Приходит с бэкэнда.
|
||||
const String columnPosID = "pos_id"; // идентификатор для создания токена на бэке.
|
||||
const String columnDocID = "doc_id"; // идентификатор, для проведения покупки на бэкенде.
|
||||
|
||||
//{
|
||||
// columnMerchantID: merchantID,
|
||||
// columnToken: token,
|
||||
// columnPosID: posID,
|
||||
// columnDocID: docID
|
||||
//}
|
||||
|
||||
/// База данных, для хранения временных данных (din, token, locale, etc.)
|
||||
class SqliteHelper {
|
||||
|
||||
Database db;
|
||||
|
||||
Future open() async {
|
||||
Directory documentsDirectory = await getApplicationDocumentsDirectory();
|
||||
String path = join(documentsDirectory.path, "demo.db");
|
||||
db = await openDatabase(path, version: 1,
|
||||
onCreate: (Database db, int version) async {
|
||||
await db.execute('''create table session (
|
||||
$columnMerchantID text primary key,
|
||||
$columnToken text,
|
||||
$columnPosID text,
|
||||
$columnDocID integer)''');
|
||||
});
|
||||
}
|
||||
|
||||
Future insert(String merchantID, String posID, String token) async {
|
||||
|
||||
Map session = {
|
||||
columnMerchantID: merchantID,
|
||||
columnPosID: posID,
|
||||
columnToken: token
|
||||
};
|
||||
|
||||
return db.insert(tableSession, session);
|
||||
}
|
||||
|
||||
Future<String> getToken() async {
|
||||
Map session = await _getSession();
|
||||
return session != null ? session[columnToken] : null;
|
||||
}
|
||||
|
||||
Future<String> getMerchantID() async {
|
||||
Map session = await _getSession();
|
||||
return session != null ? session[columnMerchantID] : null;
|
||||
}
|
||||
|
||||
Future<String> getPosID() async {
|
||||
Map session = await _getSession();
|
||||
return session != null ? session[columnPosID] : new DateTime.now().millisecondsSinceEpoch.toString();
|
||||
}
|
||||
|
||||
Future<Map> _getSession() async {
|
||||
|
||||
List<Map> maps = await db.query(tableSession, columns: null);
|
||||
|
||||
if (maps.length > 0) {
|
||||
return maps.first;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Future clear() async {
|
||||
return await db.delete(tableSession, where: null);
|
||||
}
|
||||
|
||||
Future close() async => db.close();
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:checker/db.dart';
|
||||
import 'dart:convert'; // Пакет для обработки json с ответом от сервера.
|
||||
|
||||
import 'package:checker/common.dart';
|
||||
@@ -14,12 +15,22 @@ class FinishRegistrationScreen extends StatefulWidget {
|
||||
|
||||
class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
|
||||
|
||||
SqliteHelper helper;
|
||||
|
||||
bool _tokenActive = false;
|
||||
String _merchantID = '';
|
||||
|
||||
_RegistrationScreenState() {
|
||||
helper = new SqliteHelper();
|
||||
if (textFieldValue == "") {
|
||||
getSavedMerchantID();
|
||||
helper.open().then((_){
|
||||
helper.getMerchantID().then((result) {
|
||||
setState(() {
|
||||
_merchantID = result;
|
||||
print('merchanID: ${_merchantID}');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,10 +58,11 @@ class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
|
||||
// Если нет, то отправляется запрос на проверку статуса токена.
|
||||
handleTap() async {
|
||||
if (_tokenActive) {
|
||||
helper.close();
|
||||
startScanner(context);
|
||||
} else {
|
||||
if (await platform.invokeMethod('isOnline')) {
|
||||
String token = await platform.invokeMethod('getToken');
|
||||
String token = await helper.getToken();
|
||||
checkTokenStatus(token).then((response) {
|
||||
|
||||
print(response.body);
|
||||
@@ -74,16 +86,6 @@ class _RegistrationScreenState extends BaseState<FinishRegistrationScreen> {
|
||||
style: new TextStyle(color: Colors.black, fontSize: 16.0))]);
|
||||
}
|
||||
|
||||
/// Достаем сохраненный в SharedPreferences merchantID.
|
||||
getSavedMerchantID() {
|
||||
platform.invokeMethod('getMerchantID').then((result) {
|
||||
setState(() {
|
||||
_merchantID = result;
|
||||
print('merchanID: ${_merchantID}');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Метод возвращает контейнер с текстом сообщения и бэкграундом.
|
||||
getMessage() {
|
||||
return new Container(height: _tokenActive ? 72.0 : 108.0, decoration: _getDecorationForMessageField(),
|
||||
|
||||
@@ -108,7 +108,7 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
||||
|
||||
if (await platform.invokeMethod('isOnline')) {
|
||||
|
||||
String token = await platform.invokeMethod('getToken');
|
||||
String token = await sqliteHelper.getToken();
|
||||
|
||||
var headers = {
|
||||
'DM-Authorization': 'dmapptoken $appToken',
|
||||
@@ -198,7 +198,7 @@ class PurchaseScreenState<T> extends BaseState<PurchaseScreen> {
|
||||
if (!purchaseInProgress) {
|
||||
purchaseInProgress = true;
|
||||
|
||||
String token = await platform.invokeMethod('getToken');
|
||||
String token = await sqliteHelper.getToken();
|
||||
platform.invokeMethod('getDocID').then((result) {
|
||||
|
||||
String url = user['purchases_url'];
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:checker/db.dart';
|
||||
import 'package:checker/finish_registration.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:convert'; // Пакет для обработки json с ответом от сервера.
|
||||
@@ -70,7 +71,12 @@ class _RegistrationScreenState extends BaseState<RegistrationScreen> {
|
||||
/// Получение от платформы id установки, формирование запроса на получение токена, сохранение токена.
|
||||
_register() async {
|
||||
if (await platform.invokeMethod('isOnline')) {
|
||||
createToken(textFieldValue, await platform.invokeMethod('getPosID')).then((response) {
|
||||
|
||||
SqliteHelper helper = new SqliteHelper();
|
||||
await helper.open();
|
||||
String posID = await helper.getPosID();
|
||||
|
||||
createToken(textFieldValue, posID).then((response) {
|
||||
|
||||
setState(() {
|
||||
error = null;
|
||||
@@ -80,17 +86,19 @@ class _RegistrationScreenState extends BaseState<RegistrationScreen> {
|
||||
print(response.body);
|
||||
|
||||
Map parsedMap = JSON.decode(response.body);
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
String token = parsedMap['token'];
|
||||
platform.invokeMethod('saveToken', {'token' : token});
|
||||
platform.invokeMethod('saveMerchantID', {'merchantID' : textFieldValue});
|
||||
helper.insert(textFieldValue, posID, parsedMap['token']);
|
||||
helper.close();
|
||||
pushRoute(context, new FinishRegistrationScreen());
|
||||
} else {
|
||||
helper.close();
|
||||
setState(() {
|
||||
error = parsedMap['errors'][0];
|
||||
});
|
||||
}
|
||||
}).catchError((error) {
|
||||
helper.close();
|
||||
print(error.toString());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import 'dart:async';
|
||||
@@ -9,7 +10,7 @@ import 'network.dart';
|
||||
import 'consts.dart';
|
||||
import 'registration.dart';
|
||||
import 'finish_registration.dart';
|
||||
import 'strings.dart';
|
||||
import 'db.dart';
|
||||
|
||||
class SplashScreen extends StatelessWidget {
|
||||
|
||||
@@ -18,7 +19,7 @@ class SplashScreen extends StatelessWidget {
|
||||
// Появляется splash screen, проверяется токен.
|
||||
|
||||
new Future.delayed(const Duration(milliseconds: 500), () {
|
||||
platform.invokeMethod("getLocale").then((locale) {
|
||||
platform.invokeMethod('getLocale').then((locale) {
|
||||
Intl.defaultLocale = locale;
|
||||
print(Intl.defaultLocale);
|
||||
showNextScreen(context);
|
||||
@@ -49,19 +50,24 @@ class SplashScreen extends StatelessWidget {
|
||||
/// Запуск следующего экрана приложения.
|
||||
showNextScreen(BuildContext context) async {
|
||||
|
||||
String token = await platform.invokeMethod('getToken');
|
||||
|
||||
SqliteHelper helper = new SqliteHelper();
|
||||
await helper.open();
|
||||
String token = await helper.getToken();
|
||||
|
||||
// В случае, если в приложении отсутствует токен,
|
||||
// необходимо запустить регистрацию кассы.
|
||||
if (token == null) {
|
||||
await helper.close();
|
||||
pushRoute(context, new RegistrationScreen());
|
||||
} else {
|
||||
if (await platform.invokeMethod('isOnline')) {
|
||||
checkTokenStatus(token).then((statusResponse) {
|
||||
handleStatusResponse(context, statusResponse);
|
||||
handleStatusResponse(context, statusResponse, helper);
|
||||
}).catchError((error) {
|
||||
print(error.toString());
|
||||
return false;
|
||||
helper.close().then((_) {
|
||||
print(error.toString());
|
||||
return false;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -70,14 +76,15 @@ class SplashScreen extends StatelessWidget {
|
||||
/// Обработка ответа.
|
||||
/// В случае, если токен был удален может прийти active: false, либо 404.
|
||||
/// Если токен не активен, попробовать создать его еще раз.
|
||||
handleStatusResponse(BuildContext context, var statusResponse) async {
|
||||
handleStatusResponse(BuildContext context, var statusResponse, SqliteHelper helper) async {
|
||||
int code = statusResponse.statusCode;
|
||||
print('resp: ${code}');
|
||||
|
||||
if (code == 404) {
|
||||
platform.invokeMethod('removeKeys').then((result) {
|
||||
print('try to start registration');
|
||||
pushRoute(context, new RegistrationScreen());
|
||||
helper.clear().then((result) {
|
||||
helper.close().then((_) {
|
||||
pushRoute(context, new RegistrationScreen());
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -88,7 +95,7 @@ class SplashScreen extends StatelessWidget {
|
||||
startScanner(context);
|
||||
} else {
|
||||
if (await platform.invokeMethod('isOnline')) {
|
||||
_createToken(context);
|
||||
_createToken(context, helper);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,24 +108,34 @@ class SplashScreen extends StatelessWidget {
|
||||
///
|
||||
/// Если вернулся код 200, значит токен был ранее удален и только что снова создался.
|
||||
/// Нужно удалить его и направить пользователя на экран регистрации.
|
||||
_createToken(BuildContext ctx) async {
|
||||
String merchantID = await platform.invokeMethod('getMerchantID');
|
||||
String posID = await platform.invokeMethod('getPosID');
|
||||
_createToken(BuildContext ctx, SqliteHelper helper) async {
|
||||
|
||||
String merchantID = await helper.getMerchantID();
|
||||
String posID = await helper.getPosID();
|
||||
|
||||
createToken(merchantID, posID).then((response) {
|
||||
if (response.statusCode == 409) {
|
||||
helper.close();
|
||||
pushRoute(ctx, new FinishRegistrationScreen());
|
||||
} else if (response.statusCode == 201) {
|
||||
platform.invokeMethod('removeKeys').then((result) {
|
||||
Map parsedMap = JSON.decode(result);
|
||||
deleteToken(parsedMap['token']).then((response) {
|
||||
print(response.body);
|
||||
Navigator.of(ctx).pop(); // Убираем текущий route
|
||||
pushRoute(ctx, new RegistrationScreen()); // Запускаем регистрацию
|
||||
}).catchError((error) {
|
||||
print(error.toString());
|
||||
});
|
||||
});
|
||||
clearToken(response, ctx, helper);
|
||||
}
|
||||
}).catchError((error) => print(error.toString()));
|
||||
}
|
||||
|
||||
/// Очищаем бд, делаем запрос на удаление токена.
|
||||
void clearToken(Response response, BuildContext ctx, SqliteHelper helper) {
|
||||
|
||||
helper.clear().then((_) {
|
||||
Map parsedMap = JSON.decode(response.body);
|
||||
deleteToken(parsedMap['token']).then((_) {
|
||||
helper.close();
|
||||
Navigator.of(ctx).pop(); // Убираем текущий route
|
||||
pushRoute(ctx, new RegistrationScreen()); // Запускаем регистрацию
|
||||
}).catchError((error) {
|
||||
helper.close();
|
||||
print(error.toString());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user