// 数据库启动器 const path = require("path") const fs = require("fs") const argv = require('yargs').argv // 全局配置加载 // IMPORTANT:通过apps//加载应用独立配置 var appConfig try{ appConfig = require(`./config.js`) // 默认加载包内config.js文件 }catch{} if(!appConfig) appConfig = {} var userConfig /********************* * windows: process.env.PORTABLE_EXECUTABLE_DIR * linux: process.env.OWD */ var OWN_DIR = process.env.PORTABLE_EXECUTABLE_DIR || process.env.OWD || process.cwd() || __dirname if (OWN_DIR) { let configPath = path.join(OWN_DIR, `config.js`) if (fs.existsSync(configPath)) { userConfig = require(configPath) // 用户独立配置config.js覆盖 if (userConfig) { Object.keys(userConfig).forEach(key => { appConfig[key] = userConfig[key] }) } } } global.config = global.config || {} console.log(appConfig) global.config['DATABASE_DBNAME'] = process.env["DATABASE_DBNAME"] || appConfig["DATABASE_DBNAME"] || false global.config['DATABASE_LOCAL'] = process.env["DATABASE_LOCAL"] || appConfig["DATABASE_LOCAL"] || false global.config['MCENTER_ENABLED'] = process.env["MCENTER_ENABLED"] || appConfig["MCENTER_ENABLED"] || false global.config['PARSE_SERVERURL'] = process.env["PARSE_SERVERURL"] || appConfig["PARSE_SERVERURL"] || false global.config['PARSE_APPID'] = process.env["PARSE_APPID"] || appConfig["PARSE_APPID"] || false global.config['PARSE_MASTERKEY'] = process.env["PARSE_MASTERKEY"] || appConfig["PARSE_MASTERKEY"] || false global.config['SEGMENT_COUNT'] = process.env["SEGMENT_COUNT"] || appConfig["SEGMENT_COUNT"] || false global.config["LOCAL"] = argv.local || process.env["LOCAL"] || appConfig["LOCAL"] || global.config['DATABASE_LOCAL'] || false global.config["PORT"] = argv.port || process.env["PORT"] || appConfig["PORT"] || global.config['PORT'] || 61337 import {textbookRouter} from "./api/textbook/routes"; import { defineAliOssSTS } from "./cloud/aliyun" import { defineAliSMSSend } from "./cloud/aliyun/func-aliyun-sms" import { defineAuthingLogin, defineDepartmentTrigger, defineUserAfterDelete, defineUserBeforeSave } from "./cloud/authing" import { defineAuthingDepartSync } from "./cloud/authing" import { defineUserAfterSave } from "./cloud/authing" import { defineTbookISBN } from "./cloud/tbook" import { defineTbookExportReport } from "./cloud/tbook/func-tbook-export" import { importData } from "./db/func/import-data" // 全局共享属性 global.coolMap = {} global.minerMap = {} global.monitorMap = {} // Web服务启动器 const express = require('express'); const parse = require('parse-server') const Parse = require('parse/node') const ParseServer = parse.ParseServer; const ParseDashboard = require('parse-dashboard'); // 同端口多进程集群 let processCluster = require('cluster') let cpus = require('os').cpus() console.log(cpus.length) const app = express(); const cors = require('cors'); import { importAllSchemas } from "./db/func/import-schemas" import { PostgreSQLKeep } from "./lib/pg/index.js" app.use(cors({ origin: '*' })); global.parseConfig = { port : global.config["PORT"], allowClientClassCreation: true, allowExpiredAuthDataToken: false, encodeParseObjectInCloudFunction: false, } global.parseConfig.serverURL = `http://localhost:${global.parseConfig?.port}/parse` global.parseConfig.databaseURI = global.config['DATABASE_DBNAME']; if(global.config['LOCAL']) { global.parseConfig.databaseURI = "postgresql://postgres@127.0.0.1:25432/" } global.parseConfig.appId = 'edu-textbook' global.parseConfig.appName = 'EduParse' global.parseConfig.masterKey = 'EDU2024' // global.parseConfig.cloud = './cloud/main.js' Parse.initialize(global.parseConfig.appId,null,global.parseConfig.masterKey); Parse.serverURL = global.parseConfig.serverURL; async function startParse(){ if(global.config['LOCAL']) { console.log("PostgreSQLKeep") await PostgreSQLKeep({username:"postgres",password:"postgres",port:"25432",dbpath:"database/edudata" }) // await PostgreSQLKeep(global.config['DATABASE_DBNAME'], "database/edudata/" ) } // 挂载微服务 console.log(global.parseConfig) const api = new ParseServer(global.parseConfig); await api.start(); // Serve the Parse API at /parse URL prefix app.use('/parse', api.app); // 挂载管理看板 const dashboard = new ParseDashboard({ "apps": [ global.parseConfig ] }, { allowInsecureHTTP: true }); app.use('/dashboard', dashboard); } process.on('exit', async () => { // await stopDB() }); process.on('SIGINT', async () => { /* DO SOME STUFF HERE */ // await stopDB() process.exit() }) // 在程序中捕获异常并进行处理 process.on('uncaughtException', async (err) => { console.error('Uncaught Exception:', err); process.exit(1); }); // 启动服务 async function initParseAndDatabase(){ try{ // 仅导入脚本参数 if(argv.import){ console.log("importAllSchemas") await importAllSchemas() return } console.log("正在启动微服务...") await startParse(); // console.log("parse:",parseConfig) console.log("正在启动api接口") // 加载textbook专属路由 通过代理操控局域网设备 app.use("/api/textbook",textbookRouter) app.get("/",(req,res)=>{ res.json({ code:200, data:{message:"ok"} }) }) /** * Listen on provided port, on all network interfaces. */ app.listen(global.parseConfig?.port, async function() { console.log('微服务已运行,端口 ' + global.parseConfig?.port + '.'); // 迁移数据范式 Schemas await importAllSchemas(); // 导入初始化数据 setTimeout(() => { importData() }, 500); // 导入CloudCode defineAuthingLogin(); defineAuthingDepartSync(); defineAliOssSTS(); defineAliSMSSend(); defineUserAfterSave(); defineUserBeforeSave(); defineUserAfterDelete(); defineDepartmentTrigger(); defineTbookISBN(); defineTbookExportReport(app); }); app?.setTimeout&&app.setTimeout(1000*300) console.log("正在启动管理看板...") console.log("浏览器管理看板:","http://localhost:61337/dashboard") }catch(err){ console.error(err) } } // 启动服务端及数据库 initParseAndDatabase()