Flutter: скроллинг до элемента в списке

Задача: позиционировать по нажатию кнопки список на нужном элементе списка.

Решение: используем пакет scroll_to_index:

dependencies:
  scroll_to_index : any

Код:

class _MainMenuState extends State<MainMenu> {
  final scaffoldKey = GlobalKey<ScaffoldState>();

  final scrollDirection = Axis.vertical;
  late AutoScrollController controller;

  @override
  void initState() {
    print("-инициализация класса..");
    controller = AutoScrollController(
        viewportBoundaryGetter: () =>
            Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
            suggestedRowHeight: 2000, // если большой список, и  скролл визуально идёт медленно, то это "шаг" скролла. Т.е. чем больше, тем быстрее.
            axis: scrollDirection
    );
  }

  Future _scrollToCounter(int counter) async {

    await controller.scrollToIndex(counter, duration: Duration(seconds: 1));
    controller.highlight(counter);
  }
....
...
      // список ТМЦ для инвентаризации (если есть)
      body: ListView.builder(
          physics: NeverScrollableScrollPhysics(),
          scrollDirection: scrollDirection,
          controller: controller,
          padding: const EdgeInsets.all(8),
          itemCount: globals.TMCList.length,
          itemBuilder: (BuildContext context, int index) {
            return AutoScrollTag(
              key: ValueKey(index),
              controller: controller,
              index: index,
              child: Container(
                  padding: EdgeInsets.symmetric(vertical: 10),
                  child: Column(
                    children: [
                      Text(
                        globals.TMCList[index]["name"],
                        textAlign: TextAlign.start,
                      ),
                      Align(
.....
        floatingActionButton: FloatingActionButton(
          onPressed: (){
_scrollToCounter(10);
          },

Node.js: POST запрос с авторизацией по HTTP

Задача: передать данные через POST на ресурс по протоколу https с авторизацией.

Решение:

const https = require('https');
function SendJson2Https(data){
    const options = {
      hostname: 'vqrcfwervcwe1',
      port: 443,
      path: '/owprfhwoeir/command',
      method: 'POST',
      rejectUnauthorized: false,
      strictSSL: false,
      headers: {
        "Authorization":"Basic " + new Buffer.from('Admin' + ":" + 'qrwecvwervwe').toString('base64'),          
        'Content-Type': 'application/json',
        'Content-Length': data.length
      }
    }
    const req = https.request(options, (res) => {
      console.log(statusCode: ${res.statusCode})
      res.on('data', (d) => {
        process.stdout.write(d)
      })
    })
    req.on('error', (error) => {
      console.error(error)
    })
    req.write(data)
    req.end()    
};

Пути и папки в Android

1) Системные папки

⚠️ Писать сюда никак нельзя

MethodResult
Environment.getDataDirectory()/data
Environment.getDownloadCacheDirectory()/cache
Environment.getRootDirectory()/system

2) Внешнее хранилище

⚠️ Нужны права WRITE_EXTERNAL_STORAGE

MethodResult
Environment.getExternalStorageDirectory()/storage/sdcard0
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_ALARMS)/storage/sdcard0/Alarms
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)/storage/sdcard0/DCIM
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)/storage/sdcard0/Download
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)/storage/sdcard0/Movies
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)/storage/sdcard0/Music
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_NOTIFICATIONS)/storage/sdcard0/Notifications
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)/storage/sdcard0/Pictures
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PODCASTS)/storage/sdcard0/Podcasts
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES)/storage/sdcard0/Ringtones

3) Папки приложения

MethodResult
getCacheDir()/data/data/package/cache
getFilesDir()/data/data/package/files
getFilesDir().getParent()/data/data/package

4) Папки приложения на внешнем носителе

MethodResult
getExternalCacheDir()/storage/sdcard0/Android/data/package/cache
getExternalFilesDir(null)/storage/sdcard0/Android/data/package/files
getExternalFilesDir(Environment.DIRECTORY_ALARMS)/storage/sdcard0/Android/data/package/files/Alarms
getExternalFilesDir(Environment.DIRECTORY_DCIM)/storage/sdcard0/Android/data/package/files/DCIM
getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)/storage/sdcard0/Android/data/package/files/Download
getExternalFilesDir(Environment.DIRECTORY_MOVIES)/storage/sdcard0/Android/data/package/files/Movies
getExternalFilesDir(Environment.DIRECTORY_MUSIC)/storage/sdcard0/Android/data/package/files/Music
getExternalFilesDir(Environment.DIRECTORY_NOTIFICATIONS)/storage/sdcard0/Android/data/package/files/Notifications
getExternalFilesDir(Environment.DIRECTORY_PICTURES)/storage/sdcard0/Android/data/package/files/Pictures
getExternalFilesDir(Environment.DIRECTORY_PODCASTS)/storage/sdcard0/Android/data/package/files/Podcasts
getExternalFilesDir(Environment.DIRECTORY_RINGTONES)/storage/sdcard0/Android/data/package/files/Ringtones

1С: проверка пароля пользователя

Задача: проверить соответствие имени пользователю, введённый им пароль. Пользователи хранятся в стандартном справочнике «Пользователи»

Решение: в 1С нет штатных методов проверки пароля, т.к. пароль как таковой не хранится, а хранится его хэш. Следовательно для того чтобы проверить введенный пароль, необходимо сравнить «старый» хэш с хэшэм введеного пароля. Но есть нюанс — никто не знает по какому алгоритму генерируется хэш при сохранении пароля. Следовательно подходит лишь один алгоритм:

  1. Получаем хэш текущего пароля
  2. Начинаем транзакцию
  3. Сохраняем введеный пароль пароль у пользователя
  4. Получаем хэш введенного пароля
  5. Отменяем транзакцию (тем самым отменяем изменения у пользователя)
  6. Сравниваем первый хэш со вторым. Если равны — значит пароль соответствует.

Воплощение:

// Функция по входящим body.login и body.password выдает или error=true
// или возращает полное имя, уникальный идентификатор и список доступных для проведения инвентаризации документов
Функция Auth(body)
    answer = Новый Структура("error, result",false,"");		
    ПользовательИнформационнойБазы = ПользователиИнформационнойБазы.НайтиПоИмени(body.login);
	Если ПользовательИнформационнойБазы = Неопределено Тогда
    	answer.error=true;
		answer.result="Пользователь не найден в БД";
		возврат answer;
	Иначе
			ХэшНастоящегоПароля = ПользовательИнформационнойБазы.СохраняемоеЗначениеПароля;
			НачатьТранзакцию();		    
		    ПользовательИнформационнойБазы.Пароль = body.password;
		    ПользовательИнформационнойБазы.Записать();		    
		    ХешВведенногоПароля = ПользователиИнформационнойБазы.НайтиПоИмени(body.login).СохраняемоеЗначениеПароля;
		    ОтменитьТранзакцию();
		                                      
		    Если ХешВведенногоПароля = ХэшНастоящегоПароля Тогда
		        answer.error=false;
				answer.result=Новый Структура("UserName,UserId,MyInvent",ПользовательИнформационнойБазы.ПолноеИмя,ПользовательИнформационнойБазы.УникальныйИдентификатор,Новый Массив());
		    Иначе
				answer.error=true;
				answer.result="Не верный пароль пользователя";
				возврат answer;
		    КонецЕсли;	
	конецесли;
 возврат answer;                   
КонецФункции	

Flutter: уведомления

Для Flutter существуют несколько пакетов для отображения уведомлений. Я использую flutter_easyloading, т.к. в нём по мимо собственно различного вида уведомлений, добавлена и анимация прогресбара. Который можно например использовать при загрузке сетевых запросов.

Установка в pubspec.yaml:

dependencies:
  flutter_easyloading: ^3.0.5

Пример использования:

import 'package:flutter_easyloading/flutter_easyloading.dart';
...

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        builder: EasyLoading.init(),
....
                        onPressed: (){
                          EasyLoading.show(status: 'loading...');
                          http.post(Uri.parse('https://кацукацуhp'),body: {'login':_controller1.text,'password':_controller2.text}).then((response) {
....
EasyLoading.dismiss();

Есть и некая кастомизация:

void configLoading() {
  EasyLoading.instance
    ..displayDuration = const Duration(milliseconds: 2000)
    ..indicatorType = EasyLoadingIndicatorType.fadingCircle
    ..loadingStyle = EasyLoadingStyle.dark
    ..indicatorSize = 45.0
    ..radius = 10.0
    ..progressColor = Colors.yellow
    ..backgroundColor = Colors.green
    ..indicatorColor = Colors.yellow
    ..textColor = Colors.yellow
    ..maskColor = Colors.blue.withOpacity(0.5)
    ..userInteractions = true
    ..dismissOnTap = false
    ..customAnimation = CustomAnimation();
}

1 66 67 68 69 70 310