mirror of
https://github.com/openvk/openvk
synced 2024-11-14 19:19:14 +03:00
Вопрос от Поддержки
This commit is contained in:
parent
a2384cc231
commit
ccbf892e79
11 changed files with 112 additions and 9 deletions
|
@ -32,8 +32,13 @@ class SupportAgent extends RowModel
|
||||||
return $this->getRecord()->numerate;
|
return $this->getRecord()->numerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getUser(): User
|
||||||
|
{
|
||||||
|
return (new Users)->get((int) $this->getAgentId());
|
||||||
|
}
|
||||||
|
|
||||||
function getRealName(): string
|
function getRealName(): string
|
||||||
{
|
{
|
||||||
return (new Users)->get($this->getAgentId())->getCanonicalName();
|
return $this->getUser()->getCanonicalName();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
use openvk\Web\Models\Repositories\SupportAgents;
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
|
@ -64,5 +65,15 @@ class Ticket extends RowModel
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSupportSender(): ?SupportAgent
|
||||||
|
{
|
||||||
|
return (new SupportAgents)->get((int) $this->getRecord()->support_sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFromSupport(): bool
|
||||||
|
{
|
||||||
|
return $this->getSupportSender() !== NULL;
|
||||||
|
}
|
||||||
|
|
||||||
use Traits\TRichText;
|
use Traits\TRichText;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1031,7 +1031,7 @@ class User extends RowModel
|
||||||
|
|
||||||
function adminNotify(string $message): bool
|
function adminNotify(string $message): bool
|
||||||
{
|
{
|
||||||
$admId = OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"];
|
$admId = (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["support"]["adminAccount"];
|
||||||
if(!$admId)
|
if(!$admId)
|
||||||
return false;
|
return false;
|
||||||
else if(is_null($admin = (new Users)->get($admId)))
|
else if(is_null($admin = (new Users)->get($admId)))
|
||||||
|
|
|
@ -152,7 +152,7 @@ final class SupportPresenter extends OpenVKPresenter
|
||||||
|
|
||||||
if(!empty($id)) {
|
if(!empty($id)) {
|
||||||
$ticket = $this->tickets->get($id);
|
$ticket = $this->tickets->get($id);
|
||||||
if(!$ticket || $ticket->isDeleted() != 0 || $ticket->getUserId() !== $this->user->id && !$this->hasPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0)) {
|
if(!$ticket || $ticket->isDeleted() != 0 || (($ticket->getUserId() !== $this->user->id || $ticket->isFromSupport()) && !$this->hasPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0))) {
|
||||||
$this->notFound();
|
$this->notFound();
|
||||||
} else {
|
} else {
|
||||||
if($ticket->getUserId() !== $this->user->id && $this->hasPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0))
|
if($ticket->getUserId() !== $this->user->id && $this->hasPermission('openvk\Web\Models\Entities\TicketReply', 'write', 0))
|
||||||
|
@ -396,4 +396,37 @@ final class SupportPresenter extends OpenVKPresenter
|
||||||
$this->flashFail("succ", "Успех", "Профиль создан. Теперь пользователи видят Ваши псевдоним и аватарку вместо стандартных аватарки и номера.");
|
$this->flashFail("succ", "Успех", "Профиль создан. Теперь пользователи видят Ваши псевдоним и аватарку вместо стандартных аватарки и номера.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderSendUserTicket(): void
|
||||||
|
{
|
||||||
|
$this->assertPermission("openvk\Web\Models\Entities\TicketReply", "write", 0);
|
||||||
|
$this->assertNoCSRF();
|
||||||
|
|
||||||
|
if (!$this->postParam("uid") || !$this->postParam("text"))
|
||||||
|
$this->returnJson(["success" => false, "error" => "Один или несколько обязательных параметров не были переданы"]);
|
||||||
|
|
||||||
|
$user = (new Users)->get((int) $this->postParam("uid"));
|
||||||
|
if (!$user) $this->returnJson(["success" => false, "error" => "Пользователь не найден"]);
|
||||||
|
|
||||||
|
$ticket = new Ticket;
|
||||||
|
$ticket->setType(1);
|
||||||
|
$ticket->setUser_Id($user->getId());
|
||||||
|
$ticket->setName("[Вопрос от Поддержки]" . ($this->postParam("title") ? " " . $this->postParam("title") : ""));
|
||||||
|
$ticket->setText($this->postParam("text"));
|
||||||
|
$ticket->setCreated(time());
|
||||||
|
$ticket->setSupport_Sender($this->user->id);
|
||||||
|
$ticket->save();
|
||||||
|
|
||||||
|
$comment = new TicketComment;
|
||||||
|
$comment->setUser_Id($this->user->id);
|
||||||
|
$comment->setUser_Type(1);
|
||||||
|
$comment->setText($this->postParam("text"));
|
||||||
|
$comment->setCreated(time());
|
||||||
|
$comment->setTicket_Id($ticket->getId());
|
||||||
|
$comment->save();
|
||||||
|
|
||||||
|
$user->adminNotify(($user->isFemale() ? "Дорогая " : "Дорогой ") . $user->getFirstName() . "!\n\nВы получили новый вопрос (https://$_SERVER[SERVER_NAME]/support/view/{$ticket->getId()}) от Команды Поддержки " . OPENVK_ROOT_CONF["openvk"]["appearance"]["name"]);
|
||||||
|
|
||||||
|
$this->returnJson(["success" => true, "payload" => $ticket->getId()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,16 @@
|
||||||
{block content}
|
{block content}
|
||||||
<div class="post-author">
|
<div class="post-author">
|
||||||
<a href="#" style="font-size: 13px;"><b>{$ticket->getName()}</b></a><br />
|
<a href="#" style="font-size: 13px;"><b>{$ticket->getName()}</b></a><br />
|
||||||
{_author}: <a href="/id{$ticket->getUser()->getId()}">{$ticket->getUser()->getFullName()}</a> | {$ticket->getUser()->getRegistrationIP()} | {_status}: {$ticket->getStatus()}.
|
{$ticket->isFromSupport() ? tr("user") : tr("author")}: <a href="/id{$ticket->getUser()->getId()}">{$ticket->getUser()->getFullName()}</a>
|
||||||
|
{if $ticket->isFromSupport()}
|
||||||
|
| {_author}:
|
||||||
|
<a href="{$ticket->getSupportSender()->getUser()->getURL()}">
|
||||||
|
{$ticket->getSupportSender()->getUser()->getCanonicalName()}
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
| {$ticket->getUser()->getRegistrationIP()} | {_status}: {$ticket->getStatus()}.
|
||||||
</div>
|
</div>
|
||||||
<div class="text" style="padding-top: 10px; border-bottom: #ECECEC solid 1px;">
|
<div class="text" style="padding-top: 10px; border-bottom: #ECECEC solid 1px;" n:if="!$ticket->isFromSupport()">
|
||||||
{$ticket->getText()|noescape}
|
{$ticket->getText()|noescape}
|
||||||
<br /><br />
|
<br /><br />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -34,13 +34,16 @@
|
||||||
<a href="#" style="font-size:13px;"><b>{$ticket->getName()}</b></a>
|
<a href="#" style="font-size:13px;"><b>{$ticket->getName()}</b></a>
|
||||||
<br />{_status}: {$ticket->getStatus()}
|
<br />{_status}: {$ticket->getStatus()}
|
||||||
</div>
|
</div>
|
||||||
<div class="text" style="padding-top: 10px; border-bottom: #ECECEC solid 1px;">
|
<div class="text" style="padding-top: 10px; border-bottom: #ECECEC solid 1px;" n:if="!$ticket->isFromSupport()">
|
||||||
{$ticket->getText()|noescape}
|
{$ticket->getText()|noescape}
|
||||||
<br /></br>
|
<br /><br />
|
||||||
</div>
|
</div>
|
||||||
<div style="padding-top: 5px;">
|
<div style="padding-top: 5px;">
|
||||||
{$ticket->getTime()} |
|
{$ticket->getTime()}
|
||||||
<a href="/support/delete/{$id}?hash={$csrfToken}">{_delete}</a>
|
<span n:if="!$ticket->isFromSupport()">
|
||||||
|
|
|
||||||
|
<a href="/support/delete/{$id}?hash={$csrfToken}">{_delete}</a>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{if $ticket->getType() !== 2}
|
{if $ticket->getType() !== 2}
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -128,6 +128,9 @@
|
||||||
{_ban_in_support_user_action}
|
{_ban_in_support_user_action}
|
||||||
{/if}
|
{/if}
|
||||||
</a>
|
</a>
|
||||||
|
<a href="javascript:newSupportTicketToUser()" class="profile_link" style="width: 194px;">
|
||||||
|
Вопрос от Поддержки
|
||||||
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<a style="width: 194px;" n:if="OPENVK_ROOT_CONF['openvk']['preferences']['commerce'] && $user->getGiftCount() == 0" href="/gifts?act=pick&user={$user->getId()}" class="profile_link">{_send_gift}</a>
|
<a style="width: 194px;" n:if="OPENVK_ROOT_CONF['openvk']['preferences']['commerce'] && $user->getGiftCount() == 0" href="/gifts?act=pick&user={$user->getId()}" class="profile_link">{_send_gift}</a>
|
||||||
|
@ -688,6 +691,40 @@
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
function newSupportTicketToUser() {
|
||||||
|
uTicketMsgTxt = "Вы собираетесь связаться с пользователем <b>" + {$user->getCanonicalName()} + "</b> от имени Поддержки. Он получит об этом оповещение от имени служебного аккаунта.";
|
||||||
|
uTicketMsgTxt += "<br/><br/><b>Название</b>: <input type='text' id='uTicketTitle' placeholder='В начале будет добавлено \"[Вопрос от Поддержки]\"' />";
|
||||||
|
uTicketMsgTxt += "<br/><br/><b>Текст</b>: <textarea type='text' id='uTicketText' placeholder='Текст без приветствия и завершения' style='resize: vertical; height: 185px;'></textarea>";
|
||||||
|
|
||||||
|
MessageBox("Отправить вопрос", uTicketMsgTxt, ["Отправить", "Отмена"], [
|
||||||
|
(function () {
|
||||||
|
title = $("#uTicketTitle").val();
|
||||||
|
text = $("#uTicketText").val()
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/al_helpdesk/sendTicket",
|
||||||
|
data: {
|
||||||
|
uid: {$user->getId()},
|
||||||
|
title: title,
|
||||||
|
text: text,
|
||||||
|
hash: {=$csrfToken}
|
||||||
|
},
|
||||||
|
success: (response) => {
|
||||||
|
if (response.success) {
|
||||||
|
MessageBox("Успех", "Пользователь получил вопрос и оповещения<br/><br/><a href='/support/reply/" + response.payload + "' target='_blank'>Перейти к вопросу</a>", ["OK"], [Function.noop]);
|
||||||
|
} else {
|
||||||
|
MessageBox("Ошибка", "При отправке запроса произошла ошибка: " + (response?.error ?? "Неизвестная ошибка"), ["OK"], [Function.noop]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
Function.noop
|
||||||
|
])
|
||||||
|
|
||||||
|
$(".ovk-diag-cont").width("650px");
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script n:if="isset($thisUser) && $user->getId() == $thisUser->getId()" n:syntax="off">
|
<script n:if="isset($thisUser) && $user->getId() == $thisUser->getId()" n:syntax="off">
|
||||||
|
|
|
@ -35,6 +35,8 @@ routes:
|
||||||
handler: "Support->agent"
|
handler: "Support->agent"
|
||||||
- url: "/support/agent{num}/edit"
|
- url: "/support/agent{num}/edit"
|
||||||
handler: "Support->editAgent"
|
handler: "Support->editAgent"
|
||||||
|
- url: "/al_helpdesk/sendTicket"
|
||||||
|
handler: "Support->sendUserTicket"
|
||||||
- url: "/language"
|
- url: "/language"
|
||||||
handler: "About->language"
|
handler: "About->language"
|
||||||
- url: "/language/{text}.js"
|
- url: "/language/{text}.js"
|
||||||
|
|
2
install/sqls/00038-support-tickets-from-agents.sql
Normal file
2
install/sqls/00038-support-tickets-from-agents.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE `tickets`
|
||||||
|
ADD `support_sender` BIGINT UNSIGNED NULL DEFAULT NULL AFTER `created`;
|
|
@ -913,6 +913,8 @@
|
||||||
"banned_in_support_1" = "Sorry, <b>$1</b>, but now you can't create tickets.";
|
"banned_in_support_1" = "Sorry, <b>$1</b>, but now you can't create tickets.";
|
||||||
"banned_in_support_2" = "And the reason for this is simple: <b>$1</b>. Unfortunately, this time we had to take away this opportunity from you forever.";
|
"banned_in_support_2" = "And the reason for this is simple: <b>$1</b>. Unfortunately, this time we had to take away this opportunity from you forever.";
|
||||||
|
|
||||||
|
"user" = "User";
|
||||||
|
|
||||||
/* Invite */
|
/* Invite */
|
||||||
|
|
||||||
"invite" = "Invite";
|
"invite" = "Invite";
|
||||||
|
|
|
@ -841,6 +841,7 @@
|
||||||
"ticket_changed_comment" = "Изменения вступят силу через несколько секунд.";
|
"ticket_changed_comment" = "Изменения вступят силу через несколько секунд.";
|
||||||
"banned_in_support_1" = "Извините, <b>$1</b>, но теперь вам нельзя создавать обращения.";
|
"banned_in_support_1" = "Извините, <b>$1</b>, но теперь вам нельзя создавать обращения.";
|
||||||
"banned_in_support_2" = "А причина этому проста: <b>$1</b>. К сожалению, на этот раз нам пришлось отобрать у вас эту возможность навсегда.";
|
"banned_in_support_2" = "А причина этому проста: <b>$1</b>. К сожалению, на этот раз нам пришлось отобрать у вас эту возможность навсегда.";
|
||||||
|
"user" = "Пользователь";
|
||||||
|
|
||||||
/* Invite */
|
/* Invite */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue