瀏覽代碼

Merge branch 'main' into huahai_master

# Conflicts:
#	config.js
wanghao 1 天之前
父節點
當前提交
843256b230
共有 13 個文件被更改,包括 730 次插入353 次删除
  1. 1 0
      .dockerignore
  2. 65 0
      .env.default
  3. 3 0
      .gitignore
  4. 25 0
      Dockerfile
  5. 0 120
      config.default.js
  6. 1 1
      controller/pages.controller.js
  7. 1 1
      controller/projects.controller.js
  8. 13 0
      ecosystem.config.js
  9. 303 0
      init.sql
  10. 104 3
      main.js
  11. 1 1
      package.json
  12. 204 218
      pnpm-lock.yaml
  13. 9 9
      service/dashboard.service.js

+ 1 - 0
.dockerignore

@@ -0,0 +1 @@
+node_modules

+ 65 - 0
.env.default

@@ -0,0 +1,65 @@
+# MySQL数据库配置
+SERVER_HOST = http://localhost
+# Node服务器端口
+SERVER_PORT = 3001
+# 服务器IP地址
+DATABASE_HOST = 
+# 数据库端口
+DATABASE_PORT = 3306
+# 数据库用户名
+DATABASE_USER = root
+# 数据库密码
+DATABASE_PASSWORD = 
+# 数据库名称
+DATABASE_NAME = mars
+# 模型数据库名称
+MODEL_DATABASE_NAME = mars_model
+
+# 飞书应用配置,用来发送飞书消息(暂时可忽略)
+FEISHU_APP_ID = 
+FEISHU_APP_SECRET = 
+
+# JWT签名密钥和过期时间
+JWT_SECRET = marsview-1688
+JWT_EXPIRES_IN = 5d
+
+
+# 文件上传,OSS服务配置
+# OSS_TYPE: minio | baidu | aliyun
+OSS_TYPE = baidu
+# 只有minio需要
+OSS_PORT = 9000
+# 是否使用HTTPS
+OSS_USESSL = false
+# 阿里云OSS需要填写区域,如oss-cn-hangzhou
+OSS_REGION = oss-cn-guangzhou
+# 百度云OSS填写域名、minio填写IP地址
+OSS_ENDPOINT = https://bj.bcebos.com
+OSS_BUCKET = marscloud
+OSS_ACCESSKEY = 
+OSS_ACCESSKEYSECRET = 
+# CDN域名,若没有,可填空
+OSS_CDNDOMAIN = https://marscloud.cdn.bcebos.com
+
+# 邮箱服务配置
+EMAIL_HOST = smtp.163.com
+EMAIL_PORT = 465
+EMAIL_USER = marsview@163.com
+EMAIL_PASSWORD = M***************6
+
+# 微信登录配置,没有可默认为空
+WECHAT_APP_ID = 
+WECHAT_APP_SECRET = 
+
+# 大模型配置
+AI_BASE_URL = https://c-z0-api-01.hash070.com/v1
+AI_KEY = sk-
+EMBEDDING = 
+MODEL = gpt-4.1-mini
+DATABASE_URL = 
+
+# 模型服务调用地址
+MODEL_BASE_URL = http://api-model.marsview.com.cn
+# 启用后端模型服务,此服务需付费使用(未付费开启会导致页面创建报错)
+ENABLE_MODEL_SERVICE = true
+

+ 3 - 0
.gitignore

@@ -13,3 +13,6 @@ packages/**/*/node_modules
 /dist
 /deploy.js
 /config.js
+/.idea
+
+.env

+ 25 - 0
Dockerfile

@@ -0,0 +1,25 @@
+FROM registry.cn-hangzhou.aliyuncs.com/dbfu/pnpm:8.4.0 as builder
+
+WORKDIR /app
+
+COPY pnpm-lock.yaml .
+COPY package.json .
+COPY .npmrc .
+
+RUN --mount=type=cache,target=/root/.pnpm-store \
+    pnpm config set store-dir /root/.pnpm-store && \
+    pnpm config set node-linker=isolated && \
+    pnpm install --production
+
+COPY . .
+
+FROM registry.cn-hangzhou.aliyuncs.com/dbfu/pm2:latest
+
+WORKDIR /app
+
+
+COPY --from=builder /app/ ./
+ENV TZ="Asia/Shanghai"
+
+EXPOSE 3001
+CMD ["pm2-runtime", "start", "ecosystem.config.js"]

+ 0 - 120
config.default.js

@@ -1,120 +0,0 @@
-/**
- * 重要::请根据此配置,创建一份 config.js 并修改其配置,系统默认只加载 config.js
- */
-
-/**
- * MySQL数据库配置
- */
-const SERVER_HOST = 'http://localhost';
-// Node服务器端口
-const SERVER_PORT = 3001;
-// 服务器IP地址
-const DATABASE_HOST = '';
-// 数据库端口
-const DATABASE_PORT = 3306;
-// 数据库用户名
-const DATABASE_USER = 'root';
-// 数据库密码
-const DATABASE_PASSWORD = '';
-// 数据库名称
-const DATABASE_NAME = 'marsview';
-
-/**
- * 飞书应用配置,用来发送飞书消息
- */
-const FEISHU_APP_ID = '';
-const FEISHU_APP_SECRET = '';
-
-/**
- * JWT签名密钥和过期时间
- */
-const JWT_SECRET = 'marsview_jwt_secret';
-const JWT_EXPIRES_IN = '5d';
-
-/**
- * 文件上传OSS配置
- * OSS_TYPE: minio | baidu | aliyun
- */
-// OSS服务类型
-const OSS_TYPE = 'baidu';
-//只有minio需要
-const OSS_PORT = 9000;
-// 是否使用HTTPS
-const OSS_USESSL = false;
-// 阿里云OSS需要填写区域,如oss-cn-hangzhou
-const OSS_REGION = 'oss-cn-guangzhou';
-// 百度云OSS填写域名、minio填写IP地址
-const OSS_ENDPOINT = '';
-const OSS_BUCKET = 'marsview';
-const OSS_ACCESSKEY = '';
-const OSS_ACCESSKEYSECRET = '';
-// CDN域名
-const OSS_CDNDOMAIN = 'https://marscloud.cdn.bcebos.com';
-
-/**
- * 邮箱服务配置
- */
-const EMAIL_HOST = 'smtp.163.com';
-const EMAIL_PORT = 465;
-const EMAIL_USER = '';
-const EMAIL_PASSWORD = '';
-
-/**
- * 微信登录配置,没有可默认为空
- */
-const WECHAT_APP_ID = '';
-const WECHAT_APP_SECRET = '';
-
-/**
- * 大模型配置
- */
-const AI_BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
-const AI_KEY = '';
-const EMBEDDING = 'text-embedding-v3';
-const MODEL = 'qwen-plus';
-const DATABASE_URL = 'postgresql://';
-
-/**
- * 模型配置
- * 此服务需付费使用(未付费开启会导致页面和项目创建报错)
- */
-// 模型服务调用地址
-const MODEL_BASE_URL = 'http://api-model.marsview.com.cn';
-// 启用后端模型服务,
-const ENABLE_MODEL_SERVICE = true;
-
-module.exports = {
-  SERVER_HOST,
-  SERVER_PORT,
-  DATABASE_HOST,
-  DATABASE_PORT,
-  DATABASE_USER,
-  DATABASE_PASSWORD,
-  DATABASE_NAME,
-  FEISHU_APP_ID,
-  FEISHU_APP_SECRET,
-  JWT_SECRET,
-  JWT_EXPIRES_IN,
-  OSS_TYPE,
-  OSS_REGION,
-  OSS_ENDPOINT,
-  OSS_PORT,
-  OSS_USESSL,
-  OSS_BUCKET,
-  OSS_ACCESSKEY,
-  OSS_ACCESSKEYSECRET,
-  OSS_CDNDOMAIN,
-  EMAIL_HOST,
-  EMAIL_PORT,
-  EMAIL_USER,
-  EMAIL_PASSWORD,
-  WECHAT_APP_ID,
-  WECHAT_APP_SECRET,
-  AI_BASE_URL,
-  AI_KEY,
-  EMBEDDING,
-  MODEL,
-  DATABASE_URL,
-  MODEL_BASE_URL,
-  ENABLE_MODEL_SERVICE,
-};

+ 1 - 1
controller/pages.controller.js

@@ -151,7 +151,7 @@ module.exports = {
         return ctx.throw(400, '模板不存在', 404);
       }
       // 开启模型服务后,需要复制模型
-      if (ENABLE_MODEL_SERVICE) {
+      if (ENABLE_MODEL_SERVICE === 'true') {
         // 获取项目模型列表
         const res = await request.post(
           `${MODEL_BASE_URL}/api/model/model/copy`,

+ 1 - 1
controller/projects.controller.js

@@ -79,7 +79,7 @@ module.exports = {
       });
       let dictMap = {};
       // 开启模型服务后,需要复制模型
-      if (ENABLE_MODEL_SERVICE) {
+      if (ENABLE_MODEL_SERVICE === 'true') {
         // 获取项目模型列表
         const res = await request
           .post(

+ 13 - 0
ecosystem.config.js

@@ -0,0 +1,13 @@
+module.exports = {
+  apps: [
+    {
+      name: 'editor',
+      script: './main.js',
+      instances: '1',
+      exec_mode: 'cluster',
+      env: {
+        NODE_ENV: 'production',
+      },
+    },
+  ],
+};

+ 303 - 0
init.sql

@@ -0,0 +1,303 @@
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = firefly   */
+/******************************************/
+CREATE TABLE `firefly` (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '增长ID',
+  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '名称',
+  `type` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '种类',
+  `avatar` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '头像',
+  `time` smallint NOT NULL COMMENT '繁殖周期',
+  `skill` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '技能',
+  `sales` float NOT NULL COMMENT '售价',
+  `area` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '分布区域',
+  `status` tinyint(1) NOT NULL COMMENT '状态:1 在售 2 停售 3 下架',
+  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间戳',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='数据测试表'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = imgcloud   */
+/******************************************/
+CREATE TABLE `imgcloud` (
+  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+  `user_id` int NOT NULL COMMENT '用户ID',
+  `user_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
+  `origin_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '文件原名称',
+  `file_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '文件hash名称',
+  `type` varchar(30) NOT NULL COMMENT '文件类型',
+  `size` int NOT NULL COMMENT '文件大小,单位byte',
+  `url` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '图片cdn地址',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_user_id` (`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='图片云服务'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = lib   */
+/******************************************/
+CREATE TABLE `lib` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '组件ID',
+  `tag` varchar(50) NOT NULL COMMENT '组件标识',
+  `name` varchar(50) NOT NULL COMMENT '组件中文名称',
+  `description` varchar(200) DEFAULT NULL COMMENT '组件描述',
+  `react_code` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '组件源码',
+  `less_code` text COMMENT '组件样式',
+  `config_code` text COMMENT '组件配置',
+  `md_code` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT 'markdown内容',
+  `hash` varchar(100) DEFAULT NULL COMMENT '组件hash',
+  `user_id` int NOT NULL COMMENT '通行证ID',
+  `user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '通行证名称',
+  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
+  PRIMARY KEY (`id`),
+  KEY `ix_user_id` (`user_id`),
+  KEY `ix_name` (`name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='自定义组件库表,用来满足自定义业务'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = lib_publish   */
+/******************************************/
+CREATE TABLE `lib_publish` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '索引',
+  `release_id` varchar(100) NOT NULL COMMENT '发布ID',
+  `lib_id` varchar(100) NOT NULL COMMENT '组件库关联ID',
+  `react_url` varchar(100) NOT NULL COMMENT 'React远程地址',
+  `css_url` varchar(100) DEFAULT NULL COMMENT 'css远程地址',
+  `config_url` varchar(100) DEFAULT NULL COMMENT 'config远程地址',
+  `release_hash` varchar(50) DEFAULT NULL COMMENT '版本hash',
+  `user_id` int NOT NULL COMMENT '通行证ID',
+  `user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '通行证名称',
+  `count` int NOT NULL DEFAULT '0' COMMENT '记录更新次数',
+  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
+  PRIMARY KEY (`id`),
+  KEY `ix_release_id` (`release_id`),
+  KEY `ix_lib_id` (`lib_id`),
+  KEY `ix_updated_at` (`updated_at`),
+  KEY `ix_created_at` (`created_at`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='组件库发布表'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = menu   */
+/******************************************/
+CREATE TABLE `menu` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '菜单ID',
+  `project_id` bigint NOT NULL COMMENT '项目ID',
+  `name` varchar(20) NOT NULL COMMENT '菜单名称',
+  `parent_id` bigint DEFAULT NULL COMMENT '父级菜单ID',
+  `type` int NOT NULL COMMENT '方法 1-菜单 2-按钮 3-页面 4-外链',
+  `icon` varchar(100) DEFAULT NULL COMMENT '菜单图标',
+  `path` varchar(100) DEFAULT NULL COMMENT '路径',
+  `page_id` bigint DEFAULT NULL COMMENT '页面ID',
+  `sort_num` int NOT NULL COMMENT '排序',
+  `status` int NOT NULL DEFAULT '1' COMMENT '状态 1-启用 0-禁用',
+  `code` varchar(30) DEFAULT NULL COMMENT '按钮标识',
+  `user_id` int NOT NULL COMMENT '通行证id',
+  `user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
+  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_project_id` (`project_id`),
+  KEY `idx_user_id` (`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='菜单列表'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = pages   */
+/******************************************/
+CREATE TABLE `pages` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '项目ID',
+  `name` varchar(20) NOT NULL COMMENT '项目名称',
+  `user_id` int NOT NULL COMMENT '用户ID',
+  `user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
+  `page_data` longtext CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '页面数据',
+  `remark` varchar(80) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '页面描述',
+  `is_template` tinyint(1) DEFAULT '0' COMMENT '是否为模板 1-是 0-否',
+  `is_public` tinyint(1) DEFAULT '2' COMMENT '是否开放 1-公开 2-私有',
+  `is_edit` tinyint(1) DEFAULT '2' COMMENT '是否可编辑 1-编辑 2-只读',
+  `preview_img` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '页面预览图',
+  `stg_publish_id` bigint NOT NULL DEFAULT '0' COMMENT 'stg 页面发布ID',
+  `pre_publish_id` bigint NOT NULL DEFAULT '0' COMMENT 'pre 页面发布ID',
+  `prd_publish_id` bigint NOT NULL DEFAULT '0' COMMENT 'prd 页面发布ID',
+  `stg_state` tinyint(1) NOT NULL DEFAULT '1' COMMENT '发布状态:1未保存 2已保存 3已发布',
+  `pre_state` tinyint(1) NOT NULL DEFAULT '1' COMMENT '发布状态:1未保存 2已保存 3已发布',
+  `prd_state` tinyint(1) NOT NULL DEFAULT '1' COMMENT '发布状态:1未保存 2已保存 3已发布',
+  `project_id` int DEFAULT '0' COMMENT '所属项目ID',
+  `app_type` int(1) NULL DEFAULT 1 COMMENT '应用类型',
+  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_user_id` (`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 AVG_ROW_LENGTH=11371 COMMENT='项目列表'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = pages_publish   */
+/******************************************/
+CREATE TABLE `pages_publish` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '页面发布ID',
+  `page_id` bigint NOT NULL COMMENT '页面ID',
+  `page_name` varchar(20) NOT NULL COMMENT '页面名称',
+  `page_data` longtext COMMENT '页面数据',
+  `user_id` int NOT NULL COMMENT '通行证id',
+  `user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
+  `version` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '版本号',
+  `env` enum('stg','pre','prd') NOT NULL DEFAULT 'stg' COMMENT '状态:stg、pre、 prd',
+  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  KEY `ix_updated_at` (`updated_at`),
+  KEY `ix_created_at` (`created_at`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='页面发布列表'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = pages_role   */
+/******************************************/
+CREATE TABLE `pages_role` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `page_id` bigint NOT NULL COMMENT '页面ID',
+  `role` bigint DEFAULT NULL COMMENT '角色权限 1-developer 2-visitor',
+  `type` int NOT NULL DEFAULT '1' COMMENT '项目类型 1-项目 2-页面',
+  `user_id` int NOT NULL COMMENT '用户id',
+  `user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
+  `created_uid` int DEFAULT NULL COMMENT '创建用户ID',
+  `created_uname` varchar(30) DEFAULT '' COMMENT '创建用户名称',
+  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  KEY `ix_updated_at` (`updated_at`),
+  KEY `ix_created_at` (`created_at`),
+  KEY `ix_page_id` (`page_id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='页面权限列表'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = project_user   */
+/******************************************/
+CREATE TABLE `project_user` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `system_role` int NOT NULL DEFAULT '1' COMMENT '系统角色:1:管理员 2:普通用户',
+  `project_id` bigint NOT NULL DEFAULT '0' COMMENT '项目ID',
+  `role_id` int NOT NULL DEFAULT '0' COMMENT '项目角色ID',
+  `user_id` int NOT NULL COMMENT '通行证id',
+  `user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
+  `created_uid` int DEFAULT NULL COMMENT '创建用户ID',
+  `created_uname` varchar(30) DEFAULT '' COMMENT '创建用户名',
+  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_user_id` (`user_id`),
+  KEY `idx_project_id` (`project_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 AVG_ROW_LENGTH=4096 COMMENT='用户列表'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = projects   */
+/******************************************/
+CREATE TABLE `projects` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '项目ID',
+  `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '项目名称',
+  `remark` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '项目描述',
+  `logo` varchar(100) NOT NULL COMMENT 'logo 地址',
+  `user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名称',
+  `user_id` int NOT NULL COMMENT '用户ID',
+  `is_template` tinyint(1) DEFAULT '0' COMMENT '是否为模板 1-是 0-否',
+  `is_public` tinyint(1) DEFAULT '2' COMMENT '是否开放 1-公开 2-私有',
+  `breadcrumb` tinyint(1) DEFAULT '1' COMMENT '面包屑 1-有 0 无',
+  `layout` tinyint(1) DEFAULT '1' COMMENT '布局 1-上下 2-左右 3-上中下',
+  `menu_mode` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'inline' COMMENT '菜单模式:inline-内嵌 vertical-垂直  horizontal-水平',
+  `menu_theme_color` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'dark' COMMENT '菜单主题色:dark 深色 light-浅色 支持16进制',
+  `tag` tinyint(1) DEFAULT '1' COMMENT '多页签 1-显示 0-不显示',
+  `footer` tinyint(1) DEFAULT '0' COMMENT '页脚 1-显示 0-不显示',
+  `system_theme_color` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '#1677ff' COMMENT '系统主题色',
+  `show_header` tinyint(1) DEFAULT '1' COMMENT '显示Header组件',
+  `show_tab_bar` tinyint(1) DEFAULT '0' COMMENT '显示标签栏',
+  `home_page` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT 'welcome' COMMENT '首页定制页面ID',
+  `extra_data` text COMMENT '项目额外数据',
+  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_user_id` (`user_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=5968 DEFAULT CHARSET=utf8mb3 AVG_ROW_LENGTH=2048 COMMENT='项目列表'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = roles   */
+/******************************************/
+CREATE TABLE `roles` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `project_id` bigint DEFAULT NULL COMMENT '项目ID',
+  `name` varchar(20) NOT NULL DEFAULT '' COMMENT '角色名称',
+  `half_checked` varchar(4000) DEFAULT NULL COMMENT '全选的菜单ID',
+  `checked` varchar(4000) DEFAULT NULL COMMENT '半全选的菜单ID',
+  `remark` varchar(50) DEFAULT '' COMMENT '角色备注',
+  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `user_id` int NOT NULL COMMENT '通行证id',
+  `user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
+  PRIMARY KEY (`id`),
+  KEY `ix_updated_at` (`updated_at`) USING BTREE,
+  KEY `ix_created_at` (`created_at`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 AVG_ROW_LENGTH=4096 COMMENT='页面权限列表'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = templates   */
+/******************************************/
+CREATE TABLE `templates` (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `union_id` int NOT NULL COMMENT '关联ID',
+  `type` tinyint(1) NOT NULL COMMENT '1: 项目 2:页面 3:组件',
+  `name` varchar(100) NOT NULL COMMENT '模板名称',
+  `description` varchar(100) NOT NULL COMMENT '模板描述',
+  `user_id` int NOT NULL COMMENT '创建人ID',
+  `user_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '创建人名称',
+  `install_count` int NOT NULL DEFAULT '0' COMMENT '安装次数',
+  `image_url` varchar(100) DEFAULT NULL COMMENT '封面图片',
+  `tags` varchar(200) DEFAULT NULL COMMENT '模板标签',
+  `is_recommend` tinyint(1) DEFAULT '0' COMMENT '1:推荐 0:不推荐',
+  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='项目、页面和组件库模板'
+;
+
+/******************************************/
+/*   DatabaseName = mars_async   */
+/*   TableName = users   */
+/******************************************/
+CREATE TABLE `users` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '昵称',
+  `user_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户邮箱',
+  `user_pwd` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
+  `open_id` varchar(30) DEFAULT NULL COMMENT '微信openid',
+  `union_id` varchar(30) DEFAULT NULL COMMENT '微信unionid',
+  `phone_number` int DEFAULT NULL COMMENT '手机号',
+  `avatar` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '用户头像',
+  `team_id` int DEFAULT '1' COMMENT '团队ID',
+  `parent_id` int DEFAULT NULL COMMENT '主账号id',
+  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `created_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  KEY `idx_user_name` (`user_name`)
+) ENGINE=InnoDB AUTO_INCREMENT=4647 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci AVG_ROW_LENGTH=4096 ROW_FORMAT=DYNAMIC COMMENT='用户列表'
+;

+ 104 - 3
main.js

@@ -1,6 +1,107 @@
+require('dotenv').config();
 const app = require('./app');
 const { SERVER_HOST, SERVER_PORT } = require('./config');
+const mysql2 = require('mysql2/promise');
+const config = require('./config');
+const fs = require('fs');
+const md5 = require('md5.js');
 
-app.listen(SERVER_PORT, () => {
-  console.log(`Marsview服务已启动 ${SERVER_HOST}:${SERVER_PORT}`);
-});
+async function initDatabase() {
+  const dbName = config.DATABASE_NAME;
+
+  async function connectDB() {
+    try {
+      const connection = await mysql2.createConnection({
+        host: config.DATABASE_HOST,
+        port: config.DATABASE_PORT,
+        user: config.DATABASE_USER,
+        password: config.DATABASE_PASSWORD,
+        multipleStatements: true,
+      });
+
+      await connection.connect();
+
+      return connection;
+    } catch (error) {
+      console.log(error);
+      process.exit(1);
+    }
+  }
+
+  const connection = await connectDB();
+
+  async function createUserIfNotExists() {
+    await connection.query(`USE \`${dbName}\`;`);
+    try {
+      const [userRows] = await connection.query('SELECT * FROM `users`;');
+
+      if (userRows.length === 0) {
+        const userName = config.USERNAME || 'admin@marsview.com';
+        const userPassword = config.PASSWORD || 'admin';
+        const pwd = new md5().update(userPassword).digest('hex');
+        console.log(`用户 ${userName} 不存在,正在创建...`);
+        await connection.query(
+          `INSERT INTO \`users\` (\`nick_name\`, \`user_name\`, \`user_pwd\`, \`avatar\`) VALUES ('admin', '${userName}', '${pwd}', '');`,
+        );
+        console.log(`用户 ${userName} 创建成功。`);
+      } else {
+        console.log(`用户表已存在数据,跳过创建用户。`);
+      }
+    } catch (error) {
+      console.error(`创建用户失败: ${error.message}`);
+    }
+  }
+
+  // 检查数据库是否存在,如果不存在则创建
+  async function createDatabaseIfNotExists() {
+    let [rows] = await connection.query('SHOW DATABASES LIKE ?', [dbName]);
+    if (rows.length === 0) {
+      console.log('数据库不存在,自动创建中...');
+      await connection.query(`CREATE DATABASE \`${dbName}\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;`);
+      console.log(`创建数据库 ${dbName} 成功`);
+      // 选择当前数据库
+      await connection.query(`USE \`${dbName}\`;`);
+      // 读取并执行初始化SQL脚本
+      console.log('正在执行初始化SQL脚本...');
+      const initSql = fs.readFileSync('./init.sql', 'utf8');
+      await connection.query(initSql);
+      console.log(`${dbName} 表初始化成功`);
+    } else {
+      console.log(`数据库已经存在,跳过创建。`);
+    }
+
+    [rows] = await connection.query('SHOW DATABASES LIKE ?', [config.MODEL_DATABASE_NAME]);
+
+    if (rows.length === 0) {
+      console.log(`创建数据库 ${config.MODEL_DATABASE_NAME}`);
+      const statement = `CREATE DATABASE IF NOT EXISTS ${config.MODEL_DATABASE_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;`;
+      await connection.query(statement);
+      console.log(`创建数据库 ${config.MODEL_DATABASE_NAME} 成功`);
+    } else {
+      console.log(`数据库 ${config.MODEL_DATABASE_NAME} 已经存在, 跳过创建。`);
+    }
+
+    // 判断有没有用户,如果没有,再创建
+    await createUserIfNotExists();
+  }
+
+  try {
+    await createDatabaseIfNotExists();
+  } catch (err) {
+    console.error(`初始化数据库失败: ${err.message}`);
+  } finally {
+    await connection.end();
+  }
+}
+async function main() {
+  try {
+    await initDatabase();
+    app.listen(SERVER_PORT, () => {
+      console.log(`Marsview服务已启动 ${SERVER_HOST}:${SERVER_PORT}`);
+    });
+  } catch {
+    process.exit(1);
+  }
+}
+
+main();

+ 1 - 1
package.json

@@ -20,6 +20,7 @@
     "ali-oss": "^6.22.0",
     "axios": "^1.6.3",
     "cookie": "^0.6.0",
+    "dotenv": "^17.0.0",
     "drizzle-orm": "^0.31.2",
     "events": "^3.3.0",
     "jsonwebtoken": "^9.0.2",
@@ -48,7 +49,6 @@
     "zod": "^3.23.8"
   },
   "devDependencies": {
-    "dotenv": "^16.4.7",
     "eslint": "^8.56.0",
     "prettier": "^3.5.3"
   }

文件差異過大導致無法顯示
+ 204 - 218
pnpm-lock.yaml


+ 9 - 9
service/dashboard.service.js

@@ -8,14 +8,14 @@ class DashboardService {
   }
   // 获取今天注册用户量
   async getTotalUsersByToday() {
-    const date = new Date().toLocaleDateString();
+    const date = new Date().toISOString().split('T')[0];
     const statement = `SELECT  count(id) as total FROM users WHERE created_at > '${date} 00:00:00'`;
     const [result] = await connection.execute(statement, []);
     return result[0];
   }
   // 获取今天登录用户量
   async getLoginUsersByToday() {
-    const date = new Date().toLocaleDateString();
+    const date = new Date().toISOString().split('T')[0];
     const statement = `SELECT  count(id) as total FROM users WHERE updated_at > '${date} 00:00:00'`;
     const [result] = await connection.execute(statement, []);
     return result[0];
@@ -28,14 +28,14 @@ class DashboardService {
   }
   // 今天创建项目总数
   async getTotalCreatedByToday() {
-    const date = new Date().toLocaleDateString();
+    const date = new Date().toISOString().split('T')[0];
     const statement = `SELECT  count(id) as total FROM projects WHERE created_at > '${date} 00:00:00'`;
     const [result] = await connection.execute(statement, []);
     return result[0];
   }
   // 今天更新项目总数
   async getTotalUpdatesByToday() {
-    const date = new Date().toLocaleDateString();
+    const date = new Date().toISOString().split('T')[0];
     const statement = `SELECT  count(id) as total FROM projects WHERE updated_at > '${date} 00:00:00'`;
     const [result] = await connection.execute(statement, []);
     return result[0];
@@ -48,14 +48,14 @@ class DashboardService {
   }
   // 获取页面今日创建数量
   async getCreatedPagesByToday() {
-    const date = new Date().toLocaleDateString();
+    const date = new Date().toISOString().split('T')[0];
     const statement = `SELECT  count(id) as total FROM pages WHERE created_at > '${date} 00:00:00'`;
     const [result] = await connection.execute(statement, []);
     return result[0];
   }
   // 获取页面今日更新数量
   async getUpdatedPagesByToday() {
-    const date = new Date().toLocaleDateString();
+    const date = new Date().toISOString().split('T')[0];
     const statement = `SELECT  count(id) as total FROM pages WHERE updated_at > '${date} 00:00:00'`;
     const [result] = await connection.execute(statement, []);
     return result[0];
@@ -68,14 +68,14 @@ class DashboardService {
   }
   // 获取组件今日创建数量
   async getCreatedLibsByToday() {
-    const date = new Date().toLocaleDateString();
+    const date = new Date().toISOString().split('T')[0];
     const statement = `SELECT  count(id) as total FROM lib WHERE created_at > '${date} 00:00:00'`;
     const [result] = await connection.execute(statement, []);
     return result[0];
   }
   // 获取组件今日更新数量
   async getUpdatedLibsByToday() {
-    const date = new Date().toLocaleDateString();
+    const date = new Date().toISOString().split('T')[0];
     const statement = `SELECT  count(id) as total FROM lib WHERE updated_at > '${date} 00:00:00'`;
     const [result] = await connection.execute(statement, []);
     return result[0];
@@ -139,7 +139,7 @@ class DashboardService {
   }
   // 获取今日充值总额
   async getTotalRechargeByToday() {
-    const date = new Date().toLocaleDateString();
+    const date = new Date().toISOString().split('T')[0];
     const statement = `SELECT  sum(amount) as total FROM pay_records WHERE created_at > '${date} 00:00:00'`;
     const [result] = await connection.execute(statement, []);
     return result[0];

部分文件因文件數量過多而無法顯示