This commit is contained in:
Kavalar 2025-01-23 20:02:06 +03:00
parent 485c11de5f
commit 08cdf44b67
16 changed files with 240 additions and 23 deletions

View File

@ -3,6 +3,8 @@
namespace app\modules\tgbot\controllers;
use app\modules\tgbot\models\Tgbot;
use kernel\app_modules\tag\service\TagService;
use kernel\modules\post\models\Post;
class TgBotRestController extends \kernel\app_modules\tgbot\controllers\TgBotRestController
{
@ -12,9 +14,15 @@ class TgBotRestController extends \kernel\app_modules\tgbot\controllers\TgBotRes
$dialog = Tgbot::where("dialog_id", $id)->first();
if ($dialog){
$this->renderApi([
'html' => '<a class="btn btn-primary" href="/miniapp/scan">Сканировать</a>',
'html' => '<a class="btn btn-primary" href="/miniapp/scanner">Сканировать</a>',
]);
}
}
public function actionGetNews(): void
{
}
}

View File

@ -3,7 +3,9 @@
namespace app\modules\tgbot\controllers;
use app\modules\tgbot\models\Tgbot;
use app\modules\tgbot\services\TgBotService;
use Cassandra\Decimal;
use kernel\app_modules\card\models\Card;
use kernel\app_modules\tag\service\TagService;
use kernel\Controller;
use kernel\helpers\Debug;
@ -40,4 +42,16 @@ class TgMainController extends Controller
$this->cgView->render("news.php", ['news' => $news]);
}
public function actionScanner(): void
{
$this->cgView->render("scanner.php");
}
public function actionCardAction(int $cardId): void
{
$card = Card::where("id", $cardId)->first();
$this->cgView->render("card_action.php", ['card' => $card]);
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace app\modules\tgbot\middlewares;
use app\modules\tgbot\models\Tgbot;
use app\modules\tgbot\services\TgBotService;
use kernel\Middleware;
class TgBotAuthMiddleware extends Middleware
{
function handler(): void
{
if(isset($_COOKIE['dialog_id']))
{
$model = Tgbot::where("dialog_id", $_COOKIE['dialog_id'])->first();
if ($model){
TgBotService::$currentDialog = $model;
return;
}
}
exit();
}
}

View File

@ -5,9 +5,14 @@ use kernel\CgRouteCollector;
include KERNEL_APP_MODULES_DIR . "/tgbot/routs/tgbot.php";
App::$collector->filter("tg_bot_auth", [\app\modules\tgbot\middlewares\TgBotAuthMiddleware::class, "handler"]);
App::$collector->group(["prefix" => "miniapp"], function (CGRouteCollector $router) {
App::$collector->get('/', [\app\modules\tgbot\controllers\TgMainController::class, 'actionMain']);
App::$collector->get('/news', [\app\modules\tgbot\controllers\TgMainController::class, 'actionNews']);
App::$collector->get('/promo', [\app\modules\tgbot\controllers\TgMainController::class, 'actionPromo']);
App::$collector->group(["before" => "tg_bot_auth"], function (CGRouteCollector $router){
App::$collector->get('/news', [\app\modules\tgbot\controllers\TgMainController::class, 'actionNews']);
App::$collector->get('/promo', [\app\modules\tgbot\controllers\TgMainController::class, 'actionPromo']);
App::$collector->get('/scanner', [\app\modules\tgbot\controllers\TgMainController::class, 'actionScanner']);
App::$collector->get('/card_action/{cardId}', [\app\modules\tgbot\controllers\TgMainController::class, 'actionCardAction']);
});
});

View File

@ -12,4 +12,6 @@ use kernel\services\ModuleService;
class TgBotService extends \kernel\app_modules\tgbot\services\TgBotService
{
public static null|Tgbot $currentDialog = null;
}

View File

@ -22,6 +22,7 @@
<link rel="stylesheet" href="<?= $resources ?>/css/style.css">
<link rel="stylesheet" href="<?= $resources ?>/css/tgApp.css">
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<script src="https://unpkg.com/html5-qrcode" type="text/javascript"></script>
</head>
<body>

View File

@ -0,0 +1,23 @@
<?php
/**
* @var \kernel\app_modules\card\models\Card $card
*/
use kernel\helpers\Html;
?>
<div class="row">
<div class="col-12 m-1">
<?php
echo Html::img(src: "data:image/png;base64, " . \kernel\app_modules\card\services\CardFileService::createCardPNG($card, true));
?>
</div>
</div>
<div class="row">
<div class="col-12 m-1">
<a class="btn btn-primary" href="/miniapp/add_purchase">Добавить покупку</a>
</div>
</div>

View File

@ -0,0 +1,30 @@
<div id="tg_app">
</div>
<div id="scanner_box"></div>
<script>
function domReady(fn) {
if (
document.readyState === "complete" ||
document.readyState === "interactive"
) {
setTimeout(fn, 1000);
} else {
document.addEventListener("DOMContentLoaded", fn);
}
}
domReady(function () {
// If found you qr code
function onScanSuccess(decodeText, decodeResult) {
window.location.href = "/miniapp/card_action/" + decodeText;
}
let htmlscanner = new Html5QrcodeScanner(
"scanner_box",
{fps: 10, qrbox: {width: 250, height: 250}},
);
htmlscanner.render(onScanSuccess);
});
</script>

View File

@ -52,7 +52,7 @@ class CardFileService
return false;
}
public static function createCardPNG(Card $card): false|string
public static function createCardPNG(Card $card, bool $returnBase64 = false): false|string
{
if ($card->cardTemplate) {
$formatter = BankFormatter::create();
@ -65,7 +65,9 @@ class CardFileService
$uploadDir = "/resources/cards/";
$uploadDirUri = $uploadDir . mb_substr($newFileName, 0, 2) . '/' . mb_substr($newFileName, 2, 2) . '/';
$oldMask = umask(0);
mkdir(ROOT_DIR . $uploadDirUri, 0775, true);
if (!file_exists(ROOT_DIR . $uploadDirUri)){
mkdir(ROOT_DIR . $uploadDirUri, 0775, true);
}
umask($oldMask);
$uploadFileDir = ROOT_DIR . $uploadDirUri;
@ -108,9 +110,14 @@ class CardFileService
$cardSettings['qr_box_height'] ?? 135,
100
);
$img->save($uploadFileDir . $newFileName);
if ($returnBase64){
return $img->getBase64();
}
else {
$img->save($uploadFileDir . $newFileName);
return $uploadDirUri . $newFileName;
return $uploadDirUri . $newFileName;
}
}
return false;

View File

@ -39,7 +39,7 @@ $table->rows([
$table->create();
$table->render();
echo \kernel\helpers\Html::img(\kernel\app_modules\card\services\CardFileService::createCardPNG($card));
echo \kernel\helpers\Html::img("data:image/png;base64, " . \kernel\app_modules\card\services\CardFileService::createCardPNG($card, true));
//$writer = new PngWriter();
//

View File

@ -40,6 +40,17 @@ class ImageGD
imagedestroy($this->img);
}
public function getBase64(): string
{
ob_start ();
imagepng($this->img);
$image_data = ob_get_contents ();
ob_end_clean ();
imagedestroy($this->img);
return base64_encode ($image_data);
}
public function makeCornersForImage($radius, $background): void
{
// включаем режим сопряжения цветов

View File

@ -1,18 +1,35 @@
import {Cookie} from "./tg_app/Cookie.js";
import {TgApp} from "./tg_app/TgApp.js";
import Router from "./tg_app/Router.js";
import {SimpleRouter} from "./tg_app/SimpleRouter.js";
document.addEventListener("DOMContentLoaded", () => {
let tg = window.Telegram.WebApp;
let tgApp = new TgApp("tg_app", tg.initDataUnsafe.user.id);
const router = new Router({
mode: 'hash',
root: '/miniapp'
});
// const router = new Router({
// mode: 'hash',
// root: '/miniapp'
// });
router
.add('', () => {
const cookie = new Cookie();
const routes = {
'/miniapp': () => {
cookie.setCookie("dialog_id", tg.initDataUnsafe.user.id, 3)
tgApp.actionMain();
});
},
};
// Инициализация роутера
const router = new SimpleRouter(routes);
// const router
// .add('/', () => {
// cookie.setCookie("dialog_id", tg.initDataUnsafe.user.id, 3)
// tgApp.actionMain();
// })
// .add('/scanner', () => {
// tgApp.createScanner();
// });
});

View File

@ -0,0 +1,26 @@
class Cookie {
setCookie(name,value,days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)===' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
eraseCookie(name) {
document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}
}
export {Cookie}

View File

@ -0,0 +1,33 @@
class SimpleRouter {
constructor(routes) {
this.routes = routes;
this.init();
}
init() {
// window.addEventListener('popstate', () => this.route());
// document.addEventListener('DOMContentLoaded', () => this.route());
// document.addEventListener('click', (e) => {
// if (e.target.tagName === 'A') {
// e.preventDefault();
// this.navigate(e.target.href);
// }
// });
this.route();
}
navigate(path) {
window.history.pushState({}, '', path);
this.route();
}
route() {
const path = window.location.pathname;
const route = this.routes[path] || this.routes['/404'];
if (route) {
route();
}
}
}
export {SimpleRouter}

View File

@ -6,10 +6,9 @@ class TgApp {
this.userId = userId;
this.btnBox = this.createBox("btnBox");
this.container.appendChild(this.btnBox);
console.log(userId)
}
actionMain(){
actionMain() {
this.createCardBox();
// this.createDefaultBox();
@ -56,7 +55,7 @@ class TgApp {
})
}
getScanBtn(){
getScanBtn() {
fetch(config.config.apiUrl + `api/tg-bot/get-scan-btn/${this.userId}`, {
method: 'GET', // Здесь так же могут быть GET, PUT, DELETE
headers: {
@ -71,15 +70,27 @@ class TgApp {
})
}
createBox(id){
createBox(id) {
let box = document.createElement("div");
box.setAttribute("id", id);
return box;
}
getAction(action){
if (action === "actionMain"){
// createScanner() {
// let html5QrcodeScanner = new Html5QrcodeScanner(
// "scanner_box",
// {fps: 10, qrbox: {width: 250, height: 250}},
// /* verbose= */ false);
// html5QrcodeScanner.render(this.onScanSuccess);
// }
onScanSuccess(decodedText, decodedResult) {
console.log(`Code matched = ${decodedText}`, decodedResult);
}
getAction(action) {
if (action === "actionMain") {
return this.actionMain;
}

File diff suppressed because one or more lines are too long