First Commit

This commit is contained in:
DATAEXPRESS\4734
2026-01-06 18:24:42 +08:00
commit 65f033adbc
37 changed files with 3010 additions and 0 deletions
+98
View File
@@ -0,0 +1,98 @@
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const fs = require('fs');
const http = require('http');
const https = require('https');
const morgan = require('morgan');
const logger = require('./src/utils/logger');
require('dotenv').config();
const ormService = require('./src/services/ormService');
const mailService = require('./src/services/mailService');
const upload = require('./src/services/uploadService');
const app = express();
// 整合 Morgan 到 Winston
app.use(morgan('combined', {
stream: { write: message => logger.info(message.trim()) }
}));
// --- Middleware ---
const corsOptions = {
origin: [
'https://app.gex.com.tw', // 您的正式環境前端
'http://localhost:3000' // 本地開發測試用
],
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
allowedHeaders: ['Content-Type', 'Authorization', 'token'], // 確保 token 能被傳送
credentials: true, // 如果需要帶 Cookie
optionsSuccessStatus: 200
};
app.use(cors(corsOptions));
app.use(helmet());
app.use(express.json({ limit: '100mb' }));
app.use(express.urlencoded({ extended: true, limit: '100mb' }));
//app.use('/static', express.static('public'));
app.use(express.static(__dirname + '/public')); //Serves resources from public folder
// 啟動郵件排程
mailService.initAutoMail().then(() => console.log('?? Mail Scheduler Started.'));
// --- Routes (保持不變) ---
// 支援 v1 (舊版) 與 v3 (新版)
const ormRoutes = ['/xapi/v1/:dbname/:name/:dsNo', '/xapi/v2/:dbname/:name/:dsNo', '/xapi/v3/:dbname/:name/:dsNo'];
app.post(ormRoutes, async (req, res, next) => {
try {
const params = ormService.prepareOrmPayload(req);
// 增加一個 log 觀察是哪個路徑進來的
logger.info(`Incoming Request: ${req.url} -> SP: ${req.params.name}`);
// logger.info(`Calling SP: ${req.params.name} by User: ${req.body.token || 'Guest'}`);
const result = await ormService.executeSp(req.params.name, params, req.params.dsNo);
res.json(result);
} catch (err) {
logger.error(`API Error on ${req.params.name}: ${err.message}`);
next(err);
}
});
app.post('/upload/:dbname/:typeid', upload.single('file'), (req, res) => {
if (!req.file) return res.status(400).json({ status: 400, msg: 'No file' });
const fileUrl = `/static/upload/${req.params.dbname}/${req.params.typeid}/${req.file.filename}`;
res.json({ status: 0, data: { value: fileUrl, url: fileUrl }, msg: 'success' });
});
// 全域錯誤處理
app.use((err, req, res, next) => {
res.status(err.status || 500).json({ status: err.status || 500, msg: err.message });
});
// --- Server 啟動邏輯 ---
const HTTP_PORT = process.env.PORT || 5050;
// 啟動標準 HTTP
http.createServer(app).listen(HTTP_PORT, () => {
console.log(`?? HTTP Server running on http://localhost:${HTTP_PORT}`);
});
// 根據 .env 決定是否啟動 HTTPS
if (process.env.ENABLE_HTTPS === 'true') {
try {
const options = {
key: fs.readFileSync(process.env.SSL_KEY_PATH),
cert: fs.readFileSync(process.env.SSL_CRT_PATH)
};
const HTTPS_PORT = process.env.HTTPS_PORT || 5443;
https.createServer(options, app).listen(HTTPS_PORT, () => {
console.log(`?? HTTPS Server running on https://localhost:${HTTPS_PORT}`);
});
} catch (error) {
console.error('? Failed to start HTTPS server (Check SSL paths):', error.message);
}
}