Compare commits

...

1 Commits
main ... proxy

Author SHA1 Message Date
SovietSpiderCat 4fe280d904 added proxy 2025-07-29 18:09:21 +03:00
12 changed files with 16847 additions and 451 deletions

17031
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,33 +4,33 @@
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite --port 5173", "dev": "vite --host 0.0.0.0 --port 3333",
"build": "vite build", "build": "vite build",
"lint": "eslint .", "lint": "eslint .",
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"chartjs-adapter-date-fns": "^3.0.0",
"recharts": "^2.15.1",
"d3": "^7.9.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"chart.js": "^4.0.0",
"chartjs-chart-box-and-violin-plot": "^4.0.0",
"react-chartjs-2": "^5.0.0",
"axios": "^1.7.9",
"react-datepicker": "^8.1.0",
"@emotion/react": "^11.14.0", "@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0", "@emotion/styled": "^11.14.0",
"@mui/material": "^6.4.7",
"@mui/icons-material": "^6.4.8", "@mui/icons-material": "^6.4.8",
"reactflow": "^11.11.4", "@mui/material": "^6.4.7",
"vite-plugin-svgr": "^4.3.0",
"react-scripts": "^5.0.1",
"socket.io-client": "^4.8.1",
"antd": "^5.24.7", "antd": "^5.24.7",
"axios": "^1.7.9",
"chart.js": "^4.0.0",
"chartjs-adapter-date-fns": "^3.0.0",
"chartjs-chart-box-and-violin-plot": "^4.0.0",
"d3": "^7.9.0",
"react": "^18.3.1",
"react-chartjs-2": "^5.0.0",
"react-datepicker": "^8.1.0",
"react-dom": "^18.3.1",
"react-scripts": "^5.0.1",
"react-virtualized-auto-sizer": "1.0.26",
"react-window": "1.8.11", "react-window": "1.8.11",
"react-virtualized-auto-sizer": "1.0.26" "reactflow": "^11.11.4",
"recharts": "^2.15.1",
"socket.io-client": "^4.8.1",
"vite-plugin-svgr": "^4.3.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.17.0", "@eslint/js": "^9.17.0",
@ -41,6 +41,7 @@
"eslint-plugin-react": "^7.37.2", "eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.16", "eslint-plugin-react-refresh": "^0.4.16",
"express": "^5.1.0",
"globals": "^15.14.0", "globals": "^15.14.0",
"vite": "^6.0.5" "vite": "^6.0.5"
} }

View File

@ -0,0 +1,13 @@
const devServer = 'http://192.168.2.39';
const config = [
['/api', `${devServer}:3000`],
['/ai_api', `${devServer}:5134`,
{
pathRewrite: {
'^/ai_api':''
}
}
],
];
module.exports = config;

47
proxy/package.json Normal file
View File

@ -0,0 +1,47 @@
{
"name": "trust-module",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite --port 5173",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@mui/icons-material": "^6.4.8",
"@mui/material": "^6.4.7",
"antd": "^5.24.7",
"axios": "^1.7.9",
"chart.js": "^4.0.0",
"chartjs-adapter-date-fns": "^3.0.0",
"chartjs-chart-box-and-violin-plot": "^4.0.0",
"d3": "^7.9.0",
"react": "^18.3.1",
"react-chartjs-2": "^5.0.0",
"react-datepicker": "^8.1.0",
"react-dom": "^18.3.1",
"react-scripts": "^5.0.1",
"react-virtualized-auto-sizer": "1.0.26",
"react-window": "1.8.11",
"reactflow": "^11.11.4",
"recharts": "^2.15.1",
"socket.io-client": "^4.8.1",
"vite-plugin-svgr": "^4.3.0"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.17.0",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.16",
"express": "^5.1.0",
"globals": "^15.14.0",
"vite": "^6.0.5"
}
}

56
proxy/proxy.js Normal file
View File

@ -0,0 +1,56 @@
//const express = require('express')
const express = require('express')
const yargs = require('yargs/yargs')
const { hideBin } = require('yargs/helpers')
const argv = yargs(hideBin(process.argv))
.option('config', {
alias: 'c',
description: 'Configuration file name (without .config.js extension)',
type: 'string',
demandOption: true
})
.help()
.argv
const configName = argv.config;
const config = require(`./${argv.config}.config.js`)
const { createProxyMiddleware } = require('http-proxy-middleware')
const app = express();
config.forEach(el => {
const [route, target, addOptions] = el;
let options = {
target,
changeOrigin: true,
timeout: 10000,
proxyTimeout: 30000,
...addOptions || {},
};
if (configName === '127.0.0.1' && route === '/api') {
options.pathRewrite = { '^/api': '' };
}
console.log('route', route, 'target', target);
app.use(
route,
createProxyMiddleware(options),
)
})
app.use(
'/',
createProxyMiddleware({
target: 'http://localhost:3333',
changeOrigin: true,
logLevel: 'debug',
timeout: 10000,
proxyTimeout: 30000,
}),
)
app.listen(4000)
console.log('proxy started on 4000')

View File

@ -3,7 +3,7 @@ import { ThemeProvider, CssBaseline, Switch, Box, CircularProgress, Typography }
import Dashboard from "./Components/Layout/Dashboard"; import Dashboard from "./Components/Layout/Dashboard";
import LoginModal from "./Components/UI/LoginModal"; import LoginModal from "./Components/UI/LoginModal";
import { lightTheme, darkTheme } from "./Style/theme"; import { lightTheme, darkTheme } from "./Style/theme";
import Logo from './assets/images/logo.svg?react'; // import Logo from './assets/images/logo.svg';
import { checkAuth } from "./Components/UI/auth"; import { checkAuth } from "./Components/UI/auth";
import axios from "axios"; import axios from "axios";
@ -163,7 +163,7 @@ function App() {
zIndex: 1200, zIndex: 1200,
'& svg': { width: 400, height: 'auto' } '& svg': { width: 400, height: 'auto' }
}}> }}>
<Logo /> {/* <Logo /> */}
</Box> </Box>
<LoginModal <LoginModal
open={showLoginModal} open={showLoginModal}

View File

@ -10,6 +10,7 @@ import menuData from "../TreeChart/menuData.json";
import SidebarMenuWrapper from "./SidebarMenuWrapper"; import SidebarMenuWrapper from "./SidebarMenuWrapper";
import MetricTabContent from "./MetricTabContent"; import MetricTabContent from "./MetricTabContent";
import ProfileMenu from "../UI/ProfileMenu"; import ProfileMenu from "../UI/ProfileMenu";
import AIAnalysisButton from "../UI/AIAnalysisButton";
const DashboardContainer = styled(Box)(({ theme }) => ({ const DashboardContainer = styled(Box)(({ theme }) => ({
display: 'flex', display: 'flex',
@ -140,9 +141,13 @@ const Dashboard = ({ isDarkMode, setIsDarkMode, user, onLogout }) => {
top: 12, top: 12,
right: 20, right: 20,
zIndex: (theme) => theme.zIndex.tooltip + 10, zIndex: (theme) => theme.zIndex.tooltip + 10,
pointerEvents: 'auto' pointerEvents: 'auto', //ВРЕМЕННОЕ РАСПОЛОЖЕНИЕ КНОПКИ
display: 'flex',
gap: 1,
alignItems: 'center'
}} }}
> >
<AIAnalysisButton />
<ProfileMenu user={user} onLogout={onLogout} /> <ProfileMenu user={user} onLogout={onLogout} />
</Box> </Box>

View File

@ -0,0 +1,81 @@
import React, { useState } from 'react';
import { Button, CircularProgress, Alert, Box } from '@mui/material';
import axios from 'axios';
const AIAnalysisButton = ({ onAnalysisComplete }) => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [result, setResult] = useState(null);
const handleAnalyze = async () => {
setLoading(true);
setError(null);
setResult(null);
try {
// 1. Получаем данные из ClickHouse
const metricsResponse = await axios.get('/api/clickhouse');
const sendData = metricsResponse.data.slice(0, 100);
// 2. Отправляем в AI API
const aiResponse = await axios.post(
'/ai_api/api/metrics/rest',
sendData,
{
headers: {
'Content-Type': 'application/json',
},
}
);
setResult(aiResponse.data);
if (onAnalysisComplete) {
onAnalysisComplete(aiResponse.data);
}
} catch (err) {
console.error("Детали ошибки 422:", err.response?.data);
setError(err.response?.data?.message || JSON.stringify(err.response?.data) || "Ошибка валидации данных");
} finally {
setLoading(false);
}
};
return (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
<Button
variant="contained"
color="primary"
onClick={handleAnalyze}
disabled={loading}
startIcon={loading ? <CircularProgress size={20} /> : null}
sx={{
minWidth: '180px',
backgroundColor: '#4caf50',
'&:hover': {
backgroundColor: '#388e3c',
}
}}
>
{loading ? 'Отправка в AI...' : 'Проанализировать AI'}
</Button>
{error && (
<Alert severity="error" sx={{ mt: 1 }}>
{error}
</Alert>
)}
{result && !loading && (
<Alert severity="success" sx={{ mt: 1 }}>
Анализ завершен! Результат в консоли.
</Alert>
)}
</Box>
);
};
export default AIAnalysisButton;

View File

@ -24,7 +24,8 @@ const LoginModal = ({ onLogin, onClose }) => {
e.preventDefault(); e.preventDefault();
try { try {
const { data } = await axios.post( const { data } = await axios.post(
`${import.meta.env.VITE_BACK_URL}/api/auth/login`, // `${import.meta.env.VITE_BACK_URL}/api/auth/login`,
`/api/auth/login`,
{ login: username, password }, { login: username, password },
{ {
withCredentials: true, withCredentials: true,

View File

@ -1,3 +1,5 @@
import axios from 'axios'
export const checkAuth = async () => { export const checkAuth = async () => {
try { try {
const { data } = await axios.get( const { data } = await axios.get(

View File

@ -1,3 +1,4 @@
import React from 'react'
import { StrictMode } from 'react' import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client' import { createRoot } from 'react-dom/client'
import './index.css' import './index.css'

View File

@ -4,12 +4,16 @@ import svgr from 'vite-plugin-svgr'
// https://vite.dev/config/ // https://vite.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [react(), svgr()],
react(),
svgr()
],
server: { server: {
host: true, host: true,
allowedHosts: ['dev.msf.enode', 'demo-msf.kis-npo.ru'] allowedHosts: ['dev.msf.enode', 'demo-msf.kis-npo.ru'],
// proxy: {
// '/api': {
// target: 'http://192.168.2.39:3000',
// changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, '') //
// }
// },
} }
}) });