server.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // 数据库启动器
  2. const path = require("path")
  3. const fs = require("fs")
  4. const argv = require('yargs').argv
  5. // 全局配置加载
  6. // IMPORTANT:通过apps/<appId>/加载应用独立配置
  7. var appConfig
  8. try{
  9. appConfig = require(`./config.js`) // 默认加载包内config.js文件
  10. }catch{}
  11. if(!appConfig) appConfig = {}
  12. var userConfig
  13. /*********************
  14. * windows: process.env.PORTABLE_EXECUTABLE_DIR
  15. * linux: process.env.OWD
  16. */
  17. var OWN_DIR = process.env.PORTABLE_EXECUTABLE_DIR || process.env.OWD || process.cwd() || __dirname
  18. if (OWN_DIR) {
  19. let configPath = path.join(OWN_DIR, `config.js`)
  20. if (fs.existsSync(configPath)) {
  21. userConfig = require(configPath) // 用户独立配置config.js覆盖
  22. if (userConfig) {
  23. Object.keys(userConfig).forEach(key => {
  24. appConfig[key] = userConfig[key]
  25. })
  26. }
  27. }
  28. }
  29. global.config = global.config || {}
  30. console.log(appConfig)
  31. global.config['DATABASE_DBNAME'] = process.env["DATABASE_DBNAME"] || appConfig["DATABASE_DBNAME"] || false
  32. global.config['DATABASE_LOCAL'] = process.env["DATABASE_LOCAL"] || appConfig["DATABASE_LOCAL"] || false
  33. global.config['MCENTER_ENABLED'] = process.env["MCENTER_ENABLED"] || appConfig["MCENTER_ENABLED"] || false
  34. global.config['PARSE_SERVERURL'] = process.env["PARSE_SERVERURL"] || appConfig["PARSE_SERVERURL"] || false
  35. global.config['PARSE_APPID'] = process.env["PARSE_APPID"] || appConfig["PARSE_APPID"] || false
  36. global.config['PARSE_MASTERKEY'] = process.env["PARSE_MASTERKEY"] || appConfig["PARSE_MASTERKEY"] || false
  37. global.config['SEGMENT_COUNT'] = process.env["SEGMENT_COUNT"] || appConfig["SEGMENT_COUNT"] || false
  38. global.config["LOCAL"] = argv.local || process.env["LOCAL"] || appConfig["LOCAL"] || global.config['DATABASE_LOCAL'] || false
  39. global.config["PORT"] = argv.port || process.env["PORT"] || appConfig["PORT"] || global.config['PORT'] || 61337
  40. import {textbookRouter} from "./api/textbook/routes";
  41. import { defineAliOssSTS } from "./cloud/aliyun"
  42. import { defineAliSMSSend } from "./cloud/aliyun/func-aliyun-sms"
  43. import { defineAuthingLogin, defineDepartmentTrigger, defineUserAfterDelete, defineUserBeforeSave } from "./cloud/authing"
  44. import { defineAuthingDepartSync } from "./cloud/authing"
  45. import { defineUserAfterSave } from "./cloud/authing"
  46. import { defineTbookISBN } from "./cloud/tbook"
  47. import { defineTbookExportReport } from "./cloud/tbook/func-tbook-export"
  48. import { importData } from "./db/func/import-data"
  49. // 全局共享属性
  50. global.coolMap = {}
  51. global.minerMap = {}
  52. global.monitorMap = {}
  53. // Web服务启动器
  54. const express = require('express');
  55. const parse = require('parse-server')
  56. const Parse = require('parse/node')
  57. const ParseServer = parse.ParseServer;
  58. const ParseDashboard = require('parse-dashboard');
  59. // 同端口多进程集群
  60. let processCluster = require('cluster')
  61. let cpus = require('os').cpus()
  62. console.log(cpus.length)
  63. const app = express();
  64. const cors = require('cors');
  65. import { importAllSchemas } from "./db/func/import-schemas"
  66. import { PostgreSQLKeep } from "./lib/pg/index.js"
  67. app.use(cors({
  68. origin: '*'
  69. }));
  70. global.parseConfig = {
  71. port : global.config["PORT"],
  72. allowClientClassCreation: true,
  73. allowExpiredAuthDataToken: false,
  74. encodeParseObjectInCloudFunction: false,
  75. }
  76. global.parseConfig.serverURL = `http://localhost:${global.parseConfig?.port}/parse`
  77. global.parseConfig.databaseURI = global.config['DATABASE_DBNAME'];
  78. if(global.config['LOCAL']) {
  79. global.parseConfig.databaseURI = "postgresql://postgres@127.0.0.1:25432/"
  80. }
  81. global.parseConfig.appId = 'edu-textbook'
  82. global.parseConfig.appName = 'EduParse'
  83. global.parseConfig.masterKey = 'EDU2024'
  84. // global.parseConfig.cloud = './cloud/main.js'
  85. Parse.initialize(global.parseConfig.appId,null,global.parseConfig.masterKey);
  86. Parse.serverURL = global.parseConfig.serverURL;
  87. async function startParse(){
  88. if(global.config['LOCAL']) {
  89. console.log("PostgreSQLKeep")
  90. await PostgreSQLKeep({username:"postgres",password:"postgres",port:"25432",dbpath:"database/edudata"
  91. })
  92. // await PostgreSQLKeep(global.config['DATABASE_DBNAME'], "database/edudata/" )
  93. }
  94. // 挂载微服务
  95. console.log(global.parseConfig)
  96. const api = new ParseServer(global.parseConfig);
  97. await api.start();
  98. // Serve the Parse API at /parse URL prefix
  99. app.use('/parse', api.app);
  100. // 挂载管理看板
  101. const dashboard = new ParseDashboard({
  102. "apps": [
  103. global.parseConfig
  104. ]
  105. }, { allowInsecureHTTP: true });
  106. app.use('/dashboard', dashboard);
  107. }
  108. process.on('exit', async () => {
  109. // await stopDB()
  110. });
  111. process.on('SIGINT', async () => {
  112. /* DO SOME STUFF HERE */
  113. // await stopDB()
  114. process.exit()
  115. })
  116. // 在程序中捕获异常并进行处理
  117. process.on('uncaughtException', async (err) => {
  118. console.error('Uncaught Exception:', err);
  119. process.exit(1);
  120. });
  121. // 启动服务
  122. async function initParseAndDatabase(){
  123. try{
  124. // 仅导入脚本参数
  125. if(argv.import){
  126. console.log("importAllSchemas")
  127. await importAllSchemas()
  128. return
  129. }
  130. console.log("正在启动微服务...")
  131. await startParse();
  132. // console.log("parse:",parseConfig)
  133. console.log("正在启动api接口")
  134. // 加载textbook专属路由 通过代理操控局域网设备
  135. app.use("/api/textbook",textbookRouter)
  136. app.get("/",(req,res)=>{
  137. res.json({
  138. code:200,
  139. data:{message:"ok"}
  140. })
  141. })
  142. /**
  143. * Listen on provided port, on all network interfaces.
  144. */
  145. // console.log("setTimeout",app?.setTimeout)
  146. // app?.setTimeout&&app.setTimeout(1000*300)
  147. app.listen(global.parseConfig?.port, async function() {
  148. console.log('微服务已运行,端口 ' + global.parseConfig?.port + '.');
  149. // 迁移数据范式 Schemas
  150. await importAllSchemas();
  151. // 导入初始化数据
  152. setTimeout(() => {
  153. importData()
  154. }, 500);
  155. // 导入CloudCode
  156. defineAuthingLogin();
  157. defineAuthingDepartSync();
  158. defineAliOssSTS();
  159. defineAliSMSSend();
  160. defineUserAfterSave();
  161. defineUserBeforeSave();
  162. defineUserAfterDelete();
  163. defineDepartmentTrigger();
  164. defineTbookISBN();
  165. defineTbookExportReport(app);
  166. });
  167. console.log("正在启动管理看板...")
  168. console.log("浏览器管理看板:","http://localhost:61337/dashboard")
  169. }catch(err){
  170. console.error(err)
  171. }
  172. }
  173. // 启动服务端及数据库
  174. initParseAndDatabase()