import 'dart:async'; import 'dart:convert'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:logging/logging.dart'; import 'package:fcs/util.dart'; import 'package:fcs/vo/popup_menu.dart'; import 'package:fcs/vo/role.dart'; import '../config.dart'; import '../vo/user.dart'; import 'base_model.dart'; import 'constants.dart'; import 'firebase_helper.dart'; class UserModel extends BaseModel { final log = Logger('UserModel'); StreamSubscription listener; PopupMenu popupMenu = new PopupMenu(); List users = []; List privileges = []; List userLevels = []; User user = new User(); List get getPrivileges { return privileges .where((p) => !p.sysAdminOnly || user.isSysAdmin()) .toList(); } List cont = []; void initUser(user) async { super.initUser(user); this.user = user; if (user.isBuyer()) return; _loadUsers(user); _loadPrivileges(); _loadUserLevels(user); } @override logout() async { users = []; userLevels = []; } List getUserPrivileges() { List result = new List(); if (user.privilegeIds.isNotEmpty) { user.privilegeIds.forEach((pID) { privileges.forEach((p) { if (p.id == pID) { var _priv = Privilege(id: p.id, name: p.name, desc: p.desc); result.add(_priv); } }); }); } return result; } List getBlockListUsers() { return users.where((u) => u.isBlock == true).toList(); } List getUserList() { return users.where((u) => u.docID != this.user.docID).toList(); } Future _loadUsers(User user) async { try { String path = "/$biz_collection/${setting.okEnergyId}/$user_collection"; var snaps = await Firestore.instance .collection(path) .where('user_level', isLessThanOrEqualTo: user.userLevel) .limit(1) .getDocuments(); Stream snapshots = Firestore.instance .collection(path) .where('user_level', isLessThanOrEqualTo: user.userLevel) .snapshots(); snapshots.listen((snaps) async { users = snaps.documents.map((documentSnapshot) { var data = User.fromMap(documentSnapshot.data, documentSnapshot.documentID); if (data.docID == user.docID && data.isBlock) { this.mainModel.logout(); notifyListeners(); } return data; }).toList(); notifyListeners(); }); } catch (e) { log.warning("Error!! $e"); } } Future findUser(String phoneNumber) async { var _phoneNumber = updatePhoneNumber(phoneNumber); try { var data = await request("/user/find/$_phoneNumber", "GET", token: await getToken()); return User.fromJson(data); } catch (e) { throw Exception(e); } } Future _loadPrivileges() async { // if (!user.isOwner() && !user.hasAccount()) { // return; // } try { getQuerySnapshot("/$privilege_collection") .listen((QuerySnapshot snapshot) { privileges.clear(); privileges = snapshot.documents.map((documentSnapshot) { var privilege = Privilege.fromMap( documentSnapshot.data, documentSnapshot.documentID); return privilege; }).toList(); notifyListeners(); }).onError((e) { log.warning("Error! $e"); }); } catch (e) { log.warning("Error!! $e"); } } Future _loadUserLevels(User user) async { try { Stream snapshots = Firestore.instance .collection("/$user_level_collection") .where('level', isLessThan: user.userLevel) .snapshots(); snapshots.listen((snaps) async { userLevels = snaps.documents .map((documentSnapshot) => UserLevel.fromMap( documentSnapshot.data, documentSnapshot.documentID)) .toList(); notifyListeners(); }); } catch (e) { log.warning("Error!! $e"); } } Future getUser(String id) async { String path = "/$biz_collection/${setting.okEnergyId}/$user_collection"; print("id=> $id"); var snap = await getDocSnap(path, id); print("snap=> $snap"); return User.fromMap(snap.data, snap.documentID); } Future addUserToOk(String userID, List privileges) async { await addUserToBiz(userID, setting.okEnergyId, privileges); } Future addUserToBiz( String userID, bizID, List privileges) async { try { await request("/user/add-biz", "POST", payload: { "user_id": userID, "biz_id": bizID, "privileges": privileges }, token: await getToken()); } catch (e) { throw Exception(e); } } Future forgetPassword(String id) async { var _id = updatePhoneNumber(id); await request("/forget", "POST", payload: {"id": _id}); } Future resetPassword( String id, String newPassword, String confirmationCode) async { var _id = updatePhoneNumber(id); await request( "/reset", "POST", payload: { "id": _id, "password": newPassword, "confirmation_code": confirmationCode }, ); } Future changePassword(String id, String newPassword) async { await request( "/change/password", "POST", payload: { "id": id, "password": newPassword, }, ); } Future changePhone(String id, String newPhone) async { var _newPhone = updatePhoneNumber(newPhone); await request( "/change/phone", "POST", payload: { "id": id, "phone_number": _newPhone, }, ); } Future addEmail(String id, String email) async { await request( "/email", "PUT", payload: { "id": id, "email": email, }, ); } Future confirmEmail( String id, String email, String phone, String confirmCode) async { var _id = updatePhoneNumber(id); var _phone = updatePhoneNumber(phone); await request( "/econfirm", "POST", payload: { "id": _id, "email": email == null ? '' : email, "phone_number": _phone == null ? '' : _phone, "confirmation_code": confirmCode }, ); } Future deleteStorage(String storageID) async { await request("/storage/" + storageID, "DELETE", token: await getToken()); } Future blockPhone(String phone) async { var _phone = updatePhoneNumber(phone); await request("/blist", "PUT", payload: {"phone_number": _phone}, token: await getToken()); } Future unblockPhone(String phone) async { var _phone = updatePhoneNumber(phone); await request("/wlist", "PUT", payload: {"phone_number": _phone}, token: await getToken()); } Future addLevel( String phone, String levelId, List privs) async { var _phone = updatePhoneNumber(phone); await request("/lvl", "PUT", payload: { "phone_number": _phone, "user_level_id": levelId, "privileges": privs }, token: await getToken()); } Future updatePin(String pin, String password) async { await request("/pin", "POST", payload: { "id": user.docID, "pin": pin, "password": password, }, token: await getToken()); } Future clearPin(String password) async { await request("/pin/clear", "POST", payload: { "id": user.docID, "password": password, }, token: await getToken()); } Future> searchUser(String searchUser) async { if (searchUser == null || searchUser == '') return List(); var bytes = utf8.encode(searchUser); var base64Str = base64.encode(bytes); HtmlEscape htmlEscape = const HtmlEscape(); String escapeUser = htmlEscape.convert(base64Str); int limit = 20; List _users = []; try { var data = await request( "/api/fts/$user_collection/$escapeUser/$limit", "GET", token: await getToken(), url: Config.instance.reportURL); if (data == null) return List(); data.forEach((user) { var _user = User.fromUserJson(user); _users.add(_user); }); } catch (e) { // permission error log.warning("user error:" + e.toString()); return null; } return _users; } void filterSorting(int _selectedIndex) { users.clear(); if (listener != null) { listener.cancel(); } String _fieldName; bool descending = false; if (_selectedIndex == 0) { _fieldName = 'user_name'; descending = false; } if (_selectedIndex == 1) { _fieldName = 'user_name'; descending = true; } if (_selectedIndex == 2) { _fieldName = 'phone_number'; descending = false; } if (_selectedIndex == 3) { _fieldName = 'phone_number'; descending = true; } this.popupMenu.index = _selectedIndex; String path = "/$biz_collection/${setting.okEnergyId}/$user_collection"; listener = getFilterSnapshot(path, descending, _fieldName).listen((snaps) async { users.clear(); snaps.documents.forEach((d) { users.add(User.fromMap(d.data, d.documentID)); notifyListeners(); }); users.where((user) => user.userLevel <= this.user.userLevel); notifyListeners(); }); } }