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') +})