lentryd / NetSchoolApi

Асинхронный API-враппер для 'Сетевой Город. Образование' на Node.js.
https://lentryd.su/NetSchoolApi/
MIT License
23 stars 1 forks source link

Запрос информации за прошлые учебные года #9

Closed agran closed 1 year ago

agran commented 1 year ago

Здравствуйте!

const classRes = await user.fetch("/webapi/classes?expand=chiefs");
var classes = $.parseJSON(await classRes.text());

Этим кодом я могу получить список классов и их id. Но как мне можно получить список классов за прошлые года?

p.s. И хотелось бы иметь возможность запрашивать отчёты через user.reportFile для прошлых лет.

lentryd commented 1 year ago

Привет!

И хотелось бы иметь возможность запрашивать отчёты через user.reportFile для прошлых лет.

Чтобы получать информацию за прошлые года необходимо в настройках сетевого выбрать требуемый год.

image
agran commented 1 year ago

Мне хотелось бы иметь такую возможность через эту библиотеку. Мне надо получать данные сразу за разные года.

lentryd commented 1 year ago

Хм, я попробую добавить функцию изменения настроек. Однако я не знаю, как быстро это произойдет.

lentryd commented 1 year ago

Можешь немного рассказать для каких целей тебе это необходимо? Чтобы я знал как лучше всего реализовать это все.

agran commented 1 year ago

Хочу получить список всех классов с их id за все года, а потом делать запросы к "[Отчеты] Табель успеваемости учащегося" с указанием id классов и так скачать все четверные оценки для всех учеников школы за все года. А потом уже обрабатывать эти данные для составления отчётов для руководства нашей школы.

agran commented 1 year ago

Кстати, если интересно уже сейчас с использованием этой библиотеки выгружаю данные по оценкам за последние несколько недель и вывожу таблицу с рейтингом классов на информационные табло в нашей школе. И также рейтинг по четвертным оценкам. Снимок экрана 2023-03-29 111338 2 Снимок экрана 2023-03-29 111319 1

lentryd commented 1 year ago

Хочу получить список всех классов с их id за все года, а потом делать запросы к "[Отчеты] Табель успеваемости учащегося" с указанием id классов и так скачать все четверные оценки для всех учеников школы за все года. А потом уже обрабатывать эти данные для составления отчётов для руководства нашей школы.

Правильно ли я понимаю, что у тебя есть доступ к аккаунтам разных учеников?

agran commented 1 year ago

Я администратор, доступ есть ко всей информации по нашей школе.

lentryd commented 1 year ago

Понял, посмотрю что можно будет сделать

lentryd commented 1 year ago

В версии 1.8.2-0 появилась возможность получать отчеты за разные года.

npm i netschoolapi@1.8.2-0

Приведенный ниже код позволяет вам получить список классов за все годы и получать отчеты по ним

 // Получаем список годов
  const yearList = await user
    .fetch("/webapi/mysettings/yearlist")
    .then((res) => res.json());

  // Получаем список классов (для каждого года)
  const classList = [];
  for (let i = 0; i < yearList.length; i++) {
    const yearId = yearList[i].id;

    // Меняем текущий год
    await user.fetch(`/webapi/context/year`, {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: "=" + yearId,
    });

    // Получаем список классов
    const list = await user
      .fetch("/webapi/classes?expand=chiefs")
      .then((res) => res.json());

    classList.push({ yearId, list });
  }

  // Получаем отчеты
  for (let i = 0; i < classList.length; i++) {
    const { yearId, list } = classList[i];

    for (let j = 0; j < list.length; j++) {
      const classId = list[j].id;
      const report = await user.reportFile({
        url: "reports/studenttotal/queue",
        yearId,
        filters: [
          // Другие фильтры
          { filterId: "PCLID", filterValue: classId },
        ],
      });
    }
  }
agran commented 1 year ago

Супер! Спасибо! Я сам почти такие же изменения пытался внести в библиотеку, но сходу не получилось.

agran commented 1 year ago

Попытался использовать новые функции, но не хватает возможности получить по id класса список всех учеников класса с их именами и id.

Должно быть что-то подобное, но не срабатывает.

const ucheniki = await user.reportFile({
    url: "reports/studentaveragemark/initfilters",
    yearId,
    filters: [
        {
            filterId: "PCLID",
            filterValue: classId
        }       
    ],
});
lentryd commented 1 year ago

Привет. Т.к. ты администратор, то некоторых методов у нас нет, поэтому скинь скрин запроса

Что-то подобное

agran commented 1 year ago

При запросе отчёта "Табель успеваемости учащегося" https://sgo.rso23.ru/angular/school/reports/studenttotalmarks Идёт такое обращение с нужным ответом. Снимок экрана 2023-04-05 113527 Снимок экрана 2023-04-05 113403 Снимок экрана 2023-04-05 113423

agran commented 1 year ago

Если делаю такой запрос

    try {
        const ucheniksList = await user.reportFile({
            url: "reports/studenttotalmarks/initfilters",
            yearId,
            filters: [
                {
                    filterId: "PCLID",
                    filterValue: classId
                },
                {
                    filterId: "SEPTYPE",
                    filterValue: "1"
                }       
            ],

        });
    } catch (err) {
        console.log(JSON.stringify(err));
    }           
    console.log(ucheniksList);

То на этом месте программа просто без выдачи ошибки перестаёт работать.

lentryd commented 1 year ago

При запросе отчёта "Табель успеваемости учащегося" https://sgo.rso23.ru/angular/school/reports/studenttotalmarks

Оооо, Краснодарский край

lentryd commented 1 year ago

При запросе отчёта "Табель успеваемости учащегося" https://sgo.rso23.ru/angular/school/reports/studenttotalmarks Снимок экрана 2023-04-05 113423

Возможно библиотека не возвращает данные из-за свойства params. Обычно он имеет такое значение

const params = [
    { name: "DATEFORMAT", value: context.server.dateFormat },
    { name: "SCHOOLYEARID", value: yearId ? yearId : context.year.id },
    { name: "SERVERTIMEZONE", value: 3 },
    { name: "FULLSCHOOLNAME", value: context.school.fullName },
]

Однако в вашем запросе null, есть небольшая вероятность, что из-за этого сервер не возвращает данные

p.s. Еще нет возможности полностью изменить значение params, но ты можешь вручную изменить код библиотеки (для тестов), который находится в файле ./node_modules/netschoolapi/dist/methods/reportFile.js 24:24

lentryd commented 1 year ago

При запросе отчёта "Табель успеваемости учащегося" https://sgo.rso23.ru/angular/school/reports/studenttotalmarks Идёт такое обращение с нужным ответом. Снимок экрана 2023-04-05 113527

Это такой отчет? Обычно в сетевом все отчеты в html

lentryd commented 1 year ago

То на этом месте программа просто без выдачи ошибки перестаёт работать.

Возможно либа ждет ответа (обычное ожидание длится минуту, а потом выдается ошибка)

agran commented 1 year ago

Снимок экрана 2023-04-05 122701 Это не отчёт, это скорее служебный обмен данными для заполнения формы на сайте. Похоже на основе этих данных выводится список имён с чек-боксами.

lentryd commented 1 year ago

Хм, может тогда просто делать пост запрос?

  const result = await user.fetch(
    "webapi/reports/studenttotalmarks/initfilters",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        params: null,
        selectedData: [
          { filterId: "PCLID", filterValue: 518837 },
          { filterId: "SEPTYPE", filterValue: 1 },
        ],
      }),
    }
  ).then((res) => res.json());

  console.log(result);
agran commented 1 year ago

Через такой запрос выдаёт такое:

yearId 2065181
classId 3223350
(node:1938552) UnhandledPromiseRejectionWarning: Error: Fetch failed
    at Client.<anonymous> (/home/nimda/node_modules/netschoolapi/dist/classes/Client/index.js:109:23)
    at Generator.next (<anonymous>)
    at fulfilled (/home/nimda/node_modules/netschoolapi/dist/classes/Client/index.js:5:58)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:1938552) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:1938552) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
 DONE  Сеанс ***** успешно закрыт
lentryd commented 1 year ago

Забыл добавить строчку авторизации (надо будет сделать автоматическое открытие сессии).

Вот этот код должен сработать.


  await user.logIn();
  const result = await user
    .fetch("webapi/reports/studenttotalmarks/initfilters", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        params: null,
        selectedData: [
          { filterId: "PCLID", filterValue: 518837 },
          { filterId: "SEPTYPE", filterValue: 1 },
        ],
      }),
    })
    .then((res) => res.json());

  console.log(result);
agran commented 1 year ago

Ранее я выполнял этот код уже после "await user.logIn();" и нескольких успешных обращений, так что ничего не поменялось.

lentryd commented 1 year ago

Возможно у тебя какая-то ошибка. Т.к. у меня этот код выводит требуемые данные. image

Попробуй запросить данные для классов в этом году (чтобы в коде не было запросов на смену года)

agran commented 1 year ago
(node:2077584) UnhandledPromiseRejectionWarning: Error: Fetch failed.
        - url: https://sgo.rso23.ru/webapi/reports/studenttotalmarks/initfilters
        - status: 409

Сейчас заметил выдаёт статус 409

agran commented 1 year ago

Нашёл ошибку. Если передавать PCLID filterValue в виде текста, то всё работает.

body: JSON.stringify({
          "selectedData": [
            {
              "filterId": "PCLID",
              "filterValue": "3201527",
            },
            {
              "filterId": "SEPTYPE",
              "filterValue": "1",
            }
          ],
          "params": null
        }),
lentryd commented 1 year ago

Насколько я понимаю, все получилось, верно?

agran commented 1 year ago

С этим - да, спасибо! Продолжаю разработку.