diff --git a/.gitignore b/.gitignore
index ceaea36..2fb3ca3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,132 +1,5 @@
-# ---> Node
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-.pnpm-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# Snowpack dependency directory (https://snowpack.dev/)
-web_modules/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional stylelint cache
-.stylelintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variable files
+build
+node_modules
+package-lock.json
+config.json
.env
-.env.development.local
-.env.test.local
-.env.production.local
-.env.local
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-out
-
-# Nuxt.js build / generate output
-.nuxt
-dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# vuepress v2.x temp and cache directory
-.temp
-.cache
-
-# Docusaurus cache and generated files
-.docusaurus
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v2
-.yarn/cache
-.yarn/unplugged
-.yarn/build-state.yml
-.yarn/install-state.gz
-.pnp.*
-
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..f276872
--- /dev/null
+++ b/index.html
@@ -0,0 +1,11 @@
+
+
+
\ No newline at end of file
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..ce809bb
--- /dev/null
+++ b/main.js
@@ -0,0 +1,77 @@
+import Chart from 'chart.js/auto'
+
+const rest = await fetch('http://localhost:2000/api').then(res => res.json())
+const table = document.createElement('table')
+
+// 添加表头
+const thead = document.createElement('thead')
+const tr = document.createElement('tr')
+for (let key in rest[0]) {
+ const th = document.createElement('th')
+ th.textContent = key
+ tr.appendChild(th)
+}
+thead.appendChild(tr)
+table.appendChild(thead)
+
+// 添加数据
+for (let row of rest) {
+ const tr = document.createElement('tr')
+ for (let key in row) {
+ const td = document.createElement('td')
+ td.textContent = row[key]
+ tr.appendChild(td)
+ }
+ table.appendChild(tr)
+}
+
+// 写入页面
+document.body.appendChild(table)
+
+
+// 生成随机数据
+function generateRandomData(num, minPrice, maxPrice) {
+ const data = [];
+ const today = new Date();
+ for (let i = 0; i < num; i++) {
+ const randomDays = Math.floor(Math.random() * 30); // 随机天数
+ const newDate = new Date(today.getTime() + randomDays * 24 * 60 * 60 * 1000); // 增加随机天数
+ const price = Math.floor(Math.random() * (maxPrice - minPrice + 1)) + minPrice; // 随机价格
+ data.push({
+ date: newDate.toISOString().split('T')[0], // 格式化为 YYYY-MM-DD
+ price: price
+ });
+ }
+ return data;
+}
+
+// 生成 10 条随机数据
+const numEntries = 10;
+const data = generateRandomData(numEntries, 100, 500);
+
+// 创建图表
+const ctx = document.createElement('canvas');
+document.body.appendChild(ctx);
+new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: data.map(row => row.date),
+ datasets: [{
+ label: '航班价格',
+ data: data.map(row => row.price),
+ backgroundColor: 'rgba(255, 99, 132, 0.2)', // 曲线下方填充颜色(透明度0.2)
+ borderColor: 'rgba(255, 99, 132, 1)', // 曲线颜色
+ borderWidth: 2, // 曲线宽度
+ lineTension: 0.3, // 平滑曲线
+ fill: true // 填充曲线下方区域
+ }]
+ },
+ options: {
+ scales: {
+ y: {
+ beginAtZero: true
+ }
+ }
+ }
+});
+
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..b9aa5fb
--- /dev/null
+++ b/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "hangban",
+ "version": "1.0.0",
+ "description": "",
+ "type": "module",
+ "main": "main.js",
+ "scripts": {
+ "dev": "concurrently 'vite' 'nodemon server.js --watch server.js'"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "chart.js": "^4.4.7",
+ "cors": "^2.8.5",
+ "express": "^4.21.2",
+ "mysql2": "^3.11.5"
+ },
+ "devDependencies": {
+ "concurrently": "^9.1.0",
+ "nodemon": "^3.1.7",
+ "vite": "^6.0.3"
+ }
+}
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..278b6ba
--- /dev/null
+++ b/server.js
@@ -0,0 +1,32 @@
+import cors from 'cors'
+import mysql from 'mysql2'
+import express from 'express'
+import fs from 'fs'
+
+// 从 config.json 读取配置
+const config = JSON.parse(fs.readFileSync('config.json', 'utf8'))
+
+const app = express()
+const db = mysql.createPool({
+ ...config.mysql,
+ waitForConnections: true,
+ connectionLimit: 10,
+ queueLimit: 0
+}).promise()
+
+// 设置JSON缩进为 2 个空格
+app.set('json spaces', 2)
+
+// 允许所有域名的跨域请求
+app.use(cors())
+
+// 提供接口服务
+app.get('/api', async (req, res) => {
+ const [rows] = await db.query('SELECT * FROM flights LIMIT 10')
+ res.json(rows)
+})
+
+// 启动应用
+app.listen(2000, () => {
+ console.log('服务已启动成功 http://localhost:2000/api')
+})