MiniApp updates
This commit is contained in:
Degradin 2025-01-17 02:41:24 +03:00
parent d9e5eb0d79
commit b8debe8fc4
5 changed files with 4841 additions and 33 deletions

View File

@ -1,4 +1,4 @@
require('dotenv').config();
require('dotenv').config();
const sequelize = require('./db'); // Подключение базы данных
@ -10,4 +10,3 @@ global.utils = require('./utils');
// Инициализация бота
require('./bot')
require('./server'); // Подключение модуля API

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,8 @@
color: #333;
}
.container {
max-width: 700px;
margin: 30px auto;
max-width: 600px;
margin: 20px auto;
background: white;
padding: 20px;
border-radius: 15px;
@ -26,7 +26,7 @@
font-weight: bold;
text-align: center;
margin-bottom: 20px;
color: #4e7dd1;
color: #e26f22;
}
.section {
margin-bottom: 20px;
@ -34,7 +34,7 @@
.section h2 {
font-size: 20px;
margin-bottom: 10px;
color: #4e7dd1;
color: #e26f22;
}
.section p {
margin: 5px 0;
@ -44,7 +44,7 @@
}
.button {
display: inline-block;
background-color: #4e7dd1;
background-color: #e26f22;
color: white;
padding: 10px 20px;
text-decoration: none;
@ -52,7 +52,7 @@
font-size: 16px;
margin-top: 20px;
text-align: center;
width: 100%;
width: 50%;
}
.emoji {
font-size: 1.3em;
@ -67,6 +67,159 @@
margin-top: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.profile-container {
position: relative;
width: 100px;
height: 100px;
margin: 0 auto;
}
.profile-img {
width: 100px;
height: 100px;
border-radius: 50%;
background-size: cover;
background-position: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.progress-ring {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 1;
}
svg {
transform: rotate(-90deg);
}
circle {
transition: stroke-dashoffset 1s;
}
.level-ring {
stroke-width: 10;
fill: transparent;
}
.profile-level-ring {
stroke: #e26f22;
}
.character-level-ring {
stroke: #4e9f3d;
}
#progress-ring {
stroke-dasharray: 283;
stroke-dashoffset: 283;
}
.level-circle {
position: absolute;
bottom: -7px;
right: 10px;
width: 30px;
height: 30px;
background-color: #e26f22;
border-radius: 50%;
color: white;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
font-size: 14px;
}
.progress-bar {
margin-top: 15px;
background-color: #ddd;
border-radius: 10px;
height: 10px;
width: 100%;
}
.progress-hp {
height: 100%;
border-radius: 10px;
background-color: #e26f22;
transition: width 0.5s ease;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
font-size: 14px;
}
.progress-stamina {
height: 100%;
border-radius: 10px;
background-color: #4ba100;
transition: width 0.5s ease;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
font-size: 14px;
}
.fire-stats {
display: flex;
justify-content: space-between;
background-color: #f9f9f9;
padding: 10px;
margin-top: 15px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.fire-stats .stat {
text-align: center;
}
.fire-stats .stat span {
font-weight: bold;
}
.circle {
stroke-width: 10;
fill: transparent;
transform: rotate(-90deg);
}
.profile-level-ring {
stroke: #e26f22;
stroke-dasharray: 283;
stroke-dashoffset: 283;
}
.character-level-ring {
stroke: #4e9f3d;
stroke-dasharray: 283;
stroke-dashoffset: 283;
}
/* Для создания полукругов */
.circle {
transform-origin: center;
}
.profile-level-ring {
stroke-dasharray: 141.5; /* половина окружности */
}
.character-level-ring {
stroke-dasharray: 141.5; /* половина окружности */
transform: rotate(180deg); /* Поворот правого полукруга */
}
</style>
<script src="https://telegram.org/js/telegram-web-app.js"></script>
</head>
@ -74,12 +227,52 @@
<div class="container">
<div class="title">📜 Меню игрока</div>
<div class="profile-container">
<div id="profile-img" class="profile-img"></div>
<div class="progress-ring">
<svg width="100" height="100">
<circle class="profile-level-ring circle" cx="50%" cy="50%" r="45%"/>
<circle class="character-level-ring circle" cx="50%" cy="50%" r="45%"/>
</svg>
<div id="level-circle" class="level-circle"></div>
</div>
</div>
<div class="progress-bar">
<div class="progress-hp" id="hp-bar"></div>
</div>
<div class="progress-bar">
<div class="progress-stamina" id="stamina-bar"></div>
</div>
<div class="fire-stats">
<div class="stat">
<p>Сила</p>
<span id="force"></span>
</div>
<div class="stat">
<p>Интеллект</p>
<span id="intelligence"></span>
</div>
<div class="stat">
<p>Выносливость</p>
<span id="endurance"></span>
</div>
<div class="stat">
<p>Стойкость</p>
<span id="resilience"></span>
</div>
</div>
<div class="section">
<h2>👤 Личные данные</h2>
<p>Имя: <span id="name"></span></p>
<p>Уровень: <span id="level"></span></p>
<p>Опыт: <span id="exp"></span></p>
<p>Здоровье: <span id="hp"></span> / <span id="max_hp"></span></p>
<p>Telegram ID: <span id="telegramID"></span></p>
</div>
<div class="section">
<h2>👤 Профиль</h2>
<p>Деньги: ₽<span id="money"></span></p>
<p>Грязные деньги: ₽<span id="dirtymoney"></span></p>
</div>
@ -98,7 +291,9 @@
</div>
</div>
<a href="https://t.me/yourbot" class="button">🏠 Перейти в чат бота</a>
<a href="https://t.me/CampFireGameBot" class="button">🏠 Перейти в чат бота</a>
</div>
<script>
@ -112,13 +307,50 @@
// Личные данные
document.getElementById("name").textContent = user.name || user.username;
document.getElementById("level").textContent = user.level;
document.getElementById("exp").textContent = user.exp;
document.getElementById("hp").textContent = user.hp;
document.getElementById("max_hp").textContent = user.max_hp;
document.getElementById("telegramID").textContent = user.telegramID;
// Профиль
document.getElementById("money").textContent = user.money;
document.getElementById("dirtymoney").textContent = user.dirtymoney;
// Устанавливаем картинку профиля
const profileImg = document.getElementById("profile-img");
const profilePhotoUrl = tg.initDataUnsafe.user.photo_url;
if (profilePhotoUrl) {
profileImg.style.backgroundImage = `url(${profilePhotoUrl})`;
} else {
profileImg.style.backgroundImage = `url('https://via.placeholder.com/100')`;
}
// Полоса опыта (прогресс бар вокруг аватарки)
const progressRing = document.querySelectorAll("circle");
const expProgress = (user.profileExp / user.profileExpToUp) * 100;
const offset = 283 - (283 * expProgress) / 100;
progressRing[0].style.strokeDashoffset = offset; // Левый полукруг для уровня профиля
const characterProgress = (user.characterLevel / user.characterExpToUp) * 100;
const characterOffset = 283 - (283 * characterProgress) / 100;
progressRing[1].style.strokeDashoffset = characterOffset; // Правый полукруг для уровня персонажа
// Уровень в кружке
document.getElementById("level-circle").textContent = user.profileLevel;
// Установка прогресса HP и Стамины
const hpProgress = (user.hp / user.maxHp) * 100;
const staminaProgress = (user.stamina / user.maxStamina) * 100;
document.getElementById("hp-bar").textContent = `${hpProgress}%`;
document.getElementById('hp-bar').style.width = `${hpProgress}%`;
document.getElementById("stamina-bar").textContent = `${staminaProgress}%`;
document.getElementById('stamina-bar').style.width = `${staminaProgress}%`;
// Характеристики FIRE
document.getElementById("force").textContent = user.force;
document.getElementById("intelligence").textContent = user.intelligence;
document.getElementById("endurance").textContent = user.endurance;
document.getElementById("resilience").textContent = user.resilience;
// Организация
document.getElementById("business-name").textContent = business.name;
document.getElementById("business-balance").textContent = business.balance;
@ -133,7 +365,7 @@
div.classList.add("enterprise");
div.innerHTML = `
<strong>${ent.name}</strong><br>
Тип ресурса: ${getResourceIcon(ent.resourceType)} ${ent.resourceType}<br>
Тип ресурса: ${getResourceIcon(ent.resourceType)} ${getResourceName(ent.resourceType)}<br>
Уровень: ${ent.level}<br>
Эффективность: ${ent.efficiency}/час<br>
Заполненность склада: ${ent.currentResources}/${ent.warehouseCapacity}
@ -146,18 +378,29 @@
console.error("Ошибка загрузки данных:", err);
});
// Функция для конвертации типов ресурсов в эмодзи
function getResourceIcon(resource) {
switch (resource.toLowerCase()) {
case 'дерево': return '🌳';
case 'металл': return '🛠️';
case 'нефть': return '🛢️';
case 'уголь': return '⛏️';
case 'золото': return '💰';
case 'алмазы': return '💎';
case 'wood': return '🌳';
case 'metall': return '🛠️';
case 'oil': return '🛢️';
case 'coal': return '⛏️';
case 'gold': return '💰';
case 'diamond': return '💎';
default: return '⚙️';
}
}
function getResourceName(resource) {
switch (resource.toLowerCase()) {
case 'wood': return 'Дерево';
case 'metall': return 'Металл';
case 'oil': return 'Нефть';
case 'coal': return 'Уголь';
case 'gold': return 'Золото';
case 'diamond': return 'Алмазы';
default: return 'Ресурс';
}
}
</script>
</body>
</html>

2
server.bat Normal file
View File

@ -0,0 +1,2 @@
nodemon --ignore json/ .\server.js
pause

View File

@ -1,3 +1,12 @@
require('dotenv').config();
const sequelize = require('./db'); // Подключение базы данных
// Настраиваем глобальные переменные (опционально)
global.path = require('path');
global.config = require('./config'); // Конфигурация
global.database = sequelize; // База данных
global.utils = require('./utils');
const express = require('express');
const { UserModel, CharacterModel, BusinessModel, EnterpriseModel } = global.config;
const app = express();
@ -9,10 +18,9 @@ app.get('/player/:id', async (req, res) => {
const playerId = req.params.id;
try {
console.log(playerId)
const user = await UserModel.findOne({ where: { telegram_id: req.params.id } });
const character = await CharacterModel.findOne({ where: { telegram_id: playerId } });
let business = await BusinessModel.findOne({ where: { owner: playerId.toString() } })
let business = await BusinessModel.findOne({ where: { owner: playerId } })
if(business === null){
business = await BusinessModel.findOne( {where: { owner: user.business.id} } )
}
@ -25,13 +33,25 @@ app.get('/player/:id', async (req, res) => {
res.json({
user: {
username: user.username,
telegramID: user.telegram_id,
name: user.name,
level: user.level,
exp: user.exp,
status: user.status,
profileLevel: user.level,
characterLevel: character.level,
profileExp: user.exp,
characterExp: character.exp,
profileExpToUp: global.config.expToUp[user.level],
characterExpToUp: global.config.expToUp[character.level],
hp: character.hp,
max_hp: character.max_hp,
money: user.money,
dirtymoney: character.dirtymoney,
maxHp: character.max_hp,
stamina: character.stamina,
maxStamina: character.max_stamina,
force: character.force,
intelligence: character.intelligence,
resilience: character.resilience,
endurance: character.endurance,
money: global.utils.spaces(user.money),
dirtymoney: global.utils.spaces(character.dirtymoney),
},
business: business || { name: "Отсутствует", balance: 0, materials: 0, users: [] },
enterprises: enterprises || [],