старое + новое + проломил башку
This commit is contained in:
parent
78ec4bb359
commit
b925ebe64e
178
mirzaev/spetsresurs/telegram/registry/requests/system/public/robot.php
Normal file → Executable file
178
mirzaev/spetsresurs/telegram/registry/requests/system/public/robot.php
Normal file → Executable file
|
@ -30,36 +30,61 @@ function authorization(string $id): _document|null|false
|
||||||
{
|
{
|
||||||
global $arangodb;
|
global $arangodb;
|
||||||
|
|
||||||
if (collection::init($arangodb->session, 'telegram'))
|
if (collection::init($arangodb->session, 'telegram')) {
|
||||||
if (
|
if ($telegram = collection::search($arangodb->session, sprintf("FOR d IN telegram FILTER d.id == '%s' RETURN d", $id))) {
|
||||||
($telegram = collection::search($arangodb->session, sprintf("FOR d IN telegram FILTER d.id == '%s' RETURN d", $id)))
|
|
||||||
|| $telegram = collection::search(
|
|
||||||
$arangodb->session,
|
|
||||||
sprintf(
|
|
||||||
"FOR d IN telegram FILTER d._id == '%s' RETURN d",
|
|
||||||
document::write($arangodb->session, 'telegram', ['id' => $id, 'status' => 'inactive'])
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if ($telegram->number === null) return null;
|
if ($telegram->number === null) return null;
|
||||||
else if (
|
else if (
|
||||||
$telegram->status === 'active'
|
$telegram->active
|
||||||
&& collection::init($arangodb->session, 'workers')
|
&& collection::init($arangodb->session, 'account')
|
||||||
&& $worker = collection::search(
|
&& $account = collection::search(
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
sprintf(
|
sprintf(
|
||||||
"FOR d IN workers LET e = (FOR e IN connections FILTER e._to == '%s' RETURN e._from)[0] FILTER d._id == e RETURN d",
|
"FOR d IN account FILTER d.number == '%s' RETURN d",
|
||||||
|
$telegram->number,
|
||||||
$telegram->getId()
|
$telegram->getId()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) return $worker;
|
) return $account;
|
||||||
else return false;
|
else return false;
|
||||||
else throw new exception('Не удалось найти или создать аккаунт');
|
}
|
||||||
else throw new exception('Не удалось инициализировать коллекцию');
|
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сотрудник
|
||||||
|
*
|
||||||
|
* @param string $id Идентификатор аккаунта
|
||||||
|
*
|
||||||
|
* @return _document|null|false (инстанция аккаунта, если подключен и авторизован; null, если не подключен; false, если подключен но неавторизован)
|
||||||
|
*/
|
||||||
|
function worker(string $id): _document|null|false
|
||||||
|
{
|
||||||
|
global $arangodb;
|
||||||
|
|
||||||
|
return collection::search(
|
||||||
|
$arangodb->session,
|
||||||
|
sprintf(
|
||||||
|
<<<'AQL'
|
||||||
|
FOR d IN worker
|
||||||
|
LET e = (
|
||||||
|
FOR e IN account_edge_worker
|
||||||
|
FILTER e._from == '%s'
|
||||||
|
SORT e.created DESC, e._key DESC
|
||||||
|
LIMIT 1
|
||||||
|
RETURN e
|
||||||
|
)
|
||||||
|
FILTER d._id == e[0]._to && d.active == true
|
||||||
|
SORT d.created DESC, d._key DESC
|
||||||
|
LIMIT 1
|
||||||
|
RETURN d
|
||||||
|
AQL,
|
||||||
|
$id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function registration(string $id, string $number): bool
|
function registration(string $id, string $number): bool
|
||||||
{
|
{
|
||||||
global $arangodb;
|
global $arangodb;
|
||||||
|
@ -71,49 +96,52 @@ function registration(string $id, string $number): bool
|
||||||
// Запись номера
|
// Запись номера
|
||||||
$telegram->number = $number;
|
$telegram->number = $number;
|
||||||
if (!document::update($arangodb->session, $telegram)) return false;
|
if (!document::update($arangodb->session, $telegram)) return false;
|
||||||
} else if (!collection::search(
|
} else if (
|
||||||
$arangodb->session,
|
$number === null
|
||||||
sprintf(
|
|| !$telegram = collection::search(
|
||||||
"FOR d IN telegram FILTER d._id == '%s' RETURN d",
|
|
||||||
document::write($arangodb->session, 'telegram', ['id' => $id, 'status' => 'inactive', 'number' => $number])
|
|
||||||
)
|
|
||||||
)) return false;
|
|
||||||
|
|
||||||
// Инициализация ребра: workers -> telegram
|
|
||||||
if (
|
|
||||||
collection::init($arangodb->session, 'workers')
|
|
||||||
&& ($worker = collection::search(
|
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
sprintf(
|
sprintf(
|
||||||
"FOR d IN workers FILTER d.phone == '%d' RETURN d",
|
"FOR d IN telegram FILTER d._id == '%s' RETURN d",
|
||||||
|
document::write($arangodb->session, 'telegram', ['id' => $id, 'active' => false, 'number' => $number])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) return false;
|
||||||
|
|
||||||
|
// Инициализация ребра: account -> telegram
|
||||||
|
if (
|
||||||
|
collection::init($arangodb->session, 'account')
|
||||||
|
&& ($account = collection::search(
|
||||||
|
$arangodb->session,
|
||||||
|
sprintf(
|
||||||
|
"FOR d IN account FILTER d.number == '%d' RETURN d",
|
||||||
$telegram->number
|
$telegram->number
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
&& collection::init($arangodb->session, 'connections', true)
|
&& collection::init($arangodb->session, 'connection', true)
|
||||||
&& (collection::search(
|
&& (collection::search(
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
sprintf(
|
sprintf(
|
||||||
"FOR d IN connections FILTER d._from == '%s' && d._to == '%s' RETURN d",
|
"FOR d IN connection FILTER d._from == '%s' && d._to == '%s' RETURN d",
|
||||||
$worker->getId(),
|
$account->getId(),
|
||||||
$telegram->getId()
|
$telegram->getId()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
?? collection::search(
|
?? collection::search(
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
sprintf(
|
sprintf(
|
||||||
"FOR d IN connections FILTER d._id == '%s' RETURN d",
|
"FOR d IN connection FILTER d._id == '%s' RETURN d",
|
||||||
document::write(
|
document::write(
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
'connections',
|
'connection',
|
||||||
['_from' => $worker->getId(), '_to' => $telegram->getId()]
|
['_from' => $account->getId(), '_to' => $telegram->getId()]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
// Инициализировано ребро: workers -> telegram
|
// Инициализировано ребро: account -> telegram
|
||||||
|
|
||||||
// Активация
|
// Активация
|
||||||
$telegram->status = 'active';
|
$telegram->active = true;
|
||||||
return document::update($arangodb->session, $telegram);
|
return document::update($arangodb->session, $telegram);
|
||||||
}
|
}
|
||||||
} else throw new exception('Не удалось инициализировать коллекцию');
|
} else throw new exception('Не удалось инициализировать коллекцию');
|
||||||
|
@ -137,10 +165,10 @@ function generateAuthenticationKeyboard(): array
|
||||||
|
|
||||||
function generateMenu(Context $ctx): void
|
function generateMenu(Context $ctx): void
|
||||||
{
|
{
|
||||||
if ($worker = authorization($ctx->getMessage()?->getFrom()?->getId() ?? $ctx->getCallbackQuery()->getFrom()->getId())) {
|
if ($account = authorization($ctx->getMessage()?->getFrom()?->getId() ?? $ctx->getCallbackQuery()->getFrom()->getId())) {
|
||||||
// Успешная авторизация
|
// Успешная авторизация
|
||||||
|
|
||||||
$ctx->sendMessage('👋 Здравствуйте, ' . $worker->name, [
|
$ctx->sendMessage('👋 Здравствуйте, ' . preg_replace('/([._\-()!#])/', '\\\$1', $account->name['first']), [
|
||||||
'reply_markup' => [
|
'reply_markup' => [
|
||||||
'inline_keyboard' => [
|
'inline_keyboard' => [
|
||||||
[
|
[
|
||||||
|
@ -170,12 +198,14 @@ function requests(int $amount = 5, int $page = 1): Cursor
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
[
|
[
|
||||||
'query' => sprintf(
|
'query' => sprintf(
|
||||||
"FOR d IN works FILTER d.worker == null && d.confirmed != 'да' SORT d.created DESC LIMIT %d, %d RETURN d",
|
"FOR d IN task FILTER d.date >= %s && d.date <= %s && d.worker == null && d.confirmed != true && d.published == true && d.completed != true SORT d.created DESC, d._key DESC LIMIT %d, %d RETURN d",
|
||||||
|
(new DateTime('now'))->setTime(7, 0)->format('U'),
|
||||||
|
(new DateTime('tomorrow'))->setTime(7, 0)->format('U'),
|
||||||
$offset,
|
$offset,
|
||||||
$amount + $offset
|
$amount + $offset
|
||||||
),
|
),
|
||||||
"batchSize" => 1000,
|
"batchSize" => 1000,
|
||||||
"sanitize" => true
|
"sanitize" => true
|
||||||
]
|
]
|
||||||
))->execute();
|
))->execute();
|
||||||
}
|
}
|
||||||
|
@ -207,42 +237,37 @@ function request_choose(Context $ctx): void
|
||||||
{
|
{
|
||||||
global $arangodb;
|
global $arangodb;
|
||||||
|
|
||||||
if (($worker = authorization($ctx->getCallbackQuery()->getFrom()->getId())) instanceof _document) {
|
if (($account = authorization($ctx->getCallbackQuery()->getFrom()->getId())) instanceof _document) {
|
||||||
// Авторизован
|
// Авторизован
|
||||||
|
|
||||||
// Инициализация ключа инстанции works в базе данных
|
// Инициализация ключа инстанции task в базе данных
|
||||||
preg_match('/^#(\d+)\n/', $ctx->getCallbackQuery()->getMessage()->getText(), $matches);
|
preg_match('/^#(\d+)\n/', $ctx->getCallbackQuery()->getMessage()->getText(), $matches);
|
||||||
$_key = $matches[1];
|
$_key = $matches[1];
|
||||||
|
|
||||||
// Инициализация инстанции works в базе данных (выбранного задания)
|
// Инициализация инстанции task в базе данных (выбранного задания)
|
||||||
$work = collection::search($arangodb->session, sprintf("FOR d IN works FILTER d._key == '%s' RETURN d", $_key));
|
$task = collection::search($arangodb->session, sprintf("FOR d IN task FILTER d._key == '%s' && d.published == true && d.completed != true RETURN d", $_key));
|
||||||
|
|
||||||
// Запись о том, что задание подтверждено (в будущем здесь будет отправка на потдверждение модераторам)
|
if ($worker = worker($account->getId())) {
|
||||||
$work->confirmed = 'да';
|
// Найден сотрудник
|
||||||
|
|
||||||
// Запись о том, что необходимо перенести изменения в Google Sheets
|
// Запись идентификатора нового сотрудника
|
||||||
$work->transfer_to_sheets = 'да';
|
$task->worker = $worker->getKey();
|
||||||
|
|
||||||
// Запись идентификатора Google Sheets нового сотрудника
|
// Снятие с публикации
|
||||||
$work->worker = $worker->id;
|
$task->published = false;
|
||||||
|
|
||||||
if (document::update($arangodb->session, $work)) {
|
if (document::update($arangodb->session, $task)) {
|
||||||
// Записано обновление в базу данных
|
// Записано обновление в базу данных
|
||||||
|
|
||||||
if (collection::search(
|
|
||||||
$arangodb->session,
|
|
||||||
sprintf(
|
|
||||||
"FOR d IN readinesses FILTER d._id == '%s' RETURN d",
|
|
||||||
document::write($arangodb->session, 'readinesses', ['_from' => $worker->getId(), '_to' => $work->getId()])
|
|
||||||
)
|
|
||||||
)) {
|
|
||||||
// Записано ребро: worker -> work (принятие заявки)
|
|
||||||
|
|
||||||
$ctx->sendMessage("✅ *Заявка принята:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) {
|
$ctx->sendMessage("✅ *Заявка принята:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) {
|
||||||
generateMenu($ctx);
|
generateMenu($ctx);
|
||||||
});
|
});
|
||||||
}
|
} else $ctx->sendMessage("❎ *Не удалось принять заявку:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) {
|
||||||
}
|
generateMenu($ctx);
|
||||||
|
});
|
||||||
|
} else $ctx->sendMessage("❎ *Не удалось принять заявку:* \#$_key", ['reply_markup' => ['remove_keyboard' => true]])->then(function () use ($ctx) {
|
||||||
|
generateMenu($ctx);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,29 +288,29 @@ function search(Context $ctx): void
|
||||||
}
|
}
|
||||||
|
|
||||||
// Поиск заявок из базы данных
|
// Поиск заявок из базы данных
|
||||||
$requests = requests(6, $page);
|
$tasks = requests(6, $page);
|
||||||
|
|
||||||
// Подсчёт количества прочитанных заявок из базы данных
|
// Подсчёт количества прочитанных заявок из базы данных
|
||||||
$count = $requests->getCount();
|
$count = $tasks->getCount();
|
||||||
|
|
||||||
// Проверка существования избытка
|
// Проверка существования избытка
|
||||||
$excess = $count % 6 === 0;
|
$excess = $count % 6 === 0;
|
||||||
|
|
||||||
// Обрезка заявок до размера страницы
|
// Обрезка заявок до размера страницы
|
||||||
$requests = array_slice($requests->getAll(), 0, 5);
|
$tasks = array_slice($tasks->getAll(), 0, 5);
|
||||||
|
|
||||||
if ($count === 0) $ctx->sendMessage('📦 *Заявок нет*');
|
if ($count === 0) $ctx->sendMessage('📦 *Заявок нет*');
|
||||||
else {
|
else {
|
||||||
// Найдены заявки
|
// Найдены заявки
|
||||||
|
|
||||||
foreach ($requests as $i => $request) {
|
foreach ($tasks as $i => $task) {
|
||||||
// Перебор найденных заявок
|
// Перебор найденных заявок
|
||||||
|
|
||||||
if (($market = collection::search(
|
if (($market = collection::search(
|
||||||
$arangodb->session,
|
$arangodb->session,
|
||||||
sprintf(
|
sprintf(
|
||||||
"FOR d IN markets LET e = (FOR e IN requests FILTER e._to == '%s' RETURN e._from)[0] FILTER d._id == e RETURN d",
|
"FOR d IN market FILTER d._key == '%s' RETURN d",
|
||||||
$request->getId()
|
$task->market
|
||||||
)
|
)
|
||||||
)) instanceof _document) {
|
)) instanceof _document) {
|
||||||
// Найден магазин
|
// Найден магазин
|
||||||
|
@ -303,7 +328,7 @@ function search(Context $ctx): void
|
||||||
preg_replace(
|
preg_replace(
|
||||||
'/([._\-()!#])/',
|
'/([._\-()!#])/',
|
||||||
'\\\$1',
|
'\\\$1',
|
||||||
"*#{$request->getKey()}*\n" . $request->date['converted'] . " (" . $request->start['converted'] . " - " . $request->end['converted'] . ")\n\n*Город:* $market->city\n*Адрес:* $market->address\n*Работа:* \"$request->work\""
|
"*#{$task->getKey()}*\n" . (new DateTime('@' . $task->date))->format('d.m.Y') . " (" . $task->start . " - " . $task->end . ")\n\n*Город:* $market->city\n*Адрес:* $market->address\n*Работа:* $task->work" . (mb_strlen($task->description) > 0 ? "\n\n$task->description" : '')
|
||||||
),
|
),
|
||||||
[
|
[
|
||||||
'reply_markup' => [
|
'reply_markup' => [
|
||||||
|
@ -314,10 +339,11 @@ function search(Context $ctx): void
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
)->then(function ($message) use ($ctx, $requests, $i, $page, $excess) {
|
)->then(function ($message) use ($ctx, $tasks, $i, $page, $excess) {
|
||||||
// Запись сообщения в кеш (на случай необходимости его удаления при смене страницы)
|
// Запись сообщения в кеш (на случай необходимости его удаления при смене страницы)
|
||||||
$ctx->setChatDataItem("request_$i", $message)->then(function () use ($ctx, $requests, $i, $page, $excess) {
|
$ctx->setChatDataItem("request_$i", $message)->then(function () use ($ctx, $tasks, $i, $page, $excess) {
|
||||||
if ($i === array_key_last($requests)) {
|
|
||||||
|
if ($i === array_key_last($tasks)) {
|
||||||
// Удаление предыдущего меню
|
// Удаление предыдущего меню
|
||||||
$ctx->getChatDataItem("request_menu")->then(function ($message) use ($ctx) {
|
$ctx->getChatDataItem("request_menu")->then(function ($message) use ($ctx) {
|
||||||
$ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
|
$ctx->deleteMessage($message->getChat()->getId(), $message->getMessageId());
|
||||||
|
|
0
mirzaev/spetsresurs/telegram/registry/requests/system/settings/.gitignore
vendored
Normal file → Executable file
0
mirzaev/spetsresurs/telegram/registry/requests/system/settings/.gitignore
vendored
Normal file → Executable file
0
mirzaev/spetsresurs/telegram/registry/requests/system/settings/arangodb.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/telegram/registry/requests/system/settings/arangodb.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/telegram/registry/requests/system/settings/key.php.sample
Normal file → Executable file
0
mirzaev/spetsresurs/telegram/registry/requests/system/settings/key.php.sample
Normal file → Executable file
Reference in New Issue