Initial commit: Telegram Management System
Some checks failed
Deploy / deploy (push) Has been cancelled

Full-stack web application for Telegram management
- Frontend: Vue 3 + Vben Admin
- Backend: NestJS
- Features: User management, group broadcast, statistics

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
你的用户名
2025-11-04 15:37:50 +08:00
commit 237c7802e5
3674 changed files with 525172 additions and 0 deletions

View File

@@ -0,0 +1,188 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import { visualizer } from 'rollup-plugin-visualizer'
import viteCompression from 'vite-plugin-compression'
import viteImagemin from 'vite-plugin-imagemin'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig({
plugins: [
vue(),
// Auto import components
Components({
resolvers: [ElementPlusResolver()],
dts: 'src/components.d.ts'
}),
// Auto import APIs
AutoImport({
imports: ['vue', 'vue-router', 'pinia'],
dts: 'src/auto-imports.d.ts',
resolvers: [ElementPlusResolver()]
}),
// Gzip compression
viteCompression({
verbose: true,
disable: false,
threshold: 10240,
algorithm: 'gzip',
ext: '.gz'
}),
// Brotli compression
viteCompression({
verbose: true,
disable: false,
threshold: 10240,
algorithm: 'brotliCompress',
ext: '.br'
}),
// Image optimization
viteImagemin({
gifsicle: {
optimizationLevel: 7,
interlaced: false
},
optipng: {
optimizationLevel: 7
},
mozjpeg: {
quality: 80
},
pngquant: {
quality: [0.8, 0.9],
speed: 4
},
svgo: {
plugins: [
{
name: 'removeViewBox'
},
{
name: 'removeEmptyAttrs',
active: false
}
]
}
}),
// Bundle analyzer
visualizer({
open: true,
gzipSize: true,
brotliSize: true,
filename: 'dist/bundle-analysis.html'
})
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'~': path.resolve(__dirname, './src/assets')
}
},
server: {
port: 3008,
host: '0.0.0.0',
proxy: {
'/api': {
target: 'http://localhost:3030',
changeOrigin: true
},
'/socket.io': {
target: 'http://localhost:3030',
ws: true,
changeOrigin: true
}
}
},
build: {
target: 'es2015',
outDir: 'dist',
assetsDir: 'assets',
sourcemap: false,
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
},
rollupOptions: {
output: {
// Manual chunks for better caching
manualChunks: {
'element-plus': ['element-plus', '@element-plus/icons-vue'],
'chart': ['chart.js', 'vue-chartjs'],
'vendor': ['vue', 'vue-router', 'pinia'],
'utils': ['axios', 'dayjs', 'lodash-es'],
'i18n': ['vue-i18n']
},
// Asset naming for better caching
chunkFileNames: (chunkInfo) => {
const facadeModuleId = chunkInfo.facadeModuleId ? chunkInfo.facadeModuleId.split('/').pop() : 'chunk'
return `js/[name]-${facadeModuleId}-[hash].js`
},
entryFileNames: 'js/[name]-[hash].js',
assetFileNames: (assetInfo) => {
const info = assetInfo.name.split('.')
const ext = info[info.length - 1]
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(ext)) {
return `images/[name]-[hash][extname]`
} else if (/woff|woff2|eot|ttf|otf/i.test(ext)) {
return `fonts/[name]-[hash][extname]`
} else {
return `[ext]/[name]-[hash][extname]`
}
}
}
},
// Chunk size warnings
chunkSizeWarningLimit: 500,
// CSS code splitting
cssCodeSplit: true,
// Asset inlining threshold
assetsInlineLimit: 4096
},
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/variables.scss";`
}
},
// Extract CSS for better caching
extract: true,
// CSS modules
modules: {
localsConvention: 'camelCase'
}
},
optimizeDeps: {
include: [
'vue',
'vue-router',
'pinia',
'axios',
'element-plus',
'dayjs',
'lodash-es'
],
exclude: ['@vueuse/core']
},
// Performance optimizations
esbuild: {
pure: ['console.log', 'console.debug'],
legalComments: 'none'
}
})